matrix.c (2848B)
1 /* Copyright 2021 xyzz 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #include "util.h" 18 #include "matrix.h" 19 #include "debounce.h" 20 21 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 22 static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 23 24 static void select_col(uint8_t col) { 25 gpio_set_pin_output(col_pins[col]); 26 gpio_write_pin_high(col_pins[col]); 27 } 28 29 static void unselect_col(uint8_t col) { gpio_set_pin_input_low(col_pins[col]); } 30 31 static void unselect_cols(void) { 32 for (uint8_t x = 0; x < MATRIX_COLS; x++) { 33 gpio_set_pin_input_low(col_pins[x]); 34 } 35 } 36 37 static void init_pins(void) { 38 unselect_cols(); 39 for (uint8_t x = 0; x < MATRIX_ROWS; x++) { 40 gpio_set_pin_input_low(row_pins[x]); 41 } 42 } 43 44 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { 45 bool matrix_changed = false; 46 47 // Select col and wait for col selecton to stabilize 48 select_col(current_col); 49 matrix_io_delay(); 50 51 // For each row... 52 for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) { 53 // Store last value of row prior to reading 54 matrix_row_t last_row_value = current_matrix[row_index]; 55 matrix_row_t current_row_value = last_row_value; 56 57 // Check row pin state 58 if (gpio_read_pin(row_pins[row_index]) != 0) { 59 // Pin LO, set col bit 60 current_row_value |= (MATRIX_ROW_SHIFTER << current_col); 61 } else { 62 // Pin HI, clear col bit 63 current_row_value &= ~(MATRIX_ROW_SHIFTER << current_col); 64 } 65 66 // Determine if the matrix changed state 67 if ((last_row_value != current_row_value)) { 68 matrix_changed |= true; 69 current_matrix[row_index] = current_row_value; 70 } 71 } 72 73 // Unselect col 74 unselect_col(current_col); 75 76 return matrix_changed; 77 } 78 79 void matrix_init_custom(void) { 80 // initialize key pins 81 init_pins(); 82 } 83 84 uint8_t matrix_scan_custom(matrix_row_t current_matrix[]) { 85 bool changed = false; 86 87 // Set col, read rows 88 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { 89 changed |= read_rows_on_col(current_matrix, current_col); 90 } 91 92 return (uint8_t)changed; 93 }