summaryrefslogtreecommitdiff
path: root/keyboards/handwired/dqz11n1g/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/handwired/dqz11n1g/matrix.c')
-rw-r--r--keyboards/handwired/dqz11n1g/matrix.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/keyboards/handwired/dqz11n1g/matrix.c b/keyboards/handwired/dqz11n1g/matrix.c
new file mode 100644
index 0000000000..f9f3f2b68f
--- /dev/null
+++ b/keyboards/handwired/dqz11n1g/matrix.c
@@ -0,0 +1,131 @@
+/*
+ Copyright (c) 2022 David Kuehling <dvdkhlng TA posteo TOD de>
+
+ 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 <avr/io.h>
+
+#include "spi_master.h"
+#include "quantum.h"
+#include "matrix.h"
+
+static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
+
+static void unselect_rows(void);
+
+void matrix_init_custom(void) {
+ /* initialize row pins */
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+ setPinOutput(row_pins[row]);
+ }
+ unselect_rows();
+
+ /* columns read via shift-register on SPI lines */
+
+ /* Enable SPI, Master, set clock rate fck/2. First bit already at Qh
+ * output before clock edge (CPHA=0). SN74HC165 shift register shifts
+ * on low-to-high transition (CPOL=1). Receive the LSB first (DORD=1).
+ */
+ bool lsbFirst = true;
+ uint8_t mode = 2; /* CPOL=1, CPHA=0 */
+ uint16_t divisor = 16;
+
+ /* According to Atmega32U4 datasheet, PB0 *must* be set to output,
+ * otherwise it will interfere with SPI master operation. On pro-micro
+ * it's connected to a yellew LED. */
+ pin_t slavePin = PB0;
+ spi_init();
+ spi_start(slavePin, lsbFirst, mode, divisor);
+
+ /* Initialize pin controlling the shift register's SH/~LD pin */
+ setPinOutput(ROW_SHIFT_PIN);
+}
+
+static void select_row(uint8_t row) {
+ pin_t pin = row_pins[row];
+ if (pin != NO_PIN) {
+ writePinHigh(pin);
+ }
+}
+
+static void unselect_row(uint8_t row) {
+ pin_t pin = row_pins[row];
+ if (pin != NO_PIN) {
+ writePinLow(pin);
+ }
+}
+
+static void unselect_rows(void) {
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+ unselect_row(row);
+ }
+}
+
+bool matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
+ /* Start with a clear matrix row */
+ matrix_row_t current_row_value = 0;
+
+ /* Set shift register SH/~LD pin to "load" mode */
+ writePinLow(ROW_SHIFT_PIN);
+ select_row(current_row);
+ matrix_output_select_delay();
+
+ /* Set shift register SH/~LD pin to "shift" mode */
+ writePinHigh(ROW_SHIFT_PIN);
+
+ /* For each octet of columns... */
+ for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index += 8) {
+ spi_status_t read_result = spi_read();
+ if (read_result >= 0) {
+ /* only if SPI read successful: populate the matrix row with the
+ state of the 8 consecutive column bits */
+ current_row_value |= ((matrix_row_t)read_result << col_index);
+ }
+ }
+
+ /* Unselect row & wait for all columns signals to go high. */
+ unselect_row(current_row);
+ matrix_output_unselect_delay(current_row, current_row_value != 0);
+
+ /* Update row in matrix. */
+ if (current_row_value != current_matrix[current_row]) {
+ current_matrix[current_row] = current_row_value;
+ return true;
+ }
+
+ return false;
+}
+
+bool matrix_scan_custom(matrix_row_t curr_matrix[]) {
+ bool changed = false;
+
+ /* set row, read cols */
+ for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
+ changed |= matrix_read_cols_on_row(curr_matrix, current_row);
+ }
+
+ return changed;
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset:4
+ * fill-column: 76
+ * End:
+ */