qmk_firmware

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

matrix.c (3663B)


      1 // Copyright 2023 David Hoelscher (@customMK)
      2 // SPDX-License-Identifier: GPL-2.0-or-later
      3 #include "matrix.h"
      4 #include <string.h>
      5 
      6 // Pin definitions
      7 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
      8 
      9 void matrix_wait_for_pin(pin_t pin, uint8_t target_state) {
     10     rtcnt_t start = chSysGetRealtimeCounterX();
     11     rtcnt_t end   = start + 5000;
     12     while (chSysIsCounterWithinX(chSysGetRealtimeCounterX(), start, end)) {
     13         if (gpio_read_pin(pin) == target_state) {
     14             break;
     15         }
     16     }
     17 }
     18 
     19 void matrix_wait_for_port(stm32_gpio_t *port, uint32_t target_bitmask) {
     20     rtcnt_t start = chSysGetRealtimeCounterX();
     21     rtcnt_t end   = start + 5000;
     22     while (chSysIsCounterWithinX(chSysGetRealtimeCounterX(), start, end)) {
     23         if ((palReadPort(port) & target_bitmask) == target_bitmask) {
     24             break;
     25         }
     26     }
     27 }
     28 
     29 void shift_pulse_clock(void) {
     30         gpio_write_pin_high(COL_SHIFT_CLK_PIN);
     31         matrix_wait_for_pin(COL_SHIFT_CLK_PIN, 1);
     32         gpio_write_pin_low(COL_SHIFT_CLK_PIN);
     33 }
     34 
     35 void matrix_init_custom(void) {
     36     //set all row pins as input with pullups
     37     for (int i = 0; i < MATRIX_ROWS; ++i) {
     38         gpio_write_pin_high(row_pins[i]);
     39         gpio_set_pin_input_high(row_pins[i]);
     40     }
     41 
     42     //set all column pins high in ROW2COL matrix
     43     gpio_set_pin_output(COL_SHIFT_IN_PIN);
     44     gpio_set_pin_output(COL_SHIFT_CLK_PIN);
     45     gpio_write_pin_high(COL_SHIFT_IN_PIN);
     46     matrix_wait_for_pin(COL_SHIFT_IN_PIN, 1);
     47 
     48     for (int i = 0; i < MATRIX_COLS; ++i) {
     49         shift_pulse_clock();
     50     }
     51 
     52 }
     53 
     54 bool matrix_scan_custom(matrix_row_t current_matrix[]) {
     55     static matrix_row_t temp_matrix[MATRIX_ROWS] = {0};
     56 
     57     gpio_write_pin_low(COL_SHIFT_IN_PIN);
     58     matrix_wait_for_pin(COL_SHIFT_IN_PIN, 0);
     59 
     60     // Setup the output column pin
     61     shift_pulse_clock();
     62 
     63     gpio_write_pin_high(COL_SHIFT_IN_PIN);
     64     for (int current_col = 0; current_col < MATRIX_COLS; ++current_col) {
     65 
     66         // Read the column ports
     67         uint32_t gpio_a = palReadPort(GPIOA);
     68         uint32_t gpio_b = palReadPort(GPIOB);
     69         
     70         // row 0, pin A8
     71         int current_row = 0;
     72         if ((gpio_a & (1 << 8)) >> 8) {
     73             temp_matrix[current_row] &= ~(1ul << current_col);
     74         } else {
     75             temp_matrix[current_row] |= (1ul << current_col);
     76         }
     77         // row 1, pin A1
     78         current_row = 1;
     79         if ((gpio_a & (1 << 1)) >> 1) {
     80             temp_matrix[current_row] &= ~(1ul << current_col);
     81         } else {
     82             temp_matrix[current_row] |= (1ul << current_col);
     83         }
     84         // row 2, pin A2
     85         current_row = 2;
     86         if ((gpio_a & (1 << 2)) >> 2) {
     87             temp_matrix[current_row] &= ~(1ul << current_col);
     88         } else {
     89             temp_matrix[current_row] |= (1ul << current_col);
     90         }
     91         // row 3, pin B3
     92         current_row = 3;
     93         if ((gpio_b & (1 << 1)) >> 1) {
     94             temp_matrix[current_row] &= ~(1ul << current_col);
     95         } else {
     96             temp_matrix[current_row] |= (1ul << current_col);
     97         }
     98         // row 4, pin A7
     99         current_row = 4;
    100         if ((gpio_a & (1 << 7)) >> 7) {
    101             temp_matrix[current_row] &= ~(1ul << current_col);
    102         } else {
    103             temp_matrix[current_row] |= (1ul << current_col);
    104         }
    105         
    106         // Setup the output column pin
    107         shift_pulse_clock();
    108     
    109     }
    110 
    111     // Check if matrix has changed, return the last-read data
    112     bool changed = memcmp(current_matrix, temp_matrix, sizeof(temp_matrix)) != 0;
    113     if (changed) {
    114         memcpy(current_matrix, temp_matrix, sizeof(temp_matrix));
    115     }
    116     shift_pulse_clock();
    117     return changed;
    118 }