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.

210 lines
6.1 KiB

5 years ago
5 years ago
5 years ago
  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 active) { }
  71. __attribute__ ((weak))
  72. void encoder_update(bool clockwise) { }
  73. __attribute__ ((weak))
  74. void encoder_update_kb(uint8_t index, bool clockwise) { }
  75. bool last_dip_switch[4] = {0};
  76. #ifndef ENCODER_RESOLUTION
  77. #define ENCODER_RESOLUTION 4
  78. #endif
  79. uint8_t matrix_scan(void) {
  80. // dip switch
  81. dip_switch[0] = !palReadPad(GPIOB, 14);
  82. dip_switch[1] = !palReadPad(GPIOA, 15);
  83. dip_switch[2] = !palReadPad(GPIOA, 10);
  84. dip_switch[3] = !palReadPad(GPIOB, 9);
  85. for (uint8_t i = 0; i < 4; i++) {
  86. if (last_dip_switch[i] ^ dip_switch[i])
  87. dip_update(i, dip_switch[i]);
  88. }
  89. memcpy(last_dip_switch, dip_switch, sizeof(&dip_switch));
  90. // encoder on B12 and B13
  91. encoder_state <<= 2;
  92. encoder_state |= (palReadPad(GPIOB, 12) << 0) | (palReadPad(GPIOB, 13) << 1);
  93. encoder_value += encoder_LUT[encoder_state & 0xF];
  94. if (encoder_value >= ENCODER_RESOLUTION) {
  95. encoder_update(0);
  96. encoder_update_kb(0, 0);
  97. }
  98. if (encoder_value <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise
  99. encoder_update(1);
  100. encoder_update_kb(0, 1);
  101. }
  102. encoder_value %= ENCODER_RESOLUTION;
  103. // actual matrix
  104. for (int col = 0; col < MATRIX_COLS; col++) {
  105. matrix_row_t data = 0;
  106. // strobe col { B11, B10, B2, B1, A7, B0 }
  107. switch (col) {
  108. case 0: palSetPad(GPIOB, 11); break;
  109. case 1: palSetPad(GPIOB, 10); break;
  110. case 2: palSetPad(GPIOB, 2); break;
  111. case 3: palSetPad(GPIOB, 1); break;
  112. case 4: palSetPad(GPIOA, 7); break;
  113. case 5: palSetPad(GPIOB, 0); break;
  114. }
  115. // need wait to settle pin state
  116. wait_us(20);
  117. // read row data { A10, A9, A8, B15, C13, C14, C15, A2 }
  118. data = (
  119. (palReadPad(GPIOA, 10) << 0 ) |
  120. (palReadPad(GPIOA, 9) << 1 ) |
  121. (palReadPad(GPIOA, 8) << 2 ) |
  122. (palReadPad(GPIOB, 15) << 3 ) |
  123. (palReadPad(GPIOC, 13) << 4 ) |
  124. (palReadPad(GPIOC, 14) << 5 ) |
  125. (palReadPad(GPIOC, 15) << 6 ) |
  126. (palReadPad(GPIOA, 2) << 7 )
  127. );
  128. // unstrobe col { B11, B10, B2, B1, A7, B0 }
  129. switch (col) {
  130. case 0: palClearPad(GPIOB, 11); break;
  131. case 1: palClearPad(GPIOB, 10); break;
  132. case 2: palClearPad(GPIOB, 2); break;
  133. case 3: palClearPad(GPIOB, 1); break;
  134. case 4: palClearPad(GPIOA, 7); break;
  135. case 5: palClearPad(GPIOB, 0); break;
  136. }
  137. if (matrix_debouncing[col] != data) {
  138. matrix_debouncing[col] = data;
  139. debouncing = true;
  140. debouncing_time = timer_read();
  141. }
  142. }
  143. if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) {
  144. for (int row = 0; row < MATRIX_ROWS; row++) {
  145. matrix[row] = 0;
  146. for (int col = 0; col < MATRIX_COLS; col++) {
  147. matrix[row] |= ((matrix_debouncing[col] & (1 << row) ? 1 : 0) << col);
  148. }
  149. }
  150. debouncing = false;
  151. }
  152. matrix_scan_quantum();
  153. return 1;
  154. }
  155. bool matrix_is_on(uint8_t row, uint8_t col) {
  156. return (matrix[row] & (1<<col));
  157. }
  158. matrix_row_t matrix_get_row(uint8_t row) {
  159. return matrix[row];
  160. }
  161. void matrix_print(void) {
  162. printf("\nr/c 01234567\n");
  163. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  164. printf("%X0: ", row);
  165. matrix_row_t data = matrix_get_row(row);
  166. for (int col = 0; col < MATRIX_COLS; col++) {
  167. if (data & (1<<col))
  168. printf("1");
  169. else
  170. printf("0");
  171. }
  172. printf("\n");
  173. }
  174. }