aboutsummaryrefslogtreecommitdiff
path: root/keyboards/amj96/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/amj96/matrix.c')
-rw-r--r--keyboards/amj96/matrix.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/keyboards/amj96/matrix.c b/keyboards/amj96/matrix.c
new file mode 100644
index 000000000..8e7bbaa79
--- /dev/null
+++ b/keyboards/amj96/matrix.c
@@ -0,0 +1,219 @@
1/*
2Copyright 2014 Kai Ryu <[email protected]>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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#ifdef UART_RGB_ENABLE
30#include "uart_rgb.h"
31#endif
32
33#ifndef DEBOUNCE
34# define DEBOUNCE 5
35#endif
36static uint8_t debouncing = DEBOUNCE;
37
38/* matrix state(1:on, 0:off) */
39static matrix_row_t matrix[MATRIX_ROWS];
40static matrix_row_t matrix_debouncing[MATRIX_ROWS];
41
42static matrix_row_t read_cols(void);
43static void init_cols(void);
44static void init_rows(void);
45static void unselect_rows(void);
46static void select_row(uint8_t row);
47
48inline
49uint8_t matrix_rows(void)
50{
51 return MATRIX_ROWS;
52}
53
54inline
55uint8_t matrix_cols(void)
56{
57 return MATRIX_COLS;
58}
59
60void matrix_init(void)
61{
62
63#ifdef UART_RGB_ENABLE
64 uart_rgb_init();
65#endif
66
67 // 85 REST
68 DDRD |= _BV(PD7);
69 PORTD |= _BV(PD7);
70
71 // initialize row and col
72 init_rows();
73 init_cols();
74
75 // initialize matrix state: all keys off
76 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
77 matrix[i] = 0;
78 matrix_debouncing[i] = 0;
79 }
80}
81
82uint8_t matrix_scan(void)
83{
84 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
85 select_row(i);
86 _delay_us(30); // without this wait read unstable value.
87 matrix_row_t cols = read_cols();
88 if (matrix_debouncing[i] != cols) {
89 matrix_debouncing[i] = cols;
90 if (debouncing) {
91 debug("bounce!: "); debug_hex(debouncing); debug("\n");
92 }
93 debouncing = DEBOUNCE;
94 }
95 unselect_rows();
96 }
97
98 if (debouncing) {
99 if (--debouncing) {
100 _delay_ms(1);
101 } else {
102 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
103 matrix[i] = matrix_debouncing[i];
104 }
105 }
106 }
107
108 return 1;
109}
110
111bool matrix_is_modified(void)
112{
113 if (debouncing) return false;
114 return true;
115}
116
117inline
118bool matrix_is_on(uint8_t row, uint8_t col)
119{
120 return (matrix[row] & ((matrix_row_t)1<<col));
121}
122
123inline
124matrix_row_t matrix_get_row(uint8_t row)
125{
126 return matrix[row];
127}
128
129void matrix_print(void)
130{
131 print("\nr/c 0123456789ABCDEF\n");
132 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
133 print_hex8(row); print(": ");
134 print_bin_reverse16(matrix_get_row(row));
135 print("\n");
136 }
137}
138
139uint8_t matrix_key_count(void)
140{
141 uint8_t count = 0;
142 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
143 count += bitpop16(matrix[i]);
144 }
145 return count;
146}
147
148/* Column pin configuration
149 * col: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
150 * pin: F7 F6 F5 F4 F1 F0 E6 D7 D6 D5 D1 D0 B7 B6 B0 C7
151 * */
152static void init_cols(void)
153{
154 // Input with pull-up(DDR:0, PORT:1)
155 DDRF &= 0b00001100;
156 PORTF |= 0b11110011;
157
158 DDRD &= 0b00011100;
159 PORTD |= 0b11100011;
160
161 DDRB &= ~(_BV(PB6) | _BV(PB7)| _BV(PB0));
162 PORTB |= (_BV(PB6) | _BV(PB7)| _BV(PB0));
163
164 DDRE &= ~_BV(PE6);
165 PORTE |= _BV(PE6);
166
167 DDRC &= ~_BV(PC7);
168 PORTC |= _BV(PC7);
169
170}
171
172static matrix_row_t read_cols(void)
173{
174
175 return (PINF&_BV(PF7) ? 0 : (1<<0)) |
176 (PINF&_BV(PF6) ? 0 : (1<<1)) |
177 (PINF&_BV(PF5) ? 0 : (1<<2)) |
178 (PINF&_BV(PF4) ? 0 : (1<<3)) |
179 (PINF&_BV(PF1) ? 0 : (1<<4)) |
180 (PINF&_BV(PF0) ? 0 : (1<<5)) |
181 (PINE&_BV(PE6) ? 0 : (1<<6)) |
182 (PIND&_BV(PD7) ? 0 : (1<<7)) |
183 (PIND&_BV(PD6) ? 0 : (1<<8)) |
184 (PIND&_BV(PD5) ? 0 : (1<<9)) |
185 (PIND&_BV(PD1) ? 0 : (1<<10)) |
186 (PIND&_BV(PD0) ? 0 : (1<<11)) |
187 (PINB&_BV(PB7) ? 0 : (1<<12)) |
188 (PINB&_BV(PB6) ? 0 : (1<<13)) |
189 (PINB&_BV(PB0) ? 0 : (1<<14)) |
190 (PINC&_BV(PC7) ? 0 : (1<<15));
191}
192
193/* Row pin configuration
194 * row: 0 1 2 3 4 5 x
195 * pin: B3 0 1 0 1 0 1 1
196 * B2 0 0 1 1 0 0 1
197 * B1 0 0 0 0 1 1 1
198 */
199
200static void init_rows(void)
201{
202 DDRB |= (1<<PB1 | 1<<PB2 | 1<<PB3);
203}
204
205static void unselect_rows(void)
206{
207 // Hi-Z(DDR:0, PORT:0) to unselect
208 PORTB |= (1<<PB1);
209 PORTB |= (1<<PB2);
210 PORTB |= (1<<PB3);
211}
212
213static void select_row(uint8_t row)
214{
215 // Output low(DDR:1, PORT:0) to select
216 (row & (1<<0)) ? (PORTB |= (1<<PB3)) : (PORTB &= ~(1<<PB3));
217 (row & (1<<1)) ? (PORTB |= (1<<PB2)) : (PORTB &= ~(1<<PB2));
218 (row & (1<<2)) ? (PORTB |= (1<<PB1)) : (PORTB &= ~(1<<PB1));
219}