summaryrefslogtreecommitdiff
path: root/keyboards/hazel/bad_wings/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/hazel/bad_wings/matrix.c')
-rw-r--r--keyboards/hazel/bad_wings/matrix.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/keyboards/hazel/bad_wings/matrix.c b/keyboards/hazel/bad_wings/matrix.c
new file mode 100644
index 0000000000..496bebd58f
--- /dev/null
+++ b/keyboards/hazel/bad_wings/matrix.c
@@ -0,0 +1,137 @@
+// Copyright 2022 @sadekbaroudi (Sadek Baroudi)
+// Copyright 2023 @jasonhazel (Jason Hazel)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "quantum.h"
+#include "spi_master.h"
+#include <string.h> /* memset */
+#include <unistd.h> /* close */
+#include "quantum.h"
+#include "matrix.h"
+
+#if (!defined(SHIFTREG_MATRIX_COL_CS))
+# error Missing shift register I/O pin definitions
+#endif
+
+int matrixArraySize = SHIFTREG_ROWS * sizeof(matrix_row_t);
+matrix_row_t oldMatrix[SHIFTREG_ROWS];
+
+#define SHIFTREG_OUTPUT_BITS 8
+pin_t rowPinsSR[SHIFTREG_ROWS] = MATRIX_ROW_PINS_SR;
+
+// semaphore to make sure SPI doesn't get called multiple times
+static bool shiftRegisterSPILocked = false;
+
+void semaphore_lock(bool value) {
+ shiftRegisterSPILocked = value;
+}
+
+bool semaphore_is_locked(void) {
+ return shiftRegisterSPILocked;
+}
+
+void sr_74hc595_spi_stop(void) {
+ spi_stop();
+ semaphore_lock(false);
+}
+
+bool sr_74hc595_spi_start(void) {
+ if (!spi_start(SHIFTREG_MATRIX_COL_CS, false, 0, SHIFTREG_DIVISOR)) {
+ dprintf("74hc595 matrix: failed to start spi\n");
+ sr_74hc595_spi_stop();
+ return false;
+ }
+
+ semaphore_lock(true);
+ wait_us(1); // not sure if I need this
+ return true;
+}
+
+bool sr_74hc595_spi_send_byte(uint8_t data) {
+ sr_74hc595_spi_start();
+ writePinLow(SHIFTREG_MATRIX_COL_CS);
+ matrix_io_delay();
+ spi_write(data);
+ matrix_io_delay();
+ writePinHigh(SHIFTREG_MATRIX_COL_CS);
+ sr_74hc595_spi_stop();
+ return true;
+}
+
+/**
+ * Set the entire shift register to be full of inactive bits
+ */
+void clearColumns(void) {
+ uint8_t value = 0b00000000;
+ sr_74hc595_spi_send_byte(value);
+}
+
+void setColumn(int columnShift, bool test_run) {
+ uint8_t columnShiftByte = ((uint8_t)1 << columnShift);
+ if(test_run) {
+ dprintf("byte sent: %d\n", columnShiftByte);
+ }
+ sr_74hc595_spi_send_byte(columnShiftByte);
+}
+
+/*
+ * override of the qmk intialization function
+ */
+void matrix_init_custom(void) {
+ wait_ms(300);
+ spi_init();
+ // Set up the initial states for all the row pins
+ for (int r = 0; r < SHIFTREG_ROWS; r++) {
+ // Note: This needs to use the internal pull down resistors, and atmegas do *not* support that
+ setPinInputLow(rowPinsSR[r]);
+ }
+
+ // Set the CS to low by default, and specify as an output pin
+ writePinHigh(SHIFTREG_MATRIX_COL_CS); // should be high when using SPI?
+ setPinOutput(SHIFTREG_MATRIX_COL_CS);
+
+ // Since it's the init, deactivate all the columns. We'll activate once we get to the matrix scan
+ clearColumns();
+}
+
+bool matrix_scan_custom(matrix_row_t current_matrix[]) {
+ // respect the semaphore
+ if (semaphore_is_locked()) {
+ return false;
+ }
+
+ // Keep track of if something was modified
+ bool matrix_has_changed = false;
+
+ // reset the current matrix, as we'll be updating and comparing to the old matrix
+ memset(current_matrix, 0, matrixArraySize);
+
+
+ bool debug_output = false;
+ // Loop through the columns, activating one at a time, and read the rows, and place in the new current_matrix
+ for (int c = 0; c < SHIFTREG_COLS; c++) {
+ if (debug_output) {
+ dprintf("column iteration: %d\n", c);
+ }
+ setColumn(c, debug_output);
+ matrix_io_delay();
+
+ for (int r = 0; r < SHIFTREG_ROWS; r++) {
+ current_matrix[r] |= ((readPin(rowPinsSR[r]) ? 1 : 0) << c);
+ }
+ }
+
+ matrix_has_changed = memcmp(current_matrix, oldMatrix, matrixArraySize) != 0;
+ memcpy(oldMatrix, current_matrix, matrixArraySize);
+
+ if (matrix_has_changed) {
+ matrix_print();
+ }
+
+
+ // Deactivate all the columns for the next run.
+ clearColumns();
+ matrix_io_delay();
+
+ return matrix_has_changed;
+}