matrix.c (12864B)
1 /* 2 Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar 3 Copyright 2019 Evy Dekkers 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 19 #include "matrix.h" 20 #include "gpio.h" 21 22 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 23 24 /* Cols 0 - 16 25 * These columns use two 74HC138 3 to 8 bit demultiplexer. B4, C7 is the enable pin, must be set high (1) to use it. 26 * 27 * col / pin: PA0 PA1 PA2 PB4 PC7 PC2 PC3 PC5 28 * 0: 0 ── 0 ── 0 1 ── 0 0 0 0 29 * ──────────────────────────────────────────── 30 * 1: 0 ── 0 ── 1 1 ── 0 0 0 0 31 * ──────────────────────────────────────────── 32 * 2: 0 ── 1 ── 0 1 ── 0 0 0 0 33 * ──────────────────────────────────────────── 34 * 3: 0 ── 1 ── 1 1 ── 0 0 0 0 35 * ──────────────────────────────────────────── 36 * 4: 1 ── 0 ── 0 1 ── 0 0 0 0 37 * ──────────────────────────────────────────── 38 * 5: 1 ── 0 ── 1 1 ── 0 0 0 0 39 * ──────────────────────────────────────────── 40 * 6: 1 ── 1 ── 0 1 ── 0 0 0 0 41 * ──────────────────────────────────────────── 42 * 7: 1 ── 1 ── 1 1 ── 0 0 0 0 43 * ──────────────────────────────────────────── 44 * 8: 1 ── 1 ── 1 0 ── 1 0 0 0 45 * ──────────────────────────────────────────── 46 * 9: 0 ── 0 ── 0 0 ── 1 0 0 0 47 * ──────────────────────────────────────────── 48 *10: 0 ── 0 ── 1 0 ── 1 0 0 0 49 * ──────────────────────────────────────────── 50 *11: 0 ── 1 ── 0 0 ── 1 0 0 0 51 * ──────────────────────────────────────────── 52 *12: 0 ── 1 ── 1 0 ── 1 0 0 0 53 * ──────────────────────────────────────────── 54 *13: 1 ── 0 ── 0 0 ── 1 0 0 0 55 * ──────────────────────────────────────────── 56 *14: 1 ── 0 ── 1 0 ── 1 0 0 0 57 * ──────────────────────────────────────────── 58 *15: 1 ── 1 ── 0 0 ── 1 0 0 0 59 * ──────────────────────────────────────────── 60 *16: 0 ── 0 ── 0 0 ── 0 1 0 0 61 * ──────────────────────────────────────────── 62 *17: 0 ── 0 ── 0 0 ── 0 0 1 0 63 * ──────────────────────────────────────────── 64 *18: 0 ── 0 ── 0 0 ── 0 0 0 1 65 * 66 */ 67 static void select_col(uint8_t col) { 68 switch (col) { 69 case 0: 70 gpio_write_pin_low(A0); 71 gpio_write_pin_low(A1); 72 gpio_write_pin_low(A2); 73 gpio_write_pin_high(B4); 74 break; 75 case 1: 76 gpio_write_pin_low(A0); 77 gpio_write_pin_low(A1); 78 gpio_write_pin_high(A2); 79 gpio_write_pin_high(B4); 80 break; 81 case 2: 82 gpio_write_pin_low(A0); 83 gpio_write_pin_high(A1); 84 gpio_write_pin_low(A2); 85 gpio_write_pin_high(B4); 86 break; 87 case 3: 88 gpio_write_pin_low(A0); 89 gpio_write_pin_high(A1); 90 gpio_write_pin_high(A2); 91 gpio_write_pin_high(B4); 92 break; 93 case 4: 94 gpio_write_pin_high(A0); 95 gpio_write_pin_low(A1); 96 gpio_write_pin_low(A2); 97 gpio_write_pin_high(B4); 98 break; 99 case 5: 100 gpio_write_pin_high(A0); 101 gpio_write_pin_low(A1); 102 gpio_write_pin_high(A2); 103 gpio_write_pin_high(B4); 104 break; 105 case 6: 106 gpio_write_pin_high(A0); 107 gpio_write_pin_high(A1); 108 gpio_write_pin_low(A2); 109 gpio_write_pin_high(B4); 110 break; 111 case 7: 112 gpio_write_pin_high(A0); 113 gpio_write_pin_high(A1); 114 gpio_write_pin_high(A2); 115 gpio_write_pin_high(B4); 116 break; 117 case 8: 118 gpio_write_pin_high(A0); 119 gpio_write_pin_high(A1); 120 gpio_write_pin_high(A2); 121 gpio_write_pin_high(C7); 122 break; 123 case 9: 124 gpio_write_pin_low(A0); 125 gpio_write_pin_low(A1); 126 gpio_write_pin_low(A2); 127 gpio_write_pin_high(C7); 128 break; 129 case 10: 130 gpio_write_pin_low(A0); 131 gpio_write_pin_low(A1); 132 gpio_write_pin_high(A2); 133 gpio_write_pin_high(C7); 134 break; 135 case 11: 136 gpio_write_pin_low(A0); 137 gpio_write_pin_high(A1); 138 gpio_write_pin_low(A2); 139 gpio_write_pin_high(C7); 140 break; 141 case 12: 142 gpio_write_pin_low(A0); 143 gpio_write_pin_high(A1); 144 gpio_write_pin_high(A2); 145 gpio_write_pin_high(C7); 146 break; 147 case 13: 148 gpio_write_pin_high(A0); 149 gpio_write_pin_low(A1); 150 gpio_write_pin_low(A2); 151 gpio_write_pin_high(C7); 152 break; 153 case 14: 154 gpio_write_pin_high(A0); 155 gpio_write_pin_low(A1); 156 gpio_write_pin_high(A2); 157 gpio_write_pin_high(C7); 158 break; 159 case 15: 160 gpio_write_pin_high(A0); 161 gpio_write_pin_high(A1); 162 gpio_write_pin_low(A2); 163 gpio_write_pin_high(C7); 164 break; 165 case 16: 166 gpio_write_pin_low(C2); 167 break; 168 case 17: 169 gpio_write_pin_low(C3); 170 break; 171 case 18: 172 gpio_write_pin_low(C5); 173 break; 174 } 175 } 176 177 static void unselect_col(uint8_t col) { 178 switch (col) { 179 case 0: 180 gpio_write_pin_high(A0); 181 gpio_write_pin_high(A1); 182 gpio_write_pin_high(A2); 183 gpio_write_pin_low(B4); 184 break; 185 case 1: 186 gpio_write_pin_high(A0); 187 gpio_write_pin_high(A1); 188 gpio_write_pin_low(A2); 189 gpio_write_pin_low(B4); 190 break; 191 case 2: 192 gpio_write_pin_high(A0); 193 gpio_write_pin_low(A1); 194 gpio_write_pin_high(A2); 195 gpio_write_pin_low(B4); 196 break; 197 case 3: 198 gpio_write_pin_high(A0); 199 gpio_write_pin_low(A1); 200 gpio_write_pin_low(A2); 201 gpio_write_pin_low(B4); 202 break; 203 case 4: 204 gpio_write_pin_low(A0); 205 gpio_write_pin_high(A1); 206 gpio_write_pin_high(A2); 207 gpio_write_pin_low(B4); 208 break; 209 case 5: 210 gpio_write_pin_low(A0); 211 gpio_write_pin_high(A1); 212 gpio_write_pin_low(A2); 213 gpio_write_pin_low(B4); 214 break; 215 case 6: 216 gpio_write_pin_low(A0); 217 gpio_write_pin_low(A1); 218 gpio_write_pin_high(A2); 219 gpio_write_pin_low(B4); 220 break; 221 case 7: 222 gpio_write_pin_low(A0); 223 gpio_write_pin_low(A1); 224 gpio_write_pin_low(A2); 225 gpio_write_pin_low(B4); 226 break; 227 case 8: 228 gpio_write_pin_low(A0); 229 gpio_write_pin_low(A1); 230 gpio_write_pin_low(A2); 231 gpio_write_pin_low(C7); 232 break; 233 case 9: 234 gpio_write_pin_high(A0); 235 gpio_write_pin_high(A1); 236 gpio_write_pin_high(A2); 237 gpio_write_pin_low(C7); 238 break; 239 case 10: 240 gpio_write_pin_high(A0); 241 gpio_write_pin_high(A1); 242 gpio_write_pin_low(A2); 243 gpio_write_pin_low(C7); 244 break; 245 case 11: 246 gpio_write_pin_high(A0); 247 gpio_write_pin_low(A1); 248 gpio_write_pin_high(A2); 249 gpio_write_pin_low(C7); 250 break; 251 case 12: 252 gpio_write_pin_high(A0); 253 gpio_write_pin_low(A1); 254 gpio_write_pin_low(A2); 255 gpio_write_pin_low(C7); 256 break; 257 case 13: 258 gpio_write_pin_low(A0); 259 gpio_write_pin_high(A1); 260 gpio_write_pin_high(A2); 261 gpio_write_pin_low(C7); 262 break; 263 case 14: 264 gpio_write_pin_low(A0); 265 gpio_write_pin_high(A1); 266 gpio_write_pin_low(A2); 267 gpio_write_pin_low(C7); 268 break; 269 case 15: 270 gpio_write_pin_low(A0); 271 gpio_write_pin_low(A1); 272 gpio_write_pin_high(A2); 273 gpio_write_pin_low(C7); 274 break; 275 case 16: 276 gpio_write_pin_high(C2); 277 break; 278 case 17: 279 gpio_write_pin_high(C3); 280 break; 281 case 18: 282 gpio_write_pin_high(C5); 283 break; 284 } 285 } 286 287 static void unselect_cols(void) { 288 //Native 289 gpio_write_pin_high(C2); 290 gpio_write_pin_high(C3); 291 gpio_write_pin_high(C5); 292 293 //Demultiplexer 294 gpio_write_pin_low(B4); 295 gpio_write_pin_low(C7); 296 gpio_write_pin_high(A0); 297 gpio_write_pin_high(A1); 298 gpio_write_pin_high(A2); 299 } 300 301 static void init_pins(void) { 302 unselect_cols(); 303 for (uint8_t x = 0; x < MATRIX_ROWS; x++) { 304 gpio_set_pin_input_high(row_pins[x]); 305 } 306 gpio_set_pin_output(A0); 307 gpio_set_pin_output(A1); 308 gpio_set_pin_output(A2); 309 gpio_set_pin_output(B4); 310 gpio_set_pin_output(C7); 311 gpio_set_pin_output(C2); 312 gpio_set_pin_output(C3); 313 gpio_set_pin_output(C5); 314 } 315 316 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { 317 bool matrix_changed = false; 318 319 // Select col and wait for col selecton to stabilize 320 select_col(current_col); 321 matrix_io_delay(); 322 323 // For each row... 324 for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) { 325 // Store last value of row prior to reading 326 matrix_row_t last_row_value = current_matrix[row_index]; 327 328 // Check row pin state 329 if (gpio_read_pin(row_pins[row_index]) == 0) { 330 // Pin LO, set col bit 331 current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col); 332 } else { 333 // Pin HI, clear col bit 334 current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col); 335 } 336 337 // Determine if the matrix changed state 338 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) { 339 matrix_changed = true; 340 } 341 } 342 343 // Unselect col 344 unselect_col(current_col); 345 346 return matrix_changed; 347 } 348 349 void matrix_init_custom(void) { 350 // initialize key pins 351 init_pins(); 352 } 353 354 bool matrix_scan_custom(matrix_row_t current_matrix[]) { 355 bool changed = false; 356 357 // Set col, read rows 358 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { 359 changed |= read_rows_on_col(current_matrix, current_col); 360 } 361 362 return changed; 363 }