2 Copyright 2011 Jun Wako <wakojun@gmail.com>
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.
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.
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/>.
20 #include <util/delay.h>
30 static uint8_t debouncing = DEBOUNCE;
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];
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
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
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
71 /* Specifies the ports and pin numbers for the rows */
73 uint8_t *const row_ddr[NROW] = { _DDRB, _DDRB,
75 _DDRD, _DDRD, _DDRD, _DDRD, _DDRD, _DDRD, _DDRD, _DDRD,
76 _DDRF, _DDRF, _DDRF, _DDRF, _DDRF, _DDRF};
79 uint8_t *const row_port[NROW] = { _PORTB, _PORTB,
81 _PORTD, _PORTD, _PORTD, _PORTD, _PORTD, _PORTD, _PORTD, _PORTD,
82 _PORTF, _PORTF, _PORTF, _PORTF, _PORTF, _PORTF};
85 uint8_t *const row_pin[NROW] = { _PINB, _PINB,
87 _PIND, _PIND, _PIND, _PIND, _PIND, _PIND, _PIND, _PIND,
88 _PINF, _PINF, _PINF, _PINF, _PINF, _PINF};
91 const uint8_t row_bit[NROW] = { _BIT4, _BIT7,
93 _BIT0, _BIT1, _BIT2, _BIT3, _BIT4, _BIT5, _BIT6, _BIT7,
94 _BIT0, _BIT1, _BIT4, _BIT5, _BIT6, _BIT7};
97 const uint8_t mask = 0x0E;
99 /* Specifies the ports and pin numbers for the columns */
101 const uint8_t col_bit[NCOL] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E};
104 inline void pull_column(int col) {
105 PORTB = col_bit[col] | (PORTB & ~mask);
109 inline void release_column(int col) {
112 /* PORTB is set as input with pull-up resistors
113 PORTC,D,E,F are set to high output */
115 void setup_io_pins(void) {
119 for(row = 0; row < NROW; row++) {
120 *row_ddr[row] &= ~row_bit[row];
121 *row_port[row] &= ~row_bit[row];
126 void setup_leds(void) {
133 uint8_t matrix_rows(void)
139 uint8_t matrix_cols(void)
144 void matrix_init(void)
146 // initialize row and col
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;
154 matrix_debounced = _matrix1;
157 uint8_t matrix_scan(void)
160 uint8_t *tmp = matrix_debounced;
161 matrix_debounced = matrix;
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);
174 debug("bounce!: "); debug_hex(debouncing); print("\n");
176 debouncing = DEBOUNCE;
189 bool matrix_is_modified(void)
191 // NOTE: no longer used
196 bool matrix_has_ghost(void)
202 bool matrix_is_on(uint8_t row, uint8_t col)
204 return (matrix_debounced[row] & (1<<col));
208 matrix_row_t matrix_get_row(uint8_t row)
210 return matrix_debounced[row];
213 void matrix_print(void)
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));
223 uint8_t matrix_key_count(void)
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))