matrix.c (3994B)
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 SWITCH_1 F7 23 #define SWITCH_2 D7 24 static bool read_encoder_switches(matrix_row_t current_matrix[], uint8_t current_row); 25 26 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 27 static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 28 29 /* matrix state(1:on, 0:off) */ 30 extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values 31 extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values 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(SWITCH_1); 83 gpio_set_pin_input(SWITCH_2); 84 init_pins(); 85 } 86 87 bool matrix_scan_custom(void) { 88 bool changed = false; 89 90 // Set row, read cols 91 for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { 92 changed |= read_cols_on_row(raw_matrix, current_row); 93 } 94 95 // Read encoder switches, already debounced 96 changed |= read_encoder_switches(matrix, 4); 97 98 return changed; 99 } 100 101 static bool read_encoder_switches(matrix_row_t current_matrix[], uint8_t current_row) { 102 // Store last value of row prior to reading 103 matrix_row_t last_row_value = current_matrix[current_row]; 104 105 // Clear data in matrix row 106 current_matrix[current_row] = 0; 107 108 // Debounce the encoder buttons using a shift register 109 static uint8_t btn_1_array; 110 static uint8_t btn_2_array; 111 bool btn_1_rise = 0; 112 bool btn_2_rise = 0; 113 btn_1_array <<= 1; 114 btn_2_array <<= 1; 115 btn_1_array |= gpio_read_pin(SWITCH_1); 116 btn_2_array |= gpio_read_pin(SWITCH_2); 117 (btn_1_array == 0b01111111) ? (btn_1_rise = 1) : (btn_1_rise = 0); 118 (btn_2_array == 0b01111111) ? (btn_2_rise = 1) : (btn_2_rise = 0); 119 120 // Populate the matrix row with the state of the encoder 121 current_matrix[current_row] |= btn_1_rise ? (1 << 0) : 0; 122 current_matrix[current_row] |= btn_2_rise ? (1 << 1) : 0; 123 124 return (last_row_value != current_matrix[current_row]); 125 }