]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/pegasushoof/matrix.c
Keymap: rys Tada68 ISO UK layout (#3934)
[qmk_firmware.git] / keyboards / pegasushoof / matrix.c
1 /*
2 Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
3 Copyright 2016 Daniel Svensson <dsvensson@gmail.com>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <stdint.h>
20 #include <stdbool.h>
21 #include <avr/io.h>
22 #include <util/delay.h>
23 #include "wait.h"
24 #include "print.h"
25 #include "debug.h"
26 #include "util.h"
27 #include "matrix.h"
28
29 static uint8_t debouncing = DEBOUNCING_DELAY;
30 static matrix_row_t matrix[MATRIX_ROWS];
31 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
32
33 static matrix_row_t read_cols(void);
34 static void select_row(uint8_t col);
35
36 inline uint8_t matrix_rows(void)
37 {
38         return MATRIX_ROWS;
39 }
40
41 inline uint8_t matrix_cols(void)
42 {
43         return MATRIX_COLS;
44 }
45
46 void matrix_init(void)
47 {
48         /* Column output pins */
49         DDRD  |=  0b01111011;
50         /* Row input pins */
51         DDRC  &= ~0b10000000;
52         DDRB  &= ~0b01111111;
53         PORTC |=  0b10000000;
54         PORTB |=  0b01111111;
55
56         for (uint8_t i=0; i < MATRIX_ROWS; i++)  {
57                 matrix[i] = 0;
58                 matrix_debouncing[i] = 0;
59         }
60
61         matrix_init_quantum();
62 }
63
64 uint8_t matrix_scan(void)
65 {
66         for (uint8_t col = 0; col < MATRIX_COLS; col++) {
67                 select_row(col);
68                 wait_us(30);
69                 matrix_row_t rows = read_cols();
70                 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
71                         bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
72                         bool curr_bit = rows & (1<<row);
73                         if (prev_bit != curr_bit) {
74                                 matrix_debouncing[row] ^= (matrix_row_t) 1 << col;
75                                 debouncing = DEBOUNCING_DELAY;
76                         }
77                 }
78         }
79
80         if (debouncing) {
81                 if (--debouncing) {
82                         wait_ms(1);
83                 } else {
84                         for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
85                                 matrix[i] = matrix_debouncing[i];
86                         }
87                 }
88         }
89
90         matrix_scan_quantum();
91
92         return 1;
93 }
94
95 bool matrix_is_modified(void)
96 {
97         if (debouncing)
98                 return false;
99         return true;
100 }
101
102 inline
103 bool matrix_is_on(uint8_t row, uint8_t col)
104 {
105         return matrix[row] & 1 << col;
106 }
107
108 inline
109 matrix_row_t matrix_get_row(uint8_t row)
110 {
111         return matrix[row];
112 }
113
114 void matrix_print(void)
115 {
116         print("\nr/c 0123456789ABCDEF\n");
117         for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
118                 phex(row); print(": ");
119                 pbin_reverse16(matrix_get_row(row));
120                 print("\n");
121         }
122 }
123
124 uint8_t matrix_key_count(void)
125 {
126         uint8_t count = 0;
127         for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
128                 count += bitpop16(matrix[i]);
129         }
130         return count;
131 }
132
133 static matrix_row_t read_cols(void)
134 {
135         return
136                 (PINB & (1 << 5) ? 0 : 1 << 0) |
137                 (PINC & (1 << 7) ? 0 : 1 << 1) |
138                 (PINB & (1 << 4) ? 0 : 1 << 2) |
139                 (PINB & (1 << 6) ? 0 : 1 << 3) |
140                 (PINB & (1 << 1) ? 0 : 1 << 4) |
141                 (PINB & (1 << 0) ? 0 : 1 << 5) |
142                 (PINB & (1 << 3) ? 0 : 1 << 6) |
143                 (PINB & (1 << 2) ? 0 : 1 << 7);
144 }
145
146 static void select_row(uint8_t col)
147 {
148         switch (col) {
149                 case 0:
150                         PORTD = (PORTD & ~0b01111011) | 0b00110011;
151                         break;
152                 case 1:
153                         PORTD = (PORTD & ~0b01111011) | 0b01110000;
154                         break;
155                 case 2:
156                         PORTD = (PORTD & ~0b01111011) | 0b00010011;
157                         break;
158                 case 3:
159                         PORTD = (PORTD & ~0b01111011) | 0b01101000;
160                         break;
161                 case 4:
162                         PORTD = (PORTD & ~0b01111011) | 0b00001011;
163                         break;
164                 case 5:
165                         PORTD = (PORTD & ~0b01111011) | 0b00111011;
166                         break;
167                 case 6:
168                         PORTD = (PORTD & ~0b01111011) | 0b01111000;
169                         break;
170                 case 7:
171                         PORTD = (PORTD & ~0b01111011) | 0b01100001;
172                         break;
173                 case 8:
174                         PORTD = (PORTD & ~0b01111011) | 0b01101001;
175                         break;
176                 case 9:
177                         PORTD = (PORTD & ~0b01111011) | 0b01110001;
178                         break;
179                 case 10:
180                         PORTD = (PORTD & ~0b01111011) | 0b01101010;
181                         break;
182                 case 11:
183                         PORTD = (PORTD & ~0b01111011) | 0b01100010;
184                         break;
185                 case 12:
186                         PORTD = (PORTD & ~0b01111011) | 0b01111001;
187                         break;
188                 case 13:
189                         PORTD = (PORTD & ~0b01111011) | 0b01100000;
190                         break;
191                 case 14:
192                         PORTD = (PORTD & ~0b01111011) | 0b01000011;
193                         break;
194                 case 15:
195                         PORTD = (PORTD & ~0b01111011) | 0b00011011;
196                         break;
197                 case 16:
198                         PORTD = (PORTD & ~0b01111011) | 0b00100011;
199                         break;
200                 case 17:
201                         PORTD = (PORTD & ~0b01111011) | 0b00101011;
202                         break;
203         }
204 }