matrix.c (2695B)
1 /* Copyright 2022 mohoyt 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 #include "matrix.h" 17 #include "wait.h" 18 19 #define COL_SHIFTER ((uint32_t)1) 20 21 // Column pins 22 static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 23 static const uint8_t col_pins[MATRIX_MUX_COLS] = MATRIX_COL_MUX_PINS; 24 25 // Internal functions 26 27 static void init_pins(void) { 28 // Set cols to outputs, low 29 for (uint8_t pin = 0; pin < MATRIX_MUX_COLS; pin++) { 30 gpio_set_pin_output(col_pins[pin]); 31 } 32 33 // Unselect cols 34 for (uint8_t bit = 0; bit < MATRIX_MUX_COLS; bit++) { 35 gpio_write_pin_low(col_pins[bit]); 36 } 37 38 // Set rows to input, pullup 39 for (uint8_t pin = 0; pin < MATRIX_ROWS; pin++) { 40 gpio_set_pin_input_high(row_pins[pin]); 41 } 42 } 43 44 static void select_col(uint8_t col) 45 { 46 for (uint8_t bit = 0; bit < MATRIX_MUX_COLS; bit++) { 47 uint8_t state = (col & (0b1 << bit)) >> bit; 48 gpio_write_pin(col_pins[bit], state); 49 } 50 } 51 52 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) 53 { 54 bool matrix_changed = false; 55 select_col(current_col); 56 wait_us(5); 57 58 // Read each row sequentially 59 for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) 60 { 61 matrix_row_t last_row_value = current_matrix[row_index]; 62 63 if (!gpio_read_pin(row_pins[row_index])) 64 { 65 current_matrix[row_index] |= (COL_SHIFTER << current_col); 66 } 67 else 68 { 69 current_matrix[row_index] &= ~(COL_SHIFTER << current_col); 70 } 71 72 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) 73 { 74 matrix_changed = true; 75 } 76 } 77 78 return matrix_changed; 79 } 80 81 // Matrix scan functions 82 83 void matrix_init_custom(void) { 84 init_pins(); 85 } 86 87 bool matrix_scan_custom(matrix_row_t current_matrix[]) { 88 bool changed = false; 89 90 //Set col, read rows 91 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { 92 changed |= read_rows_on_col(current_matrix, current_col); 93 } 94 95 return (uint8_t)changed; 96 }