summaryrefslogtreecommitdiff
path: root/keyboards/handwired/datahand/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/handwired/datahand/matrix.c')
-rw-r--r--keyboards/handwired/datahand/matrix.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/keyboards/handwired/datahand/matrix.c b/keyboards/handwired/datahand/matrix.c
new file mode 100644
index 0000000000..a08450d779
--- /dev/null
+++ b/keyboards/handwired/datahand/matrix.c
@@ -0,0 +1,125 @@
+/* Copyright 2017-2019 Nikolaus Wittenstein <nikolaus.wittenstein@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "datahand.h"
+
+#include "matrix.h"
+#include "action.h"
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <avr/io.h>
+
+static matrix_row_t matrix[MATRIX_ROWS];
+
+static matrix_row_t read_cols(void);
+static void select_row(uint8_t row);
+
+void matrix_init(void) {
+ /* See datahand.h for more detail on pins. */
+
+ /* 7 - matrix scan; 6-3 - mode LEDs */
+ DDRB = 0b11111000;
+
+ /* 1-0 - matrix scan */
+ DDRD = 0b00000011;
+
+ /* 6 - matrix scan */
+ DDRE = 0b01000000;
+
+ /* 7-4 - lock LEDs */
+ DDRF = 0b11110000;
+
+ /* Turn off the non-Normal LEDs (they're active low). */
+ PORTB |= LED_TENKEY | LED_FN | LED_NAS;
+
+ /* Turn off the lock LEDs. */
+ PORTF |= LED_CAPS_LOCK | LED_NUM_LOCK | LED_SCROLL_LOCK | LED_MOUSE_LOCK;
+
+ matrix_init_user();
+}
+
+uint8_t matrix_scan(void) {
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+ select_row(row);
+ /* The default hardware works down to at least 100us, but I have a replacement
+ * photodiode that responds a little more slowly. Cranking it up to 1000us fixes
+ * shadowing issues.
+ */
+ _delay_us(1000);
+ matrix[row] = read_cols();
+ }
+
+ matrix_scan_user();
+
+ return 1;
+}
+
+matrix_row_t matrix_get_row(uint8_t row) {
+ return matrix[row];
+}
+
+void matrix_print(void) {
+ print("\nr/c 01234567\n");
+
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+ phex(row);
+ print(": ");
+ print_bin_reverse8(matrix_get_row(row));
+ print("\n");
+ }
+}
+
+bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
+ return process_record_user(keycode, record);
+}
+
+static void select_row(uint8_t row) {
+ /* Original 8051: P1 bits 0-3 (pins 1-4)
+ * Teensy++: PE0, PB7, PD0, PD1
+ */
+
+ if (row & (1<<0)) {
+ PORTE |= (1<<6);
+ } else {
+ PORTE &= ~(1<<6);
+ }
+
+ if (row & (1<<1)) {
+ PORTB |= (1<<7);
+ } else {
+ PORTB &= ~(1<<7);
+ }
+
+ if (row & (1<<2)) {
+ PORTD |= (1<<0);
+ } else {
+ PORTD &= ~(1<<0);
+ }
+
+ if (row & (1<<3)) {
+ PORTD |= (1<<1);
+ } else {
+ PORTD &= ~(1<<1);
+ }
+}
+
+static matrix_row_t read_cols(void) {
+ /* Original 8051: P1 bits 4-7 (pins 5-8)
+ * Teensy++: PD bits 2-5
+ */
+
+ return (PIND & 0b00111100) >> 2;
+}