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.

249 lines
8.3 KiB

  1. /*
  2. Copyright 2019 Yiancar
  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 <stdint.h>
  15. #include <stdbool.h>
  16. #include <string.h>
  17. #include "quantum.h"
  18. #include "timer.h"
  19. #include "wait.h"
  20. #include "print.h"
  21. #include "matrix.h"
  22. #include <ch.h>
  23. #include <hal.h>
  24. static matrix_row_t matrix[MATRIX_ROWS];
  25. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  26. volatile uint16_t porta_buffer = 0;
  27. volatile uint16_t portb_buffer = 0;
  28. static uint32_t switch_buffer = 0;
  29. static void pal_cb(void* unused);
  30. static void enable_input_events(void)
  31. {
  32. palDisablePadEventI(GPIOA, 0);
  33. palDisablePadEventI(GPIOA, 1);
  34. palDisablePadEventI(GPIOA, 2);
  35. palDisablePadEventI(GPIOA, 9);
  36. palDisablePadEventI(GPIOA, 10);
  37. palDisablePadEventI(GPIOB, 12);
  38. palDisablePadEventI(GPIOB, 13);
  39. palDisablePadEventI(GPIOB, 14);
  40. palDisablePadEventI(GPIOB, 15);
  41. palEnablePadEventI(GPIOA, 0, PAL_EVENT_MODE_FALLING_EDGE);
  42. palEnablePadEventI(GPIOA, 1, PAL_EVENT_MODE_FALLING_EDGE);
  43. palEnablePadEventI(GPIOA, 2, PAL_EVENT_MODE_FALLING_EDGE);
  44. palEnablePadEventI(GPIOA, 9, PAL_EVENT_MODE_FALLING_EDGE);
  45. palEnablePadEventI(GPIOA, 10, PAL_EVENT_MODE_FALLING_EDGE);
  46. palEnablePadEventI(GPIOB, 12, PAL_EVENT_MODE_FALLING_EDGE);
  47. palEnablePadEventI(GPIOB, 13, PAL_EVENT_MODE_FALLING_EDGE);
  48. palEnablePadEventI(GPIOB, 14, PAL_EVENT_MODE_FALLING_EDGE);
  49. palEnablePadEventI(GPIOB, 15, PAL_EVENT_MODE_FALLING_EDGE);
  50. palSetPadCallbackI(GPIOA, 0, &pal_cb, 0);
  51. palSetPadCallbackI(GPIOA, 1, &pal_cb, 0);
  52. palSetPadCallbackI(GPIOA, 2, &pal_cb, 0);
  53. palSetPadCallbackI(GPIOA, 9, &pal_cb, 0);
  54. palSetPadCallbackI(GPIOA, 10, &pal_cb, 0);
  55. palSetPadCallbackI(GPIOB, 12, &pal_cb, 0);
  56. palSetPadCallbackI(GPIOB, 13, &pal_cb, 0);
  57. palSetPadCallbackI(GPIOB, 14, &pal_cb, 0);
  58. palSetPadCallbackI(GPIOB, 15, &pal_cb, 0);
  59. }
  60. // Trigger on negative edge of any of the sense lines.
  61. static void pal_cb(void* unused) {
  62. (void)unused;
  63. chSysLockFromISR();
  64. porta_buffer = palReadPort(GPIOA);
  65. portb_buffer = palReadPort(GPIOB);
  66. //Disable further interrupts that might occur on same button press.
  67. enable_input_events();
  68. chSysUnlockFromISR();
  69. }
  70. void matrix_init(void) {
  71. //Set I/O as pull-up inputs to read states
  72. gpio_set_pin_input_high(A0);
  73. gpio_set_pin_input_high(A1);
  74. gpio_set_pin_input_high(A2);
  75. gpio_set_pin_input_high(A3);
  76. gpio_set_pin_input_high(A4);
  77. gpio_set_pin_input_high(A5);
  78. gpio_set_pin_input_high(A6);
  79. gpio_set_pin_input_high(A7);
  80. gpio_set_pin_input_high(A8);
  81. gpio_set_pin_input_high(A9);
  82. gpio_set_pin_input_high(A10);
  83. gpio_set_pin_input_high(B3);
  84. gpio_set_pin_input_high(B4);
  85. gpio_set_pin_input_high(B5);
  86. gpio_set_pin_input_high(B6);
  87. gpio_set_pin_input_high(B7);
  88. gpio_set_pin_input_high(B8);
  89. gpio_set_pin_input_high(B9);
  90. gpio_set_pin_input_high(B11);
  91. gpio_set_pin_input_high(B12);
  92. gpio_set_pin_input_high(B13);
  93. gpio_set_pin_input_high(B14);
  94. gpio_set_pin_input_high(B15);
  95. memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t));
  96. memset(matrix_debouncing, 0, MATRIX_ROWS * sizeof(matrix_row_t));
  97. matrix_init_kb();
  98. osalSysLock();
  99. enable_input_events();
  100. osalSysUnlock();
  101. }
  102. uint8_t matrix_scan(void) {
  103. switch_buffer = ((uint32_t)(porta_buffer & 0x7FF)) | ((uint32_t)(portb_buffer & 0x3F8) << 8);
  104. switch (switch_buffer) {
  105. case 0x1134E: matrix[0] = 0x01; break;
  106. case 0x3774D: matrix[0] = 0x02; break;
  107. case 0x10BCC: matrix[0] = 0x04; break;
  108. case 0x16B4B: matrix[0] = 0x08; break;
  109. case 0x167CA: matrix[0] = 0x10; break;
  110. case 0x35FC9: matrix[0] = 0x20; break;
  111. case 0x15B48: matrix[0] = 0x40; break;
  112. case 0x28347: matrix[0] = 0x80; break;
  113. case 0x173C6: matrix[0] = 0x100; break;
  114. case 0x143CF: matrix[0] = 0x200; break;
  115. case 0x3FDC5: matrix[0] = 0x400; break;
  116. case 0x3FD21: matrix[0] = 0x800; break;
  117. case 0x3FD77: matrix[0] = 0x1000; break;
  118. case 0x3FD72: matrix[0] = 0x2000; break;
  119. //Special pin
  120. case 0x3E7FA: matrix[0] = 0x8000; break;
  121. case 0x183EE: matrix[0] = 0x10000; break;
  122. case 0x197F3: matrix[0] = 0x20000; break;
  123. case 0x1AB7E: matrix[0] = 0x40000; break;
  124. case 0x107C3: matrix[1] = 0x01; break;
  125. case 0x3FD2E: matrix[1] = 0x02; break;
  126. case 0x3FD28: matrix[1] = 0x04; break;
  127. case 0x3FD3A: matrix[1] = 0x08; break;
  128. case 0x3FD2D: matrix[1] = 0x10; break;
  129. case 0x3FD2B: matrix[1] = 0x20; break;
  130. case 0x3FDA5: matrix[1] = 0x40; break;
  131. case 0x3FDAA: matrix[1] = 0x80; break;
  132. case 0x3FD36: matrix[1] = 0x100; break;
  133. case 0x3FD30: matrix[1] = 0x200; break;
  134. case 0x3FDAF: matrix[1] = 0x400; break;
  135. case 0x3FD22: matrix[1] = 0x800; break;
  136. case 0x157D4: matrix[1] = 0x1000; break;
  137. //Does not exist in matrix
  138. //Special pin
  139. case 0x1C778: matrix[1] = 0x8000; break;
  140. case 0x387ED: matrix[1] = 0x10000; break;
  141. case 0x19B74: matrix[1] = 0x20000; break;
  142. case 0x3FD7D: matrix[1] = 0x40000; break;
  143. //Special pin
  144. case 0x3FDBE: matrix[2] = 0x02; break;
  145. case 0x3FDAC: matrix[2] = 0x04; break;
  146. case 0x3FDBB: matrix[2] = 0x08; break;
  147. case 0x3FD39: matrix[2] = 0x10; break;
  148. case 0x3FDB8: matrix[2] = 0x20; break;
  149. case 0x3FDB7: matrix[2] = 0x40; break;
  150. case 0x3FD35: matrix[2] = 0x80; break;
  151. case 0x3FDB4: matrix[2] = 0x100; break;
  152. case 0x3FD33: matrix[2] = 0x200; break;
  153. case 0x3FDA3: matrix[2] = 0x400; break;
  154. case 0x3FD24: matrix[2] = 0x800; break;
  155. case 0x0FFDB: matrix[2] = 0x1000; break;
  156. case 0x3FDF5: matrix[2] = 0x2000; break;
  157. case 0x3FDFF: matrix[2] = 0x4000; break;
  158. case 0x3C3E4: matrix[2] = 0x8000; break;
  159. case 0x38B6C: matrix[2] = 0x10000; break;
  160. case 0x39FF6: matrix[2] = 0x20000; break;
  161. case 0x3FDFC: matrix[2] = 0x40000; break;
  162. //Special pin
  163. case 0x3FDA6: matrix[3] = 0x02; break;
  164. case 0x3FD27: matrix[3] = 0x04; break;
  165. case 0x3FD3C: matrix[3] = 0x08; break;
  166. case 0x3FDA9: matrix[3] = 0x10; break;
  167. case 0x3FDBD: matrix[3] = 0x20; break;
  168. case 0x3FDB1: matrix[3] = 0x40; break;
  169. case 0x3FDB2: matrix[3] = 0x80; break;
  170. case 0x30353: matrix[3] = 0x100; break;
  171. case 0x37BD1: matrix[3] = 0x200; break;
  172. case 0x363D2: matrix[3] = 0x400; break;
  173. case 0x3FD5F: matrix[3] = 0x800; break;
  174. //Does not exist in matrix
  175. //Does not exist in matrix
  176. //Special pin
  177. case 0x1BF00: matrix[3] = 0x8000; break;
  178. case 0x18FEB: matrix[3] = 0x10000; break;
  179. case 0x3FF69: matrix[3] = 0x20000; break;
  180. case 0x3A37B: matrix[3] = 0x40000; break;
  181. default:
  182. if ((portb_buffer & 0x1000) == 0) { matrix[1] = 0x4000; break; }
  183. if ((portb_buffer & 0x2000) == 0) { matrix[3] = 0x4000; break; }
  184. if ((portb_buffer & 0x4000) == 0) { matrix[0] = 0x4000; break; }
  185. if ((portb_buffer & 0x8000) == 0) { matrix[2] = 0x01; break; }
  186. matrix[0] = 0x00;
  187. matrix[1] = 0x00;
  188. matrix[2] = 0x00;
  189. matrix[3] = 0x00;
  190. }
  191. //Special case for Shift
  192. if (gpio_read_pin(B11) == 0) { matrix[3] |= 0x01; }
  193. porta_buffer = 65535;
  194. portb_buffer = 65535;
  195. matrix_scan_kb();
  196. return 1;
  197. }
  198. matrix_row_t matrix_get_row(uint8_t row)
  199. {
  200. return matrix[row];
  201. }
  202. void matrix_print(void)
  203. {
  204. }
  205. __attribute__ ((weak))
  206. void matrix_init_kb(void) {
  207. matrix_init_user();
  208. }
  209. __attribute__ ((weak))
  210. void matrix_scan_kb(void) {
  211. matrix_scan_user();
  212. }
  213. __attribute__ ((weak))
  214. void matrix_init_user(void) {
  215. }
  216. __attribute__ ((weak))
  217. void matrix_scan_user(void) {
  218. }