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.

403 lines
10 KiB

  1. /*
  2. Copyright 2012 Jun Wako
  3. Copyright 2014 Jack Humbert
  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 <stdint.h>
  16. #include <stdbool.h>
  17. #if defined(__AVR__)
  18. #include <avr/io.h>
  19. #include <avr/wdt.h>
  20. #include <avr/interrupt.h>
  21. #include <util/delay.h>
  22. #endif
  23. #include "wait.h"
  24. #include "print.h"
  25. #include "debug.h"
  26. #include "util.h"
  27. #include "matrix.h"
  28. #include "timer.h"
  29. #include "i2c_slave.h"
  30. #include "lufa.h"
  31. #define SLAVE_I2C_ADDRESS 0x19
  32. /* Set 0 if debouncing isn't needed */
  33. #ifndef DEBOUNCE
  34. # define DEBOUNCE 5
  35. #endif
  36. #if (DEBOUNCE > 0)
  37. static uint16_t debouncing_time;
  38. static bool debouncing = false;
  39. #endif
  40. #if (MATRIX_COLS <= 8)
  41. # define print_matrix_header() print("\nr/c 01234567\n")
  42. # define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
  43. # define matrix_bitpop(i) bitpop(matrix[i])
  44. # define ROW_SHIFTER ((uint8_t)1)
  45. #elif (MATRIX_COLS <= 16)
  46. # define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
  47. # define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
  48. # define matrix_bitpop(i) bitpop16(matrix[i])
  49. # define ROW_SHIFTER ((uint16_t)1)
  50. #elif (MATRIX_COLS <= 32)
  51. # define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
  52. # define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
  53. # define matrix_bitpop(i) bitpop32(matrix[i])
  54. # define ROW_SHIFTER ((uint32_t)1)
  55. #endif
  56. #ifdef MATRIX_MASKED
  57. extern const matrix_row_t matrix_mask[];
  58. #endif
  59. #if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
  60. static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
  61. static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
  62. #endif
  63. /* matrix state(1:on, 0:off) */
  64. static matrix_row_t matrix[MATRIX_ROWS];
  65. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  66. #if (DIODE_DIRECTION == COL2ROW)
  67. static void init_cols(void);
  68. static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row);
  69. static void unselect_rows(void);
  70. static void select_row(uint8_t row);
  71. static void unselect_row(uint8_t row);
  72. #elif (DIODE_DIRECTION == ROW2COL)
  73. static void init_rows(void);
  74. static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
  75. static void unselect_cols(void);
  76. static void unselect_col(uint8_t col);
  77. static void select_col(uint8_t col);
  78. #endif
  79. __attribute__ ((weak))
  80. void matrix_init_quantum(void) {
  81. matrix_init_kb();
  82. }
  83. __attribute__ ((weak))
  84. void matrix_scan_quantum(void) {
  85. matrix_scan_kb();
  86. }
  87. __attribute__ ((weak))
  88. void matrix_init_kb(void) {
  89. matrix_init_user();
  90. }
  91. __attribute__ ((weak))
  92. void matrix_scan_kb(void) {
  93. matrix_scan_user();
  94. }
  95. __attribute__ ((weak))
  96. void matrix_init_user(void) {
  97. }
  98. __attribute__ ((weak))
  99. void matrix_scan_user(void) {
  100. }
  101. inline
  102. uint8_t matrix_rows(void) {
  103. return MATRIX_ROWS;
  104. }
  105. inline
  106. uint8_t matrix_cols(void) {
  107. return MATRIX_COLS;
  108. }
  109. void matrix_init(void) {
  110. // initialize row and col
  111. #if (DIODE_DIRECTION == COL2ROW)
  112. unselect_rows();
  113. init_cols();
  114. #elif (DIODE_DIRECTION == ROW2COL)
  115. unselect_cols();
  116. init_rows();
  117. #endif
  118. // initialize matrix state: all keys off
  119. for (uint8_t i=0; i < MATRIX_ROWS; i++) {
  120. matrix[i] = 0;
  121. matrix_debouncing[i] = 0;
  122. }
  123. matrix_init_quantum();
  124. }
  125. uint8_t matrix_scan(void)
  126. {
  127. #if (DIODE_DIRECTION == COL2ROW)
  128. // Set row, read cols
  129. for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
  130. # if (DEBOUNCE > 0)
  131. bool matrix_changed = read_cols_on_row(matrix_debouncing, current_row);
  132. if (matrix_changed) {
  133. debouncing = true;
  134. debouncing_time = timer_read();
  135. }
  136. # else
  137. read_cols_on_row(matrix, current_row);
  138. # endif
  139. }
  140. #elif (DIODE_DIRECTION == ROW2COL)
  141. // Set col, read rows
  142. for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
  143. # if (DEBOUNCE > 0)
  144. bool matrix_changed = read_rows_on_col(matrix_debouncing, current_col);
  145. if (matrix_changed) {
  146. debouncing = true;
  147. debouncing_time = timer_read();
  148. }
  149. # else
  150. read_rows_on_col(matrix, current_col);
  151. # endif
  152. }
  153. #endif
  154. # if (DEBOUNCE > 0)
  155. if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCE)) {
  156. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  157. matrix[i] = matrix_debouncing[i];
  158. }
  159. debouncing = false;
  160. }
  161. # endif
  162. if (USB_DeviceState != DEVICE_STATE_Configured){
  163. i2c_slave_reg[1] = 0x55;
  164. for (uint8_t i = 0; i < MATRIX_ROWS; i++){
  165. i2c_slave_reg[i+2] = matrix[i]; //send matrix over i2c
  166. }
  167. }
  168. matrix_scan_quantum();
  169. return 1;
  170. }
  171. bool matrix_is_modified(void)
  172. {
  173. #if (DEBOUNCE > 0)
  174. if (debouncing) return false;
  175. #endif
  176. return true;
  177. }
  178. inline
  179. bool matrix_is_on(uint8_t row, uint8_t col)
  180. {
  181. return (matrix[row] & ((matrix_row_t)1<<col));
  182. }
  183. inline
  184. matrix_row_t matrix_get_row(uint8_t row)
  185. {
  186. // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a
  187. // switch blocker installed and the switch is always pressed.
  188. #ifdef MATRIX_MASKED
  189. return matrix[row] & matrix_mask[row];
  190. #else
  191. return matrix[row];
  192. #endif
  193. }
  194. void matrix_print(void)
  195. {
  196. print_matrix_header();
  197. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  198. print_hex8(row); print(": ");
  199. print_matrix_row(row);
  200. print("\n");
  201. }
  202. }
  203. uint8_t matrix_key_count(void)
  204. {
  205. uint8_t count = 0;
  206. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  207. count += matrix_bitpop(i);
  208. }
  209. return count;
  210. }
  211. #if (DIODE_DIRECTION == COL2ROW)
  212. static void init_cols(void)
  213. {
  214. for(uint8_t x = 0; x < MATRIX_COLS; x++) {
  215. uint8_t pin = col_pins[x];
  216. _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
  217. _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
  218. }
  219. }
  220. static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
  221. {
  222. // Store last value of row prior to reading
  223. matrix_row_t last_row_value = current_matrix[current_row];
  224. // Clear data in matrix row
  225. current_matrix[current_row] = 0;
  226. // Select row and wait for row selecton to stabilize
  227. select_row(current_row);
  228. wait_us(30);
  229. // For each col...
  230. for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
  231. // Select the col pin to read (active low)
  232. uint8_t pin = col_pins[col_index];
  233. uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF));
  234. // Populate the matrix row with the state of the col pin
  235. current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index);
  236. }
  237. // Unselect row
  238. unselect_row(current_row);
  239. return (last_row_value != current_matrix[current_row]);
  240. }
  241. static void select_row(uint8_t row)
  242. {
  243. uint8_t pin = row_pins[row];
  244. _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
  245. _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
  246. }
  247. static void unselect_row(uint8_t row)
  248. {
  249. uint8_t pin = row_pins[row];
  250. _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
  251. _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
  252. }
  253. static void unselect_rows(void)
  254. {
  255. for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
  256. uint8_t pin = row_pins[x];
  257. _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
  258. _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
  259. }
  260. }
  261. #elif (DIODE_DIRECTION == ROW2COL)
  262. static void init_rows(void)
  263. {
  264. for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
  265. uint8_t pin = row_pins[x];
  266. _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
  267. _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
  268. }
  269. }
  270. static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
  271. {
  272. bool matrix_changed = false;
  273. // Select col and wait for col selecton to stabilize
  274. select_col(current_col);
  275. wait_us(30);
  276. // For each row...
  277. for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++)
  278. {
  279. // Store last value of row prior to reading
  280. matrix_row_t last_row_value = current_matrix[row_index];
  281. // Check row pin state
  282. if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0)
  283. {
  284. // Pin LO, set col bit
  285. current_matrix[row_index] |= (ROW_SHIFTER << current_col);
  286. }
  287. else
  288. {
  289. // Pin HI, clear col bit
  290. current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
  291. }
  292. // Determine if the matrix changed state
  293. if ((last_row_value != current_matrix[row_index]) && !(matrix_changed))
  294. {
  295. matrix_changed = true;
  296. }
  297. }
  298. // Unselect col
  299. unselect_col(current_col);
  300. return matrix_changed;
  301. }
  302. static void select_col(uint8_t col)
  303. {
  304. uint8_t pin = col_pins[col];
  305. _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
  306. _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
  307. }
  308. static void unselect_col(uint8_t col)
  309. {
  310. uint8_t pin = col_pins[col];
  311. _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
  312. _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
  313. }
  314. static void unselect_cols(void)
  315. {
  316. for(uint8_t x = 0; x < MATRIX_COLS; x++) {
  317. uint8_t pin = col_pins[x];
  318. _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
  319. _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
  320. }
  321. }
  322. #endif
  323. //this replases tmk code
  324. void matrix_setup(void){
  325. if (USB_DeviceState != DEVICE_STATE_Configured){
  326. i2c_slave_init(SLAVE_I2C_ADDRESS); //setup address of slave i2c
  327. sei(); //enable interupts
  328. }
  329. }