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 }