]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/handwired/datahand/matrix.c
Usbasploader bootloader option addition (#6304)
[qmk_firmware.git] / keyboards / handwired / datahand / matrix.c
1 /* Copyright 2017-2019 Nikolaus Wittenstein <nikolaus.wittenstein@gmail.com>
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
9  * FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13  * PERFORMANCE OF THIS SOFTWARE.
14  */
15
16 #include "datahand.h"
17
18 #include "matrix.h"
19 #include "action.h"
20
21 #include <stdint.h>
22 #include <stdbool.h>
23 #include <avr/io.h>
24
25 static matrix_row_t matrix[MATRIX_ROWS];
26
27 static matrix_row_t read_cols(void);
28 static void select_row(uint8_t row);
29
30 void matrix_init(void) {
31   /* See datahand.h for more detail on pins. */
32
33   /* 7 - matrix scan; 6-3 - mode LEDs */
34   DDRB = 0b11111000;
35
36   /* 1-0 - matrix scan */
37   DDRD = 0b00000011;
38
39   /* 6 - matrix scan */
40   DDRE = 0b01000000;
41
42   /* 7-4 - lock LEDs */
43   DDRF = 0b11110000;
44
45   /* Turn off the non-Normal LEDs (they're active low). */
46   PORTB |= LED_TENKEY | LED_FN | LED_NAS;
47
48   /* Turn off the lock LEDs. */
49   PORTF |= LED_CAPS_LOCK | LED_NUM_LOCK | LED_SCROLL_LOCK | LED_MOUSE_LOCK;
50
51   matrix_init_user();
52 }
53
54 uint8_t matrix_scan(void) {
55   for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
56     select_row(row);
57     /* The default hardware works down to at least 100us, but I have a replacement
58      * photodiode that responds a little more slowly. Cranking it up to 1000us fixes
59      * shadowing issues.
60      */
61     _delay_us(1000);
62     matrix[row] = read_cols();
63   }
64
65   matrix_scan_user();
66
67   return 1;
68 }
69
70 matrix_row_t matrix_get_row(uint8_t row) {
71   return matrix[row];
72 }
73
74 void matrix_print(void) {
75   print("\nr/c 01234567\n");
76
77   for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
78     phex(row);
79     print(": ");
80     print_bin_reverse8(matrix_get_row(row));
81     print("\n");
82   }
83 }
84
85 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
86   return process_record_user(keycode, record);
87 }
88
89 static void select_row(uint8_t row) {
90   /* Original 8051: P1 bits 0-3 (pins 1-4)
91    * Teensy++: PE0, PB7, PD0, PD1
92    */
93
94   if (row & (1<<0)) {
95     PORTE |= (1<<6);
96   } else {
97     PORTE &= ~(1<<6);
98   }
99
100   if (row & (1<<1)) {
101     PORTB |= (1<<7);
102   } else {
103     PORTB &= ~(1<<7);
104   }
105
106   if (row & (1<<2)) {
107     PORTD |= (1<<0);
108   } else {
109     PORTD &= ~(1<<0);
110   }
111
112   if (row & (1<<3)) {
113     PORTD |= (1<<1);
114   } else {
115     PORTD &= ~(1<<1);
116   }
117 }
118
119 static matrix_row_t read_cols(void) {
120   /* Original 8051: P1 bits 4-7 (pins 5-8)
121    * Teensy++: PD bits 2-5
122    */
123
124   return (PIND & 0b00111100) >> 2;
125 }