logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

matrix.c (6167B)


  1. /*
  2. Copyright 2016-2017 Ralf Schmitt <ralf@bunkertor.net> Rasmus Schults <rasmusx@gmail.com>
  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. #include <util/delay.h>
  15. #include <avr/io.h>
  16. #include <stdio.h>
  17. #include "matrix.h"
  18. #include "util.h"
  19. #include "print.h"
  20. #include "debug.h"
  21. #ifndef DEBOUNCE
  22. # define DEBOUNCE 5
  23. #endif
  24. static uint8_t debouncing = DEBOUNCE;
  25. /* matrix state(1:on, 0:off) */
  26. static matrix_row_t matrix[MATRIX_ROWS];
  27. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  28. static uint8_t read_rows(void);
  29. static uint8_t read_fwkey(void);
  30. static void init_rows(void);
  31. static void unselect_cols(void);
  32. static void select_col(uint8_t col);
  33. __attribute__ ((weak))
  34. void matrix_init_kb(void) {
  35. matrix_init_user();
  36. }
  37. __attribute__ ((weak))
  38. void matrix_scan_kb(void) {
  39. matrix_scan_user();
  40. }
  41. __attribute__ ((weak))
  42. void matrix_init_user(void) {
  43. }
  44. __attribute__ ((weak))
  45. void matrix_scan_user(void) {
  46. }
  47. void matrix_init(void) {
  48. DDRD |= 0b11010000;
  49. PORTD &= ~0b01010000;
  50. DDRB |= 0b00011111;
  51. PORTB &= ~0b00001110;
  52. PORTB |= 0b00010001;
  53. DDRE |= 0b01000000;
  54. PORTE &= ~0b01000000;
  55. unselect_cols();
  56. init_rows();
  57. for (uint8_t i=0; i < MATRIX_ROWS; i++) {
  58. matrix[i] = 0;
  59. matrix_debouncing[i] = 0;
  60. }
  61. matrix_init_kb();
  62. }
  63. uint8_t matrix_scan(void) {
  64. for (uint8_t col = 0; col < MATRIX_COLS; col++) {
  65. select_col(col);
  66. _delay_us(3);
  67. uint8_t rows = read_rows();
  68. if(col == 0) {
  69. rows |= read_fwkey();
  70. }
  71. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  72. bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
  73. bool curr_bit = rows & (1<<row);
  74. if (prev_bit != curr_bit) {
  75. matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
  76. if (debouncing) {
  77. dprint("bounce!: "); dprintf("%02X", debouncing); dprintln();
  78. }
  79. debouncing = DEBOUNCE;
  80. }
  81. }
  82. unselect_cols();
  83. }
  84. if (debouncing) {
  85. if (--debouncing) {
  86. _delay_ms(1);
  87. } else {
  88. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  89. matrix[i] = matrix_debouncing[i];
  90. }
  91. }
  92. }
  93. matrix_scan_kb();
  94. return 1;
  95. }
  96. inline matrix_row_t matrix_get_row(uint8_t row) {
  97. return matrix[row];
  98. }
  99. void matrix_print(void) {
  100. print("\nr/c 0123456789ABCDEF\n");
  101. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  102. xprintf("%02X: %032lb\n", row, bitrev32(matrix_get_row(row)));
  103. }
  104. }
  105. /* Row pin configuration
  106. * row: 0 1 2 3 4 5
  107. * pin: PB7 PD0 PD1 PD2 PD3 PD5
  108. *
  109. * Esc uses its own pin PE2
  110. */
  111. static void init_rows(void) {
  112. DDRB &= ~0b10000000;
  113. PORTB &= ~0b10000000;
  114. DDRD &= ~0b00101111;
  115. PORTD &= ~0b00101111;
  116. DDRE &= ~0b00000100;
  117. PORTE |= 0b00000100;
  118. }
  119. static uint8_t read_rows(void) {
  120. return (PINB&(1<<7) ? (1<<0) : 0) |
  121. (PIND&(1<<0) ? (1<<1) : 0) |
  122. (PIND&(1<<1) ? (1<<2) : 0) |
  123. (PIND&(1<<2) ? (1<<3) : 0) |
  124. (PIND&(1<<3) ? (1<<4) : 0) |
  125. (PIND&(1<<5) ? (1<<5) : 0);
  126. }
  127. static uint8_t read_fwkey(void)
  128. {
  129. return PINE&(1<<2) ? 0 : (1<<0);
  130. }
  131. /* Columns 0 - 15
  132. * These columns uses two 74HC237D 3 to 8 bit demultiplexers.
  133. * col / pin: PC6 PB6 PF0 PF1 PC7
  134. * 0: 1 0 0 0 0
  135. * 1: 1 0 1 0 0
  136. * 2: 1 0 0 1 0
  137. * 3: 1 0 1 1 0
  138. * 4: 1 0 0 0 1
  139. * 5: 1 0 1 0 1
  140. * 6: 1 0 0 1 1
  141. * 7: 1 0 1 1 1
  142. * 8: 0 1 0 0 0
  143. * 9: 0 1 1 0 0
  144. * 10: 0 1 0 1 0
  145. * 11: 0 1 1 1 0
  146. * 12: 0 1 0 0 1
  147. * 13: 0 1 1 0 1
  148. * 14: 0 1 0 1 1
  149. * 15: 0 1 1 1 1
  150. *
  151. * col: 16
  152. * pin: PB5
  153. *
  154. * col: 17
  155. * pin: PB4
  156. *
  157. * col: 18
  158. * pin: PD7
  159. */
  160. static void unselect_cols(void) {
  161. DDRB |= 0b01110000;
  162. PORTB &= ~0b01110000;
  163. DDRC |= (1<<6) | (1<<7);
  164. PORTC &= ~((1<<6) | (1<<7));
  165. DDRF |= (1<<0) | (1<<1);
  166. PORTF &= ~((1<<0) | (1<<1));
  167. DDRD |= (1<<7);
  168. PORTD &= ~(1<<7);
  169. }
  170. static void select_col(uint8_t col) {
  171. switch (col) {
  172. case 0:
  173. PORTC |= (1<<6);
  174. break;
  175. case 1:
  176. PORTC |= (1<<6);
  177. PORTF |= (1<<0);
  178. break;
  179. case 2:
  180. PORTC |= (1<<6);
  181. PORTF |= (1<<1);
  182. break;
  183. case 3:
  184. PORTC |= (1<<6);
  185. PORTF |= (1<<0) | (1<<1);
  186. break;
  187. case 4:
  188. PORTC |= (1<<6);
  189. PORTC |= (1<<7);
  190. break;
  191. case 5:
  192. PORTC |= (1<<6);
  193. PORTF |= (1<<0);
  194. PORTC |= (1<<7);
  195. break;
  196. case 6:
  197. PORTC |= (1<<6);
  198. PORTF |= (1<<1);
  199. PORTC |= (1<<7);
  200. break;
  201. case 7:
  202. PORTC |= (1<<6);
  203. PORTF |= (1<<0) | (1<<1);
  204. PORTC |= (1<<7);
  205. break;
  206. case 8:
  207. PORTB |= (1<<6);
  208. break;
  209. case 9:
  210. PORTB |= (1<<6);
  211. PORTF |= (1<<0);
  212. break;
  213. case 10:
  214. PORTB |= (1<<6);
  215. PORTF |= (1<<1);
  216. break;
  217. case 11:
  218. PORTB |= (1<<6);
  219. PORTF |= (1<<0) | (1<<1);
  220. break;
  221. case 12:
  222. PORTB |= (1<<6);
  223. PORTC |= (1<<7);
  224. break;
  225. case 13:
  226. PORTB |= (1<<6);
  227. PORTF |= (1<<0);
  228. PORTC |= (1<<7);
  229. break;
  230. case 14:
  231. PORTB |= (1<<6);
  232. PORTF |= (1<<1);
  233. PORTC |= (1<<7);
  234. break;
  235. case 15:
  236. PORTB |= (1<<6);
  237. PORTF |= (1<<0) | (1<<1);
  238. PORTC |= (1<<7);
  239. break;
  240. case 16:
  241. PORTB |= (1<<5);
  242. break;
  243. case 17:
  244. PORTB |= (1<<4);
  245. break;
  246. case 18:
  247. PORTD |= (1<<7);
  248. break;
  249. }
  250. }