]> git.donarmstrong.com Git - tmk_firmware.git/blob - matrix.c
delete unused KEY_* definitions.
[tmk_firmware.git] / matrix.c
1 /*
2  * scan matrix
3  */
4 #include <avr/io.h>
5 #include <util/delay.h>
6 #include "keymap.h"
7 #include "matrix.h"
8 #include "print.h"
9
10 // matrix is active low. (key on: 0/key off: 1)
11 // row: Hi-Z(unselected)/low output(selected)
12 //      PD:0,1,2,3,6,7/PC:6,7/PF:7
13 // col: input w/pullup
14 //      PB:0-8
15
16 // matrix state buffer
17 uint8_t *matrix;
18 uint8_t *matrix_prev;
19 static uint8_t _matrix0[MATRIX_ROWS];
20 static uint8_t _matrix1[MATRIX_ROWS];
21
22 static uint8_t read_col(void);
23 static void unselect_rows(void);
24 static void select_row(uint8_t row);
25
26
27 // this must be called once before matrix_scan.
28 void matrix_init(void)
29 {
30     // initialize row and col
31     unselect_rows();
32     DDRB = 0x00;
33     PORTB = 0xFF;
34
35     // initialize matrix state: all keys off
36     for (int i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0xFF;
37     for (int i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0xFF;
38     matrix = _matrix0;
39     matrix_prev = _matrix1;
40 }
41
42 uint8_t matrix_scan(void)
43 {
44     uint8_t row, state;
45     uint8_t *tmp;
46
47     tmp = matrix_prev;
48     matrix_prev = matrix;
49     matrix = tmp;
50
51     for (row = 0; row < MATRIX_ROWS; row++) {
52         select_row(row);
53         _delay_us(30);  // without this wait read unstable value.
54         state = read_col();
55         unselect_rows();
56
57         matrix[row] = state;
58     }
59     return 1;
60 }
61
62 bool matrix_is_modified(void) {
63     for (int i=0; i <MATRIX_ROWS; i++) {
64         if (matrix[i] != matrix_prev[i])
65             return true;
66     }
67     return false;
68 }
69
70 bool matrix_has_ghost(void) {
71     for (int i=0; i <MATRIX_ROWS; i++) {
72         if (matrix_has_ghost_in_row(i))
73             return true;
74     }
75     return false;
76 }
77
78 bool matrix_has_ghost_in_row(uint8_t row) {
79     uint8_t state = ~matrix[row];
80     // no ghost exists in case less than 2 keys on
81     if (((state - 1) & state) == 0)
82         return false;
83
84     // ghost exists in case same state as other row
85     for (int i=0; i < MATRIX_ROWS; i++) {
86         if (i == row) continue;
87         if ((~matrix[i] & state) == state) return true;
88     }
89     return false;
90 }
91
92 static uint8_t read_col(void)
93 {
94     return PINB;
95 }
96
97 static void unselect_rows(void) {
98     DDRD  = 0x00;
99     PORTD = 0x00;
100     DDRC  = 0x00;
101     PORTC = 0x00;
102     DDRF  = 0x00;
103     PORTF = 0x00;
104 }
105
106 static void select_row(uint8_t row)
107 {
108     switch (row) {
109         case 0:
110             DDRD  = (1<<0);
111             PORTD = 0x00;
112             DDRC  = 0x00;
113             PORTC = 0x00;
114             DDRF  = 0x00;
115             PORTF = 0x00;
116             break;
117         case 1:
118             DDRD  = (1<<1);
119             PORTD = 0x00;
120             DDRC  = 0x00;
121             PORTC = 0x00;
122             DDRF  = 0x00;
123             PORTF = 0x00;
124             break;
125         case 2:
126             DDRD  = (1<<2);
127             PORTD = 0x00;
128             DDRC  = 0x00;
129             PORTC = 0x00;
130             DDRF  = 0x00;
131             PORTF = 0x00;
132             break;
133         case 3:
134             DDRD  = (1<<3);
135             PORTD = 0x00;
136             DDRC  = 0x00;
137             PORTC = 0x00;
138             DDRF  = 0x00;
139             PORTF = 0x00;
140             break;
141         case 4:
142             DDRD  = (1<<6);
143             PORTD = 0x00;
144             DDRC  = 0x00;
145             PORTC = 0x00;
146             DDRF  = 0x00;
147             PORTF = 0x00;
148             break;
149         case 5:
150             DDRD  = (1<<7);
151             PORTD = 0x00;
152             DDRC  = 0x00;
153             PORTC = 0x00;
154             DDRF  = 0x00;
155             PORTF = 0x00;
156             break;
157         case 6:
158             DDRD  = 0x00;
159             PORTD = 0x00;
160             DDRC  = (1<<6);
161             PORTC = 0x00;
162             DDRF  = 0x00;
163             PORTF = 0x00;
164             break;
165         case 7:
166             DDRD  = 0x00;
167             PORTD = 0x00;
168             DDRC  = (1<<7);
169             PORTC = 0x00;
170             DDRF  = 0x00;
171             PORTF = 0x00;
172             break;
173         case 8:
174             DDRD  = 0x00;
175             PORTD = 0x00;
176             DDRC  = 0x00;
177             PORTC = 0x00;
178             DDRF  = (1<<7);
179             PORTF = 0x00;
180             break;
181     }
182 }