You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

kimera.c 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. Copyright 2014 Kai Ryu <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #define KIMERA_C
  15. #include <stdbool.h>
  16. #include <avr/eeprom.h>
  17. #include "kimera.h"
  18. uint8_t mux_mapping[MUX_COUNT] = {
  19. MUX_FOR_ROW, MUX_FOR_COL, MUX_FOR_COL, MUX_FOR_COL
  20. };
  21. uint8_t row_mapping[MATRIX_ROWS] = {
  22. 0, 1, 2, 3, 4, 5, 6, 7,
  23. UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED,
  24. UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED
  25. };
  26. uint8_t col_mapping[MATRIX_COLS] = {
  27. 8, 9, 10, 11, 12, 13, 14, 15,
  28. 16, 17, 18, 19, 20, 21, 22, 23,
  29. 24, 25, 26, 27, 28, 29, 30, 31
  30. };
  31. uint8_t row_max_count = MUX_PORTS * 1;
  32. uint8_t col_max_count = MUX_PORTS * (MUX_COUNT - 1);
  33. uint16_t shift_out_cache = 0;
  34. void kimera_init(void)
  35. {
  36. // read config
  37. if (read_matrix_mapping()) {
  38. write_matrix_mapping();
  39. }
  40. // init shift out pins
  41. MOSI_DDR |= (1<<MOSI_BIT);
  42. SCK_DDR |= (1<<SCK_BIT);
  43. RCK_DDR |= (1<<RCK_BIT);
  44. RCK_PORT |= (1<<RCK_BIT);
  45. // init spi
  46. SPCR |= ((1<<SPE) | (1<<MSTR));
  47. SPSR |= ((1<<SPI2X));
  48. }
  49. uint8_t read_matrix_mapping(void)
  50. {
  51. uint8_t error = 0;
  52. uint8_t mux_config = 0;
  53. row_max_count = 0;
  54. col_max_count = 0;
  55. mux_config = eeprom_read_byte(EECONFIG_MUX_MAPPING);
  56. if (mux_config & (1<<7)) {
  57. error++;
  58. return error;
  59. }
  60. for (uint8_t i = 0; i < MUX_COUNT; i++) {
  61. mux_mapping[i] = mux_config & (1<<i);
  62. if (mux_mapping[i] == MUX_FOR_COL) {
  63. col_max_count += MUX_PORTS;
  64. }
  65. else {
  66. row_max_count += MUX_PORTS;
  67. }
  68. }
  69. if ((col_max_count == 0) || (row_max_count == 0)) {
  70. error++;
  71. }
  72. uint8_t *mapping = EECONFIG_ROW_COL_MAPPING;
  73. for (uint8_t i = 0; i < row_max_count; i++) {
  74. row_mapping[i] = eeprom_read_byte(mapping++);
  75. if (row_mapping[i] != UNCONFIGURED) {
  76. if (mux_mapping[PX_TO_MUX(row_mapping[i])] != MUX_FOR_ROW) {
  77. row_mapping[i] = UNCONFIGURED;
  78. error++;
  79. }
  80. }
  81. }
  82. for (uint8_t i = 0; i < col_max_count; i++) {
  83. col_mapping[i] = eeprom_read_byte(mapping++);
  84. if (col_mapping[i] != UNCONFIGURED) {
  85. if (mux_mapping[PX_TO_MUX(col_mapping[i])] != MUX_FOR_COL) {
  86. col_mapping[i] = UNCONFIGURED;
  87. error++;
  88. }
  89. }
  90. }
  91. return error;
  92. }
  93. void write_matrix_mapping(void)
  94. {
  95. uint8_t mux_config = 0;
  96. row_max_count = 0;
  97. col_max_count = 0;
  98. for (uint8_t i = 0; i < MUX_COUNT; i++) {
  99. mux_config |= (mux_mapping[i] << i);
  100. if (mux_mapping[i] == MUX_FOR_COL) {
  101. col_max_count += MUX_PORTS;
  102. }
  103. else {
  104. row_max_count += MUX_PORTS;
  105. }
  106. }
  107. eeprom_write_byte(EECONFIG_MUX_MAPPING, mux_config);
  108. uint8_t *mapping = EECONFIG_ROW_COL_MAPPING;
  109. for (uint8_t i = 0; i < row_max_count; i++) {
  110. eeprom_write_byte(mapping++, row_mapping[i]);
  111. }
  112. for (uint8_t i = 0; i < col_max_count; i++) {
  113. eeprom_write_byte(mapping++, col_mapping[i]);
  114. }
  115. }
  116. void shift_out_word(uint16_t data)
  117. {
  118. SPDR = (data & 0xFF);
  119. while (!(SPSR & (1<<SPIF)));
  120. SPDR = ((data>>8) & 0xFF);
  121. while (!(SPSR & (1<<SPIF)));
  122. RCK_PORT &= ~(1<<RCK_BIT);
  123. RCK_PORT |= (1<<RCK_BIT);
  124. }
  125. void init_cols(void)
  126. {
  127. // init mux io pins
  128. for (uint8_t i = 0; i < MUX_COUNT; i++) {
  129. if (mux_mapping[i] == MUX_FOR_COL) {
  130. ZX_DDR &= ~(1 << zx_bit[i]);
  131. ZX_PORT |= (1 << zx_bit[i]);
  132. }
  133. else {
  134. ZX_DDR |= (1 << zx_bit[i]);
  135. ZX_PORT |= (1 << zx_bit[i]);
  136. }
  137. }
  138. }
  139. matrix_row_t read_cols(void)
  140. {
  141. matrix_row_t cols = 0;
  142. for (uint8_t i = 0; i < MATRIX_COLS; i++) {
  143. uint8_t px = col_mapping[i];
  144. if (px != UNCONFIGURED) {
  145. shift_out_word(shift_out_cache | px_to_shift_out[px]);
  146. // TODO: delay
  147. if (!(ZX_PIN & (1 << zx_bit[PX_TO_MUX(px)]))) {
  148. cols |= (1 << i);
  149. }
  150. }
  151. }
  152. return cols;
  153. }
  154. void unselect_rows(void)
  155. {
  156. shift_out_word(0);
  157. }
  158. void select_row(uint8_t row)
  159. {
  160. uint8_t px = row_mapping[row];
  161. if (px != UNCONFIGURED) {
  162. ZX_PORT &= ~(1 << zx_bit[PX_TO_MUX(px)]);
  163. shift_out_cache = px_to_shift_out[px] | mux_inh_to_shift_out[PX_TO_MUX(px)];
  164. shift_out_word(shift_out_cache);
  165. }
  166. }