]> git.gir.st - tmk_keyboard.git/blob - macway/matrix.c
Add PS/2 mouse support to connect TrackPoint Unit.
[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 "print.h"
9 #include "util.h"
10 #include "matrix_skel.h"
11
12
13 // matrix state buffer (key on: 1/key off: 0)
14 static uint8_t *matrix;
15 static uint8_t *matrix_prev;
16 static uint8_t _matrix0[MATRIX_ROWS];
17 static uint8_t _matrix1[MATRIX_ROWS];
18
19 static bool matrix_has_ghost_in_row(uint8_t row);
20 static uint8_t read_col(void);
21 static void unselect_rows(void);
22 static void select_row(uint8_t row);
23
24
25 inline
26 int matrix_rows(void)
27 {
28 return MATRIX_ROWS;
29 }
30
31 inline
32 int matrix_cols(void)
33 {
34 return MATRIX_COLS;
35 }
36
37 // this must be called once before matrix_scan.
38 void matrix_init(void)
39 {
40 // initialize row and col
41 unselect_rows();
42 // Input with pull-up(DDR:0, PORT:1)
43 DDRB = 0x00;
44 PORTB = 0xFF;
45
46 // initialize matrix state: all keys off
47 for (int i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00;
48 for (int i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0x00;
49 matrix = _matrix0;
50 matrix_prev = _matrix1;
51 }
52
53 int matrix_scan(void)
54 {
55 uint8_t *tmp;
56
57 tmp = matrix_prev;
58 matrix_prev = matrix;
59 matrix = tmp;
60
61 for (int i = 0; i < MATRIX_ROWS; i++) {
62 unselect_rows();
63 select_row(i);
64 _delay_us(30); // without this wait read unstable value.
65 matrix[i] = ~read_col();
66 }
67 unselect_rows();
68 return 1;
69 }
70
71 bool matrix_is_modified(void)
72 {
73 for (int i = 0; i < MATRIX_ROWS; i++) {
74 if (matrix[i] != matrix_prev[i])
75 return true;
76 }
77 return false;
78 }
79
80 bool matrix_has_ghost(void)
81 {
82 for (int i = 0; i < MATRIX_ROWS; i++) {
83 if (matrix_has_ghost_in_row(i))
84 return true;
85 }
86 return false;
87 }
88
89 inline
90 bool matrix_is_on(int row, int col)
91 {
92 return (matrix[row] & (1<<col));
93 }
94
95 inline
96 uint16_t matrix_get_row(int row)
97 {
98 return matrix[row];
99 }
100
101 void matrix_print(void)
102 {
103 print("\nr/c 01234567\n");
104 for (int row = 0; row < matrix_rows(); row++) {
105 phex(row); print(": ");
106 pbin_reverse(matrix_get_row(row));
107 if (matrix_has_ghost_in_row(row)) {
108 print(" <ghost");
109 }
110 print("\n");
111 }
112 }
113
114 int matrix_key_count(void)
115 {
116 int count = 0;
117 for (int i = 0; i < MATRIX_ROWS; i++) {
118 count += bitpop(matrix[i]);
119 }
120 return count;
121 }
122
123 static bool matrix_has_ghost_in_row(uint8_t row)
124 {
125 // no ghost exists in case less than 2 keys on
126 if (((matrix[row] - 1) & matrix[row]) == 0)
127 return false;
128
129 // ghost exists in case same state as other row
130 for (int i=0; i < MATRIX_ROWS; i++) {
131 if (i != row && (matrix[i] & matrix[row]) == matrix[row])
132 return true;
133 }
134 return false;
135 }
136
137 static uint8_t read_col(void)
138 {
139 return PINB;
140 }
141
142 static void unselect_rows(void)
143 {
144 // Hi-Z(DDR:0, PORT:0) to unselect
145 DDRC &= ~0b11000000; // PC: 7,6
146 PORTC &= ~0b11000000;
147 DDRD &= ~0b11000111; // PD: 7,6,2,1,0
148 PORTD &= ~0b11000111;
149 DDRF &= ~0b11000000; // PF: 7,6
150 PORTF &= ~0b11000000;
151 }
152
153 static void select_row(uint8_t row)
154 {
155 // Output low(DDR:1, PORT:0) to select
156 // row: 0 1 2 3 4 5 6 7 8
157 // pin: PD0, PC7, PD7, PF6, PD6, PD1, PD2, PC6, PF7
158 switch (row) {
159 case 0:
160 DDRD |= (1<<0);
161 PORTD &= ~(1<<0);
162 break;
163 case 1:
164 DDRC |= (1<<7);
165 PORTC &= ~(1<<7);
166 break;
167 case 2:
168 DDRD |= (1<<7);
169 PORTD &= ~(1<<7);
170 break;
171 case 3:
172 DDRF |= (1<<6);
173 PORTF &= ~(1<<6);
174 break;
175 case 4:
176 DDRD |= (1<<6);
177 PORTD &= ~(1<<6);
178 break;
179 case 5:
180 DDRD |= (1<<1);
181 PORTD &= ~(1<<1);
182 break;
183 case 6:
184 DDRD |= (1<<2);
185 PORTD &= ~(1<<2);
186 break;
187 case 7:
188 DDRC |= (1<<6);
189 PORTC &= ~(1<<6);
190 break;
191 case 8:
192 DDRF |= (1<<7);
193 PORTF &= ~(1<<7);
194 break;
195 }
196 }
Imprint / Impressum