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