qmk_firmware

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

matrix.c (15768B)


      1 /*
      2 Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar
      3 Copyright 2019 Evy Dekkers
      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 
     19 #include "wait.h"
     20 #include "util.h"
     21 #include "matrix.h"
     22 #include "debounce.h"
     23 
     24 #ifdef DIRECT_PINS
     25 static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
     26 #elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
     27 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
     28 //static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
     29 #endif
     30 
     31 // matrix code
     32 
     33 #ifdef DIRECT_PINS
     34 
     35 static void init_pins(void) {
     36     for (int row = 0; row < MATRIX_ROWS; row++) {
     37         for (int col = 0; col < MATRIX_COLS; col++) {
     38             pin_t pin = direct_pins[row][col];
     39             if (pin != NO_PIN) {
     40                 gpio_set_pin_input_high(pin);
     41             }
     42         }
     43     }
     44 }
     45 
     46 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
     47     matrix_row_t last_row_value = current_matrix[current_row];
     48     current_matrix[current_row] = 0;
     49 
     50     for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
     51         pin_t pin = direct_pins[current_row][col_index];
     52         if (pin != NO_PIN) {
     53             current_matrix[current_row] |= gpio_read_pin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index);
     54         }
     55     }
     56 
     57     return (last_row_value != current_matrix[current_row]);
     58 }
     59 
     60 #elif (DIODE_DIRECTION == COL2ROW)
     61 
     62 static void select_row(uint8_t row) {
     63     gpio_set_pin_output(row_pins[row]);
     64     gpio_write_pin_low(row_pins[row]);
     65 }
     66 
     67 static void unselect_row(uint8_t row) { gpio_set_pin_input_high(row_pins[row]); }
     68 
     69 static void unselect_rows(void) {
     70     for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
     71         gpio_set_pin_input_high(row_pins[x]);
     72     }
     73 }
     74 
     75 static void init_pins(void) {
     76     unselect_rows();
     77     for (uint8_t x = 0; x < MATRIX_COLS; x++) {
     78         gpio_set_pin_input_high(col_pins[x]);
     79     }
     80 }
     81 
     82 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
     83     // Store last value of row prior to reading
     84     matrix_row_t last_row_value = current_matrix[current_row];
     85 
     86     // Clear data in matrix row
     87     current_matrix[current_row] = 0;
     88 
     89     // Select row and wait for row selecton to stabilize
     90     select_row(current_row);
     91     wait_us(30);
     92 
     93     // For each col...
     94     for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
     95 
     96         // Select the col pin to read (active low)
     97         uint8_t pin_state = gpio_read_pin(col_pins[col_index]);
     98 
     99         // Populate the matrix row with the state of the col pin
    100         current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index);
    101     }
    102 
    103     // Unselect row
    104     unselect_row(current_row);
    105 
    106     return (last_row_value != current_matrix[current_row]);
    107 }
    108 
    109 #elif (DIODE_DIRECTION == ROW2COL)
    110 
    111 /* Cols 0 - 16
    112  * These columns use two 74HC138 3 to 8 bit demultiplexer. B4, C7 is the enable pin, must be set high (1) to use it.
    113  *
    114  * col / pin:     PA0  PA1  PA2  PB4  PC7  PC2  PC3  PC5
    115  * 0:              0 ── 0 ── 0    1 ── 0    0    0    0
    116  * ────────────────────────────────────────────
    117  * 1:              0 ── 0 ── 1    1 ── 0    0    0    0
    118  * ────────────────────────────────────────────    
    119  * 2:              0 ── 1 ── 0    1 ── 0    0    0    0 
    120  * ────────────────────────────────────────────    
    121  * 3:              0 ── 1 ── 1    1 ── 0    0    0    0 
    122  * ────────────────────────────────────────────    
    123  * 4:              1 ── 0 ── 0    1 ── 0    0    0    0 
    124  * ────────────────────────────────────────────    
    125  * 5:              1 ── 0 ── 1    1 ── 0    0    0    0 
    126  * ────────────────────────────────────────────    
    127  * 6:              1 ── 1 ── 0    1 ── 0    0    0    0 
    128  * ────────────────────────────────────────────    
    129  * 7:              1 ── 1 ── 1    1 ── 0    0    0    0 
    130  * ────────────────────────────────────────────    
    131  * 8:              1 ── 1 ── 1    0 ── 1    0    0    0 
    132  * ────────────────────────────────────────────    
    133  * 9:              0 ── 0 ── 0    0 ── 1    0    0    0 
    134  * ────────────────────────────────────────────    
    135  *10:              0 ── 0 ── 1    0 ── 1    0    0    0 
    136  * ────────────────────────────────────────────    
    137  *11:              0 ── 1 ── 0    0 ── 1    0    0    0 
    138  * ────────────────────────────────────────────    
    139  *12:              0 ── 1 ── 1    0 ── 1    0    0    0 
    140  * ────────────────────────────────────────────    
    141  *13:              1 ── 0 ── 0    0 ── 1    0    0    0 
    142  * ────────────────────────────────────────────    
    143  *14:              1 ── 0 ── 1    0 ── 1    0    0    0 
    144  * ────────────────────────────────────────────    
    145  *15:              1 ── 1 ── 0    0 ── 1    0    0    0 
    146  * ────────────────────────────────────────────    
    147  *16:              0 ── 0 ── 0    0 ── 0    1    0    0  
    148  * ────────────────────────────────────────────    
    149  *17:              0 ── 0 ── 0    0 ── 0    0    1    0  
    150  * ────────────────────────────────────────────    
    151  *18:              0 ── 0 ── 0    0 ── 0    0    0    1  
    152  *
    153  */
    154 static void select_col(uint8_t col) {
    155     switch (col) {
    156         case 0:
    157           gpio_write_pin_low(A0);
    158           gpio_write_pin_low(A1);
    159           gpio_write_pin_low(A2);
    160           gpio_write_pin_high(B4);
    161           break;
    162         case 1:
    163           gpio_write_pin_low(A0);
    164           gpio_write_pin_low(A1);
    165           gpio_write_pin_high(A2);
    166           gpio_write_pin_high(B4);
    167           break;
    168         case 2:
    169           gpio_write_pin_low(A0);
    170           gpio_write_pin_high(A1);
    171           gpio_write_pin_low(A2);
    172           gpio_write_pin_high(B4);
    173           break;
    174         case 3:
    175           gpio_write_pin_low(A0);
    176           gpio_write_pin_high(A1);
    177           gpio_write_pin_high(A2);
    178           gpio_write_pin_high(B4);
    179           break;
    180         case 4:
    181           gpio_write_pin_high(A0);
    182           gpio_write_pin_low(A1);
    183           gpio_write_pin_low(A2);
    184           gpio_write_pin_high(B4);
    185           break;
    186         case 5:
    187           gpio_write_pin_high(A0);
    188           gpio_write_pin_low(A1);
    189           gpio_write_pin_high(A2);
    190           gpio_write_pin_high(B4);
    191           break;
    192         case 6:
    193           gpio_write_pin_high(A0);
    194           gpio_write_pin_high(A1);
    195           gpio_write_pin_low(A2);
    196           gpio_write_pin_high(B4);
    197           break;
    198         case 7:
    199           gpio_write_pin_high(A0);
    200           gpio_write_pin_high(A1);
    201           gpio_write_pin_high(A2);
    202           gpio_write_pin_high(B4);
    203           break;
    204         case 8:
    205           gpio_write_pin_high(A0);
    206           gpio_write_pin_high(A1);
    207           gpio_write_pin_high(A2);
    208           gpio_write_pin_high(C7);
    209           break;
    210         case 9:
    211           gpio_write_pin_low(A0);
    212           gpio_write_pin_low(A1);
    213           gpio_write_pin_low(A2);
    214           gpio_write_pin_high(C7);
    215           break;
    216         case 10:
    217           gpio_write_pin_low(A0);
    218           gpio_write_pin_low(A1);
    219           gpio_write_pin_high(A2);
    220           gpio_write_pin_high(C7);
    221           break;
    222         case 11:
    223           gpio_write_pin_low(A0);
    224           gpio_write_pin_high(A1);
    225           gpio_write_pin_low(A2);
    226           gpio_write_pin_high(C7);
    227           break;
    228         case 12:
    229           gpio_write_pin_low(A0);
    230           gpio_write_pin_high(A1);
    231           gpio_write_pin_high(A2);
    232           gpio_write_pin_high(C7);
    233           break;
    234         case 13:
    235           gpio_write_pin_high(A0);
    236           gpio_write_pin_low(A1);
    237           gpio_write_pin_low(A2);
    238           gpio_write_pin_high(C7);
    239           break;
    240         case 14:
    241           gpio_write_pin_high(A0);
    242           gpio_write_pin_low(A1);
    243           gpio_write_pin_high(A2);
    244           gpio_write_pin_high(C7);
    245           break;
    246         case 15:
    247           gpio_write_pin_high(A0);
    248           gpio_write_pin_high(A1);
    249           gpio_write_pin_low(A2);
    250           gpio_write_pin_high(C7);
    251           break;
    252         case 16:
    253           gpio_write_pin_low(C2);
    254           break;
    255         case 17:
    256           gpio_write_pin_low(C3);
    257           break;
    258         case 18:
    259           gpio_write_pin_low(C5);
    260           break;
    261     }
    262 }
    263 
    264 static void unselect_col(uint8_t col) {
    265     switch (col) {
    266         case 0:
    267           gpio_write_pin_high(A0);
    268           gpio_write_pin_high(A1);
    269           gpio_write_pin_high(A2);
    270           gpio_write_pin_low(B4);
    271           break;
    272         case 1:
    273           gpio_write_pin_high(A0);
    274           gpio_write_pin_high(A1);
    275           gpio_write_pin_low(A2);
    276           gpio_write_pin_low(B4);
    277           break;
    278         case 2:
    279           gpio_write_pin_high(A0);
    280           gpio_write_pin_low(A1);
    281           gpio_write_pin_high(A2);
    282           gpio_write_pin_low(B4);
    283           break;
    284         case 3:
    285           gpio_write_pin_high(A0);
    286           gpio_write_pin_low(A1);
    287           gpio_write_pin_low(A2);
    288           gpio_write_pin_low(B4);
    289           break;
    290         case 4:
    291           gpio_write_pin_low(A0);
    292           gpio_write_pin_high(A1);
    293           gpio_write_pin_high(A2);
    294           gpio_write_pin_low(B4);
    295           break;
    296         case 5:
    297           gpio_write_pin_low(A0);
    298           gpio_write_pin_high(A1);
    299           gpio_write_pin_low(A2);
    300           gpio_write_pin_low(B4);
    301           break;
    302         case 6:
    303           gpio_write_pin_low(A0);
    304           gpio_write_pin_low(A1);
    305           gpio_write_pin_high(A2);
    306           gpio_write_pin_low(B4);
    307           break;
    308         case 7:
    309           gpio_write_pin_low(A0);
    310           gpio_write_pin_low(A1);
    311           gpio_write_pin_low(A2);
    312           gpio_write_pin_low(B4);
    313           break;
    314         case 8:
    315           gpio_write_pin_low(A0);
    316           gpio_write_pin_low(A1);
    317           gpio_write_pin_low(A2);
    318           gpio_write_pin_low(C7);
    319           break;
    320         case 9:
    321           gpio_write_pin_high(A0);
    322           gpio_write_pin_high(A1);
    323           gpio_write_pin_high(A2);
    324           gpio_write_pin_low(C7);
    325           break;
    326         case 10:
    327           gpio_write_pin_high(A0);
    328           gpio_write_pin_high(A1);
    329           gpio_write_pin_low(A2);
    330           gpio_write_pin_low(C7);
    331           break;
    332         case 11:
    333           gpio_write_pin_high(A0);
    334           gpio_write_pin_low(A1);
    335           gpio_write_pin_high(A2);
    336           gpio_write_pin_low(C7);
    337           break;
    338         case 12:
    339           gpio_write_pin_high(A0);
    340           gpio_write_pin_low(A1);
    341           gpio_write_pin_low(A2);
    342           gpio_write_pin_low(C7);
    343           break;
    344         case 13:
    345           gpio_write_pin_low(A0);
    346           gpio_write_pin_high(A1);
    347           gpio_write_pin_high(A2);
    348           gpio_write_pin_low(C7);
    349           break;
    350         case 14:
    351           gpio_write_pin_low(A0);
    352           gpio_write_pin_high(A1);
    353           gpio_write_pin_low(A2);
    354           gpio_write_pin_low(C7);
    355           break;
    356         case 15:
    357           gpio_write_pin_low(A0);
    358           gpio_write_pin_low(A1);
    359           gpio_write_pin_high(A2);
    360           gpio_write_pin_low(C7);
    361           break;
    362         case 16:
    363           gpio_write_pin_high(C2);
    364           break;
    365         case 17:
    366           gpio_write_pin_high(C3);
    367           break;
    368         case 18:
    369           gpio_write_pin_high(C5);
    370           break;
    371     }
    372 }
    373 
    374 static void unselect_cols(void) {
    375     //Native
    376     gpio_write_pin_high(C2);
    377     gpio_write_pin_high(C3);
    378     gpio_write_pin_high(C5);
    379 
    380     //Demultiplexer
    381     gpio_write_pin_low(B4);
    382     gpio_write_pin_low(C7);
    383     gpio_write_pin_high(A0);
    384     gpio_write_pin_high(A1);
    385     gpio_write_pin_high(A2);
    386 }
    387 
    388 static void init_pins(void) {
    389     unselect_cols();
    390     for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
    391         gpio_set_pin_input_high(row_pins[x]);
    392     }
    393     gpio_set_pin_output(A0);
    394     gpio_set_pin_output(A1);
    395     gpio_set_pin_output(A2);
    396     gpio_set_pin_output(B4);
    397     gpio_set_pin_output(C7);
    398     gpio_set_pin_output(C2);
    399     gpio_set_pin_output(C3);
    400     gpio_set_pin_output(C5);
    401 }
    402 
    403 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
    404     bool matrix_changed = false;
    405 
    406     // Select col and wait for col selecton to stabilize
    407     select_col(current_col);
    408     wait_us(30);
    409 
    410     // For each row...
    411     for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) {
    412         // Store last value of row prior to reading
    413         matrix_row_t last_row_value = current_matrix[row_index];
    414 
    415         // Check row pin state
    416         if (gpio_read_pin(row_pins[row_index]) == 0) {
    417             // Pin LO, set col bit
    418             current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col);
    419         } else {
    420             // Pin HI, clear col bit
    421             current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col);
    422         }
    423 
    424         // Determine if the matrix changed state
    425         if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
    426             matrix_changed = true;
    427         }
    428     }
    429 
    430     // Unselect col
    431     unselect_col(current_col);
    432 
    433     return matrix_changed;
    434 }
    435 
    436 #endif
    437 
    438 void matrix_init_custom(void) {
    439     // initialize key pins
    440     init_pins();
    441 }
    442 
    443 bool matrix_scan_custom(matrix_row_t current_matrix[]) {
    444     bool changed = false;
    445 
    446 #if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
    447     // Set row, read cols
    448     for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
    449         changed |= read_cols_on_row(current_matrix, current_row);
    450     }
    451 #elif (DIODE_DIRECTION == ROW2COL)
    452     // Set col, read rows
    453     for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
    454         changed |= read_rows_on_col(current_matrix, current_col);
    455     }
    456 #endif
    457 
    458     return changed;
    459 }