matrix.c (3680B)
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 "wait.h" 18 #include "util.h" 19 #include "matrix.h" 20 21 // Encoder things 22 #define ENC_SW F7 23 static bool read_encoder_switches(matrix_row_t current_matrix[], uint8_t current_row); 24 25 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 26 static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 27 28 /* matrix state(1:on, 0:off) */ 29 extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values 30 extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values 31 32 33 static void select_row(uint8_t row) { 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) { gpio_set_pin_input_high(row_pins[row]); } 39 40 static void unselect_rows(void) { 41 for (uint8_t x = 0; x < MATRIX_ROWS; x++) { 42 gpio_set_pin_input_high(row_pins[x]); 43 } 44 } 45 46 static void init_pins(void) { 47 unselect_rows(); 48 for (uint8_t x = 0; x < MATRIX_COLS; x++) { 49 gpio_set_pin_input_high(col_pins[x]); 50 } 51 } 52 53 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { 54 // Store last value of row prior to reading 55 matrix_row_t last_row_value = current_matrix[current_row]; 56 57 // Clear data in matrix row 58 current_matrix[current_row] = 0; 59 60 // Select row and wait for row selecton to stabilize 61 select_row(current_row); 62 wait_us(30); 63 64 // For each col... 65 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 66 // Select the col pin to read (active low) 67 uint8_t pin_state = gpio_read_pin(col_pins[col_index]); 68 69 // Populate the matrix row with the state of the col pin 70 current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); 71 } 72 73 // Unselect row 74 unselect_row(current_row); 75 76 return (last_row_value != current_matrix[current_row]); 77 } 78 79 80 void matrix_init_custom(void) { 81 // initialize key pins 82 gpio_set_pin_input(ENC_SW); 83 init_pins(); 84 } 85 86 bool matrix_scan_custom(void) { 87 bool changed = false; 88 89 // Set row, read cols 90 for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { 91 changed |= read_cols_on_row(raw_matrix, current_row); 92 } 93 94 // Read encoder switches, already debounced 95 changed |= read_encoder_switches(matrix, 2); 96 97 return changed; 98 } 99 100 static bool read_encoder_switches(matrix_row_t current_matrix[], uint8_t current_row) { 101 // Store last value of row prior to reading 102 matrix_row_t last_row_value = current_matrix[current_row]; 103 104 // Clear data in matrix row 105 current_matrix[current_row] = 0; 106 107 // Debounce the encoder buttons using a shift register 108 static uint8_t btn_1_array; 109 bool btn_1_pressed = 0; 110 btn_1_array <<= 1; 111 btn_1_array |= gpio_read_pin(ENC_SW); 112 (btn_1_array == 0b11111111) ? (btn_1_pressed = 1) : (btn_1_pressed = 0); 113 114 // Populate the matrix row with the state of the encoder 115 current_matrix[current_row] |= btn_1_pressed ? (1 << 0) : 0; 116 117 return (last_row_value != current_matrix[current_row]); 118 }