diff options
Diffstat (limited to 'keyboards/nullbitsco/snap/matrix.c')
-rw-r--r-- | keyboards/nullbitsco/snap/matrix.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/keyboards/nullbitsco/snap/matrix.c b/keyboards/nullbitsco/snap/matrix.c new file mode 100644 index 0000000000..ceb9cd8984 --- /dev/null +++ b/keyboards/nullbitsco/snap/matrix.c @@ -0,0 +1,126 @@ +/* Copyright 2021 Jay Greco + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <stdint.h> +#include <stdbool.h> +#include <string.h> +#include "util.h" +#include "matrix.h" +#include "split_util.h" +#include "quantum.h" + +#define VIRT_COLS_PER_HAND 1 +#define PHYS_COLS_PER_HAND (MATRIX_COLS - VIRT_COLS_PER_HAND) +#define ROWS_PER_HAND (MATRIX_ROWS / 2) +#define COL_SHIFTER ((uint32_t)1) +#define EXT_PIN_ROW 2 +#define EXT_PIN_COL 8 + +// Row & column pins +static uint8_t row_pins_left[MATRIX_ROWS] = MATRIX_ROW_PINS; +static uint8_t col_pins_left[MATRIX_MUX_COLS] = MATRIX_COL_MUX_PINS; +static uint8_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT; +static uint8_t col_pins_right[MATRIX_MUX_COLS] = MATRIX_COL_MUX_PINS_RIGHT; +static uint8_t* row_pins = row_pins_left; +static uint8_t* col_pins = col_pins_left; + +// Internal functions +static void init_pins(void) { + // Set cols to outputs, low + for (uint8_t pin = 0; pin < MATRIX_MUX_COLS; pin++) { + setPinOutput(col_pins[pin]); + } + + // Unselect cols + for (uint8_t bit = 0; bit < MATRIX_MUX_COLS; bit++) { + writePinLow(col_pins[bit]); + } + + // Set rows to input, pullup + for (uint8_t pin = 0; pin < ROWS_PER_HAND; pin++) { + setPinInputHigh(row_pins[pin]); + } + + // Set extended pin (only on right side) + if (!isLeftHand) { + // Set extended pin to input, pullup + setPinInputHigh(MATRIX_EXT_PIN_RIGHT); + } +} + +static void select_col(uint8_t col) { + // Drive demux with correct column address + for (uint8_t bit = 0; bit < MATRIX_MUX_COLS; bit++) { + uint8_t state = (col & (0b1 << bit)) >> bit; + writePin(col_pins[bit], !state); + } +} + +static void read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { + select_col(current_col % PHYS_COLS_PER_HAND); + wait_us(5); + + // Read each row sequentially + for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) { + if (readPin(row_pins[row_index]) == 0) { + current_matrix[row_index] |= (COL_SHIFTER << current_col); + } else { + current_matrix[row_index] &= ~(COL_SHIFTER << current_col); + } + } +} + +static void read_ext_pin(matrix_row_t current_matrix[]) { + // Read the state of the extended matrix pin + if (!isLeftHand) { + if (readPin(MATRIX_EXT_PIN_RIGHT) == 0) { + current_matrix[EXT_PIN_ROW] |= (COL_SHIFTER << EXT_PIN_COL); + } else { + current_matrix[EXT_PIN_ROW] &= ~(COL_SHIFTER << EXT_PIN_COL); + } + } +} + +void matrix_init_custom(void) { + if (!isLeftHand) { + row_pins = row_pins_right; + col_pins = col_pins_right; + } + + init_pins(); +} + +bool matrix_scan_custom(matrix_row_t current_matrix[]) { + matrix_row_t last_matrix[MATRIX_ROWS]; + memcpy(last_matrix, current_matrix, sizeof(last_matrix)); + + #ifdef DEBUG_SLOW_MATRIX + // Slow for debugging + wait_ms(1000); + #endif + + // Set col, read rows + for (uint8_t current_col = 0; current_col < PHYS_COLS_PER_HAND; current_col++) { + read_rows_on_col(current_matrix, current_col); + } + + // Read extended pin and store in matrix + read_ext_pin(current_matrix); + + // Check if the matrix changed + bool changed = memcmp(last_matrix, current_matrix, sizeof(last_matrix)) != 0; + + return changed; +} |