qmk_firmware

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

matrix.c (2788B)


      1 /*
      2 Copyright 2012-2020 Jun Wako, Jack Humbert, Yiancar, Takeshi Nishio
      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 "matrix.h"
     18 
     19 #define ROW_SHIFTER ((uint16_t)1)
     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_row(uint8_t row) {
     25     gpio_set_pin_output(row_pins[row]);
     26     gpio_write_pin_low(row_pins[row]);
     27 }
     28 
     29 static void unselect_row(uint8_t row) {
     30     gpio_set_pin_input_high(row_pins[row]);
     31 }
     32 
     33 static void unselect_rows(void) {
     34     for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
     35         gpio_set_pin_input_high(row_pins[x]);
     36     }
     37 }
     38 
     39 static void init_pins(void) {
     40     unselect_rows();
     41     for (uint8_t x = 0; x < MATRIX_COLS; x++) {
     42         gpio_set_pin_input_high(col_pins[x]);
     43     }
     44 }
     45 
     46 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
     47     // Store last value of row prior to reading
     48     matrix_row_t last_row_value = current_matrix[current_row];
     49 
     50     // Clear data in matrix row
     51     current_matrix[current_row] = 0;
     52 
     53     // Select row and wait for row selecton to stabilize
     54     select_row(current_row);
     55     matrix_io_delay();
     56 
     57     // For each col...
     58     for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
     59 
     60         // skip reading when index equals (= pin itself)
     61         if (col_index != current_row) {
     62             // Check col pin pin_state
     63             if (gpio_read_pin(col_pins[col_index]) == 0) {
     64                 // Pin LO, set col bit
     65                 current_matrix[current_row] |= (ROW_SHIFTER << col_index);
     66             } else {
     67                 // Pin HI, clear col bit
     68                 current_matrix[current_row] &= ~(ROW_SHIFTER << col_index);
     69             }
     70         }
     71     }
     72 
     73     // Unselect row
     74     unselect_row(current_row);
     75 
     76     return (last_row_value != current_matrix[current_row]);
     77 }
     78 
     79 void matrix_init_custom(void) {
     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 }