qmk_firmware

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

matrix.c (3680B)


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