qmk_firmware

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

matrix.c (11964B)


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