qmk_firmware

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

matrix.c (4472B)


      1 /*
      2 Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar
      3 Copyright 2022 jun10000
      4 
      5 This program is free software: you can redistribute it and/or modify
      6 it under the terms of the GNU General Public License as published by
      7 the Free Software Foundation, either version 2 of the License, or
      8 (at your option) any later version.
      9 
     10 This program is distributed in the hope that it will be useful,
     11 but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 GNU General Public License for more details.
     14 
     15 You should have received a copy of the GNU General Public License
     16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 */
     18 #include "matrix.h"
     19 #include "wait.h"
     20 
     21 #if (MATRIX_COLS <= 8)
     22 #    define ROW_SHIFTER ((uint8_t)1)
     23 #elif (MATRIX_COLS <= 16)
     24 #    define ROW_SHIFTER ((uint16_t)1)
     25 #elif (MATRIX_COLS <= 32)
     26 #    define ROW_SHIFTER  ((uint32_t)1)
     27 #endif
     28 
     29 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
     30 static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
     31 
     32 static void select_row(uint8_t row)
     33 {
     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)
     39 {
     40     gpio_set_pin_input_high(row_pins[row]);
     41 }
     42 
     43 static void unselect_rows(void)
     44 {
     45     for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
     46         gpio_set_pin_input_high(row_pins[x]);
     47     }
     48 }
     49 
     50 static void select_col(uint8_t col)
     51 {
     52     gpio_set_pin_output(col_pins[col]);
     53     gpio_write_pin_low(col_pins[col]);
     54 }
     55 
     56 static void unselect_col(uint8_t col)
     57 {
     58     gpio_set_pin_input_high(col_pins[col]);
     59 }
     60 
     61 static void unselect_cols(void)
     62 {
     63     for(uint8_t x = 0; x < MATRIX_COLS; x++) {
     64         gpio_set_pin_input_high(col_pins[x]);
     65     }
     66 }
     67 
     68 static void init_pins(void) {
     69   unselect_rows();
     70   unselect_cols();
     71   for (uint8_t x = 0; x < MATRIX_COLS; x++) {
     72     gpio_set_pin_input_high(col_pins[x]);
     73   }
     74   for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
     75     gpio_set_pin_input_high(row_pins[x]);
     76   }
     77 }
     78 
     79 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
     80 {
     81     // Store last value of row prior to reading
     82     matrix_row_t last_row_value = current_matrix[current_row];
     83 
     84     // Clear data in matrix row
     85     current_matrix[current_row] = 0;
     86 
     87     // Select row and wait for row selecton to stabilize
     88     select_row(current_row);
     89     wait_us(30);
     90 
     91     // For each col...
     92     for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
     93 
     94         // Select the col pin to read (active low)
     95         uint8_t pin_state = gpio_read_pin(col_pins[col_index]);
     96 
     97         // Populate the matrix row with the state of the col pin
     98         current_matrix[current_row] |=  pin_state ? 0 : (ROW_SHIFTER << col_index);
     99     }
    100 
    101     // Unselect row
    102     unselect_row(current_row);
    103 
    104     return (last_row_value != current_matrix[current_row]);
    105 }
    106 
    107 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
    108 {
    109     bool matrix_changed = false;
    110 
    111     // Select col and wait for col selecton to stabilize
    112     select_col(current_col);
    113     wait_us(30);
    114 
    115     // For each row...
    116     for(uint8_t row_index = 0; row_index < MATRIX_ROWS/2; row_index++)
    117     {
    118         uint8_t tmp = row_index + MATRIX_ROWS/2;
    119         // Store last value of row prior to reading
    120         matrix_row_t last_row_value = current_matrix[tmp];
    121 
    122         // Check row pin state
    123         if (gpio_read_pin(row_pins[row_index]) == 0)
    124         {
    125             // Pin LO, set col bit
    126             current_matrix[tmp] |= (ROW_SHIFTER << current_col);
    127         }
    128         else
    129         {
    130             // Pin HI, clear col bit
    131             current_matrix[tmp] &= ~(ROW_SHIFTER << current_col);
    132         }
    133 
    134         // Determine if the matrix changed state
    135         if ((last_row_value != current_matrix[tmp]) && !(matrix_changed))
    136         {
    137             matrix_changed = true;
    138         }
    139     }
    140 
    141     // Unselect col
    142     unselect_col(current_col);
    143 
    144     return matrix_changed;
    145 }
    146 
    147 void matrix_init_custom(void) {
    148     // initialize key pins
    149     init_pins();
    150 }
    151 
    152 bool matrix_scan_custom(matrix_row_t current_matrix[])
    153 {
    154   bool changed = false;
    155 
    156   // Set row, read cols
    157   for (uint8_t current_row = 0; current_row < MATRIX_ROWS / 2; current_row++) {
    158     changed |= read_cols_on_row(current_matrix, current_row);
    159   }
    160   //else
    161   // Set col, read rows
    162   for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
    163     changed |= read_rows_on_col(current_matrix, current_col);
    164   }
    165   
    166   return (uint8_t)changed;
    167 }