Commit | Line | Data |
---|---|---|
d1ea398f G |
1 | /* |
2 | Copyright 2012 Jun Wako | |
3 | Copyright 2014 Jack Humbert | |
4 | ||
5 | This program is free software: you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation, either version 2 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | #include <stdint.h> | |
19 | #include <stdbool.h> | |
20 | #if defined(__AVR__) | |
21 | #include <avr/io.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 | ||
30 | #if (MATRIX_COLS <= 8) | |
31 | # define print_matrix_header() print("\nr/c 01234567\n") | |
32 | # define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) | |
33 | # define matrix_bitpop(i) bitpop(matrix[i]) | |
34 | # define ROW_SHIFTER ((uint8_t)1) | |
35 | #elif (MATRIX_COLS <= 16) | |
36 | # define print_matrix_header() print("\nr/c 0123456789ABCDEF\n") | |
37 | # define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row)) | |
38 | # define matrix_bitpop(i) bitpop16(matrix[i]) | |
39 | # define ROW_SHIFTER ((uint16_t)1) | |
40 | #elif (MATRIX_COLS <= 32) | |
41 | # define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n") | |
42 | # define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row)) | |
43 | # define matrix_bitpop(i) bitpop32(matrix[i]) | |
44 | # define ROW_SHIFTER ((uint32_t)1) | |
45 | #endif | |
46 | ||
47 | /* matrix state(1:on, 0:off) */ | |
48 | static matrix_row_t matrix[MATRIX_ROWS]; | |
49 | ||
50 | __attribute__ ((weak)) | |
51 | void matrix_init_quantum(void) { | |
52 | matrix_init_kb(); | |
53 | } | |
54 | ||
55 | __attribute__ ((weak)) | |
56 | void matrix_scan_quantum(void) { | |
57 | matrix_scan_kb(); | |
58 | } | |
59 | ||
60 | __attribute__ ((weak)) | |
61 | void matrix_init_kb(void) { | |
62 | matrix_init_user(); | |
63 | } | |
64 | ||
65 | __attribute__ ((weak)) | |
66 | void matrix_scan_kb(void) { | |
67 | matrix_scan_user(); | |
68 | } | |
69 | ||
70 | __attribute__ ((weak)) | |
71 | void matrix_init_user(void) { | |
72 | } | |
73 | ||
74 | __attribute__ ((weak)) | |
75 | void matrix_scan_user(void) { | |
76 | } | |
77 | ||
78 | inline | |
79 | uint8_t matrix_rows(void) { | |
80 | return MATRIX_ROWS; | |
81 | } | |
82 | ||
83 | inline | |
84 | uint8_t matrix_cols(void) { | |
85 | return MATRIX_COLS; | |
86 | } | |
87 | ||
88 | void matrix_init(void) { | |
89 | ||
90 | matrix_init_quantum(); | |
91 | } | |
92 | ||
93 | uint8_t matrix_scan(void) | |
94 | { | |
95 | SERIAL_UART_INIT(); | |
96 | ||
97 | uint32_t timeout = 0; | |
98 | ||
99 | //the s character requests the RF slave to send the matrix | |
100 | SERIAL_UART_DATA = 's'; | |
101 | ||
102 | //trust the external keystates entirely, erase the last data | |
103 | uint8_t uart_data[14] = {0}; | |
104 | ||
105 | //there are 10 bytes corresponding to 10 columns, and an end byte | |
106 | for (uint8_t i = 0; i < 14; i++) { | |
107 | //wait for the serial data, timeout if it's been too long | |
108 | //this only happened in testing with a loose wire, but does no | |
109 | //harm to leave it in here | |
110 | while(!SERIAL_UART_RXD_PRESENT){ | |
111 | timeout++; | |
112 | if (timeout > 10000){ | |
113 | break; | |
114 | } | |
6d2071ad | 115 | } |
d1ea398f G |
116 | uart_data[i] = SERIAL_UART_DATA; |
117 | } | |
118 | ||
119 | //check for the end packet, the key state bytes use the LSBs, so 0xE0 | |
120 | //will only show up here if the correct bytes were recieved | |
121 | if (uart_data[10] == 0xE0) | |
122 | { | |
123 | //shifting and transferring the keystates to the QMK matrix variable | |
124 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |
125 | matrix[i] = (uint16_t) uart_data[i*2] | (uint16_t) uart_data[i*2+1] << 6; | |
126 | } | |
127 | } | |
128 | ||
129 | ||
130 | matrix_scan_quantum(); | |
131 | return 1; | |
132 | } | |
133 | ||
134 | inline | |
135 | bool matrix_is_on(uint8_t row, uint8_t col) | |
136 | { | |
6d2071ad | 137 | return (matrix[row] & ((matrix_row_t)1<<col)); |
d1ea398f G |
138 | } |
139 | ||
140 | inline | |
141 | matrix_row_t matrix_get_row(uint8_t row) | |
142 | { | |
143 | return matrix[row]; | |
144 | } | |
145 | ||
146 | void matrix_print(void) | |
147 | { | |
148 | print_matrix_header(); | |
149 | ||
150 | for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | |
151 | phex(row); print(": "); | |
152 | print_matrix_row(row); | |
153 | print("\n"); | |
154 | } | |
155 | } | |
156 | ||
157 | uint8_t matrix_key_count(void) | |
158 | { | |
159 | uint8_t count = 0; | |
160 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |
161 | count += matrix_bitpop(i); | |
162 | } | |
163 | return count; | |
164 | } |