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.

пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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. /*
  15. * scan matrix
  16. */
  17. #include <stdint.h>
  18. #include <stdbool.h>
  19. #include <avr/io.h>
  20. #include <util/delay.h>
  21. #include "print.h"
  22. #include "debug.h"
  23. #include "util.h"
  24. #include "matrix.h"
  25. #include "i2c_wrapper.h"
  26. #include "kimera.h"
  27. #include "keymap_in_eeprom.h"
  28. #include "timer.h"
  29. #ifndef DEBOUNCE
  30. # define DEBOUNCE 5
  31. #endif
  32. /* matrix state(1:on, 0:off) */
  33. static matrix_row_t matrix[MATRIX_ROWS];
  34. #define IMPROVED_DEBOUNCE 1
  35. #if IMPROVED_DEBOUNCE
  36. #define DEBOUNCE_MASK ((1 << DEBOUNCE) - 1)
  37. static uint8_t matrix_current_row;
  38. static uint16_t matrix_row_timestamp[MATRIX_ROWS];
  39. static uint8_t matrix_debouncing[MATRIX_ROWS][MATRIX_COLS];
  40. #else
  41. static uint8_t debouncing = DEBOUNCE;
  42. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  43. #endif
  44. static uint16_t kimera_scan_timestamp;
  45. inline
  46. uint8_t matrix_rows(void)
  47. {
  48. return kimera_matrix_rows();
  49. }
  50. inline
  51. uint8_t matrix_cols(void)
  52. {
  53. return kimera_matrix_cols();
  54. }
  55. void matrix_init(void)
  56. {
  57. // disable JTAG
  58. MCUCR = (1<<JTD);
  59. MCUCR = (1<<JTD);
  60. i2c_wrapper_init();
  61. _delay_ms(1);
  62. kimera_init();
  63. kimera_scan_timestamp = timer_read();
  64. rgb_init();
  65. // initialize row and col
  66. kimera_unselect_rows();
  67. // initialize matrix state: all keys off
  68. #if IMPROVED_DEBOUNCE
  69. for (uint8_t i = 0; i < matrix_rows(); i++) {
  70. matrix[i] = 0;
  71. matrix_current_row = 0;
  72. matrix_row_timestamp[i] = timer_read();
  73. for (uint8_t j = 0; j < matrix_cols(); j++) {
  74. matrix_debouncing[i][j] = 0;
  75. }
  76. }
  77. #else
  78. for (uint8_t i=0; i < matrix_rows(); i++) {
  79. matrix[i] = 0;
  80. matrix_debouncing[i] = 0;
  81. }
  82. #endif
  83. PORTD &= ~(1<<PD4);
  84. }
  85. uint8_t matrix_scan(void)
  86. {
  87. i2c_wrapper_task();
  88. if (timer_elapsed(kimera_scan_timestamp) >= 1000) {
  89. xprintf("======== 1s task ========\n");
  90. xprintf("Scan, %u\n", kimera_scan_timestamp);
  91. kimera_scan_timestamp = timer_read();
  92. kimera_scan();
  93. xprintf("=========================\n");
  94. }
  95. #if IMPROVED_DEBOUNCE
  96. uint16_t elapsed = timer_elapsed(matrix_row_timestamp[matrix_current_row]);
  97. if (elapsed >= 1) {
  98. matrix_row_timestamp[matrix_current_row] = timer_read();
  99. kimera_select_row(matrix_current_row);
  100. _delay_us(30);
  101. kimera_read_cols();
  102. for (uint8_t i = 0; i < matrix_cols(); i++) {
  103. uint8_t *debounce = &matrix_debouncing[matrix_current_row][i];
  104. uint8_t col = kimera_get_col(matrix_current_row, i);
  105. uint8_t count = elapsed;
  106. do {
  107. *debounce <<= 1;
  108. *debounce |= col;
  109. } while (--count);
  110. matrix_row_t *row = &matrix[matrix_current_row];
  111. matrix_row_t mask = ((matrix_row_t)1 << i);
  112. switch (*debounce & DEBOUNCE_MASK) {
  113. case DEBOUNCE_MASK:
  114. #if DEBOUNCE > 1
  115. case (DEBOUNCE_MASK >> 1):
  116. #if DEBOUNCE > 2
  117. case (DEBOUNCE_MASK >> 2):
  118. #if DEBOUNCE > 3
  119. case (DEBOUNCE_MASK >> 3):
  120. #if DEBOUNCE > 4
  121. case (DEBOUNCE_MASK >> 4):
  122. #if DEBOUNCE > 5
  123. case (DEBOUNCE_MASK >> 5):
  124. #if DEBOUNCE > 6
  125. case (DEBOUNCE_MASK >> 6):
  126. #if DEBOUNCE > 7
  127. case (DEBOUNCE_MASK >> 7):
  128. #if DEBOUNCE > 8
  129. case (DEBOUNCE_MASK >> 8):
  130. #if DEBOUNCE > 9
  131. case (DEBOUNCE_MASK >> 9):
  132. #if DEBOUNCE > 10
  133. case (DEBOUNCE_MASK >> 10):
  134. #endif
  135. #endif
  136. #endif
  137. #endif
  138. #endif
  139. #endif
  140. #endif
  141. #endif
  142. #endif
  143. #endif
  144. if ((*row & mask) == 0) {
  145. *row |= mask;
  146. }
  147. break;
  148. #if DEBOUNCE > 1
  149. case ((DEBOUNCE_MASK << 1) & DEBOUNCE_MASK):
  150. #if DEBOUNCE > 2
  151. case ((DEBOUNCE_MASK << 2) & DEBOUNCE_MASK):
  152. #if DEBOUNCE > 3
  153. case ((DEBOUNCE_MASK << 3) & DEBOUNCE_MASK):
  154. #if DEBOUNCE > 4
  155. case ((DEBOUNCE_MASK << 4) & DEBOUNCE_MASK):
  156. #if DEBOUNCE > 5
  157. case ((DEBOUNCE_MASK << 5) & DEBOUNCE_MASK):
  158. #if DEBOUNCE > 6
  159. case ((DEBOUNCE_MASK << 6) & DEBOUNCE_MASK):
  160. #if DEBOUNCE > 7
  161. case ((DEBOUNCE_MASK << 7) & DEBOUNCE_MASK):
  162. #if DEBOUNCE > 8
  163. case ((DEBOUNCE_MASK << 8) & DEBOUNCE_MASK):
  164. #if DEBOUNCE > 9
  165. case ((DEBOUNCE_MASK << 9) & DEBOUNCE_MASK):
  166. #if DEBOUNCE > 10
  167. case ((DEBOUNCE_MASK << 10) & DEBOUNCE_MASK):
  168. #endif
  169. #endif
  170. #endif
  171. #endif
  172. #endif
  173. #endif
  174. #endif
  175. #endif
  176. #endif
  177. #endif
  178. break;
  179. case 0:
  180. if ((*row & mask) != 0) {
  181. *row &= ~mask;
  182. }
  183. break;
  184. default:
  185. debug("bounce!: ");
  186. debug_bin8(*debounce & DEBOUNCE_MASK);
  187. debug("\n");
  188. break;
  189. }
  190. }
  191. kimera_unselect_rows();
  192. }
  193. matrix_current_row++;
  194. if (matrix_current_row >= matrix_rows()) {
  195. matrix_current_row = 0;
  196. }
  197. #else
  198. for (uint8_t i = 0; i < matrix_rows(); i++) {
  199. kimera_select_row(i);
  200. _delay_us(30); // without this wait read unstable value.
  201. matrix_row_t cols = kimera_read_row(i);
  202. if (matrix_debouncing[i] != cols) {
  203. matrix_debouncing[i] = cols;
  204. if (debouncing) {
  205. debug("bounce!: "); debug_hex(debouncing); debug("\n");
  206. }
  207. debouncing = DEBOUNCE;
  208. }
  209. kimera_unselect_rows();
  210. }
  211. if (debouncing) {
  212. if (--debouncing) {
  213. _delay_ms(1);
  214. } else {
  215. for (uint8_t i = 0; i < matrix_rows(); i++) {
  216. matrix[i] = matrix_debouncing[i];
  217. }
  218. }
  219. }
  220. #endif
  221. return 1;
  222. }
  223. #if IMPROVED_DEBOUNCE
  224. #else
  225. bool matrix_is_modified(void)
  226. {
  227. if (debouncing) return false;
  228. return true;
  229. }
  230. #endif
  231. inline
  232. bool matrix_is_on(uint8_t row, uint8_t col)
  233. {
  234. return (matrix[row] & ((matrix_row_t)1<<col));
  235. }
  236. inline
  237. matrix_row_t matrix_get_row(uint8_t row)
  238. {
  239. return matrix[row];
  240. }
  241. void matrix_print(void)
  242. {
  243. print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n");
  244. for (uint8_t row = 0; row < matrix_rows(); row++) {
  245. phex(row); print(": ");
  246. print_bin_reverse32(matrix_get_row(row));
  247. print("\n");
  248. }
  249. }
  250. uint8_t matrix_key_count(void)
  251. {
  252. uint8_t count = 0;
  253. for (uint8_t i = 0; i < matrix_rows(); i++) {
  254. count += bitpop32(matrix[i]);
  255. }
  256. return count;
  257. }