]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/amj96/matrix.c
[Keyboard] Use GPIO macros for E6 LED in Planck and Preonic default keymaps (#7098)
[qmk_firmware.git] / keyboards / amj96 / matrix.c
1 /*
2 Copyright 2014 Kai Ryu <kai1103@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 #ifdef UART_RGB_ENABLE
30 #include "uart_rgb.h"
31 #endif
32
33 #ifndef DEBOUNCE
34 #   define DEBOUNCE 5
35 #endif
36 static uint8_t debouncing = DEBOUNCE;
37
38 /* matrix state(1:on, 0:off) */
39 static matrix_row_t matrix[MATRIX_ROWS];
40 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
41
42 static matrix_row_t read_cols(void);
43 static void init_cols(void);
44 static void init_rows(void);
45 static void unselect_rows(void);
46 static void select_row(uint8_t row);
47
48 inline
49 uint8_t matrix_rows(void)
50 {
51     return MATRIX_ROWS;
52 }
53
54 inline
55 uint8_t matrix_cols(void)
56 {
57     return MATRIX_COLS;
58 }
59
60 void 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
82 uint8_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
111 bool matrix_is_modified(void)
112 {
113     if (debouncing) return false;
114     return true;
115 }
116
117 inline
118 bool matrix_is_on(uint8_t row, uint8_t col)
119 {
120     return (matrix[row] & ((matrix_row_t)1<<col));
121 }
122
123 inline
124 matrix_row_t matrix_get_row(uint8_t row)
125 {
126     return matrix[row];
127 }
128
129 void matrix_print(void)
130 {
131     print("\nr/c 0123456789ABCDEF\n");
132     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
133         phex(row); print(": ");
134         pbin_reverse16(matrix_get_row(row));
135         print("\n");
136     }
137 }
138
139 uint8_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  * */
152 static 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
172 static 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
200 static void init_rows(void)
201 {
202      DDRB  |= (1<<PB1 | 1<<PB2 | 1<<PB3);
203 }
204
205 static 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
213 static 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 }