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.

362 lines
12 KiB

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