qmk_firmware

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

matrix.c (2848B)


      1 /* Copyright 2021 xyzz
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 2 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15  */
     16 
     17 #include "util.h"
     18 #include "matrix.h"
     19 #include "debounce.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 select_col(uint8_t col) {
     25     gpio_set_pin_output(col_pins[col]);
     26     gpio_write_pin_high(col_pins[col]);
     27 }
     28 
     29 static void unselect_col(uint8_t col) { gpio_set_pin_input_low(col_pins[col]); }
     30 
     31 static void unselect_cols(void) {
     32     for (uint8_t x = 0; x < MATRIX_COLS; x++) {
     33         gpio_set_pin_input_low(col_pins[x]);
     34     }
     35 }
     36 
     37 static void init_pins(void) {
     38     unselect_cols();
     39     for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
     40         gpio_set_pin_input_low(row_pins[x]);
     41     }
     42 }
     43 
     44 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
     45     bool matrix_changed = false;
     46 
     47     // Select col and wait for col selecton to stabilize
     48     select_col(current_col);
     49     matrix_io_delay();
     50 
     51     // For each row...
     52     for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) {
     53         // Store last value of row prior to reading
     54         matrix_row_t last_row_value    = current_matrix[row_index];
     55         matrix_row_t current_row_value = last_row_value;
     56 
     57         // Check row pin state
     58         if (gpio_read_pin(row_pins[row_index]) != 0) {
     59             // Pin LO, set col bit
     60             current_row_value |= (MATRIX_ROW_SHIFTER << current_col);
     61         } else {
     62             // Pin HI, clear col bit
     63             current_row_value &= ~(MATRIX_ROW_SHIFTER << current_col);
     64         }
     65 
     66         // Determine if the matrix changed state
     67         if ((last_row_value != current_row_value)) {
     68             matrix_changed |= true;
     69             current_matrix[row_index] = current_row_value;
     70         }
     71     }
     72 
     73     // Unselect col
     74     unselect_col(current_col);
     75 
     76     return matrix_changed;
     77 }
     78 
     79 void matrix_init_custom(void) {
     80     // initialize key pins
     81     init_pins();
     82 }
     83 
     84 uint8_t matrix_scan_custom(matrix_row_t current_matrix[]) {
     85     bool changed = false;
     86 
     87     // Set col, read rows
     88     for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
     89         changed |= read_rows_on_col(current_matrix, current_col);
     90     }
     91 
     92     return (uint8_t)changed;
     93 }