matrix.c (3610B)
1 /* 2 Copyright 2012-2019 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 #include "wait.h" 19 #include "i2c_master.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 unselect_rows(void) { 25 for(uint8_t x = 0; x < MATRIX_ROWS; x++) { 26 gpio_set_pin_input_high(row_pins[x]); 27 } 28 } 29 30 static void select_row(uint8_t row) { 31 gpio_set_pin_output(row_pins[row]); 32 gpio_write_pin_low(row_pins[row]); 33 } 34 35 static void unselect_row(uint8_t row) { 36 gpio_set_pin_input_high(row_pins[row]); 37 } 38 39 static void init_pins(void) { 40 unselect_rows(); 41 // Set I/O 42 uint8_t send_data = 0x07; 43 i2c_write_register((PORT_EXPANDER_ADDRESS << 1), 0x00, &send_data, 1, 20); 44 // Set Pull-up 45 i2c_write_register((PORT_EXPANDER_ADDRESS << 1), 0x06, &send_data, 1, 20); 46 47 for (uint8_t x = 0; x < MATRIX_COLS; x++) { 48 if ( (x > 0) && (x < 12) ) { 49 gpio_set_pin_input_high(col_pins[x]); 50 } 51 } 52 } 53 54 void matrix_init_custom(void) { 55 // TODO: initialize hardware here 56 // Initialize I2C 57 i2c_init(); 58 59 // initialize key pins 60 init_pins(); 61 wait_ms(50); 62 } 63 64 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { 65 // Store last value of row prior to reading 66 matrix_row_t last_row_value = current_matrix[current_row]; 67 68 // Clear data in matrix row 69 current_matrix[current_row] = 0; 70 71 // Select row and wait for row selecton to stabilize 72 select_row(current_row); 73 wait_us(30); 74 75 // For each col... 76 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 77 uint8_t pin_state; 78 // Select the col pin to read (active low) 79 switch (col_index) { 80 case 0 : 81 i2c_read_register((PORT_EXPANDER_ADDRESS << 1), 0x09, &pin_state, 1, 20); 82 pin_state = pin_state & 0x01; 83 break; 84 case 12 : 85 i2c_read_register((PORT_EXPANDER_ADDRESS << 1), 0x09, &pin_state, 1, 20); 86 pin_state = pin_state & (1 << 2); 87 break; 88 case 13 : 89 i2c_read_register((PORT_EXPANDER_ADDRESS << 1), 0x09, &pin_state, 1, 20); 90 pin_state = pin_state & (1 << 1); 91 break; 92 default : 93 pin_state = gpio_read_pin(col_pins[col_index]); 94 } 95 96 // Populate the matrix row with the state of the col pin 97 current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); 98 } 99 100 // Unselect row 101 unselect_row(current_row); 102 103 return (last_row_value != current_matrix[current_row]); 104 } 105 106 bool matrix_scan_custom(matrix_row_t current_matrix[]) { 107 bool matrix_has_changed = false; 108 109 // Set row, read cols 110 for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { 111 matrix_has_changed |= read_cols_on_row(current_matrix, current_row); 112 } 113 114 return matrix_has_changed; 115 }