qmk_firmware

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

matrix.c (13180B)


      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 == ROW2COL)
     61 
     62 /* Cols 0 - 16
     63  * These columns use two 74HC138 3 to 8 bit demultiplexer. B0, F1 is the enable pin, must be set high (1) to use it.
     64  *
     65  * col / pin:     PB5  PB7  PF0  PB0  PF1  PE6
     66  * 0:              0 ── 0 ── 0    1 ── 0    0 
     67  * ────────────────────────────────────────────
     68  * 1:              0 ── 0 ── 1    1 ── 0    0
     69  * ────────────────────────────────────────────    
     70  * 2:              0 ── 1 ── 0    1 ── 0    0 
     71  * ────────────────────────────────────────────    
     72  * 3:              0 ── 1 ── 1    1 ── 0    0 
     73  * ────────────────────────────────────────────    
     74  * 4:              1 ── 0 ── 0    1 ── 0    0 
     75  * ────────────────────────────────────────────    
     76  * 5:              1 ── 0 ── 1    1 ── 0    0 
     77  * ────────────────────────────────────────────    
     78  * 6:              1 ── 1 ── 0    1 ── 0    0 
     79  * ────────────────────────────────────────────    
     80  * 7:              1 ── 1 ── 1    1 ── 0    0 
     81  * ────────────────────────────────────────────    
     82  * 8:              0 ── 0 ── 0    0 ── 1    0 
     83  * ────────────────────────────────────────────    
     84  * 9:              0 ── 0 ── 1    0 ── 1    0 
     85  * ────────────────────────────────────────────    
     86  *10:              0 ── 1 ── 0    0 ── 1    0 
     87  * ────────────────────────────────────────────    
     88  *11:              0 ── 1 ── 1    0 ── 1    0 
     89  * ────────────────────────────────────────────    
     90  *12:              1 ── 0 ── 0    0 ── 1    0 
     91  * ────────────────────────────────────────────    
     92  *13:              1 ── 0 ── 1    0 ── 1    0 
     93  * ────────────────────────────────────────────    
     94  *14:              1 ── 1 ── 1    0 ── 1    0 
     95  * ────────────────────────────────────────────    
     96  *15:              1 ── 1 ── 0    0 ── 1    0 
     97  * ────────────────────────────────────────────    
     98  *16:              0 ── 0 ── 0    0 ── 0    1  
     99  *
    100  */
    101 static void select_col(uint8_t col) {
    102     switch (col) {
    103         case 0:
    104           gpio_write_pin_low(B5);
    105           gpio_write_pin_low(B7);
    106           gpio_write_pin_low(F0);
    107           gpio_write_pin_high(B0);
    108           break;
    109         case 1:
    110           gpio_write_pin_low(B5);
    111           gpio_write_pin_low(B7);
    112           gpio_write_pin_high(F0);
    113           gpio_write_pin_high(B0);
    114           break;
    115         case 2:
    116           gpio_write_pin_low(B5);
    117           gpio_write_pin_high(B7);
    118           gpio_write_pin_low(F0);
    119           gpio_write_pin_high(B0);
    120           break;
    121         case 3:
    122           gpio_write_pin_low(B5);
    123           gpio_write_pin_high(B7);
    124           gpio_write_pin_high(F0);
    125           gpio_write_pin_high(B0);
    126           break;
    127         case 4:
    128           gpio_write_pin_high(B5);
    129           gpio_write_pin_low(B7);
    130           gpio_write_pin_low(F0);
    131           gpio_write_pin_high(B0);
    132           break;
    133         case 5:
    134           gpio_write_pin_high(B5);
    135           gpio_write_pin_low(B7);
    136           gpio_write_pin_high(F0);
    137           gpio_write_pin_high(B0);
    138           break;
    139         case 6:
    140           gpio_write_pin_high(B5);
    141           gpio_write_pin_high(B7);
    142           gpio_write_pin_low(F0);
    143           gpio_write_pin_high(B0);
    144           break;
    145         case 7:
    146           gpio_write_pin_high(B5);
    147           gpio_write_pin_high(B7);
    148           gpio_write_pin_high(F0);
    149           gpio_write_pin_high(B0);
    150           break;
    151         case 8:
    152           gpio_write_pin_low(B5);
    153           gpio_write_pin_low(B7);
    154           gpio_write_pin_low(F0);
    155           gpio_write_pin_high(F1);
    156           break;
    157         case 9:
    158           gpio_write_pin_low(B5);
    159           gpio_write_pin_low(B7);
    160           gpio_write_pin_high(F0);
    161           gpio_write_pin_high(F1);
    162           break;
    163         case 10:
    164           gpio_write_pin_low(B5);
    165           gpio_write_pin_high(B7);
    166           gpio_write_pin_low(F0);
    167           gpio_write_pin_high(F1);
    168           break;
    169         case 11:
    170           gpio_write_pin_low(B5);
    171           gpio_write_pin_high(B7);
    172           gpio_write_pin_high(F0);
    173           gpio_write_pin_high(F1);
    174           break;
    175         case 12:
    176           gpio_write_pin_high(B5);
    177           gpio_write_pin_low(B7);
    178           gpio_write_pin_low(F0);
    179           gpio_write_pin_high(F1);
    180           break;
    181         case 13:
    182           gpio_write_pin_high(B5);
    183           gpio_write_pin_low(B7);
    184           gpio_write_pin_high(F0);
    185           gpio_write_pin_high(F1);
    186           break;
    187         case 14:
    188           gpio_write_pin_high(B5);
    189           gpio_write_pin_high(B7);
    190           gpio_write_pin_high(F0);
    191           gpio_write_pin_high(F1);
    192           break;
    193         case 15:
    194           gpio_write_pin_high(B5);
    195           gpio_write_pin_high(B7);
    196           gpio_write_pin_low(F0);
    197           gpio_write_pin_high(F1);
    198           break;
    199         case 16:
    200           gpio_write_pin_low(E6);
    201           break;
    202     }
    203 }
    204 
    205 static void unselect_col(uint8_t col) {
    206     switch (col) {
    207         case 0:
    208           gpio_write_pin_high(B5);
    209           gpio_write_pin_high(B7);
    210           gpio_write_pin_high(F0);
    211           gpio_write_pin_low(B0);
    212           break;
    213         case 1:
    214           gpio_write_pin_high(B5);
    215           gpio_write_pin_high(B7);
    216           gpio_write_pin_low(F0);
    217           gpio_write_pin_low(B0);
    218           break;
    219         case 2:
    220           gpio_write_pin_high(B5);
    221           gpio_write_pin_low(B7);
    222           gpio_write_pin_high(F0);
    223           gpio_write_pin_low(B0);
    224           break;
    225         case 3:
    226           gpio_write_pin_high(B5);
    227           gpio_write_pin_low(B7);
    228           gpio_write_pin_low(F0);
    229           gpio_write_pin_low(B0);
    230           break;
    231         case 4:
    232           gpio_write_pin_low(B5);
    233           gpio_write_pin_high(B7);
    234           gpio_write_pin_high(F0);
    235           gpio_write_pin_low(B0);
    236           break;
    237         case 5:
    238           gpio_write_pin_low(B5);
    239           gpio_write_pin_high(B7);
    240           gpio_write_pin_low(F0);
    241           gpio_write_pin_low(B0);
    242           break;
    243         case 6:
    244           gpio_write_pin_low(B5);
    245           gpio_write_pin_low(B7);
    246           gpio_write_pin_high(F0);
    247           gpio_write_pin_low(B0);
    248           break;
    249         case 7:
    250           gpio_write_pin_low(B5);
    251           gpio_write_pin_low(B7);
    252           gpio_write_pin_low(F0);
    253           gpio_write_pin_low(B0);
    254           break;
    255         case 8:
    256           gpio_write_pin_high(B5);
    257           gpio_write_pin_high(B7);
    258           gpio_write_pin_high(F0);
    259           gpio_write_pin_low(F1);
    260           break;
    261         case 9:
    262           gpio_write_pin_high(B5);
    263           gpio_write_pin_high(B7);
    264           gpio_write_pin_low(F0);
    265           gpio_write_pin_low(F1);
    266           break;
    267         case 10:
    268           gpio_write_pin_high(B5);
    269           gpio_write_pin_low(B7);
    270           gpio_write_pin_high(F0);
    271           gpio_write_pin_low(F1);
    272           break;
    273         case 11:
    274           gpio_write_pin_high(B5);
    275           gpio_write_pin_low(B7);
    276           gpio_write_pin_low(F0);
    277           gpio_write_pin_low(F1);
    278           break;
    279         case 12:
    280           gpio_write_pin_low(B5);
    281           gpio_write_pin_high(B7);
    282           gpio_write_pin_high(F0);
    283           gpio_write_pin_low(F1);
    284           break;
    285         case 13:
    286           gpio_write_pin_low(B5);
    287           gpio_write_pin_high(B7);
    288           gpio_write_pin_low(F0);
    289           gpio_write_pin_low(F1);
    290           break;
    291         case 14:
    292           gpio_write_pin_low(B5);
    293           gpio_write_pin_low(B7);
    294           gpio_write_pin_low(F0);
    295           gpio_write_pin_low(F1);
    296           break;
    297         case 15:
    298           gpio_write_pin_low(B5);
    299           gpio_write_pin_low(B7);
    300           gpio_write_pin_high(F0);
    301           gpio_write_pin_low(F1);
    302           break;
    303         case 16:
    304           gpio_write_pin_high(E6);
    305           break;
    306     }
    307 }
    308 
    309 static void unselect_cols(void) {
    310     //Native
    311     gpio_write_pin_high(E6);
    312 
    313     //Demultiplexer
    314     gpio_write_pin_low(B0);
    315     gpio_write_pin_low(F1);
    316     gpio_write_pin_high(B5);
    317     gpio_write_pin_high(B7);
    318     gpio_write_pin_high(F0);
    319 }
    320 
    321 static void init_pins(void) {
    322     unselect_cols();
    323     for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
    324         gpio_set_pin_input_high(row_pins[x]);
    325     }
    326     gpio_set_pin_output(B5);
    327     gpio_set_pin_output(B7);
    328     gpio_set_pin_output(F0);
    329     gpio_set_pin_output(B0);
    330     gpio_set_pin_output(F1);
    331     gpio_set_pin_output(E6);
    332 }
    333 
    334 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
    335     bool matrix_changed = false;
    336 
    337     // Select col and wait for col selecton to stabilize
    338     select_col(current_col);
    339     wait_us(30);
    340 
    341     // For each row...
    342     for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) {
    343         // Store last value of row prior to reading
    344         matrix_row_t last_row_value = current_matrix[row_index];
    345 
    346         // Check row pin state
    347         if (gpio_read_pin(row_pins[row_index]) == 0) {
    348             // Pin LO, set col bit
    349             current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col);
    350         } else {
    351             // Pin HI, clear col bit
    352             current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col);
    353         }
    354 
    355         // Determine if the matrix changed state
    356         if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
    357             matrix_changed = true;
    358         }
    359     }
    360 
    361     // Unselect col
    362     unselect_col(current_col);
    363 
    364     return matrix_changed;
    365 }
    366 
    367 #endif
    368 
    369 void matrix_init_custom(void) {
    370     // initialize key pins
    371     init_pins();
    372 }
    373 
    374 bool matrix_scan_custom(matrix_row_t current_matrix[]) {
    375     bool changed = false;
    376 
    377 #if defined(DIRECT_PINS) || (DIODE_DIRECTION == ROW2COL)
    378     // Set col, read rows
    379     for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
    380         changed |= read_rows_on_col(current_matrix, current_col);
    381     }
    382 #endif
    383 
    384     return changed;
    385 }