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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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. uint16_t shift_out_cache = 0;
  32. void kimera_init(void)
  33. {
  34. // read config
  35. if (read_matrix_mapping()) {
  36. write_matrix_mapping();
  37. }
  38. // init shift out pins
  39. MOSI_DDR |= (1<<MOSI_BIT);
  40. SCK_DDR |= (1<<SCK_BIT);
  41. RCK_DDR |= (1<<RCK_BIT);
  42. RCK_PORT |= (1<<RCK_BIT);
  43. // init spi
  44. SPCR |= ((1<<SPE) | (1<<MSTR));
  45. SPSR |= ((1<<SPI2X));
  46. }
  47. uint8_t read_matrix_mapping(void)
  48. {
  49. uint8_t error = 0;
  50. uint8_t mux_config = 0;
  51. uint8_t row_max_count = 0;
  52. uint8_t col_max_count = 0;
  53. mux_config = eeprom_read_byte(EECONFIG_MUX_MAPPING);
  54. if (mux_config & (1<<7)) {
  55. error++;
  56. return error;
  57. }
  58. for (uint8_t i = 0; i < MUX_COUNT; i++) {
  59. mux_mapping[i] = mux_config & (1<<i);
  60. if (mux_mapping[i] == MUX_FOR_COL) {
  61. col_max_count += MUX_PORTS;
  62. }
  63. else {
  64. row_max_count += MUX_PORTS;
  65. }
  66. }
  67. if ((col_max_count == 0) || (row_max_count == 0)) {
  68. error++;
  69. }
  70. uint8_t *mapping = EECONFIG_ROW_COL_MAPPING;
  71. for (uint8_t i = 0; i < row_max_count; i++) {
  72. row_mapping[i] = eeprom_read_byte(mapping++);
  73. if (row_mapping[i] != UNCONFIGURED) {
  74. if (mux_mapping[PX_TO_MUX(row_mapping[i])] != MUX_FOR_ROW) {
  75. row_mapping[i] = UNCONFIGURED;
  76. error++;
  77. }
  78. }
  79. }
  80. for (uint8_t i = 0; i < col_max_count; i++) {
  81. col_mapping[i] = eeprom_read_byte(mapping++);
  82. if (col_mapping[i] != UNCONFIGURED) {
  83. if (mux_mapping[PX_TO_MUX(col_mapping[i])] != MUX_FOR_COL) {
  84. col_mapping[i] = UNCONFIGURED;
  85. error++;
  86. }
  87. }
  88. }
  89. return error;
  90. }
  91. void write_matrix_mapping(void)
  92. {
  93. uint8_t mux_config = 0;
  94. uint8_t row_max_count = 0;
  95. uint8_t col_max_count = 0;
  96. for (uint8_t i = 0; i < MUX_COUNT; i++) {
  97. mux_config |= (mux_mapping[i] << i);
  98. if (mux_mapping[i] == MUX_FOR_COL) {
  99. col_max_count += MUX_PORTS;
  100. }
  101. else {
  102. row_max_count += MUX_PORTS;
  103. }
  104. }
  105. eeprom_write_byte(EECONFIG_MUX_MAPPING, mux_config);
  106. uint8_t *mapping = EECONFIG_ROW_COL_MAPPING;
  107. for (uint8_t i = 0; i < row_max_count; i++) {
  108. eeprom_write_byte(mapping++, row_mapping[i]);
  109. }
  110. for (uint8_t i = 0; i < col_max_count; i++) {
  111. eeprom_write_byte(mapping++, col_mapping[i]);
  112. }
  113. }
  114. void shift_out_word(uint16_t data)
  115. {
  116. SPDR = (data & 0xFF);
  117. while (!(SPSR & (1<<SPIF)));
  118. SPDR = ((data>>8) & 0xFF);
  119. while (!(SPSR & (1<<SPIF)));
  120. RCK_PORT &= ~(1<<RCK_BIT);
  121. RCK_PORT |= (1<<RCK_BIT);
  122. }
  123. void init_cols(void)
  124. {
  125. // init mux io pins
  126. for (uint8_t i = 0; i < MUX_COUNT; i++) {
  127. if (mux_mapping[i] == MUX_FOR_COL) {
  128. ZX_DDR &= ~(1 << zx_bit[i]);
  129. ZX_PORT |= (1 << zx_bit[i]);
  130. }
  131. else {
  132. ZX_DDR |= (1 << zx_bit[i]);
  133. ZX_PORT |= (1 << zx_bit[i]);
  134. }
  135. }
  136. }
  137. matrix_row_t read_cols(void)
  138. {
  139. matrix_row_t cols = 0;
  140. for (uint8_t i = 0; i < MATRIX_COLS; i++) {
  141. uint8_t px = col_mapping[i];
  142. if (px != UNCONFIGURED) {
  143. shift_out_word(shift_out_cache | px_to_shift_out[px]);
  144. // TODO: delay
  145. if (!(ZX_PIN & (1 << zx_bit[PX_TO_MUX(px)]))) {
  146. cols |= (1 << i);
  147. }
  148. }
  149. }
  150. return cols;
  151. }
  152. void unselect_rows(void)
  153. {
  154. shift_out_word(0);
  155. }
  156. void select_row(uint8_t row)
  157. {
  158. uint8_t px = row_mapping[row];
  159. if (px != UNCONFIGURED) {
  160. ZX_PORT &= ~(1 << zx_bit[PX_TO_MUX(px)]);
  161. shift_out_cache = px_to_shift_out[px] | mux_inh_to_shift_out[PX_TO_MUX(px)];
  162. shift_out_word(shift_out_cache);
  163. }
  164. }