qmk_firmware

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

matrix.c (1984B)


      1 // Copyright 2024 splitkb.com (support@splitkb.com)
      2 // SPDX-License-Identifier: GPL-2.0-or-later
      3 
      4 #include "matrix.h"
      5 #include "spi_master.h"
      6 
      7 // The matrix is hooked up to a chain of 74xx165 shift registers.
      8 // Pin F0 acts as Chip Select (active-low)
      9 // The signal goes to a NOT gate, whose output is wired to
     10 // a) the latch pin of the shift registers
     11 // b) the "enable" pin of a tri-state buffer,
     12 //    attached between the shift registers and MISO
     13 // F0 has an external pull-up.
     14 // SCK works as usual.
     15 //
     16 // Note that the matrix contains a variety of data.
     17 // In addition to the keys, it also reads the rotary encoders
     18 // and whether the board is the left/right half.
     19 
     20 void matrix_init_custom(void) {
     21     // Note: `spi_init` has already been called
     22     // in `keyboard_pre_init_kb()`, so nothing to do here
     23 }
     24 
     25 bool matrix_scan_custom(matrix_row_t current_matrix[]) {
     26     // Enough to hold the shift registers
     27     uint16_t length = 5;
     28     uint8_t  data[length];
     29 
     30     // Matrix SPI config
     31     // 1) Pin
     32     // 2) Mode: Register shifts on rising clock, and clock idles low
     33     //      pol = 0 & pha = 0 => mode 0
     34     // 3) LSB first: Register outputs H first, and we want H as MSB,
     35     //      as this result in a neat A-H order in the layout macro.
     36     // 4) Divisor: 2 is the fastest possible, at Fclk / 2.
     37     //      range is 2-128
     38     spi_start(GP13, false, 0, 128);
     39     spi_receive(data, length);
     40     spi_stop();
     41 
     42     bool matrix_has_changed = false;
     43     for (uint8_t i = 0; i < length; i++) {
     44         // Bitwise NOT because we use pull-ups,
     45         // and switches short the pin to ground,
     46         // but the matrix uses 1 to indicate a pressed switch
     47         uint8_t word = ~data[i];
     48         matrix_has_changed |= current_matrix[i] ^ word;
     49         current_matrix[i] = word;
     50     }
     51 #ifdef MYRIAD_ENABLE
     52     bool myriad_hook_matrix(matrix_row_t current_matrix[]);
     53     return matrix_has_changed || myriad_hook_matrix(current_matrix);
     54 #else
     55     return matrix_has_changed;
     56 #endif
     57 }