diff options
author | Josh Johnson <josh@joshajohnson.com> | 2020-02-11 00:16:27 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-10 14:16:27 +0100 |
commit | 89c528e443561731eb3cf4ed3d49002545421afe (patch) | |
tree | 9beae0152d07b742d7a3ee6323816312d03fb805 /keyboards/hub16/matrix.c | |
parent | 8f333138f5cc76ecc7538100ce93af5e228f0eb0 (diff) | |
download | qmk_firmware-89c528e443561731eb3cf4ed3d49002545421afe.tar.gz qmk_firmware-89c528e443561731eb3cf4ed3d49002545421afe.zip |
[Keyboard] Add support for Hub16 (#7794)
Co-Authored-By: James Young <18669334+noroadsleft@users.noreply.github.com>
Co-Authored-By: fauxpark <fauxpark@gmail.com>
Diffstat (limited to 'keyboards/hub16/matrix.c')
-rw-r--r-- | keyboards/hub16/matrix.c | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/keyboards/hub16/matrix.c b/keyboards/hub16/matrix.c new file mode 100644 index 000000000..ad77c923b --- /dev/null +++ b/keyboards/hub16/matrix.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar | ||
3 | |||
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 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | #include <stdint.h> | ||
18 | #include <stdbool.h> | ||
19 | #include "wait.h" | ||
20 | #include "util.h" | ||
21 | #include "matrix.h" | ||
22 | #include "debounce.h" | ||
23 | #include "quantum.h" | ||
24 | |||
25 | // Encoder things | ||
26 | #define SWITCH_1 F7 | ||
27 | #define SWITCH_2 D7 | ||
28 | static bool read_encoder_values(matrix_row_t current_matrix[], uint8_t current_row); | ||
29 | |||
30 | #ifdef MATRIX_MASKED | ||
31 | extern const matrix_row_t matrix_mask[]; | ||
32 | #endif | ||
33 | |||
34 | #ifdef DIRECT_PINS | ||
35 | static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS; | ||
36 | #elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) | ||
37 | static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; | ||
38 | static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; | ||
39 | #endif | ||
40 | |||
41 | /* matrix state(1:on, 0:off) */ | ||
42 | static matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values | ||
43 | static matrix_row_t matrix[MATRIX_ROWS]; // debounced values | ||
44 | |||
45 | // helper functions | ||
46 | |||
47 | inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); } | ||
48 | |||
49 | inline matrix_row_t matrix_get_row(uint8_t row) { | ||
50 | // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a | ||
51 | // switch blocker installed and the switch is always pressed. | ||
52 | #ifdef MATRIX_MASKED | ||
53 | return matrix[row] & matrix_mask[row]; | ||
54 | #else | ||
55 | return matrix[row]; | ||
56 | #endif | ||
57 | } | ||
58 | |||
59 | // matrix code | ||
60 | |||
61 | #ifdef DIRECT_PINS | ||
62 | |||
63 | static void init_pins(void) { | ||
64 | for (int row = 0; row < MATRIX_ROWS; row++) { | ||
65 | for (int col = 0; col < MATRIX_COLS; col++) { | ||
66 | pin_t pin = direct_pins[row][col]; | ||
67 | if (pin != NO_PIN) { | ||
68 | setPinInputHigh(pin); | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { | ||
75 | matrix_row_t last_row_value = current_matrix[current_row]; | ||
76 | current_matrix[current_row] = 0; | ||
77 | |||
78 | for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { | ||
79 | pin_t pin = direct_pins[current_row][col_index]; | ||
80 | if (pin != NO_PIN) { | ||
81 | current_matrix[current_row] |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | return (last_row_value != current_matrix[current_row]); | ||
86 | } | ||
87 | |||
88 | #elif (DIODE_DIRECTION == COL2ROW) | ||
89 | |||
90 | static void select_row(uint8_t row) { | ||
91 | setPinOutput(row_pins[row]); | ||
92 | writePinLow(row_pins[row]); | ||
93 | } | ||
94 | |||
95 | static void unselect_row(uint8_t row) { setPinInputHigh(row_pins[row]); } | ||
96 | |||
97 | static void unselect_rows(void) { | ||
98 | for (uint8_t x = 0; x < MATRIX_ROWS; x++) { | ||
99 | setPinInputHigh(row_pins[x]); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | static void init_pins(void) { | ||
104 | unselect_rows(); | ||
105 | for (uint8_t x = 0; x < MATRIX_COLS; x++) { | ||
106 | setPinInputHigh(col_pins[x]); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { | ||
111 | // Store last value of row prior to reading | ||
112 | matrix_row_t last_row_value = current_matrix[current_row]; | ||
113 | |||
114 | // Clear data in matrix row | ||
115 | current_matrix[current_row] = 0; | ||
116 | |||
117 | // Select row and wait for row selecton to stabilize | ||
118 | select_row(current_row); | ||
119 | wait_us(30); | ||
120 | |||
121 | // For each col... | ||
122 | for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { | ||
123 | // Select the col pin to read (active low) | ||
124 | uint8_t pin_state = readPin(col_pins[col_index]); | ||
125 | |||
126 | // Populate the matrix row with the state of the col pin | ||
127 | current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); | ||
128 | } | ||
129 | |||
130 | // Unselect row | ||
131 | unselect_row(current_row); | ||
132 | |||
133 | return (last_row_value != current_matrix[current_row]); | ||
134 | } | ||
135 | |||
136 | #elif (DIODE_DIRECTION == ROW2COL) | ||
137 | |||
138 | static void select_col(uint8_t col) { | ||
139 | setPinOutput(col_pins[col]); | ||
140 | writePinLow(col_pins[col]); | ||
141 | } | ||
142 | |||
143 | static void unselect_col(uint8_t col) { setPinInputHigh(col_pins[col]); } | ||
144 | |||
145 | static void unselect_cols(void) { | ||
146 | for (uint8_t x = 0; x < MATRIX_COLS; x++) { | ||
147 | setPinInputHigh(col_pins[x]); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static void init_pins(void) { | ||
152 | unselect_cols(); | ||
153 | for (uint8_t x = 0; x < MATRIX_ROWS; x++) { | ||
154 | setPinInputHigh(row_pins[x]); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { | ||
159 | bool matrix_changed = false; | ||
160 | |||
161 | // Select col and wait for col selecton to stabilize | ||
162 | select_col(current_col); | ||
163 | wait_us(30); | ||
164 | |||
165 | // For each row... | ||
166 | for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) { | ||
167 | // Store last value of row prior to reading | ||
168 | matrix_row_t last_row_value = current_matrix[row_index]; | ||
169 | |||
170 | // Check row pin state | ||
171 | if (readPin(row_pins[row_index]) == 0) { | ||
172 | // Pin LO, set col bit | ||
173 | current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col); | ||
174 | } else { | ||
175 | // Pin HI, clear col bit | ||
176 | current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col); | ||
177 | } | ||
178 | |||
179 | // Determine if the matrix changed state | ||
180 | if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) { | ||
181 | matrix_changed = true; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | // Unselect col | ||
186 | unselect_col(current_col); | ||
187 | |||
188 | return matrix_changed; | ||
189 | } | ||
190 | |||
191 | #endif | ||
192 | |||
193 | void matrix_init(void) { | ||
194 | // initialize key pins | ||
195 | init_pins(); | ||
196 | |||
197 | // initialize matrix state: all keys off | ||
198 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
199 | raw_matrix[i] = 0; | ||
200 | matrix[i] = 0; | ||
201 | } | ||
202 | |||
203 | debounce_init(MATRIX_ROWS); | ||
204 | |||
205 | matrix_init_quantum(); | ||
206 | } | ||
207 | |||
208 | uint8_t matrix_scan(void) { | ||
209 | bool changed = false; | ||
210 | |||
211 | #if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW) | ||
212 | // Set row, read cols | ||
213 | for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { | ||
214 | changed |= read_cols_on_row(raw_matrix, current_row); | ||
215 | } | ||
216 | #elif (DIODE_DIRECTION == ROW2COL) | ||
217 | // Set col, read rows | ||
218 | for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { | ||
219 | changed |= read_rows_on_col(raw_matrix, current_col); | ||
220 | } | ||
221 | #endif | ||
222 | |||
223 | debounce(raw_matrix, matrix, MATRIX_ROWS, changed); | ||
224 | |||
225 | // Read encoder switches, already debounced | ||
226 | changed |= read_encoder_values(matrix, 4); | ||
227 | |||
228 | matrix_scan_quantum(); | ||
229 | return (uint8_t)changed; | ||
230 | } | ||
231 | |||
232 | // Customisations for the encoders | ||
233 | void matrix_init_kb(void){ | ||
234 | setPinInput(SWITCH_1); | ||
235 | setPinInput(SWITCH_2); | ||
236 | } | ||
237 | |||
238 | void matrix_scan_kb(void){ | ||
239 | |||
240 | } | ||
241 | |||
242 | void matrix_print(void){ | ||
243 | |||
244 | } | ||
245 | |||
246 | static bool read_encoder_values(matrix_row_t current_matrix[], uint8_t current_row) { | ||
247 | // Store last value of row prior to reading | ||
248 | matrix_row_t last_row_value = current_matrix[current_row]; | ||
249 | |||
250 | // Clear data in matrix row | ||
251 | current_matrix[current_row] = 0; | ||
252 | |||
253 | // Debounce the encoder buttons using a shift register | ||
254 | static uint8_t btn_1_array; | ||
255 | static uint8_t btn_2_array; | ||
256 | bool btn_1_rising = 0; | ||
257 | bool btn_2_rising = 0; | ||
258 | btn_1_array <<= 1; | ||
259 | btn_2_array <<= 1; | ||
260 | btn_1_array |= readPin(SWITCH_1); | ||
261 | btn_2_array |= readPin(SWITCH_2); | ||
262 | (btn_1_array == 0b01111111) ? (btn_1_rising = 1) : (btn_1_rising = 0); | ||
263 | (btn_2_array == 0b01111111) ? (btn_2_rising = 1) : (btn_2_rising = 0); | ||
264 | |||
265 | // Populate the matrix row with the state of the encoder | ||
266 | current_matrix[current_row] |= btn_1_rising ? (1 << 0) : 0; | ||
267 | current_matrix[current_row] |= btn_2_rising ? (1 << 1) : 0; | ||
268 | |||
269 | return (last_row_value != current_matrix[current_row]); | ||
270 | } \ No newline at end of file | ||