Commit | Line | Data |
---|---|---|
105c90bd | 1 | /* |
2 | Copyright 2019 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 <string.h> | |
20 | #include "quantum.h" | |
21 | #include "timer.h" | |
22 | #include "wait.h" | |
23 | #include "print.h" | |
24 | #include "matrix.h" | |
25 | #include "ch.h" | |
26 | #include "hal.h" | |
27 | ||
28 | static matrix_row_t matrix[MATRIX_ROWS]; | |
29 | static matrix_row_t matrix_debouncing[MATRIX_ROWS]; | |
30 | ||
31 | volatile uint16_t porta_buffer = 0; | |
32 | volatile uint16_t portb_buffer = 0; | |
33 | ||
34 | static uint32_t switch_buffer = 0; | |
35 | ||
26eef35f JY |
36 | static void pal_cb(void* unused); |
37 | ||
38 | static void enable_input_events(void) | |
39 | { | |
40 | palDisablePadEventI(GPIOA, 0); | |
41 | palDisablePadEventI(GPIOA, 1); | |
42 | palDisablePadEventI(GPIOA, 2); | |
43 | palDisablePadEventI(GPIOA, 9); | |
44 | palDisablePadEventI(GPIOA, 10); | |
45 | palDisablePadEventI(GPIOB, 12); | |
46 | palDisablePadEventI(GPIOB, 13); | |
47 | palDisablePadEventI(GPIOB, 14); | |
48 | palDisablePadEventI(GPIOB, 15); | |
49 | ||
50 | palEnablePadEventI(GPIOA, 0, PAL_EVENT_MODE_FALLING_EDGE); | |
51 | palEnablePadEventI(GPIOA, 1, PAL_EVENT_MODE_FALLING_EDGE); | |
52 | palEnablePadEventI(GPIOA, 2, PAL_EVENT_MODE_FALLING_EDGE); | |
53 | palEnablePadEventI(GPIOA, 9, PAL_EVENT_MODE_FALLING_EDGE); | |
54 | palEnablePadEventI(GPIOA, 10, PAL_EVENT_MODE_FALLING_EDGE); | |
55 | palEnablePadEventI(GPIOB, 12, PAL_EVENT_MODE_FALLING_EDGE); | |
56 | palEnablePadEventI(GPIOB, 13, PAL_EVENT_MODE_FALLING_EDGE); | |
57 | palEnablePadEventI(GPIOB, 14, PAL_EVENT_MODE_FALLING_EDGE); | |
58 | palEnablePadEventI(GPIOB, 15, PAL_EVENT_MODE_FALLING_EDGE); | |
59 | ||
60 | palSetPadCallbackI(GPIOA, 0, &pal_cb, 0); | |
61 | palSetPadCallbackI(GPIOA, 1, &pal_cb, 0); | |
62 | palSetPadCallbackI(GPIOA, 2, &pal_cb, 0); | |
63 | palSetPadCallbackI(GPIOA, 9, &pal_cb, 0); | |
64 | palSetPadCallbackI(GPIOA, 10, &pal_cb, 0); | |
65 | palSetPadCallbackI(GPIOB, 12, &pal_cb, 0); | |
66 | palSetPadCallbackI(GPIOB, 13, &pal_cb, 0); | |
67 | palSetPadCallbackI(GPIOB, 14, &pal_cb, 0); | |
68 | palSetPadCallbackI(GPIOB, 15, &pal_cb, 0); | |
69 | } | |
70 | ||
105c90bd | 71 | // Trigger on negative edge of any of the sense lines. |
26eef35f | 72 | static void pal_cb(void* unused) { |
105c90bd | 73 | |
26eef35f | 74 | (void)unused; |
105c90bd | 75 | chSysLockFromISR(); |
76 | porta_buffer = palReadPort(GPIOA); | |
77 | portb_buffer = palReadPort(GPIOB); | |
78 | //Disable further interrupts that might occur on same button press. | |
26eef35f | 79 | enable_input_events(); |
105c90bd | 80 | chSysUnlockFromISR(); |
81 | } | |
82 | ||
105c90bd | 83 | void matrix_init(void) { |
84 | //Set I/O as pull-up inputs to read states | |
85 | setPinInputHigh(A0); | |
86 | setPinInputHigh(A1); | |
87 | setPinInputHigh(A2); | |
88 | setPinInputHigh(A3); | |
89 | setPinInputHigh(A4); | |
90 | setPinInputHigh(A5); | |
91 | setPinInputHigh(A6); | |
92 | setPinInputHigh(A7); | |
93 | setPinInputHigh(A8); | |
94 | setPinInputHigh(A9); | |
95 | setPinInputHigh(A10); | |
96 | setPinInputHigh(B3); | |
97 | setPinInputHigh(B4); | |
98 | setPinInputHigh(B5); | |
99 | setPinInputHigh(B6); | |
100 | setPinInputHigh(B7); | |
101 | setPinInputHigh(B8); | |
102 | setPinInputHigh(B9); | |
103 | setPinInputHigh(B11); | |
104 | setPinInputHigh(B12); | |
105 | setPinInputHigh(B13); | |
106 | setPinInputHigh(B14); | |
107 | setPinInputHigh(B15); | |
108 | ||
109 | memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t)); | |
110 | memset(matrix_debouncing, 0, MATRIX_ROWS * sizeof(matrix_row_t)); | |
111 | ||
112 | matrix_init_quantum(); | |
26eef35f JY |
113 | |
114 | osalSysLock(); | |
115 | enable_input_events(); | |
116 | osalSysUnlock(); | |
105c90bd | 117 | } |
118 | ||
119 | uint8_t matrix_scan(void) { | |
120 | switch_buffer = ((uint32_t)(porta_buffer & 0x7FF)) | ((uint32_t)(portb_buffer & 0x3F8) << 8); | |
121 | ||
122 | switch (switch_buffer) { | |
123 | case 0x1134E: matrix[0] = 0x01; break; | |
124 | case 0x3774D: matrix[0] = 0x02; break; | |
125 | case 0x10BCC: matrix[0] = 0x04; break; | |
126 | case 0x16B4B: matrix[0] = 0x08; break; | |
127 | case 0x167CA: matrix[0] = 0x10; break; | |
128 | case 0x35FC9: matrix[0] = 0x20; break; | |
129 | case 0x15B48: matrix[0] = 0x40; break; | |
130 | case 0x28347: matrix[0] = 0x80; break; | |
131 | case 0x173C6: matrix[0] = 0x100; break; | |
132 | case 0x143CF: matrix[0] = 0x200; break; | |
133 | case 0x3FDC5: matrix[0] = 0x400; break; | |
134 | case 0x3FD21: matrix[0] = 0x800; break; | |
135 | case 0x3FD77: matrix[0] = 0x1000; break; | |
136 | case 0x3FD72: matrix[0] = 0x2000; break; | |
137 | //Special pin | |
138 | case 0x3E7FA: matrix[0] = 0x8000; break; | |
139 | case 0x183EE: matrix[0] = 0x10000; break; | |
140 | case 0x197F3: matrix[0] = 0x20000; break; | |
141 | case 0x1AB7E: matrix[0] = 0x40000; break; | |
142 | ||
143 | case 0x107C3: matrix[1] = 0x01; break; | |
144 | case 0x3FD2E: matrix[1] = 0x02; break; | |
145 | case 0x3FD28: matrix[1] = 0x04; break; | |
146 | case 0x3FD3A: matrix[1] = 0x08; break; | |
147 | case 0x3FD2D: matrix[1] = 0x10; break; | |
148 | case 0x3FD2B: matrix[1] = 0x20; break; | |
149 | case 0x3FDA5: matrix[1] = 0x40; break; | |
150 | case 0x3FDAA: matrix[1] = 0x80; break; | |
151 | case 0x3FD36: matrix[1] = 0x100; break; | |
152 | case 0x3FD30: matrix[1] = 0x200; break; | |
153 | case 0x3FDAF: matrix[1] = 0x400; break; | |
154 | case 0x3FD22: matrix[1] = 0x800; break; | |
155 | case 0x157D4: matrix[1] = 0x1000; break; | |
156 | //Does not exist in matrix | |
157 | //Special pin | |
158 | case 0x1C778: matrix[1] = 0x8000; break; | |
159 | case 0x387ED: matrix[1] = 0x10000; break; | |
160 | case 0x19B74: matrix[1] = 0x20000; break; | |
161 | case 0x3FD7D: matrix[1] = 0x40000; break; | |
162 | ||
163 | //Special pin | |
164 | case 0x3FDBE: matrix[2] = 0x02; break; | |
165 | case 0x3FDAC: matrix[2] = 0x04; break; | |
166 | case 0x3FDBB: matrix[2] = 0x08; break; | |
167 | case 0x3FD39: matrix[2] = 0x10; break; | |
168 | case 0x3FDB8: matrix[2] = 0x20; break; | |
169 | case 0x3FDB7: matrix[2] = 0x40; break; | |
170 | case 0x3FD35: matrix[2] = 0x80; break; | |
171 | case 0x3FDB4: matrix[2] = 0x100; break; | |
172 | case 0x3FD33: matrix[2] = 0x200; break; | |
173 | case 0x3FDA3: matrix[2] = 0x400; break; | |
174 | case 0x3FD24: matrix[2] = 0x800; break; | |
175 | case 0x0FFDB: matrix[2] = 0x1000; break; | |
176 | case 0x3FDF5: matrix[2] = 0x2000; break; | |
177 | case 0x3FDFF: matrix[2] = 0x4000; break; | |
178 | case 0x3C3E4: matrix[2] = 0x8000; break; | |
179 | case 0x38B6C: matrix[2] = 0x10000; break; | |
180 | case 0x39FF6: matrix[2] = 0x20000; break; | |
181 | case 0x3FDFC: matrix[2] = 0x40000; break; | |
182 | ||
183 | //Special pin | |
184 | case 0x3FDA6: matrix[3] = 0x02; break; | |
185 | case 0x3FD27: matrix[3] = 0x04; break; | |
186 | case 0x3FD3C: matrix[3] = 0x08; break; | |
187 | case 0x3FDA9: matrix[3] = 0x10; break; | |
188 | case 0x3FDBD: matrix[3] = 0x20; break; | |
189 | case 0x3FDB1: matrix[3] = 0x40; break; | |
190 | case 0x3FDB2: matrix[3] = 0x80; break; | |
191 | case 0x30353: matrix[3] = 0x100; break; | |
192 | case 0x37BD1: matrix[3] = 0x200; break; | |
193 | case 0x363D2: matrix[3] = 0x400; break; | |
194 | case 0x3FD5F: matrix[3] = 0x800; break; | |
195 | //Does not exist in matrix | |
196 | //Does not exist in matrix | |
197 | //Special pin | |
198 | case 0x1BF00: matrix[3] = 0x8000; break; | |
199 | case 0x18FEB: matrix[3] = 0x10000; break; | |
200 | case 0x3FF69: matrix[3] = 0x20000; break; | |
201 | case 0x3A37B: matrix[3] = 0x40000; break; | |
26eef35f | 202 | default: |
105c90bd | 203 | if ((portb_buffer & 0x1000) == 0) { matrix[1] = 0x4000; break; } |
204 | if ((portb_buffer & 0x2000) == 0) { matrix[3] = 0x4000; break; } | |
205 | if ((portb_buffer & 0x4000) == 0) { matrix[0] = 0x4000; break; } | |
206 | if ((portb_buffer & 0x8000) == 0) { matrix[2] = 0x01; break; } | |
207 | matrix[0] = 0x00; | |
208 | matrix[1] = 0x00; | |
209 | matrix[2] = 0x00; | |
210 | matrix[3] = 0x00; | |
211 | } | |
212 | //Special case for Shift | |
213 | if (readPin(B11) == 0) { matrix[3] |= 0x01; } | |
214 | ||
215 | porta_buffer = 65535; | |
216 | portb_buffer = 65535; | |
217 | ||
218 | matrix_scan_quantum(); | |
219 | return 1; | |
220 | } | |
221 | ||
222 | matrix_row_t matrix_get_row(uint8_t row) | |
223 | { | |
224 | return matrix[row]; | |
225 | } | |
226 | ||
227 | void matrix_print(void) | |
228 | { | |
229 | ||
230 | } | |
231 | ||
232 | __attribute__ ((weak)) | |
233 | void matrix_init_kb(void) { | |
234 | matrix_init_user(); | |
235 | } | |
236 | ||
237 | __attribute__ ((weak)) | |
238 | void matrix_scan_kb(void) { | |
239 | matrix_scan_user(); | |
240 | } | |
241 | ||
242 | __attribute__ ((weak)) | |
243 | void matrix_init_user(void) { | |
244 | } | |
245 | ||
246 | __attribute__ ((weak)) | |
247 | void matrix_scan_user(void) { | |
248 | } | |
249 |