]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/al1/matrix.c
[Keyboard] fixed pins for numpad_5x4 layout (#6311)
[qmk_firmware.git] / keyboards / al1 / matrix.c
1 #include <stdint.h>
2 #include <stdbool.h>
3 #include <avr/io.h>
4 #include <util/delay.h>
5 #include "print.h"
6 #include "debug.h"
7 #include "util.h"
8 #include "matrix.h"
9
10 #ifndef DEBOUNCE
11 #   define DEBOUNCE 5
12 #endif
13 static uint8_t debouncing = DEBOUNCE;
14
15 static matrix_row_t matrix[MATRIX_ROWS];
16 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
17
18 static uint8_t read_rows(void);
19 static void init_rows(void);
20 static void unselect_cols(void);
21 static void select_col(uint8_t col);
22
23 inline uint8_t matrix_rows(void) {
24   return MATRIX_ROWS;
25 }
26
27 inline uint8_t matrix_cols(void) {
28   return MATRIX_COLS;
29 }
30
31 __attribute__ ((weak))
32 void matrix_init_kb(void) {
33         matrix_init_user();
34 }
35
36 __attribute__ ((weak))
37 void matrix_scan_kb(void) {
38     matrix_scan_user();
39 }
40
41 __attribute__ ((weak))
42 void matrix_init_user(void) {
43 }
44
45 __attribute__ ((weak))
46 void matrix_scan_user(void) {
47 }
48
49 void matrix_init(void) {
50   // initialize row and col
51     unselect_cols();
52     init_rows();
53
54     // initialize matrix state: all keys off
55     for (uint8_t i=0; i < MATRIX_ROWS; i++) {
56         matrix[i] = 0;
57         matrix_debouncing[i] = 0;
58     }
59   matrix_init_quantum();
60 }
61
62 uint8_t matrix_scan(void) {
63   for (uint8_t col = 0; col < MATRIX_COLS; col++) {
64     select_col(col);
65     _delay_us(3);
66     uint8_t rows = read_rows();
67     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
68       bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
69       bool curr_bit = rows & (1<<row);
70       if (prev_bit != curr_bit) {
71         matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
72         debouncing = DEBOUNCE;
73       }
74     }
75     unselect_cols();
76   }
77
78   if (debouncing) {
79     if (--debouncing) {
80       _delay_ms(1);
81     } else {
82       for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
83         matrix[i] = matrix_debouncing[i];
84       }
85     }
86   }
87
88   matrix_scan_quantum();
89   return 1;
90 }
91
92 bool matrix_is_modified(void) {
93   if (debouncing)
94     return false;
95   else
96     return true;
97 }
98
99 inline bool matrix_is_on(uint8_t row, uint8_t col) {
100   return (matrix[row] & ((matrix_row_t)1<<col));
101 }
102
103 inline matrix_row_t matrix_get_row(uint8_t row) {
104   return matrix[row];
105 }
106
107 void matrix_print(void) {
108   print("\nr/c 0123456789ABCDEF\n");
109   for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
110     xprintf("%02X: %032lb\n", row, bitrev32(matrix_get_row(row)));
111   }
112 }
113
114 uint8_t matrix_key_count(void) {
115   uint8_t count = 0;
116   for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
117     count += bitpop32(matrix[i]);
118   }
119   return count;
120 }
121
122 /* Row pin configuration
123  *
124  * row: 0    1    2    3    4    5
125  * pin: C7   B1   B2   C6   B4   B5
126  *
127  */
128 static void init_rows(void)
129 {
130   DDRC &= ~0b11000000;
131   DDRB &= ~0b00110110;
132   PORTC |= 0b11000000;
133   PORTB |= 0b00110110;
134 }
135
136 static uint8_t read_rows(void) {
137   return (PINC&(1<<PC7) ? 0 : (1<<0)) |
138     (PINB&(1<<PB1) ? 0 : (1<<1)) |
139     (PINB&(1<<PB2) ? 0 : (1<<2)) |
140     (PINC&(1<<PC6) ? 0 : (1<<3)) |
141     (PINB&(1<<PB4) ? 0 : (1<<4)) |
142     (PINB&(1<<PB5) ? 0 : (1<<5));
143 }
144
145 /* Row pin configuration
146  * pin:     D3  D7  D6  D5  D4
147  * row: off  0   x   x   x   x
148  *      0    1   0   0   0   0
149  *      1    1   0   0   0   1
150  *      2    1   0   0   1   0
151  *      3    1   0   0   1   1
152  *      4    1   0   1   0   0
153  *      5    1   0   1   0   1
154  *      6    1   0   1   1   0
155  *      7    1   0   1   1   1
156  *      8    1   1   0   0   0
157  *      9    1   1   0   0   1
158  *      10   1   1   0   1   0
159  *      11   1   1   0   1   1
160  *      12   1   1   1   0   0
161  *      13   1   1   1   0   1
162  *      14   1   1   1   1   0
163  *      15   1   1   1   1   1
164  */
165 static void  unselect_cols(void)
166 {
167   // output high(DDR:1, PORT:1) to unselect
168   DDRB  |= (1 << PD3);
169   PORTB |= (1 << PD3);
170 }
171
172 static void select_col(uint8_t col) {
173   DDRD  |= (1<<PD3 | 1<<PD4 | 1<<PD5 | 1<<PD6 | 1<<PD7);
174
175   PORTD &= ~(1<<PD3);
176
177   if (col & (1<<0)) {
178     PORTD |= (1<<PD4);
179   }
180   else {
181     PORTD &= ~(1<<PD4);
182   }
183   if (col & (1<<1)) {
184     PORTD |= (1<<PD5);
185   }
186   else {
187     PORTD &= ~(1<<PD5);
188   }
189   if (col & (1<<2)) {
190     PORTD |= (1<<PD6);
191   }
192   else {
193     PORTD &= ~(1<<PD6);
194   }
195   if (col & (1<<3)) {
196     PORTD |= (1<<PD7);
197   }
198   else {
199     PORTD &= ~(1<<PD7);
200   }
201 }