matrix.c (11821B)
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 - 14 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: PF4 PF1 PF0 PF5 PF6 66 * 0: 0 ── 0 ── 1 1 ── 0 67 * ───────────────────────────────────── 68 * 1: 0 ── 1 ── 0 1 ── 0 69 * ───────────────────────────────────── 70 * 2: 0 ── 1 ── 1 1 ── 0 71 * ───────────────────────────────────── 72 * 3: 1 ── 0 ── 0 1 ── 0 73 * ───────────────────────────────────── 74 * 4: 1 ── 0 ── 1 1 ── 0 75 * ───────────────────────────────────── 76 * 5: 1 ── 1 ── 1 1 ── 0 77 * ───────────────────────────────────── 78 * 6: 1 ── 1 ── 1 0 ── 1 79 * ───────────────────────────────────── 80 * 7: 0 ── 0 ── 0 0 ── 1 81 * ───────────────────────────────────── 82 * 8: 0 ── 0 ── 1 0 ── 1 83 * ───────────────────────────────────── 84 * 9: 0 ── 1 ── 0 0 ── 1 85 * ───────────────────────────────────── 86 *10: 0 ── 1 ── 1 0 ── 1 87 * ───────────────────────────────────── 88 *11: 1 ── 0 ── 0 0 ── 1 89 * ───────────────────────────────────── 90 *12: 1 ── 0 ── 1 0 ── 1 91 * ───────────────────────────────────── 92 *13: 1 ── 1 ── 0 0 ── 1 93 * ───────────────────────────────────── 94 *14: 0 ── 0 ── 0 1 ── 0 95 * 96 */ 97 static void select_col(uint8_t col) { 98 switch (col) { 99 case 0: 100 gpio_write_pin_low(F4); 101 gpio_write_pin_low(F1); 102 gpio_write_pin_high(F0); 103 gpio_write_pin_high(F5); 104 break; 105 case 1: 106 gpio_write_pin_low(F4); 107 gpio_write_pin_high(F1); 108 gpio_write_pin_low(F0); 109 gpio_write_pin_high(F5); 110 break; 111 case 2: 112 gpio_write_pin_low(F4); 113 gpio_write_pin_high(F1); 114 gpio_write_pin_high(F0); 115 gpio_write_pin_high(F5); 116 break; 117 case 3: 118 gpio_write_pin_high(F4); 119 gpio_write_pin_low(F1); 120 gpio_write_pin_low(F0); 121 gpio_write_pin_high(F5); 122 break; 123 case 4: 124 gpio_write_pin_high(F4); 125 gpio_write_pin_low(F1); 126 gpio_write_pin_high(F0); 127 gpio_write_pin_high(F5); 128 break; 129 case 5: 130 gpio_write_pin_high(F4); 131 gpio_write_pin_high(F1); 132 gpio_write_pin_high(F0); 133 gpio_write_pin_high(F5); 134 break; 135 case 6: 136 gpio_write_pin_high(F4); 137 gpio_write_pin_high(F1); 138 gpio_write_pin_high(F0); 139 gpio_write_pin_high(F6); 140 break; 141 case 7: 142 gpio_write_pin_low(F4); 143 gpio_write_pin_low(F1); 144 gpio_write_pin_low(F0); 145 gpio_write_pin_high(F6); 146 break; 147 case 8: 148 gpio_write_pin_low(F4); 149 gpio_write_pin_low(F1); 150 gpio_write_pin_high(F0); 151 gpio_write_pin_high(F6); 152 break; 153 case 9: 154 gpio_write_pin_low(F4); 155 gpio_write_pin_high(F1); 156 gpio_write_pin_low(F0); 157 gpio_write_pin_high(F6); 158 break; 159 case 10: 160 gpio_write_pin_low(F4); 161 gpio_write_pin_high(F1); 162 gpio_write_pin_high(F0); 163 gpio_write_pin_high(F6); 164 break; 165 case 11: 166 gpio_write_pin_high(F4); 167 gpio_write_pin_low(F1); 168 gpio_write_pin_low(F0); 169 gpio_write_pin_high(F6); 170 break; 171 case 12: 172 gpio_write_pin_high(F4); 173 gpio_write_pin_low(F1); 174 gpio_write_pin_high(F0); 175 gpio_write_pin_high(F6); 176 break; 177 case 13: 178 gpio_write_pin_high(F4); 179 gpio_write_pin_high(F1); 180 gpio_write_pin_low(F0); 181 gpio_write_pin_high(F6); 182 break; 183 case 14: 184 gpio_write_pin_low(F4); 185 gpio_write_pin_low(F1); 186 gpio_write_pin_low(F0); 187 gpio_write_pin_high(F5); 188 break; 189 } 190 } 191 192 static void unselect_col(uint8_t col) { 193 switch (col) { 194 case 0: 195 gpio_write_pin_high(F4); 196 gpio_write_pin_high(F1); 197 gpio_write_pin_low(F0); 198 gpio_write_pin_low(F5); 199 break; 200 case 1: 201 gpio_write_pin_high(F4); 202 gpio_write_pin_low(F1); 203 gpio_write_pin_high(F0); 204 gpio_write_pin_low(F5); 205 break; 206 case 2: 207 gpio_write_pin_high(F4); 208 gpio_write_pin_low(F1); 209 gpio_write_pin_low(F0); 210 gpio_write_pin_low(F5); 211 break; 212 case 3: 213 gpio_write_pin_low(F4); 214 gpio_write_pin_high(F1); 215 gpio_write_pin_high(F0); 216 gpio_write_pin_low(F5); 217 break; 218 case 4: 219 gpio_write_pin_low(F4); 220 gpio_write_pin_high(F1); 221 gpio_write_pin_low(F0); 222 gpio_write_pin_low(F5); 223 break; 224 case 5: 225 gpio_write_pin_low(F4); 226 gpio_write_pin_low(F1); 227 gpio_write_pin_low(F0); 228 gpio_write_pin_low(F5); 229 break; 230 case 6: 231 gpio_write_pin_low(F4); 232 gpio_write_pin_low(F1); 233 gpio_write_pin_low(F0); 234 gpio_write_pin_low(F6); 235 break; 236 case 7: 237 gpio_write_pin_high(F4); 238 gpio_write_pin_high(F1); 239 gpio_write_pin_high(F0); 240 gpio_write_pin_low(F6); 241 break; 242 case 8: 243 gpio_write_pin_high(F4); 244 gpio_write_pin_high(F1); 245 gpio_write_pin_low(F0); 246 gpio_write_pin_low(F6); 247 break; 248 case 9: 249 gpio_write_pin_high(F4); 250 gpio_write_pin_low(F1); 251 gpio_write_pin_high(F0); 252 gpio_write_pin_low(F6); 253 break; 254 case 10: 255 gpio_write_pin_high(F4); 256 gpio_write_pin_low(F1); 257 gpio_write_pin_low(F0); 258 gpio_write_pin_low(F6); 259 break; 260 case 11: 261 gpio_write_pin_low(F4); 262 gpio_write_pin_high(F1); 263 gpio_write_pin_high(F0); 264 gpio_write_pin_low(F6); 265 break; 266 case 12: 267 gpio_write_pin_low(F4); 268 gpio_write_pin_high(F1); 269 gpio_write_pin_low(F0); 270 gpio_write_pin_low(F6); 271 break; 272 case 13: 273 gpio_write_pin_low(F4); 274 gpio_write_pin_low(F1); 275 gpio_write_pin_high(F0); 276 gpio_write_pin_low(F6); 277 break; 278 case 14: 279 gpio_write_pin_high(F4); 280 gpio_write_pin_high(F1); 281 gpio_write_pin_high(F0); 282 gpio_write_pin_low(F5); 283 break; 284 } 285 } 286 287 static void unselect_cols(void) { 288 289 //Demultiplexer 290 gpio_write_pin_high(F0); 291 gpio_write_pin_high(F1); 292 gpio_write_pin_high(F4); 293 gpio_write_pin_low(F5); 294 gpio_write_pin_low(F6); 295 } 296 297 static void init_pins(void) { 298 unselect_cols(); 299 for (uint8_t x = 0; x < MATRIX_ROWS; x++) { 300 gpio_set_pin_input_high(row_pins[x]); 301 } 302 gpio_set_pin_output(F0); 303 gpio_set_pin_output(F1); 304 gpio_set_pin_output(F4); 305 gpio_set_pin_output(F5); 306 gpio_set_pin_output(F6); 307 } 308 309 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { 310 bool matrix_changed = false; 311 312 // Select col and wait for col selecton to stabilize 313 select_col(current_col); 314 wait_us(30); 315 316 // For each row... 317 for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) { 318 // Store last value of row prior to reading 319 matrix_row_t last_row_value = current_matrix[row_index]; 320 321 // Check row pin state 322 if (gpio_read_pin(row_pins[row_index]) == 0) { 323 // Pin LO, set col bit 324 current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col); 325 } else { 326 // Pin HI, clear col bit 327 current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col); 328 } 329 330 // Determine if the matrix changed state 331 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) { 332 matrix_changed = true; 333 } 334 } 335 336 // Unselect col 337 unselect_col(current_col); 338 339 return matrix_changed; 340 } 341 342 #endif 343 344 void matrix_init_custom(void) { 345 // initialize key pins 346 init_pins(); 347 } 348 349 bool matrix_scan_custom(matrix_row_t current_matrix[]) { 350 bool changed = false; 351 352 #if defined(DIRECT_PINS) || (DIODE_DIRECTION == ROW2COL) 353 // Set col, read rows 354 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { 355 changed |= read_rows_on_col(current_matrix, current_col); 356 } 357 #endif 358 359 return changed; 360 }