]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - macway/matrix.c
Add PS/2 mouse support to connect TrackPoint Unit.
[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 "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 }