matrix.c (4257B)
1 /* 2 Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 #include "matrix.h" 18 19 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 20 static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 21 22 static void select_row(uint8_t row) 23 { 24 gpio_set_pin_output(row_pins[row]); 25 gpio_write_pin_low(row_pins[row]); 26 } 27 28 static void unselect_row(uint8_t row) 29 { 30 gpio_set_pin_input_high(row_pins[row]); 31 } 32 33 static void unselect_rows(void) 34 { 35 for(uint8_t x = 0; x < MATRIX_ROWS; x++) { 36 gpio_set_pin_input_high(row_pins[x]); 37 } 38 } 39 40 static void select_col(uint8_t col) 41 { 42 gpio_set_pin_output(col_pins[col]); 43 gpio_write_pin_low(col_pins[col]); 44 } 45 46 static void unselect_col(uint8_t col) 47 { 48 gpio_set_pin_input_high(col_pins[col]); 49 } 50 51 static void unselect_cols(void) 52 { 53 for(uint8_t x = 0; x < MATRIX_COLS; x++) { 54 gpio_set_pin_input_high(col_pins[x]); 55 } 56 } 57 58 static void init_pins(void) { 59 unselect_rows(); 60 unselect_cols(); 61 for (uint8_t x = 0; x < MATRIX_COLS; x++) { 62 gpio_set_pin_input_high(col_pins[x]); 63 } 64 for (uint8_t x = 0; x < MATRIX_ROWS; x++) { 65 gpio_set_pin_input_high(row_pins[x]); 66 } 67 } 68 69 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) 70 { 71 // Store last value of row prior to reading 72 matrix_row_t last_row_value = current_matrix[current_row]; 73 74 // Clear data in matrix row 75 current_matrix[current_row] = 0; 76 77 // Select row and wait for row selecton to stabilize 78 select_row(current_row); 79 matrix_io_delay(); 80 81 // For each col... 82 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 83 84 // Select the col pin to read (active low) 85 uint8_t pin_state = gpio_read_pin(col_pins[col_index]); 86 87 // Populate the matrix row with the state of the col pin 88 current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); 89 } 90 91 // Unselect row 92 unselect_row(current_row); 93 94 return (last_row_value != current_matrix[current_row]); 95 } 96 97 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) 98 { 99 bool matrix_changed = false; 100 101 // Select col and wait for col selecton to stabilize 102 select_col(current_col); 103 matrix_io_delay(); 104 105 // For each row... 106 for(uint8_t row_index = 0; row_index < MATRIX_ROWS/2; row_index++) 107 { 108 uint8_t tmp = row_index + MATRIX_ROWS/2; 109 // Store last value of row prior to reading 110 matrix_row_t last_row_value = current_matrix[tmp]; 111 112 // Check row pin state 113 if (gpio_read_pin(row_pins[row_index]) == 0) 114 { 115 // Pin LO, set col bit 116 current_matrix[tmp] |= (MATRIX_ROW_SHIFTER << current_col); 117 } 118 else 119 { 120 // Pin HI, clear col bit 121 current_matrix[tmp] &= ~(MATRIX_ROW_SHIFTER << current_col); 122 } 123 124 // Determine if the matrix changed state 125 if ((last_row_value != current_matrix[tmp]) && !(matrix_changed)) 126 { 127 matrix_changed = true; 128 } 129 } 130 131 // Unselect col 132 unselect_col(current_col); 133 134 return matrix_changed; 135 } 136 137 void matrix_init_custom(void) { 138 // initialize key pins 139 init_pins(); 140 } 141 142 bool matrix_scan_custom(matrix_row_t current_matrix[]) 143 { 144 bool changed = false; 145 146 // Set row, read cols 147 for (uint8_t current_row = 0; current_row < MATRIX_ROWS / 2; current_row++) { 148 changed |= read_cols_on_row(current_matrix, current_row); 149 } 150 //else 151 // Set col, read rows 152 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { 153 changed |= read_rows_on_col(current_matrix, current_col); 154 } 155 156 return changed; 157 }