qmk_firmware

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

matrix.c (11821B)


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