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