qmk_firmware

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

matrix.c (6308B)


      1 /**
      2  * matrix.c
      3  *
      4   Copyright 2020 astro <yuleiz@gmail.com>
      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     This program is distributed in the hope that it will be useful,
     10     but WITHOUT ANY WARRANTY; without even the implied warranty of
     11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12     GNU General Public License for more details.
     13     You should have received a copy of the GNU General Public License
     14     along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15 */
     16 #include "matrix.h"
     17 #include "print.h"
     18 #include "bitwise.h"
     19 #include "wait.h"
     20 
     21 #ifndef DEBOUNCE
     22 #    define DEBOUNCE 5
     23 #endif
     24 
     25 static uint8_t debouncing = DEBOUNCE;
     26 
     27 static matrix_row_t matrix[MATRIX_ROWS];
     28 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
     29 
     30 static uint8_t read_rows(void);
     31 static void init_rows(void);
     32 static void init_cols(void);
     33 static void unselect_cols(void);
     34 static void select_col(uint8_t col);
     35 
     36 
     37 __attribute__ ((weak))
     38 void matrix_init_kb(void)
     39 {
     40     matrix_init_user();
     41 }
     42 
     43 __attribute__ ((weak))
     44 void matrix_scan_kb(void)
     45 {
     46     matrix_scan_user();
     47 }
     48 
     49 __attribute__ ((weak))
     50 void matrix_init_user(void) {}
     51 
     52 __attribute__ ((weak))
     53 void matrix_scan_user(void) {}
     54 
     55 void matrix_init(void)
     56 {
     57   //gpio_set_pin_output(F0);
     58   //gpio_write_pin_high(F0);
     59   gpio_set_pin_output(B4);
     60   gpio_write_pin_low(B4);
     61 
     62   init_cols();
     63   init_rows();
     64 
     65   for (uint8_t i=0; i < MATRIX_ROWS; i++)  {
     66     matrix[i] = 0;
     67     matrix_debouncing[i] = 0;
     68   }
     69 
     70   matrix_init_kb();
     71 }
     72 
     73 uint8_t matrix_scan(void)
     74 {
     75   for (uint8_t col = 0; col < MATRIX_COLS; col++) {
     76     select_col(col);
     77     _delay_us(3);
     78 
     79     uint8_t rows = read_rows();
     80 
     81     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
     82       bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
     83       bool curr_bit = rows & (1<<row);
     84       if (prev_bit != curr_bit) {
     85         matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
     86         debouncing = DEBOUNCE;
     87       }
     88     }
     89     unselect_cols();
     90   }
     91 
     92   if (debouncing) {
     93     if (--debouncing) {
     94       _delay_ms(1);
     95     } else {
     96       for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
     97         matrix[i] = matrix_debouncing[i];
     98       }
     99     }
    100   }
    101 
    102   matrix_scan_kb();
    103   return 1;
    104 }
    105 
    106 inline matrix_row_t matrix_get_row(uint8_t row)
    107 {
    108   return matrix[row];
    109 }
    110 
    111 void matrix_print(void)
    112 {
    113   print("\nr/c 0123456789ABCDEF\n");
    114   for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
    115     xprintf("%02X: %032lb\n", row, bitrev32(matrix_get_row(row)));
    116   }
    117 }
    118 
    119 /*
    120  * Row pin configuration
    121  * row: 0    1    2    3    4
    122  * pin: PE6  PF6  PF7  PB7  PD4
    123  */
    124 static void init_rows(void)
    125 {
    126   gpio_set_pin_input_high(E6);
    127   gpio_set_pin_input_high(F6);
    128   gpio_set_pin_input_high(F7);
    129   gpio_set_pin_input_high(B7);
    130   gpio_set_pin_input_high(D4);
    131 }
    132 
    133 static uint8_t read_rows(void)
    134 {
    135   return ((gpio_read_pin(E6) ? 0 : (1 << 0)) |
    136           (gpio_read_pin(F6) ? 0 : (1 << 1)) |
    137           (gpio_read_pin(F7) ? 0 : (1 << 2)) |
    138           (gpio_read_pin(B7) ? 0 : (1 << 3)) |
    139           (gpio_read_pin(D4) ? 0 : (1 << 4)));
    140 }
    141 
    142 /*
    143  * Columns 0 - 13
    144  * These columns uses two 74LVC138 3 to 8 bit demultiplexers.
    145  * EN Pin, PF5, PD6
    146  *
    147  * col / pin:    PF0  PF1  PF4
    148  * 0:             0    0    0
    149  * 1:             1    0    0
    150  * 2:             0    1    0
    151  * 3:             1    1    0
    152  * 4:             0    0    1
    153  * 5:             1    0    1
    154  * 6:             0    1    1
    155  *               PD2  PD3  PD5
    156  * 7:             0    0    0
    157  * 8:             1    0    0
    158  * 9:             0    1    0
    159  * 10:            1    1    0
    160  * 11:            0    0    1
    161  * 12:            1    0    1
    162  * 13:            0    1    1
    163  *
    164  */
    165 static void init_cols(void)
    166 {
    167   gpio_set_pin_output(F0);
    168   gpio_set_pin_output(F1);
    169   gpio_set_pin_output(F4);
    170   gpio_set_pin_output(F5);
    171 
    172   gpio_set_pin_output(D2);
    173   gpio_set_pin_output(D3);
    174   gpio_set_pin_output(D5);
    175   gpio_set_pin_output(D6);
    176 
    177   unselect_cols();
    178 }
    179 
    180 static void unselect_cols(void)
    181 {
    182   gpio_write_pin_high(F0);
    183   gpio_write_pin_high(F1);
    184   gpio_write_pin_high(F4);
    185   gpio_write_pin_high(F5);
    186 
    187   gpio_write_pin_high(D2);
    188   gpio_write_pin_high(D3);
    189   gpio_write_pin_high(D5);
    190   gpio_write_pin_high(D6);
    191 }
    192 
    193 static void select_col(uint8_t col) {
    194 
    195    switch (col) {
    196         case 0:
    197           gpio_write_pin_low(F0);
    198           gpio_write_pin_low(F1);
    199           gpio_write_pin_low(F4);
    200           break;
    201         case 1:
    202           gpio_write_pin_high(F0);
    203           gpio_write_pin_low(F1);
    204           gpio_write_pin_low(F4);
    205           break;
    206         case 2:
    207           gpio_write_pin_low(F0);
    208           gpio_write_pin_high(F1);
    209           gpio_write_pin_low(F4);
    210           break;
    211         case 3:
    212           gpio_write_pin_high(F0);
    213           gpio_write_pin_high(F1);
    214           gpio_write_pin_low(F4);
    215           break;
    216         case 4:
    217           gpio_write_pin_low(F0);
    218           gpio_write_pin_low(F1);
    219           gpio_write_pin_high(F4);
    220           break;
    221         case 5:
    222           gpio_write_pin_high(F0);
    223           gpio_write_pin_low(F1);
    224           gpio_write_pin_high(F4);
    225           break;
    226         case 6:
    227           gpio_write_pin_low(F0);
    228           gpio_write_pin_high(F1);
    229           gpio_write_pin_high(F4);
    230           break;
    231         case 7:
    232           gpio_write_pin_low(D2);
    233           gpio_write_pin_low(D3);
    234           gpio_write_pin_low(D5);
    235           break;
    236         case 8:
    237           gpio_write_pin_high(D2);
    238           gpio_write_pin_low(D3);
    239           gpio_write_pin_low(D5);
    240           break;
    241         case 9:
    242           gpio_write_pin_low(D2);
    243           gpio_write_pin_high(D3);
    244           gpio_write_pin_low(D5);
    245           break;
    246         case 10:
    247           gpio_write_pin_high(D2);
    248           gpio_write_pin_high(D3);
    249           gpio_write_pin_low(D5);
    250           break;
    251         case 11:
    252           gpio_write_pin_low(D2);
    253           gpio_write_pin_low(D3);
    254           gpio_write_pin_high(D5);
    255           break;
    256         case 12:
    257           gpio_write_pin_high(D2);
    258           gpio_write_pin_low(D3);
    259           gpio_write_pin_high(D5);
    260           break;
    261         case 13:
    262           gpio_write_pin_low(D2);
    263           gpio_write_pin_high(D3);
    264           gpio_write_pin_high(D5);
    265           break;
    266     }
    267 }