qmk_firmware

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

matrix.c (4102B)


      1 /* Copyright 2023 ArthurCyy <https://github.com/ArthurCyy>
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 2 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11  * GNU General Public License for more details.
     12  *
     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 
     17 #include "matrix.h"
     18 #include "wait.h"
     19 #include "common/shift_register.h"
     20 
     21 static uint8_t read_rows(void);
     22 static void    init_cols(void);
     23 static void    select_col(uint8_t col);
     24 static void    unselect_col(uint8_t col);
     25 static void    unselect_cols(void);
     26 
     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 
     30 #ifdef DIP_SWITCH_PINS
     31 #    define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad) / sizeof(pin_t))
     32 static pin_t dip_switch_pad[] = DIP_SWITCH_PINS;
     33 #endif
     34 
     35 void matrix_init_custom(void) {
     36     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
     37         gpio_set_pin_input_low(row_pins[row]);
     38     }
     39     
     40     shift_init();
     41     init_cols();
     42 }
     43 
     44 bool matrix_scan_custom(matrix_row_t current_matrix[]) {
     45     bool changed = false;
     46 
     47     for (uint8_t col = 0; col < MATRIX_COLS; col++) {
     48         select_col(col);
     49         waitInputPinDelay();
     50         uint8_t rows = read_rows();
     51         for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
     52             bool prev_bit = ((uint32_t)(current_matrix[row]) & (matrix_row_t)(1UL << col)) ? 1 : 0;
     53             bool curr_bit = ((uint32_t)rows & (uint32_t)(1UL << row)) ? 1 : 0;
     54             if (prev_bit != curr_bit) {
     55                 current_matrix[row] = (uint32_t)(current_matrix[row]) ^ (uint32_t)(1UL << col);
     56                 changed = true;
     57             }
     58         }
     59         unselect_col(col);
     60     }
     61 
     62     return changed;
     63 }
     64 
     65 void matrix_power_up(void) {
     66     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
     67         palDisableLineEvent(row_pins[row]);
     68         gpio_set_pin_input_low(row_pins[row]);
     69     }
     70     init_cols();
     71 #ifdef DIP_SWITCH_PINS
     72     for (uint8_t i = 1; i < NUMBER_OF_DIP_SWITCHES; i++) {
     73         gpio_set_pin_input_high(dip_switch_pad[i]);
     74     }
     75 #endif
     76 }
     77 
     78 void matrix_power_down(void) {
     79     unselect_cols();
     80     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
     81         gpio_set_pin_input_low(row_pins[row]);
     82         palEnableLineEvent(row_pins[row], PAL_EVENT_MODE_RISING_EDGE);
     83     }
     84 #ifdef DIP_SWITCH_PINS
     85     for (uint8_t i = 1; i < NUMBER_OF_DIP_SWITCHES; i++) {
     86         gpio_set_pin_input_low(dip_switch_pad[i]);
     87     }
     88 #endif
     89 }
     90 
     91 static uint8_t read_rows(void) {
     92     uint8_t row_value = 0;
     93     for(uint8_t row = 0; row < MATRIX_ROWS; row++) {
     94         row_value |= (gpio_read_pin(row_pins[row]) << row);
     95     }
     96     return row_value;
     97 }
     98 
     99 static void init_cols(void) {
    100     shift_writeAll(0);
    101     for(uint8_t col = 0; col < MATRIX_COLS; col++) {
    102         if(col_pins[col] < H0) {
    103             gpio_set_pin_output(col_pins[col]);
    104             gpio_write_pin_low(col_pins[col]);
    105         }
    106     }
    107 }
    108 
    109 static void select_col(uint8_t col) {
    110     if(col_pins[col] < H0){
    111         gpio_write_pin_high(col_pins[col]);
    112         waitInputPinDelay();
    113         waitInputPinDelay();
    114         waitInputPinDelay();
    115         waitInputPinDelay();
    116         waitInputPinDelay();
    117         waitInputPinDelay();
    118     }else{
    119         shift_writePin(col_pins[col], 1);
    120     }
    121 }
    122 
    123 static void unselect_col(uint8_t col) {
    124     if(col_pins[col] < H0){
    125         gpio_write_pin_low(col_pins[col]);
    126     }else{
    127         shift_writePin(col_pins[col], 0);
    128     }
    129 }
    130 
    131 static void unselect_cols(void) {
    132     shift_writeAll(1);
    133     for(uint8_t col = 0; col < MATRIX_COLS; col++) {
    134         if(col_pins[col] < H0) {
    135             gpio_set_pin_output(col_pins[col]);
    136             gpio_write_pin_high(col_pins[col]);
    137         }
    138     }
    139 }