]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - macway/matrix.c
new build method for macway
[max/tmk_keyboard.git] / macway / matrix.c
1 /*
2  * scan matrix
3  */
4 #include <stdint.h>
5 #include <stdbool.h>
6 #include <avr/io.h>
7 #include <util/delay.h>
8 #include "matrix.h"
9 #include "print.h"
10 #include "util.h"
11
12 // matrix is active low. (key on: 0/key off: 1)
13 // row: Hi-Z(unselected)/low output(selected)
14 //      PD0, PC7, PD7, PF6, PD6, PD1, PD2, PC6, PF7
15 // col: input w/pullup
16 //      PB0-PB7
17
18 // matrix state buffer
19 uint8_t *matrix;
20 uint8_t *matrix_prev;
21 static uint8_t _matrix0[MATRIX_ROWS];
22 static uint8_t _matrix1[MATRIX_ROWS];
23
24 static bool matrix_has_ghost_in_row(uint8_t row);
25 static uint8_t read_col(void);
26 static void unselect_rows(void);
27 static void select_row(uint8_t row);
28
29
30 inline
31 int matrix_rows(void)
32 {
33     return MATRIX_ROWS;
34 }
35
36 inline
37 int matrix_cols(void)
38 {
39     return MATRIX_COLS;
40 }
41
42 // this must be called once before matrix_scan.
43 void matrix_init(void)
44 {
45     // initialize row and col
46     unselect_rows();
47     DDRB = 0x00;
48     PORTB = 0xFF;
49
50     // initialize matrix state: all keys off
51     for (int i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00;
52     for (int i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0x00;
53     matrix = _matrix0;
54     matrix_prev = _matrix1;
55 }
56
57 int matrix_scan(void)
58 {
59     uint8_t *tmp;
60
61     tmp = matrix_prev;
62     matrix_prev = matrix;
63     matrix = tmp;
64
65     for (int i = 0; i < MATRIX_ROWS; i++) {
66         select_row(i);
67         _delay_us(30);  // without this wait read unstable value.
68         matrix[i] = ~read_col();
69         unselect_rows();
70     }
71     return 1;
72 }
73
74 bool matrix_is_modified(void)
75 {
76     for (int i = 0; i < MATRIX_ROWS; i++) {
77         if (matrix[i] != matrix_prev[i])
78             return true;
79     }
80     return false;
81 }
82
83 bool matrix_has_ghost(void)
84 {
85     for (int i = 0; i < MATRIX_ROWS; i++) {
86         if (matrix_has_ghost_in_row(i))
87             return true;
88     }
89     return false;
90 }
91
92 inline
93 bool matrix_is_on(int row, int col)
94 {
95     return (matrix[row] & (1<<col));
96 }
97
98 inline
99 uint16_t matrix_get_row(int row)
100 {
101     return matrix[row];
102 }
103
104 void matrix_print(void)
105 {
106     print("\nr/c 01234567\n");
107     for (int row = 0; row < matrix_rows(); row++) {
108         phex(row); print(": ");
109         pbin_reverse(matrix_get_row(row));
110         if (matrix_has_ghost_in_row(row)) {
111             print(" <ghost");
112         }
113         print("\n");
114     }
115 }
116
117 int matrix_key_count(void)
118 {
119     int count = 0;
120     for (int i = 0; i < MATRIX_ROWS; i++) {
121         count += bitpop(matrix[i]);
122     }
123     return count;
124 }
125
126 static bool matrix_has_ghost_in_row(uint8_t row)
127 {
128     // no ghost exists in case less than 2 keys on
129     if (((matrix[row] - 1) & matrix[row]) == 0)
130         return false;
131
132     // ghost exists in case same state as other row
133     for (int i=0; i < MATRIX_ROWS; i++) {
134         if (i != row && (matrix[i] & matrix[row]) == matrix[row])
135             return true;
136     }
137     return false;
138 }
139
140 static uint8_t read_col(void)
141 {
142     return PINB;
143 }
144
145 static void unselect_rows(void)
146 {
147     DDRD  = 0x00;
148     PORTD = 0x00;
149     DDRC  = 0x00;
150     PORTC = 0x00;
151     DDRF  = 0x00;
152     PORTF = 0x00;
153 }
154
155 static void select_row(uint8_t row)
156 {
157     switch (row) {
158         case 0:
159             DDRD  = (1<<0);
160             PORTD = 0x00;
161             DDRC  = 0x00;
162             PORTC = 0x00;
163             DDRF  = 0x00;
164             PORTF = 0x00;
165             break;
166         case 1:
167             DDRD  = 0x00;
168             PORTD = 0x00;
169             DDRC  = (1<<7);
170             PORTC = 0x00;
171             DDRF  = 0x00;
172             PORTF = 0x00;
173             break;
174         case 2:
175             DDRD  = (1<<7);
176             PORTD = 0x00;
177             DDRC  = 0x00;
178             PORTC = 0x00;
179             DDRF  = 0x00;
180             PORTF = 0x00;
181             break;
182         case 3:
183             DDRD  = 0x00;
184             PORTD = 0x00;
185             DDRC  = 0x00;
186             PORTC = 0x00;
187             DDRF  = (1<<6);
188             PORTF = 0x00;
189             break;
190         case 4:
191             DDRD  = (1<<6);
192             PORTD = 0x00;
193             DDRC  = 0x00;
194             PORTC = 0x00;
195             DDRF  = 0x00;
196             PORTF = 0x00;
197             break;
198         case 5:
199             DDRD  = (1<<1);
200             PORTD = 0x00;
201             DDRC  = 0x00;
202             PORTC = 0x00;
203             DDRF  = 0x00;
204             PORTF = 0x00;
205             break;
206         case 6:
207             DDRD  = (1<<2);
208             PORTD = 0x00;
209             DDRC  = 0x00;
210             PORTC = 0x00;
211             DDRF  = 0x00;
212             PORTF = 0x00;
213             break;
214         case 7:
215             DDRD  = 0x00;
216             PORTD = 0x00;
217             DDRC  = (1<<6);
218             PORTC = 0x00;
219             DDRF  = 0x00;
220             PORTF = 0x00;
221             break;
222         case 8:
223             DDRD  = 0x00;
224             PORTD = 0x00;
225             DDRC  = 0x00;
226             PORTC = 0x00;
227             DDRF  = (1<<7);
228             PORTF = 0x00;
229             break;
230     }
231 }