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.
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.
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/>.
28 static matrix_row_t matrix[MATRIX_ROWS];
29 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
31 volatile uint16_t porta_buffer = 0;
32 volatile uint16_t portb_buffer = 0;
34 static uint32_t switch_buffer = 0;
36 // Trigger on negative edge of any of the sense lines.
37 static void extcb1(EXTDriver *extp, expchannel_t channel) {
42 porta_buffer = palReadPort(GPIOA);
43 portb_buffer = palReadPort(GPIOB);
44 //Disable further interrupts that might occur on same button press.
45 extChannelDisable(&EXTD1,0);
46 extChannelDisable(&EXTD1,1);
47 extChannelDisable(&EXTD1,2);
48 extChannelDisable(&EXTD1,9);
49 extChannelDisable(&EXTD1,10);
50 extChannelDisable(&EXTD1,12);
51 extChannelDisable(&EXTD1,13);
52 extChannelDisable(&EXTD1,14);
53 extChannelDisable(&EXTD1,15);
55 extChannelEnable(&EXTD1,0);
56 extChannelEnable(&EXTD1,1);
57 extChannelEnable(&EXTD1,2);
58 extChannelEnable(&EXTD1,9);
59 extChannelEnable(&EXTD1,10);
60 extChannelEnable(&EXTD1,12);
61 extChannelEnable(&EXTD1,13);
62 extChannelEnable(&EXTD1,14);
63 extChannelEnable(&EXTD1,15);
67 static const EXTConfig extcfg = {
69 {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 }, //0
70 {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 }, //1
71 {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 }, //2
72 {EXT_CH_MODE_DISABLED, NULL},
73 {EXT_CH_MODE_DISABLED, NULL},
74 {EXT_CH_MODE_DISABLED, NULL},
75 {EXT_CH_MODE_DISABLED, NULL},
76 {EXT_CH_MODE_DISABLED, NULL},
77 {EXT_CH_MODE_DISABLED, NULL},
78 {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 }, //9
79 {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 }, //10
80 {EXT_CH_MODE_DISABLED, NULL},
81 {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOB, extcb1 }, //12
82 {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOB, extcb1 }, //13
83 {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOB, extcb1 }, //14
84 {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOB, extcb1 } //15
88 void matrix_init(void) {
89 //Set I/O as pull-up inputs to read states
100 setPinInputHigh(A10);
108 setPinInputHigh(B11);
109 setPinInputHigh(B12);
110 setPinInputHigh(B13);
111 setPinInputHigh(B14);
112 setPinInputHigh(B15);
114 memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t));
115 memset(matrix_debouncing, 0, MATRIX_ROWS * sizeof(matrix_row_t));
117 matrix_init_quantum();
118 //Start interrupt driver
119 extStart(&EXTD1, &extcfg);
122 uint8_t matrix_scan(void) {
123 switch_buffer = ((uint32_t)(porta_buffer & 0x7FF)) | ((uint32_t)(portb_buffer & 0x3F8) << 8);
125 switch (switch_buffer) {
126 case 0x1134E: matrix[0] = 0x01; break;
127 case 0x3774D: matrix[0] = 0x02; break;
128 case 0x10BCC: matrix[0] = 0x04; break;
129 case 0x16B4B: matrix[0] = 0x08; break;
130 case 0x167CA: matrix[0] = 0x10; break;
131 case 0x35FC9: matrix[0] = 0x20; break;
132 case 0x15B48: matrix[0] = 0x40; break;
133 case 0x28347: matrix[0] = 0x80; break;
134 case 0x173C6: matrix[0] = 0x100; break;
135 case 0x143CF: matrix[0] = 0x200; break;
136 case 0x3FDC5: matrix[0] = 0x400; break;
137 case 0x3FD21: matrix[0] = 0x800; break;
138 case 0x3FD77: matrix[0] = 0x1000; break;
139 case 0x3FD72: matrix[0] = 0x2000; break;
141 case 0x3E7FA: matrix[0] = 0x8000; break;
142 case 0x183EE: matrix[0] = 0x10000; break;
143 case 0x197F3: matrix[0] = 0x20000; break;
144 case 0x1AB7E: matrix[0] = 0x40000; break;
146 case 0x107C3: matrix[1] = 0x01; break;
147 case 0x3FD2E: matrix[1] = 0x02; break;
148 case 0x3FD28: matrix[1] = 0x04; break;
149 case 0x3FD3A: matrix[1] = 0x08; break;
150 case 0x3FD2D: matrix[1] = 0x10; break;
151 case 0x3FD2B: matrix[1] = 0x20; break;
152 case 0x3FDA5: matrix[1] = 0x40; break;
153 case 0x3FDAA: matrix[1] = 0x80; break;
154 case 0x3FD36: matrix[1] = 0x100; break;
155 case 0x3FD30: matrix[1] = 0x200; break;
156 case 0x3FDAF: matrix[1] = 0x400; break;
157 case 0x3FD22: matrix[1] = 0x800; break;
158 case 0x157D4: matrix[1] = 0x1000; break;
159 //Does not exist in matrix
161 case 0x1C778: matrix[1] = 0x8000; break;
162 case 0x387ED: matrix[1] = 0x10000; break;
163 case 0x19B74: matrix[1] = 0x20000; break;
164 case 0x3FD7D: matrix[1] = 0x40000; break;
167 case 0x3FDBE: matrix[2] = 0x02; break;
168 case 0x3FDAC: matrix[2] = 0x04; break;
169 case 0x3FDBB: matrix[2] = 0x08; break;
170 case 0x3FD39: matrix[2] = 0x10; break;
171 case 0x3FDB8: matrix[2] = 0x20; break;
172 case 0x3FDB7: matrix[2] = 0x40; break;
173 case 0x3FD35: matrix[2] = 0x80; break;
174 case 0x3FDB4: matrix[2] = 0x100; break;
175 case 0x3FD33: matrix[2] = 0x200; break;
176 case 0x3FDA3: matrix[2] = 0x400; break;
177 case 0x3FD24: matrix[2] = 0x800; break;
178 case 0x0FFDB: matrix[2] = 0x1000; break;
179 case 0x3FDF5: matrix[2] = 0x2000; break;
180 case 0x3FDFF: matrix[2] = 0x4000; break;
181 case 0x3C3E4: matrix[2] = 0x8000; break;
182 case 0x38B6C: matrix[2] = 0x10000; break;
183 case 0x39FF6: matrix[2] = 0x20000; break;
184 case 0x3FDFC: matrix[2] = 0x40000; break;
187 case 0x3FDA6: matrix[3] = 0x02; break;
188 case 0x3FD27: matrix[3] = 0x04; break;
189 case 0x3FD3C: matrix[3] = 0x08; break;
190 case 0x3FDA9: matrix[3] = 0x10; break;
191 case 0x3FDBD: matrix[3] = 0x20; break;
192 case 0x3FDB1: matrix[3] = 0x40; break;
193 case 0x3FDB2: matrix[3] = 0x80; break;
194 case 0x30353: matrix[3] = 0x100; break;
195 case 0x37BD1: matrix[3] = 0x200; break;
196 case 0x363D2: matrix[3] = 0x400; break;
197 case 0x3FD5F: matrix[3] = 0x800; break;
198 //Does not exist in matrix
199 //Does not exist in matrix
201 case 0x1BF00: matrix[3] = 0x8000; break;
202 case 0x18FEB: matrix[3] = 0x10000; break;
203 case 0x3FF69: matrix[3] = 0x20000; break;
204 case 0x3A37B: matrix[3] = 0x40000; break;
206 if ((portb_buffer & 0x1000) == 0) { matrix[1] = 0x4000; break; }
207 if ((portb_buffer & 0x2000) == 0) { matrix[3] = 0x4000; break; }
208 if ((portb_buffer & 0x4000) == 0) { matrix[0] = 0x4000; break; }
209 if ((portb_buffer & 0x8000) == 0) { matrix[2] = 0x01; break; }
215 //Special case for Shift
216 if (readPin(B11) == 0) { matrix[3] |= 0x01; }
218 porta_buffer = 65535;
219 portb_buffer = 65535;
221 matrix_scan_quantum();
225 matrix_row_t matrix_get_row(uint8_t row)
230 void matrix_print(void)
235 __attribute__ ((weak))
236 void matrix_init_kb(void) {
240 __attribute__ ((weak))
241 void matrix_scan_kb(void) {
245 __attribute__ ((weak))
246 void matrix_init_user(void) {
249 __attribute__ ((weak))
250 void matrix_scan_user(void) {