logo

qmk_firmware

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

matrix.c (12864B)


  1. /*
  2. Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar
  3. Copyright 2019 Evy Dekkers
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "matrix.h"
  16. #include "gpio.h"
  17. static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
  18. /* Cols 0 - 16
  19. * These columns use two 74HC138 3 to 8 bit demultiplexer. B4, C7 is the enable pin, must be set high (1) to use it.
  20. *
  21. * col / pin: PA0 PA1 PA2 PB4 PC7 PC2 PC3 PC5
  22. * 0: 0 ── 0 ── 0 1 ── 0 0 0 0
  23. * ────────────────────────────────────────────
  24. * 1: 0 ── 0 ── 1 1 ── 0 0 0 0
  25. * ────────────────────────────────────────────
  26. * 2: 0 ── 1 ── 0 1 ── 0 0 0 0
  27. * ────────────────────────────────────────────
  28. * 3: 0 ── 1 ── 1 1 ── 0 0 0 0
  29. * ────────────────────────────────────────────
  30. * 4: 1 ── 0 ── 0 1 ── 0 0 0 0
  31. * ────────────────────────────────────────────
  32. * 5: 1 ── 0 ── 1 1 ── 0 0 0 0
  33. * ────────────────────────────────────────────
  34. * 6: 1 ── 1 ── 0 1 ── 0 0 0 0
  35. * ────────────────────────────────────────────
  36. * 7: 1 ── 1 ── 1 1 ── 0 0 0 0
  37. * ────────────────────────────────────────────
  38. * 8: 1 ── 1 ── 1 0 ── 1 0 0 0
  39. * ────────────────────────────────────────────
  40. * 9: 0 ── 0 ── 0 0 ── 1 0 0 0
  41. * ────────────────────────────────────────────
  42. *10: 0 ── 0 ── 1 0 ── 1 0 0 0
  43. * ────────────────────────────────────────────
  44. *11: 0 ── 1 ── 0 0 ── 1 0 0 0
  45. * ────────────────────────────────────────────
  46. *12: 0 ── 1 ── 1 0 ── 1 0 0 0
  47. * ────────────────────────────────────────────
  48. *13: 1 ── 0 ── 0 0 ── 1 0 0 0
  49. * ────────────────────────────────────────────
  50. *14: 1 ── 0 ── 1 0 ── 1 0 0 0
  51. * ────────────────────────────────────────────
  52. *15: 1 ── 1 ── 0 0 ── 1 0 0 0
  53. * ────────────────────────────────────────────
  54. *16: 0 ── 0 ── 0 0 ── 0 1 0 0
  55. * ────────────────────────────────────────────
  56. *17: 0 ── 0 ── 0 0 ── 0 0 1 0
  57. * ────────────────────────────────────────────
  58. *18: 0 ── 0 ── 0 0 ── 0 0 0 1
  59. *
  60. */
  61. static void select_col(uint8_t col) {
  62. switch (col) {
  63. case 0:
  64. gpio_write_pin_low(A0);
  65. gpio_write_pin_low(A1);
  66. gpio_write_pin_low(A2);
  67. gpio_write_pin_high(B4);
  68. break;
  69. case 1:
  70. gpio_write_pin_low(A0);
  71. gpio_write_pin_low(A1);
  72. gpio_write_pin_high(A2);
  73. gpio_write_pin_high(B4);
  74. break;
  75. case 2:
  76. gpio_write_pin_low(A0);
  77. gpio_write_pin_high(A1);
  78. gpio_write_pin_low(A2);
  79. gpio_write_pin_high(B4);
  80. break;
  81. case 3:
  82. gpio_write_pin_low(A0);
  83. gpio_write_pin_high(A1);
  84. gpio_write_pin_high(A2);
  85. gpio_write_pin_high(B4);
  86. break;
  87. case 4:
  88. gpio_write_pin_high(A0);
  89. gpio_write_pin_low(A1);
  90. gpio_write_pin_low(A2);
  91. gpio_write_pin_high(B4);
  92. break;
  93. case 5:
  94. gpio_write_pin_high(A0);
  95. gpio_write_pin_low(A1);
  96. gpio_write_pin_high(A2);
  97. gpio_write_pin_high(B4);
  98. break;
  99. case 6:
  100. gpio_write_pin_high(A0);
  101. gpio_write_pin_high(A1);
  102. gpio_write_pin_low(A2);
  103. gpio_write_pin_high(B4);
  104. break;
  105. case 7:
  106. gpio_write_pin_high(A0);
  107. gpio_write_pin_high(A1);
  108. gpio_write_pin_high(A2);
  109. gpio_write_pin_high(B4);
  110. break;
  111. case 8:
  112. gpio_write_pin_high(A0);
  113. gpio_write_pin_high(A1);
  114. gpio_write_pin_high(A2);
  115. gpio_write_pin_high(C7);
  116. break;
  117. case 9:
  118. gpio_write_pin_low(A0);
  119. gpio_write_pin_low(A1);
  120. gpio_write_pin_low(A2);
  121. gpio_write_pin_high(C7);
  122. break;
  123. case 10:
  124. gpio_write_pin_low(A0);
  125. gpio_write_pin_low(A1);
  126. gpio_write_pin_high(A2);
  127. gpio_write_pin_high(C7);
  128. break;
  129. case 11:
  130. gpio_write_pin_low(A0);
  131. gpio_write_pin_high(A1);
  132. gpio_write_pin_low(A2);
  133. gpio_write_pin_high(C7);
  134. break;
  135. case 12:
  136. gpio_write_pin_low(A0);
  137. gpio_write_pin_high(A1);
  138. gpio_write_pin_high(A2);
  139. gpio_write_pin_high(C7);
  140. break;
  141. case 13:
  142. gpio_write_pin_high(A0);
  143. gpio_write_pin_low(A1);
  144. gpio_write_pin_low(A2);
  145. gpio_write_pin_high(C7);
  146. break;
  147. case 14:
  148. gpio_write_pin_high(A0);
  149. gpio_write_pin_low(A1);
  150. gpio_write_pin_high(A2);
  151. gpio_write_pin_high(C7);
  152. break;
  153. case 15:
  154. gpio_write_pin_high(A0);
  155. gpio_write_pin_high(A1);
  156. gpio_write_pin_low(A2);
  157. gpio_write_pin_high(C7);
  158. break;
  159. case 16:
  160. gpio_write_pin_low(C2);
  161. break;
  162. case 17:
  163. gpio_write_pin_low(C3);
  164. break;
  165. case 18:
  166. gpio_write_pin_low(C5);
  167. break;
  168. }
  169. }
  170. static void unselect_col(uint8_t col) {
  171. switch (col) {
  172. case 0:
  173. gpio_write_pin_high(A0);
  174. gpio_write_pin_high(A1);
  175. gpio_write_pin_high(A2);
  176. gpio_write_pin_low(B4);
  177. break;
  178. case 1:
  179. gpio_write_pin_high(A0);
  180. gpio_write_pin_high(A1);
  181. gpio_write_pin_low(A2);
  182. gpio_write_pin_low(B4);
  183. break;
  184. case 2:
  185. gpio_write_pin_high(A0);
  186. gpio_write_pin_low(A1);
  187. gpio_write_pin_high(A2);
  188. gpio_write_pin_low(B4);
  189. break;
  190. case 3:
  191. gpio_write_pin_high(A0);
  192. gpio_write_pin_low(A1);
  193. gpio_write_pin_low(A2);
  194. gpio_write_pin_low(B4);
  195. break;
  196. case 4:
  197. gpio_write_pin_low(A0);
  198. gpio_write_pin_high(A1);
  199. gpio_write_pin_high(A2);
  200. gpio_write_pin_low(B4);
  201. break;
  202. case 5:
  203. gpio_write_pin_low(A0);
  204. gpio_write_pin_high(A1);
  205. gpio_write_pin_low(A2);
  206. gpio_write_pin_low(B4);
  207. break;
  208. case 6:
  209. gpio_write_pin_low(A0);
  210. gpio_write_pin_low(A1);
  211. gpio_write_pin_high(A2);
  212. gpio_write_pin_low(B4);
  213. break;
  214. case 7:
  215. gpio_write_pin_low(A0);
  216. gpio_write_pin_low(A1);
  217. gpio_write_pin_low(A2);
  218. gpio_write_pin_low(B4);
  219. break;
  220. case 8:
  221. gpio_write_pin_low(A0);
  222. gpio_write_pin_low(A1);
  223. gpio_write_pin_low(A2);
  224. gpio_write_pin_low(C7);
  225. break;
  226. case 9:
  227. gpio_write_pin_high(A0);
  228. gpio_write_pin_high(A1);
  229. gpio_write_pin_high(A2);
  230. gpio_write_pin_low(C7);
  231. break;
  232. case 10:
  233. gpio_write_pin_high(A0);
  234. gpio_write_pin_high(A1);
  235. gpio_write_pin_low(A2);
  236. gpio_write_pin_low(C7);
  237. break;
  238. case 11:
  239. gpio_write_pin_high(A0);
  240. gpio_write_pin_low(A1);
  241. gpio_write_pin_high(A2);
  242. gpio_write_pin_low(C7);
  243. break;
  244. case 12:
  245. gpio_write_pin_high(A0);
  246. gpio_write_pin_low(A1);
  247. gpio_write_pin_low(A2);
  248. gpio_write_pin_low(C7);
  249. break;
  250. case 13:
  251. gpio_write_pin_low(A0);
  252. gpio_write_pin_high(A1);
  253. gpio_write_pin_high(A2);
  254. gpio_write_pin_low(C7);
  255. break;
  256. case 14:
  257. gpio_write_pin_low(A0);
  258. gpio_write_pin_high(A1);
  259. gpio_write_pin_low(A2);
  260. gpio_write_pin_low(C7);
  261. break;
  262. case 15:
  263. gpio_write_pin_low(A0);
  264. gpio_write_pin_low(A1);
  265. gpio_write_pin_high(A2);
  266. gpio_write_pin_low(C7);
  267. break;
  268. case 16:
  269. gpio_write_pin_high(C2);
  270. break;
  271. case 17:
  272. gpio_write_pin_high(C3);
  273. break;
  274. case 18:
  275. gpio_write_pin_high(C5);
  276. break;
  277. }
  278. }
  279. static void unselect_cols(void) {
  280. //Native
  281. gpio_write_pin_high(C2);
  282. gpio_write_pin_high(C3);
  283. gpio_write_pin_high(C5);
  284. //Demultiplexer
  285. gpio_write_pin_low(B4);
  286. gpio_write_pin_low(C7);
  287. gpio_write_pin_high(A0);
  288. gpio_write_pin_high(A1);
  289. gpio_write_pin_high(A2);
  290. }
  291. static void init_pins(void) {
  292. unselect_cols();
  293. for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
  294. gpio_set_pin_input_high(row_pins[x]);
  295. }
  296. gpio_set_pin_output(A0);
  297. gpio_set_pin_output(A1);
  298. gpio_set_pin_output(A2);
  299. gpio_set_pin_output(B4);
  300. gpio_set_pin_output(C7);
  301. gpio_set_pin_output(C2);
  302. gpio_set_pin_output(C3);
  303. gpio_set_pin_output(C5);
  304. }
  305. static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
  306. bool matrix_changed = false;
  307. // Select col and wait for col selecton to stabilize
  308. select_col(current_col);
  309. matrix_io_delay();
  310. // For each row...
  311. for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) {
  312. // Store last value of row prior to reading
  313. matrix_row_t last_row_value = current_matrix[row_index];
  314. // Check row pin state
  315. if (gpio_read_pin(row_pins[row_index]) == 0) {
  316. // Pin LO, set col bit
  317. current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col);
  318. } else {
  319. // Pin HI, clear col bit
  320. current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col);
  321. }
  322. // Determine if the matrix changed state
  323. if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
  324. matrix_changed = true;
  325. }
  326. }
  327. // Unselect col
  328. unselect_col(current_col);
  329. return matrix_changed;
  330. }
  331. void matrix_init_custom(void) {
  332. // initialize key pins
  333. init_pins();
  334. }
  335. bool matrix_scan_custom(matrix_row_t current_matrix[]) {
  336. bool changed = false;
  337. // Set col, read rows
  338. for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
  339. changed |= read_rows_on_col(current_matrix, current_col);
  340. }
  341. return changed;
  342. }