qmk_firmware

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

matrix.c (4201B)


      1 /*
      2 Copyright 2012-2020 Jun Wako, Jack Humbert, Yiancar, Ein Terakawa, Drashna, Josh Hinnebusch
      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 "util.h"
     18 #include "matrix.h"
     19 #include "debounce.h"
     20 
     21 static const pin_t row_pins[] = MATRIX_ROW_PINS;
     22 static const pin_t col_pins[] = MATRIX_COL_PINS;
     23 
     24 /* matrix state(1:on, 0:off) */
     25 static matrix_row_t last_matrix[MATRIX_ROWS];  // raw values of last scan
     26 
     27 // matrix code
     28 
     29  void select_row(uint8_t row) {
     30     gpio_set_pin_output(row_pins[row]);
     31     gpio_write_pin_low(row_pins[row]);
     32 }
     33 
     34  void unselect_row(uint8_t row) { gpio_set_pin_input_high(row_pins[row]); }
     35 
     36  bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
     37     // Store last value of row prior to reading
     38     matrix_row_t last_row_value = current_matrix[current_row];
     39 
     40     // Clear data in matrix row
     41     current_matrix[current_row] = 0;
     42 
     43     // Select row and wait for row selecton to stabilize
     44     select_row(current_row);
     45     matrix_io_delay();
     46 
     47     // For each col...
     48     for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
     49         // Select the col pin to read (active low)
     50         uint8_t pin_state = gpio_read_pin(col_pins[col_index]);
     51 
     52         // Populate the matrix row with the state of the col pin
     53         current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index);
     54     }
     55 
     56     // Unselect row
     57     unselect_row(current_row);
     58 
     59     return (last_row_value != current_matrix[current_row]);
     60 }
     61 
     62  void select_col(uint8_t col) {
     63     gpio_set_pin_output(col_pins[col]);
     64     gpio_write_pin_low(col_pins[col]);
     65 }
     66 
     67  void unselect_col(uint8_t col) { gpio_set_pin_input_high(col_pins[col]); }
     68 
     69  bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
     70     bool matrix_changed = false;
     71 
     72     // Select col and wait for col selecton to stabilize
     73     select_col(current_col);
     74     matrix_io_delay();
     75 
     76     // For each row...
     77     for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) {
     78         // Store last value of row prior to reading
     79         matrix_row_t last_row_value = current_matrix[row_index];
     80 
     81         // Check row pin state
     82         if (gpio_read_pin(row_pins[row_index]) == 0) {
     83             // Pin LO, set col bit
     84             current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col);
     85         }
     86 
     87         // Determine if the matrix changed state
     88         if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
     89             matrix_changed = true;
     90         }
     91     }
     92 
     93     // Unselect col
     94     unselect_col(current_col);
     95 
     96     return matrix_changed;
     97 }
     98 
     99  void unselect_rows(void) {
    100     for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
    101         gpio_set_pin_input_high(row_pins[x]);
    102     }
    103 }
    104 
    105  void unselect_cols(void) {
    106     for (uint8_t x = 0; x < MATRIX_COLS; x++) {
    107         gpio_set_pin_input_high(col_pins[x]);
    108     }
    109 }
    110 
    111  void init_pins(void) {
    112     unselect_rows();
    113     unselect_cols();
    114 }
    115 
    116 void matrix_init_custom(void) {
    117     // initialize key pins
    118     init_pins();
    119 }
    120 
    121 bool matrix_scan_custom(matrix_row_t current_matrix[]) {
    122     bool changed = false;
    123     for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
    124         last_matrix[current_row] = current_matrix[current_row];
    125         read_cols_on_row(current_matrix, current_row);
    126     }
    127     for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
    128         read_rows_on_col(current_matrix, current_col);
    129     }
    130     for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
    131         if (last_matrix[current_row] != current_matrix[current_row]) {
    132             changed = true;
    133         }
    134     }
    135     return (uint8_t)changed;
    136 }