aboutsummaryrefslogtreecommitdiff
path: root/keyboards/converter/ibm_terminal/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/converter/ibm_terminal/matrix.c')
-rw-r--r--keyboards/converter/ibm_terminal/matrix.c237
1 files changed, 237 insertions, 0 deletions
diff --git a/keyboards/converter/ibm_terminal/matrix.c b/keyboards/converter/ibm_terminal/matrix.c
new file mode 100644
index 000000000..caa0a3805
--- /dev/null
+++ b/keyboards/converter/ibm_terminal/matrix.c
@@ -0,0 +1,237 @@
1/*
2Copyright 2011 Jun Wako <[email protected]>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <stdint.h>
19#include <stdbool.h>
20#include <avr/io.h>
21#include <util/delay.h>
22#include "print.h"
23#include "util.h"
24#include "debug.h"
25#include "ps2.h"
26#include "matrix.h"
27
28#define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
29#define print_matrix_header() print("\nr/c 01234567\n")
30#define matrix_bitpop(i) bitpop(matrix[i])
31#define ROW_SHIFTER ((uint8_t)1)
32
33
34static void matrix_make(uint8_t code);
35static void matrix_break(uint8_t code);
36
37
38/*
39 * Matrix Array usage:
40 * 'Scan Code Set 3' is assigned into 17x8 cell matrix.
41 *
42 * 8bit wide
43 * +---------+
44 * 0| |
45 * :| | 0x00-0x87
46 * ;| |
47 * 17| |
48 * +---------+
49 */
50static uint8_t matrix[MATRIX_ROWS];
51#define ROW(code) (code>>3)
52#define COL(code) (code&0x07)
53
54
55__attribute__ ((weak))
56void matrix_init_user(void) {
57}
58
59void matrix_init(void)
60{
61 debug_enable = true;
62 //debug_matrix = true;
63 //debug_keyboard = true;
64 //debug_mouse = false;
65
66 ps2_host_init();
67
68 // initialize matrix state: all keys off
69 for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
70
71 matrix_init_user();
72 return;
73}
74
75uint8_t matrix_scan(void)
76{
77
78 // scan code reading states
79 static enum {
80 RESET,
81 RESET_RESPONSE,
82 KBD_ID0,
83 KBD_ID1,
84 CONFIG,
85 READY,
86 F0,
87 } state = RESET;
88
89 uint8_t code;
90 if ((code = ps2_host_recv())) {
91 debug("r"); debug_hex(code); debug(" ");
92 }
93
94 switch (state) {
95 case RESET:
96 debug("wFF ");
97 if (ps2_host_send(0xFF) == 0xFA) {
98 debug("[ack]\nRESET_RESPONSE: ");
99 state = RESET_RESPONSE;
100 }
101 break;
102 case RESET_RESPONSE:
103 if (code == 0xAA) {
104 debug("[ok]\nKBD_ID: ");
105 state = KBD_ID0;
106 } else if (code) {
107 debug("err\nRESET: ");
108 state = RESET;
109 }
110 break;
111 // after reset receive keyboard ID(2 bytes)
112 case KBD_ID0:
113 if (code) {
114 state = KBD_ID1;
115 }
116 break;
117 case KBD_ID1:
118 if (code) {
119 debug("\nCONFIG: ");
120 state = CONFIG;
121 }
122 break;
123 case CONFIG:
124 debug("wF8 ");
125 if (ps2_host_send(0xF8) == 0xFA) {
126 debug("[ack]\nREADY\n");
127 state = READY;
128 }
129 break;
130 case READY:
131 switch (code) {
132 case 0x00:
133 break;
134 case 0xF0:
135 state = F0;
136 debug(" ");
137 break;
138 default: // normal key make
139 if (code < 0x88) {
140 matrix_make(code);
141 } else {
142 debug("unexpected scan code at READY: "); debug_hex(code); debug("\n");
143 }
144 state = READY;
145 debug("\n");
146 }
147 break;
148 case F0: // Break code
149 switch (code) {
150 case 0x00:
151 break;
152 default:
153 if (code < 0x88) {
154 matrix_break(code);
155 } else {
156 debug("unexpected scan code at F0: "); debug_hex(code); debug("\n");
157 }
158 state = READY;
159 debug("\n");
160 }
161 break;
162 }
163 return 1;
164}
165
166inline
167uint8_t matrix_get_row(uint8_t row)
168{
169 return matrix[row];
170}
171
172inline
173static void matrix_make(uint8_t code)
174{
175 if (!matrix_is_on(ROW(code), COL(code))) {
176 matrix[ROW(code)] |= 1<<COL(code);
177 }
178}
179
180inline
181static void matrix_break(uint8_t code)
182{
183 if (matrix_is_on(ROW(code), COL(code))) {
184 matrix[ROW(code)] &= ~(1<<COL(code));
185 }
186}
187
188bool matrix_is_on(uint8_t row, uint8_t col)
189{
190 return (matrix_get_row(row) & (1<<col));
191}
192
193void matrix_print(void)
194{
195#if (MATRIX_COLS <= 8)
196 print("r/c 01234567\n");
197#elif (MATRIX_COLS <= 16)
198 print("r/c 0123456789ABCDEF\n");
199#elif (MATRIX_COLS <= 32)
200 print("r/c 0123456789ABCDEF0123456789ABCDEF\n");
201#endif
202
203 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
204
205#if (MATRIX_COLS <= 8)
206 xprintf("%02X: %08b%s\n", row, bitrev(matrix_get_row(row)),
207#elif (MATRIX_COLS <= 16)
208 xprintf("%02X: %016b%s\n", row, bitrev16(matrix_get_row(row)),
209#elif (MATRIX_COLS <= 32)
210 xprintf("%02X: %032b%s\n", row, bitrev32(matrix_get_row(row)),
211#endif
212#ifdef MATRIX_HAS_GHOST
213 matrix_has_ghost_in_row(row) ? " <ghost" : ""
214#else
215 ""
216#endif
217 );
218 }
219}
220
221#ifdef MATRIX_HAS_GHOST
222__attribute__ ((weak))
223bool matrix_has_ghost_in_row(uint8_t row)
224{
225 matrix_row_t matrix_row = matrix_get_row(row);
226 // No ghost exists when less than 2 keys are down on the row
227 if (((matrix_row - 1) & matrix_row) == 0)
228 return false;
229
230 // Ghost occurs when the row shares column line with other row
231 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
232 if (i != row && (matrix_get_row(i) & matrix_row))
233 return true;
234 }
235 return false;
236}
237#endif