]> git.donarmstrong.com Git - tmk_firmware.git/blob - keyboard/hid_liber/matrix.c
Rename to hid_liber.
[tmk_firmware.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 }