qmk_firmware

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

matrix.c (12864B)


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