matrix.c (4472B)
1 /* 2 Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar 3 Copyright 2022 jun10000 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 #include "matrix.h" 19 #include "wait.h" 20 21 #if (MATRIX_COLS <= 8) 22 # define ROW_SHIFTER ((uint8_t)1) 23 #elif (MATRIX_COLS <= 16) 24 # define ROW_SHIFTER ((uint16_t)1) 25 #elif (MATRIX_COLS <= 32) 26 # define ROW_SHIFTER ((uint32_t)1) 27 #endif 28 29 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 30 static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 31 32 static void select_row(uint8_t row) 33 { 34 gpio_set_pin_output(row_pins[row]); 35 gpio_write_pin_low(row_pins[row]); 36 } 37 38 static void unselect_row(uint8_t row) 39 { 40 gpio_set_pin_input_high(row_pins[row]); 41 } 42 43 static void unselect_rows(void) 44 { 45 for(uint8_t x = 0; x < MATRIX_ROWS; x++) { 46 gpio_set_pin_input_high(row_pins[x]); 47 } 48 } 49 50 static void select_col(uint8_t col) 51 { 52 gpio_set_pin_output(col_pins[col]); 53 gpio_write_pin_low(col_pins[col]); 54 } 55 56 static void unselect_col(uint8_t col) 57 { 58 gpio_set_pin_input_high(col_pins[col]); 59 } 60 61 static void unselect_cols(void) 62 { 63 for(uint8_t x = 0; x < MATRIX_COLS; x++) { 64 gpio_set_pin_input_high(col_pins[x]); 65 } 66 } 67 68 static void init_pins(void) { 69 unselect_rows(); 70 unselect_cols(); 71 for (uint8_t x = 0; x < MATRIX_COLS; x++) { 72 gpio_set_pin_input_high(col_pins[x]); 73 } 74 for (uint8_t x = 0; x < MATRIX_ROWS; x++) { 75 gpio_set_pin_input_high(row_pins[x]); 76 } 77 } 78 79 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) 80 { 81 // Store last value of row prior to reading 82 matrix_row_t last_row_value = current_matrix[current_row]; 83 84 // Clear data in matrix row 85 current_matrix[current_row] = 0; 86 87 // Select row and wait for row selecton to stabilize 88 select_row(current_row); 89 wait_us(30); 90 91 // For each col... 92 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 93 94 // Select the col pin to read (active low) 95 uint8_t pin_state = gpio_read_pin(col_pins[col_index]); 96 97 // Populate the matrix row with the state of the col pin 98 current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index); 99 } 100 101 // Unselect row 102 unselect_row(current_row); 103 104 return (last_row_value != current_matrix[current_row]); 105 } 106 107 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) 108 { 109 bool matrix_changed = false; 110 111 // Select col and wait for col selecton to stabilize 112 select_col(current_col); 113 wait_us(30); 114 115 // For each row... 116 for(uint8_t row_index = 0; row_index < MATRIX_ROWS/2; row_index++) 117 { 118 uint8_t tmp = row_index + MATRIX_ROWS/2; 119 // Store last value of row prior to reading 120 matrix_row_t last_row_value = current_matrix[tmp]; 121 122 // Check row pin state 123 if (gpio_read_pin(row_pins[row_index]) == 0) 124 { 125 // Pin LO, set col bit 126 current_matrix[tmp] |= (ROW_SHIFTER << current_col); 127 } 128 else 129 { 130 // Pin HI, clear col bit 131 current_matrix[tmp] &= ~(ROW_SHIFTER << current_col); 132 } 133 134 // Determine if the matrix changed state 135 if ((last_row_value != current_matrix[tmp]) && !(matrix_changed)) 136 { 137 matrix_changed = true; 138 } 139 } 140 141 // Unselect col 142 unselect_col(current_col); 143 144 return matrix_changed; 145 } 146 147 void matrix_init_custom(void) { 148 // initialize key pins 149 init_pins(); 150 } 151 152 bool matrix_scan_custom(matrix_row_t current_matrix[]) 153 { 154 bool changed = false; 155 156 // Set row, read cols 157 for (uint8_t current_row = 0; current_row < MATRIX_ROWS / 2; current_row++) { 158 changed |= read_cols_on_row(current_matrix, current_row); 159 } 160 //else 161 // Set col, read rows 162 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { 163 changed |= read_rows_on_col(current_matrix, current_col); 164 } 165 166 return (uint8_t)changed; 167 }