matrix.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include <stdint.h>
  2. #include <stdbool.h>
  3. #include <string.h>
  4. #include "hal.h"
  5. #include "timer.h"
  6. #include "wait.h"
  7. #include "printf.h"
  8. #include "backlight.h"
  9. #include "matrix.h"
  10. #include "action.h"
  11. #include "keycode.h"
  12. #include <string.h>
  13. /*
  14. * col: { B11, B10, B2, B1, A7, B0 }
  15. * row: { A10, A9, A8, B15, C13, C14, C15, A2 }
  16. */
  17. /* matrix state(1:on, 0:off) */
  18. static matrix_row_t matrix[MATRIX_ROWS];
  19. static matrix_row_t matrix_debouncing[MATRIX_COLS];
  20. static bool debouncing = false;
  21. static uint16_t debouncing_time = 0;
  22. static uint8_t encoder_state = 0;
  23. static int8_t encoder_value = 0;
  24. static int8_t encoder_LUT[] = { 0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0 };
  25. static bool dip_switch[4] = {0, 0, 0, 0};
  26. __attribute__ ((weak))
  27. void matrix_init_user(void) {}
  28. __attribute__ ((weak))
  29. void matrix_scan_user(void) {}
  30. __attribute__ ((weak))
  31. void matrix_init_kb(void) {
  32. matrix_init_user();
  33. }
  34. __attribute__ ((weak))
  35. void matrix_scan_kb(void) {
  36. matrix_scan_user();
  37. }
  38. void matrix_init(void) {
  39. printf("matrix init\n");
  40. //debug_matrix = true;
  41. // dip switch setup
  42. palSetPadMode(GPIOB, 14, PAL_MODE_INPUT_PULLUP);
  43. palSetPadMode(GPIOA, 15, PAL_MODE_INPUT_PULLUP);
  44. palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLUP);
  45. palSetPadMode(GPIOB, 9, PAL_MODE_INPUT_PULLUP);
  46. // encoder setup
  47. palSetPadMode(GPIOB, 12, PAL_MODE_INPUT_PULLUP);
  48. palSetPadMode(GPIOB, 13, PAL_MODE_INPUT_PULLUP);
  49. encoder_state = (palReadPad(GPIOB, 12) << 0) | (palReadPad(GPIOB, 13) << 1);
  50. // actual matrix setup
  51. palSetPadMode(GPIOB, 11, PAL_MODE_OUTPUT_PUSHPULL);
  52. palSetPadMode(GPIOB, 10, PAL_MODE_OUTPUT_PUSHPULL);
  53. palSetPadMode(GPIOB, 2, PAL_MODE_OUTPUT_PUSHPULL);
  54. palSetPadMode(GPIOB, 1, PAL_MODE_OUTPUT_PUSHPULL);
  55. palSetPadMode(GPIOA, 7, PAL_MODE_OUTPUT_PUSHPULL);
  56. palSetPadMode(GPIOB, 0, PAL_MODE_OUTPUT_PUSHPULL);
  57. palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLDOWN);
  58. palSetPadMode(GPIOA, 9, PAL_MODE_INPUT_PULLDOWN);
  59. palSetPadMode(GPIOA, 8, PAL_MODE_INPUT_PULLDOWN);
  60. palSetPadMode(GPIOB, 15, PAL_MODE_INPUT_PULLDOWN);
  61. palSetPadMode(GPIOC, 13, PAL_MODE_INPUT_PULLDOWN);
  62. palSetPadMode(GPIOC, 14, PAL_MODE_INPUT_PULLDOWN);
  63. palSetPadMode(GPIOC, 15, PAL_MODE_INPUT_PULLDOWN);
  64. palSetPadMode(GPIOA, 2, PAL_MODE_INPUT_PULLDOWN);
  65. memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t));
  66. memset(matrix_debouncing, 0, MATRIX_COLS * sizeof(matrix_row_t));
  67. matrix_init_quantum();
  68. }
  69. __attribute__ ((weak))
  70. void dip_update(uint8_t index, bool value) { }
  71. __attribute__ ((weak))
  72. void encoder_update(bool direction) { }
  73. bool last_dip_switch[4] = {0};
  74. uint8_t matrix_scan(void) {
  75. // dip switch
  76. dip_switch[0] = palReadPad(GPIOB, 14);
  77. dip_switch[1] = palReadPad(GPIOA, 15);
  78. dip_switch[2] = palReadPad(GPIOA, 10);
  79. dip_switch[3] = palReadPad(GPIOB, 9);
  80. for (uint8_t i = 0; i < 4; i++) {
  81. if (last_dip_switch[i] ^ dip_switch[i])
  82. dip_update(i, dip_switch[i]);
  83. }
  84. memcpy(last_dip_switch, dip_switch, sizeof(&dip_switch));
  85. // encoder on B12 and B13
  86. encoder_state <<= 2;
  87. encoder_state |= (palReadPad(GPIOB, 12) << 0) | (palReadPad(GPIOB, 13) << 1);
  88. encoder_value += encoder_LUT[encoder_state & 0xF];
  89. if (encoder_value >= ENCODER_RESOLUTION) {
  90. encoder_update(1);
  91. }
  92. if (encoder_value <= -ENCODER_RESOLUTION) {
  93. encoder_update(0);
  94. }
  95. encoder_value %= ENCODER_RESOLUTION;
  96. // actual matrix
  97. for (int col = 0; col < MATRIX_COLS; col++) {
  98. matrix_row_t data = 0;
  99. // strobe col { B11, B10, B2, B1, A7, B0 }
  100. switch (col) {
  101. case 0: palSetPad(GPIOB, 11); break;
  102. case 1: palSetPad(GPIOB, 10); break;
  103. case 2: palSetPad(GPIOB, 2); break;
  104. case 3: palSetPad(GPIOB, 1); break;
  105. case 4: palSetPad(GPIOA, 7); break;
  106. case 5: palSetPad(GPIOB, 0); break;
  107. }
  108. // need wait to settle pin state
  109. wait_us(20);
  110. // read row data { A10, A9, A8, B15, C13, C14, C15, A2 }
  111. data = (
  112. (palReadPad(GPIOA, 10) << 0 ) |
  113. (palReadPad(GPIOA, 9) << 1 ) |
  114. (palReadPad(GPIOA, 8) << 2 ) |
  115. (palReadPad(GPIOB, 15) << 3 ) |
  116. (palReadPad(GPIOC, 13) << 4 ) |
  117. (palReadPad(GPIOC, 14) << 5 ) |
  118. (palReadPad(GPIOC, 15) << 6 ) |
  119. (palReadPad(GPIOA, 2) << 7 )
  120. );
  121. // unstrobe col { B11, B10, B2, B1, A7, B0 }
  122. switch (col) {
  123. case 0: palClearPad(GPIOB, 11); break;
  124. case 1: palClearPad(GPIOB, 10); break;
  125. case 2: palClearPad(GPIOB, 2); break;
  126. case 3: palClearPad(GPIOB, 1); break;
  127. case 4: palClearPad(GPIOA, 7); break;
  128. case 5: palClearPad(GPIOB, 0); break;
  129. }
  130. if (matrix_debouncing[col] != data) {
  131. matrix_debouncing[col] = data;
  132. debouncing = true;
  133. debouncing_time = timer_read();
  134. }
  135. }
  136. if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) {
  137. for (int row = 0; row < MATRIX_ROWS; row++) {
  138. matrix[row] = 0;
  139. for (int col = 0; col < MATRIX_COLS; col++) {
  140. matrix[row] |= ((matrix_debouncing[col] & (1 << row) ? 1 : 0) << col);
  141. }
  142. }
  143. debouncing = false;
  144. }
  145. matrix_scan_quantum();
  146. return 1;
  147. }
  148. bool matrix_is_on(uint8_t row, uint8_t col) {
  149. return (matrix[row] & (1<<col));
  150. }
  151. matrix_row_t matrix_get_row(uint8_t row) {
  152. return matrix[row];
  153. }
  154. void matrix_print(void) {
  155. printf("\nr/c 01234567\n");
  156. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  157. printf("%X0: ", row);
  158. matrix_row_t data = matrix_get_row(row);
  159. for (int col = 0; col < MATRIX_COLS; col++) {
  160. if (data & (1<<col))
  161. printf("1");
  162. else
  163. printf("0");
  164. }
  165. printf("\n");
  166. }
  167. }