qmk_firmware

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

matrix.c (8443B)


      1 /*
      2 Copyright 2019 Yiancar
      3 
      4 This program is free software: you can redistribute it and/or modify
      5 it under the terms of the GNU General Public License as published by
      6 the Free Software Foundation, either version 2 of the License, or
      7 (at your option) any later version.
      8 
      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 
     14 You should have received a copy of the GNU General Public License
     15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17 #include <string.h>
     18 #include "timer.h"
     19 #include "wait.h"
     20 #include "print.h"
     21 #include "matrix.h"
     22 #include <ch.h>
     23 #include <hal.h>
     24 
     25 static matrix_row_t matrix[MATRIX_ROWS];
     26 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
     27 
     28 volatile uint16_t porta_buffer = 0;
     29 volatile uint16_t portb_buffer = 0;
     30 
     31 static uint32_t switch_buffer = 0;
     32 
     33 static void pal_cb(void* unused);
     34 
     35 static void enable_input_events(void)
     36 {
     37     palDisablePadEventI(GPIOA, 0);
     38     palDisablePadEventI(GPIOA, 1);
     39     palDisablePadEventI(GPIOA, 2);
     40     palDisablePadEventI(GPIOA, 9);
     41     palDisablePadEventI(GPIOA, 10);
     42     palDisablePadEventI(GPIOB, 12);
     43     palDisablePadEventI(GPIOB, 13);
     44     palDisablePadEventI(GPIOB, 14);
     45     palDisablePadEventI(GPIOB, 15);
     46 
     47     palEnablePadEventI(GPIOA, 0, PAL_EVENT_MODE_FALLING_EDGE);
     48     palEnablePadEventI(GPIOA, 1, PAL_EVENT_MODE_FALLING_EDGE);
     49     palEnablePadEventI(GPIOA, 2, PAL_EVENT_MODE_FALLING_EDGE);
     50     palEnablePadEventI(GPIOA, 9, PAL_EVENT_MODE_FALLING_EDGE);
     51     palEnablePadEventI(GPIOA, 10, PAL_EVENT_MODE_FALLING_EDGE);
     52     palEnablePadEventI(GPIOB, 12, PAL_EVENT_MODE_FALLING_EDGE);
     53     palEnablePadEventI(GPIOB, 13, PAL_EVENT_MODE_FALLING_EDGE);
     54     palEnablePadEventI(GPIOB, 14, PAL_EVENT_MODE_FALLING_EDGE);
     55     palEnablePadEventI(GPIOB, 15, PAL_EVENT_MODE_FALLING_EDGE);
     56 
     57     palSetPadCallbackI(GPIOA, 0, &pal_cb, 0);
     58     palSetPadCallbackI(GPIOA, 1, &pal_cb, 0);
     59     palSetPadCallbackI(GPIOA, 2, &pal_cb, 0);
     60     palSetPadCallbackI(GPIOA, 9, &pal_cb, 0);
     61     palSetPadCallbackI(GPIOA, 10, &pal_cb, 0);
     62     palSetPadCallbackI(GPIOB, 12, &pal_cb, 0);
     63     palSetPadCallbackI(GPIOB, 13, &pal_cb, 0);
     64     palSetPadCallbackI(GPIOB, 14, &pal_cb, 0);
     65     palSetPadCallbackI(GPIOB, 15, &pal_cb, 0);
     66 }
     67 
     68 // Trigger on negative edge of any of the sense lines.
     69 static void pal_cb(void* unused) {
     70 
     71     (void)unused;
     72     chSysLockFromISR();
     73     porta_buffer = palReadPort(GPIOA);
     74     portb_buffer = palReadPort(GPIOB);
     75     //Disable further interrupts that might occur on same button press.
     76     enable_input_events();
     77     chSysUnlockFromISR();
     78 }
     79 
     80 void matrix_init(void) {
     81     //Set I/O as pull-up inputs to read states
     82     gpio_set_pin_input_high(A0);
     83     gpio_set_pin_input_high(A1);
     84     gpio_set_pin_input_high(A2);
     85     gpio_set_pin_input_high(A3);
     86     gpio_set_pin_input_high(A4);
     87     gpio_set_pin_input_high(A5);
     88     gpio_set_pin_input_high(A6);
     89     gpio_set_pin_input_high(A7);
     90     gpio_set_pin_input_high(A8);
     91     gpio_set_pin_input_high(A9);
     92     gpio_set_pin_input_high(A10);
     93     gpio_set_pin_input_high(B3);
     94     gpio_set_pin_input_high(B4);
     95     gpio_set_pin_input_high(B5);
     96     gpio_set_pin_input_high(B6);
     97     gpio_set_pin_input_high(B7);
     98     gpio_set_pin_input_high(B8);
     99     gpio_set_pin_input_high(B9);
    100     gpio_set_pin_input_high(B11);
    101     gpio_set_pin_input_high(B12);
    102     gpio_set_pin_input_high(B13);
    103     gpio_set_pin_input_high(B14);
    104     gpio_set_pin_input_high(B15);
    105 
    106     memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t));
    107     memset(matrix_debouncing, 0, MATRIX_ROWS * sizeof(matrix_row_t));
    108 
    109     matrix_init_kb();
    110 
    111     osalSysLock();
    112     enable_input_events();
    113     osalSysUnlock();
    114 }
    115 
    116 uint8_t matrix_scan(void) {
    117     switch_buffer = ((uint32_t)(porta_buffer & 0x7FF)) | ((uint32_t)(portb_buffer & 0x3F8) << 8);
    118 
    119     switch (switch_buffer) {
    120         case 0x1134E: matrix[0] = 0x01; break;
    121         case 0x3774D: matrix[0] = 0x02; break;
    122         case 0x10BCC: matrix[0] = 0x04; break;
    123         case 0x16B4B: matrix[0] = 0x08; break;
    124         case 0x167CA: matrix[0] = 0x10; break;
    125         case 0x35FC9: matrix[0] = 0x20; break;
    126         case 0x15B48: matrix[0] = 0x40; break;
    127         case 0x28347: matrix[0] = 0x80; break;
    128         case 0x173C6: matrix[0] = 0x100; break;
    129         case 0x143CF: matrix[0] = 0x200; break;
    130         case 0x3FDC5: matrix[0] = 0x400; break;
    131         case 0x3FD21: matrix[0] = 0x800; break;
    132         case 0x3FD77: matrix[0] = 0x1000; break;
    133         case 0x3FD72: matrix[0] = 0x2000; break;
    134         //Special pin
    135         case 0x3E7FA: matrix[0] = 0x8000; break;
    136         case 0x183EE: matrix[0] = 0x10000; break;
    137         case 0x197F3: matrix[0] = 0x20000; break;
    138         case 0x1AB7E: matrix[0] = 0x40000; break;
    139 
    140         case 0x107C3: matrix[1] = 0x01; break;
    141         case 0x3FD2E: matrix[1] = 0x02; break;
    142         case 0x3FD28: matrix[1] = 0x04; break;
    143         case 0x3FD3A: matrix[1] = 0x08; break;
    144         case 0x3FD2D: matrix[1] = 0x10; break;
    145         case 0x3FD2B: matrix[1] = 0x20; break;
    146         case 0x3FDA5: matrix[1] = 0x40; break;
    147         case 0x3FDAA: matrix[1] = 0x80; break;
    148         case 0x3FD36: matrix[1] = 0x100; break;
    149         case 0x3FD30: matrix[1] = 0x200; break;
    150         case 0x3FDAF: matrix[1] = 0x400; break;
    151         case 0x3FD22: matrix[1] = 0x800; break;
    152         case 0x157D4: matrix[1] = 0x1000; break;
    153         //Does not exist in matrix
    154         //Special pin
    155         case 0x1C778: matrix[1] = 0x8000; break;
    156         case 0x387ED: matrix[1] = 0x10000; break;
    157         case 0x19B74: matrix[1] = 0x20000; break;
    158         case 0x3FD7D: matrix[1] = 0x40000; break;
    159 
    160         //Special pin
    161         case 0x3FDBE: matrix[2] = 0x02; break;
    162         case 0x3FDAC: matrix[2] = 0x04; break;
    163         case 0x3FDBB: matrix[2] = 0x08; break;
    164         case 0x3FD39: matrix[2] = 0x10; break;
    165         case 0x3FDB8: matrix[2] = 0x20; break;
    166         case 0x3FDB7: matrix[2] = 0x40; break;
    167         case 0x3FD35: matrix[2] = 0x80; break;
    168         case 0x3FDB4: matrix[2] = 0x100; break;
    169         case 0x3FD33: matrix[2] = 0x200; break;
    170         case 0x3FDA3: matrix[2] = 0x400; break;
    171         case 0x3FD24: matrix[2] = 0x800; break;
    172         case 0x0FFDB: matrix[2] = 0x1000; break;
    173         case 0x3FDF5: matrix[2] = 0x2000; break;
    174         case 0x3FDFF: matrix[2] = 0x4000; break;
    175         case 0x3C3E4: matrix[2] = 0x8000; break;
    176         case 0x38B6C: matrix[2] = 0x10000; break;
    177         case 0x39FF6: matrix[2] = 0x20000; break;
    178         case 0x3FDFC: matrix[2] = 0x40000; break;
    179 
    180         //Special pin
    181         case 0x3FDA6: matrix[3] = 0x02; break;
    182         case 0x3FD27: matrix[3] = 0x04; break;
    183         case 0x3FD3C: matrix[3] = 0x08; break;
    184         case 0x3FDA9: matrix[3] = 0x10; break;
    185         case 0x3FDBD: matrix[3] = 0x20; break;
    186         case 0x3FDB1: matrix[3] = 0x40; break;
    187         case 0x3FDB2: matrix[3] = 0x80; break;
    188         case 0x30353: matrix[3] = 0x100; break;
    189         case 0x37BD1: matrix[3] = 0x200; break;
    190         case 0x363D2: matrix[3] = 0x400; break;
    191         case 0x3FD5F: matrix[3] = 0x800; break;
    192         //Does not exist in matrix
    193         //Does not exist in matrix
    194         //Special pin
    195         case 0x1BF00: matrix[3] = 0x8000; break;
    196         case 0x18FEB: matrix[3] = 0x10000; break;
    197         case 0x3FF69: matrix[3] = 0x20000; break;
    198         case 0x3A37B: matrix[3] = 0x40000; break;
    199         default:
    200                  if ((portb_buffer & 0x1000) == 0) { matrix[1] = 0x4000; break; }
    201                  if ((portb_buffer & 0x2000) == 0) { matrix[3] = 0x4000; break; }
    202                  if ((portb_buffer & 0x4000) == 0) { matrix[0] = 0x4000; break; }
    203                  if ((portb_buffer & 0x8000) == 0) { matrix[2] = 0x01; break; }
    204                  matrix[0] = 0x00;
    205                  matrix[1] = 0x00;
    206                  matrix[2] = 0x00;
    207                  matrix[3] = 0x00;
    208     }
    209     //Special case for Shift
    210     if (gpio_read_pin(B11) == 0) { matrix[3] |= 0x01; }
    211 
    212     porta_buffer = 65535;
    213     portb_buffer = 65535;
    214 
    215     matrix_scan_kb();
    216     return 1;
    217 }
    218 
    219 matrix_row_t matrix_get_row(uint8_t row)
    220 {
    221     return matrix[row];
    222 }
    223 
    224 void matrix_print(void)
    225 {
    226 
    227 }
    228 
    229 __attribute__ ((weak))
    230 void matrix_init_kb(void) {
    231     matrix_init_user();
    232 }
    233 
    234 __attribute__ ((weak))
    235 void matrix_scan_kb(void) {
    236     matrix_scan_user();
    237 }
    238 
    239 __attribute__ ((weak))
    240 void matrix_init_user(void) {
    241 }
    242 
    243 __attribute__ ((weak))
    244 void matrix_scan_user(void) {
    245 }
    246