]> git.gir.st - tmk_keyboard.git/blob - keyboard/alps64/matrix.c
alps64: unimap definition
[tmk_keyboard.git] / keyboard / alps64 / matrix.c
1 /*
2 Copyright 2012 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
18 /*
19 * scan matrix
20 */
21 #include <stdint.h>
22 #include <stdbool.h>
23 #include <avr/io.h>
24 #include <util/delay.h>
25 #include "print.h"
26 #include "debug.h"
27 #include "util.h"
28 #include "matrix.h"
29
30
31 #ifndef DEBOUNCE
32 # define DEBOUNCE 5
33 #endif
34 static uint8_t debouncing = DEBOUNCE;
35
36 /* matrix state(1:on, 0:off) */
37 static matrix_row_t matrix[MATRIX_ROWS];
38 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
39
40 static matrix_row_t read_cols(void);
41 static void init_cols(void);
42 static void unselect_rows(void);
43 static void select_row(uint8_t row);
44
45
46 #define LED_ON() do { DDRC |= (1<<5); PORTC |= (1<<5); } while (0)
47 #define LED_OFF() do { DDRC &= ~(1<<5); PORTC &= ~(1<<5); } while (0)
48 #define LED_TGL() do { DDRC |= (1<<5); PINC |= (1<<5); } while (0)
49
50 void matrix_init(void)
51 {
52 // initialize row and col
53 unselect_rows();
54 init_cols();
55
56 // initialize matrix state: all keys off
57 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
58 matrix[i] = 0;
59 matrix_debouncing[i] = 0;
60 }
61
62 //debug
63 debug_matrix = true;
64 LED_ON();
65 _delay_ms(500);
66 LED_OFF();
67 }
68
69 uint8_t matrix_scan(void)
70 {
71 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
72 select_row(i);
73 _delay_us(30); // without this wait read unstable value.
74 matrix_row_t cols = read_cols();
75 if (matrix_debouncing[i] != cols) {
76 matrix_debouncing[i] = cols;
77 if (debouncing) {
78 debug("bounce!: "); debug_hex(debouncing); debug("\n");
79 }
80 debouncing = DEBOUNCE;
81 }
82 unselect_rows();
83 }
84
85 if (debouncing) {
86 if (--debouncing) {
87 _delay_ms(1);
88 } else {
89 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
90 matrix[i] = matrix_debouncing[i];
91 }
92 }
93 }
94
95 return 1;
96 }
97
98 inline
99 matrix_row_t matrix_get_row(uint8_t row)
100 {
101 return matrix[row];
102 }
103
104 /* Column pin configuration
105 * col: 0 1 2 3 4 5 6 7
106 * pin: B0 B1 B2 B3 B4 B5 B6 B7
107 */
108 static void init_cols(void)
109 {
110 // Input with pull-up(DDR:0, PORT:1)
111 DDRB &= ~0b11111111;
112 PORTB |= 0b11111111;
113 }
114
115 /* Returns status of switches(1:on, 0:off) */
116 static matrix_row_t read_cols(void)
117 {
118 // Invert because PIN indicates 'switch on' with low(0) and 'off' with high(1)
119 return ~PINB;
120 }
121
122 /* Row pin configuration
123 * row: 0 1 2 3 4 5 6 7
124 * pin: D0 D1 D2 D3 D4 D5 D6 C2
125 */
126 static void unselect_rows(void)
127 {
128 // Hi-Z(DDR:0, PORT:0) to unselect
129 DDRD &= ~0b01111111;
130 PORTD &= ~0b01111111;
131 DDRC &= ~0b00000100;
132 PORTC &= ~0b00000100;
133 }
134
135 static void select_row(uint8_t row)
136 {
137 // Output low(DDR:1, PORT:0) to select
138 switch (row) {
139 case 0:
140 DDRD |= (1<<0);
141 PORTD &= ~(1<<0);
142 break;
143 case 1:
144 DDRD |= (1<<1);
145 PORTD &= ~(1<<1);
146 break;
147 case 2:
148 DDRD |= (1<<2);
149 PORTD &= ~(1<<2);
150 break;
151 case 3:
152 DDRD |= (1<<3);
153 PORTD &= ~(1<<3);
154 break;
155 case 4:
156 DDRD |= (1<<4);
157 PORTD &= ~(1<<4);
158 break;
159 case 5:
160 DDRD |= (1<<5);
161 PORTD &= ~(1<<5);
162 break;
163 case 6:
164 DDRD |= (1<<6);
165 PORTD &= ~(1<<6);
166 break;
167 case 7:
168 DDRC |= (1<<2);
169 PORTC &= ~(1<<2);
170 break;
171 }
172 }
Imprint / Impressum