summaryrefslogtreecommitdiffstats
path: root/keyboards/tzarc/djinn/djinn_portscan_matrix.c
diff options
context:
space:
mode:
authorlokher <lokher@gmail.com>2022-12-06 17:04:10 +0800
committerlokher <lokher@gmail.com>2022-12-06 17:04:10 +0800
commit27fc28fd2ff52e079a5bc58d6aaea4c752420615 (patch)
tree7ac943fb1ba4f430a7220efd18f66f6a77205c30 /keyboards/tzarc/djinn/djinn_portscan_matrix.c
parente736133392fe6427cfb995da0787337189828272 (diff)
parent2709b6ed616f8012ff4cfd3ee69a822a8d188351 (diff)
Merge upstream master
Diffstat (limited to 'keyboards/tzarc/djinn/djinn_portscan_matrix.c')
-rw-r--r--keyboards/tzarc/djinn/djinn_portscan_matrix.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/keyboards/tzarc/djinn/djinn_portscan_matrix.c b/keyboards/tzarc/djinn/djinn_portscan_matrix.c
new file mode 100644
index 0000000000..6fcfd48bba
--- /dev/null
+++ b/keyboards/tzarc/djinn/djinn_portscan_matrix.c
@@ -0,0 +1,117 @@
+// Copyright 2018-2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "quantum.h"
+#include <hal_pal.h>
+#include "djinn.h"
+
+#define GPIOB_BITMASK (1 << 13 | 1 << 14 | 1 << 15) // B13, B14, B15
+#define GPIOB_OFFSET 13
+#define GPIOB_COUNT 3
+#define GPIOC_BITMASK (1 << 6 | 1 << 7 | 1 << 8) // C6, C7, C8
+#define GPIOC_OFFSET 6
+
+// Pin definitions
+static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
+static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
+
+void matrix_wait_for_pin(pin_t pin, uint8_t target_state) {
+ rtcnt_t start = chSysGetRealtimeCounterX();
+ rtcnt_t end = start + 5000;
+ while (chSysIsCounterWithinX(chSysGetRealtimeCounterX(), start, end)) {
+ if (readPin(pin) == target_state) {
+ break;
+ }
+ }
+}
+
+void matrix_wait_for_port(stm32_gpio_t *port, uint32_t target_bitmask) {
+ rtcnt_t start = chSysGetRealtimeCounterX();
+ rtcnt_t end = start + 5000;
+ while (chSysIsCounterWithinX(chSysGetRealtimeCounterX(), start, end)) {
+ if ((palReadPort(port) & target_bitmask) == target_bitmask) {
+ break;
+ }
+ }
+}
+
+void matrix_init_custom(void) {
+ for (int i = 0; i < MATRIX_ROWS; ++i) {
+ setPinInputHigh(row_pins[i]);
+ }
+ for (int i = 0; i < MATRIX_COLS; ++i) {
+ setPinInputHigh(col_pins[i]);
+ }
+}
+
+bool matrix_scan_custom(matrix_row_t current_matrix[]) {
+ static matrix_row_t temp_matrix[MATRIX_ROWS] = {0};
+
+ for (int current_col = 0; current_col < MATRIX_COLS; ++current_col) {
+ // Keep track of the pin we're working with
+ pin_t curr_col_pin = col_pins[current_col];
+
+ // Setup the output column pin
+ setPinOutput(curr_col_pin);
+ writePinLow(curr_col_pin);
+ matrix_wait_for_pin(curr_col_pin, 0);
+
+ // Read the row ports
+ uint32_t gpio_b = palReadPort(GPIOB);
+ uint32_t gpio_c = palReadPort(GPIOC);
+
+ // Unselect the row pin
+ setPinInputHigh(curr_col_pin);
+
+ // Construct the packed bitmask for the pins
+ uint32_t readback = ~(((gpio_b & GPIOB_BITMASK) >> GPIOB_OFFSET) | (((gpio_c & GPIOC_BITMASK) >> GPIOC_OFFSET) << GPIOB_COUNT));
+
+ // Inject values into the matrix
+ for (int i = 0; i < MATRIX_ROWS; ++i) {
+ if (readback & (1 << i)) {
+ temp_matrix[i] |= (1ul << current_col);
+ } else {
+ temp_matrix[i] &= ~(1ul << current_col);
+ }
+ }
+
+ // Wait for readback of the unselected column to go high
+ matrix_wait_for_pin(curr_col_pin, 1);
+
+ // Wait for readback of each port to go high -- unselecting the row would have been completed
+ matrix_wait_for_port(GPIOB, GPIOB_BITMASK);
+ matrix_wait_for_port(GPIOC, GPIOC_BITMASK);
+ }
+
+ // Check if we've changed, return the last-read data
+ bool changed = memcmp(current_matrix, temp_matrix, sizeof(temp_matrix)) != 0;
+ if (changed) {
+ memcpy(current_matrix, temp_matrix, sizeof(temp_matrix));
+ }
+ return changed;
+}
+
+void matrix_wait_for_interrupt(void) {
+ // Set up row/col pins and attach callback
+ for (int i = 0; i < ARRAY_SIZE(col_pins); ++i) {
+ setPinOutput(col_pins[i]);
+ writePinLow(col_pins[i]);
+ }
+ for (int i = 0; i < ARRAY_SIZE(row_pins); ++i) {
+ setPinInputHigh(row_pins[i]);
+ palEnableLineEvent(row_pins[i], PAL_EVENT_MODE_BOTH_EDGES);
+ }
+
+ // Wait for an interrupt
+ __WFI();
+
+ // Now that the interrupt has woken us up, reset all the row/col pins back to defaults
+ for (int i = 0; i < ARRAY_SIZE(row_pins); ++i) {
+ palDisableLineEvent(row_pins[i]);
+ writePinHigh(row_pins[i]);
+ setPinInputHigh(row_pins[i]);
+ }
+ for (int i = 0; i < ARRAY_SIZE(col_pins); ++i) {
+ writePinHigh(col_pins[i]);
+ setPinInputHigh(col_pins[i]);
+ }
+} \ No newline at end of file