]> git.gir.st - tmk_keyboard.git/blob - keyboard/hid_liber/matrix.c
Rename to hid_liber.
[tmk_keyboard.git] / keyboard / hid_liber / matrix.c
1 /*
2 Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include <stdint.h>
18 #include <stdbool.h>
19 #include <avr/io.h>
20 #include <util/delay.h>
21 #include "print.h"
22 #include "debug.h"
23 #include "util.h"
24 #include "matrix.h"
25
26
27 #ifndef DEBOUNCE
28 # define DEBOUNCE 5
29 #endif
30 static uint8_t debouncing = DEBOUNCE;
31
32 // bit array of key state(1:on, 0:off)
33 static matrix_row_t *matrix;
34 static matrix_row_t *matrix_debounced;
35 static matrix_row_t _matrix0[MATRIX_ROWS];
36 static matrix_row_t _matrix1[MATRIX_ROWS];
37
38
39 #define NROW 18
40 #define NCOL 8
41 #define _DDRA (uint8_t *const)&DDRA
42 #define _DDRB (uint8_t *const)&DDRB
43 #define _DDRC (uint8_t *const)&DDRC
44 #define _DDRD (uint8_t *const)&DDRD
45 #define _DDRE (uint8_t *const)&DDRE
46 #define _DDRF (uint8_t *const)&DDRF
47
48 #define _PINA (uint8_t *const)&PINA
49 #define _PINB (uint8_t *const)&PINB
50 #define _PINC (uint8_t *const)&PINC
51 #define _PIND (uint8_t *const)&PIND
52 #define _PINE (uint8_t *const)&PINE
53 #define _PINF (uint8_t *const)&PINF
54
55 #define _PORTA (uint8_t *const)&PORTA
56 #define _PORTB (uint8_t *const)&PORTB
57 #define _PORTC (uint8_t *const)&PORTC
58 #define _PORTD (uint8_t *const)&PORTD
59 #define _PORTE (uint8_t *const)&PORTE
60 #define _PORTF (uint8_t *const)&PORTF
61
62 #define _BIT0 0x01
63 #define _BIT1 0x02
64 #define _BIT2 0x04
65 #define _BIT3 0x08
66 #define _BIT4 0x10
67 #define _BIT5 0x20
68 #define _BIT6 0x40
69 #define _BIT7 0x80
70
71 /* Specifies the ports and pin numbers for the rows */
72 static
73 uint8_t *const row_ddr[NROW] = { _DDRB, _DDRB,
74 _DDRC, _DDRC,
75 _DDRD, _DDRD, _DDRD, _DDRD, _DDRD, _DDRD, _DDRD, _DDRD,
76 _DDRF, _DDRF, _DDRF, _DDRF, _DDRF, _DDRF};
77
78 static
79 uint8_t *const row_port[NROW] = { _PORTB, _PORTB,
80 _PORTC, _PORTC,
81 _PORTD, _PORTD, _PORTD, _PORTD, _PORTD, _PORTD, _PORTD, _PORTD,
82 _PORTF, _PORTF, _PORTF, _PORTF, _PORTF, _PORTF};
83
84 static
85 uint8_t *const row_pin[NROW] = { _PINB, _PINB,
86 _PINC, _PINC,
87 _PIND, _PIND, _PIND, _PIND, _PIND, _PIND, _PIND, _PIND,
88 _PINF, _PINF, _PINF, _PINF, _PINF, _PINF};
89
90 static
91 const uint8_t row_bit[NROW] = { _BIT4, _BIT7,
92 _BIT6, _BIT7,
93 _BIT0, _BIT1, _BIT2, _BIT3, _BIT4, _BIT5, _BIT6, _BIT7,
94 _BIT0, _BIT1, _BIT4, _BIT5, _BIT6, _BIT7};
95
96 static
97 const uint8_t mask = 0x0E;
98
99 /* Specifies the ports and pin numbers for the columns */
100 static
101 const uint8_t col_bit[NCOL] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E};
102
103 static
104 inline void pull_column(int col) {
105 PORTB = col_bit[col] | (PORTB & ~mask);
106 }
107
108 static
109 inline void release_column(int col) {
110 }
111
112 /* PORTB is set as input with pull-up resistors
113 PORTC,D,E,F are set to high output */
114 static
115 void setup_io_pins(void) {
116 uint8_t row;
117 DDRB |= 0x0E;
118 PORTB &= ~0x0E;
119 for(row = 0; row < NROW; row++) {
120 *row_ddr[row] &= ~row_bit[row];
121 *row_port[row] &= ~row_bit[row];
122 }
123 }
124
125 static
126 void setup_leds(void) {
127 DDRB |= 0x60;
128 PORTB |= 0x60;
129 }
130
131
132 inline
133 uint8_t matrix_rows(void)
134 {
135 return MATRIX_ROWS;
136 }
137
138 inline
139 uint8_t matrix_cols(void)
140 {
141 return MATRIX_COLS;
142 }
143
144 void matrix_init(void)
145 {
146 // initialize row and col
147 setup_io_pins();
148 setup_leds();
149
150 // initialize matrix state: all keys off
151 for (uint8_t i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00;
152 for (uint8_t i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0x00;
153 matrix = _matrix0;
154 matrix_debounced = _matrix1;
155 }
156
157 uint8_t matrix_scan(void)
158 {
159 if (!debouncing) {
160 uint8_t *tmp = matrix_debounced;
161 matrix_debounced = matrix;
162 matrix = tmp;
163 }
164
165 for (uint8_t col = 0; col < NCOL; col++) { // 0-7
166 pull_column(col); // output hi on theline
167 _delay_us(1); // without this wait it won't read stable value.
168 for (uint8_t row = 0; row < NROW; row++) { // 0-17
169 bool prev_bit = matrix[row] & (1<<col);
170 bool curr_bit = *row_pin[row] & row_bit[row];
171 if (prev_bit != curr_bit) {
172 matrix[row] ^= (1<<col);
173 if (debouncing) {
174 debug("bounce!: "); debug_hex(debouncing); print("\n");
175 }
176 debouncing = DEBOUNCE;
177 }
178 }
179 release_column(col);
180 }
181
182 if (debouncing) {
183 debouncing--;
184 }
185
186 return 1;
187 }
188
189 bool matrix_is_modified(void)
190 {
191 // NOTE: no longer used
192 return true;
193 }
194
195 inline
196 bool matrix_has_ghost(void)
197 {
198 return false;
199 }
200
201 inline
202 bool matrix_is_on(uint8_t row, uint8_t col)
203 {
204 return (matrix_debounced[row] & (1<<col));
205 }
206
207 inline
208 matrix_row_t matrix_get_row(uint8_t row)
209 {
210 return matrix_debounced[row];
211 }
212
213 void matrix_print(void)
214 {
215 print("\nr/c 01234567\n");
216 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
217 phex(row); print(": ");
218 pbin_reverse(matrix_get_row(row));
219 print("\n");
220 }
221 }
222
223 uint8_t matrix_key_count(void)
224 {
225 uint8_t count = 0;
226 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
227 for (uint8_t j = 0; j < MATRIX_COLS; j++) {
228 if (matrix_is_on(i, j))
229 count++;
230 }
231 }
232 return count;
233 }
Imprint / Impressum