matrix.c 5.3 KB

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