qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

matrix.c (2630B)


      1 /*
      2 Copyright 2022 somepin
      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 
     18 #include "matrix.h"
     19 #include "sn74x138.h"
     20 
     21 static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
     22 
     23 /* All rows use a 74HC138 3 to 8 bit demultiplexer.
     24  *
     25  *     A2   A1   A0
     26  *     D0   D1   D2
     27  * 0:   0    0    0
     28  * 1:   0    0    1
     29  * 2:   0    1    0
     30  * 3:   0    1    1
     31  * 4:   1    0    0
     32  * 5:   1    0    1
     33  * 6:   1    1    0
     34  */
     35 static void select_row(uint8_t row) {
     36     sn74x138_set_addr(row);
     37 }
     38 
     39 static void init_pins(void) {
     40     for (uint8_t x = 0; x < MATRIX_COLS; x++) {
     41         gpio_set_pin_input_high(col_pins[x]);
     42     }
     43 }
     44 
     45 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
     46     bool matrix_changed = false;
     47 
     48     // Store last value of row prior to reading
     49     matrix_row_t last_row_value = current_matrix[current_row];
     50 
     51     // Start with a clear matrix row
     52     current_matrix[current_row] = 0;
     53 
     54     // Select row and wait for row selection to stabilize
     55     select_row(current_row);
     56     matrix_io_delay();
     57 
     58     // For each col...
     59     matrix_row_t row_shifter = MATRIX_ROW_SHIFTER;
     60     for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
     61 
     62         // Select the col pin to read (active low)
     63         uint8_t pin_state = gpio_read_pin(col_pins[col_index]);
     64 
     65         // Populate the matrix row with the state of the col pin
     66         current_matrix[current_row] |=  pin_state ? 0 : (row_shifter << col_index);
     67     }
     68     
     69     // Determine if matrix changed state
     70     if ((last_row_value != current_matrix[current_row]) && !(matrix_changed)) {
     71         matrix_changed = true;
     72     }
     73 
     74     return matrix_changed;
     75 }
     76 
     77 void matrix_init_custom(void) {
     78     // initialize demultiplexer
     79     sn74x138_init();
     80     // initialize key pins
     81     init_pins();
     82 }
     83 
     84 bool matrix_scan_custom(matrix_row_t current_matrix[]) {
     85     bool changed = false;
     86 
     87     // Set row, read cols
     88     for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
     89         changed |= read_cols_on_row(current_matrix, current_row);
     90     }
     91 
     92     return changed;
     93 }