aboutsummaryrefslogtreecommitdiff
path: root/keyboards/converter/palm_usb/matrix.c
diff options
context:
space:
mode:
authorAkshay <[email protected]>2022-04-10 12:13:40 +0100
committerAkshay <[email protected]>2022-04-10 12:13:40 +0100
commitdc90387ce7d8ba7b607d9c48540bf6d8b560f14d (patch)
tree4ccb8fa5886b66fa9d480edef74236c27f035e16 /keyboards/converter/palm_usb/matrix.c
Diffstat (limited to 'keyboards/converter/palm_usb/matrix.c')
-rw-r--r--keyboards/converter/palm_usb/matrix.c397
1 files changed, 397 insertions, 0 deletions
diff --git a/keyboards/converter/palm_usb/matrix.c b/keyboards/converter/palm_usb/matrix.c
new file mode 100644
index 000000000..289284b61
--- /dev/null
+++ b/keyboards/converter/palm_usb/matrix.c
@@ -0,0 +1,397 @@
1/*
2Copyright 2018 milestogo
3with elements Copyright 2014 cy384 under a modified BSD license
4building on qmk structure Copyright 2012 Jun Wako <[email protected]>
5
6This program is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include QMK_KEYBOARD_H
21#include "protocol/serial.h"
22#include "timer.h"
23
24
25/*
26 * Matrix Array usage:
27 *
28 * ROW: 12(4bits)
29 * COL: 8(3bits)
30 *
31 * +---------+
32 * 0|00 ... 07|
33 * 1|00 ... 07|
34 * :| ... |
35 * :| ... |
36 * A| |
37 * B| |
38 * +---------+
39 */
40static uint8_t matrix[MATRIX_ROWS];
41
42
43// we're going to need a sleep timer
44static uint16_t last_activity ;
45// and a byte to track duplicate up events signalling all keys up.
46static uint16_t last_upKey ;
47// serial device can disconnect. Check every MAXDROP characters.
48static uint16_t disconnect_counter = 0;
49
50
51// bitmath masks.
52#define KEY_MASK 0b10000000
53#define COL_MASK 0b00000111
54#define ROW_MASK 0b01111000
55
56
57#define ROW(code) (( code & ROW_MASK ) >>3)
58#define COL(code) ((code & COL_MASK) )
59#define KEYUP(code) ((code & KEY_MASK) >>7 )
60
61static bool is_modified = false;
62
63__attribute__ ((weak))
64void matrix_init_kb(void) {
65 matrix_init_user();
66}
67
68__attribute__ ((weak))
69void matrix_scan_kb(void) {
70 matrix_scan_user();
71}
72
73__attribute__ ((weak))
74void matrix_init_user(void) {
75}
76
77__attribute__ ((weak))
78void matrix_scan_user(void) {
79}
80
81inline
82uint8_t matrix_rows(void)
83{
84 return MATRIX_ROWS;
85}
86
87inline
88uint8_t matrix_cols(void)
89{
90 return MATRIX_COLS;
91}
92
93
94void pins_init(void) {
95 // set pins for pullups, Rts , power &etc.
96
97 //print ("pins setup\n");
98 setPinOutput(VCC_PIN);
99 writePinLow(VCC_PIN);
100
101#if ( HANDSPRING == 0)
102
103#ifdef CY835
104 setPinOutput(GND_PIN);
105 writePinLow(GND_PIN);
106
107 setPinOutput(PULLDOWN_PIN);
108 writePinLow(PULLDOWN_PIN);
109#endif
110
111 setPinInput(DCD_PIN);
112 setPinInput(RTS_PIN);
113#endif
114
115/* check that the other side isn't powered up.
116 test=readPin(DCD_PIN);
117 xprintf("b%02X:", test);
118 test=readPin(RTS_PIN);
119 xprintf("%02X\n", test);
120*/
121
122}
123
124uint8_t rts_reset(void) {
125 static uint8_t firstread ;
126/* bounce RTS so device knows it is rebooted */
127
128// On boot, we keep rts as input, then switch roles here
129// on leaving sleep, we toggle the same way
130
131 firstread=readPin(RTS_PIN);
132 // printf("r%02X:", firstread);
133
134 setPinOutput(RTS_PIN);
135
136 if (firstread) {
137 writePinLow(RTS_PIN);
138 }
139 _delay_ms(10);
140 writePinHigh(RTS_PIN);
141
142
143/* the future is Arm
144 if (!palReadPad(RTS_PIN_IOPRT))
145 {
146 _delay_ms(10);
147 palSetPadMode(RTS_PINn_IOPORT, PinDirectionOutput_PUSHPULL);
148 palSetPad(RTS_PORT, RTS_PIN);
149 }
150 else
151 {
152 palSetPadMode(RTS_PIN_RTS_PORT, PinDirectionOutput_PUSHPULL);
153 palSetPad(RTS_PORT, RTS_PIN);
154 palClearPad(RTS_PORT, RTS_PIN);
155 _delay_ms(10);
156 palSetPad(RTS_PORT, RTS_PIN);
157 }
158*/
159
160
161 _delay_ms(5);
162 //print("rts\n");
163 return 1;
164}
165
166uint8_t get_serial_byte(void) {
167 static uint8_t code;
168 while(1) {
169 code = serial_recv();
170 if (code) {
171 debug_hex(code); debug(" ");
172 return code;
173 }
174 }
175}
176
177uint8_t palm_handshake(void) {
178 // assumes something has seen DCD go high, we've toggled RTS
179 // and we now need to verify handshake.
180 // listen for up to 4 packets before giving up.
181 // usually I get the sequence FF FA FD
182 static uint8_t codeA=0;
183
184 for (uint8_t i=0; i < 5; i++) {
185 codeA=get_serial_byte();
186 if ( 0xFA == codeA) {
187 if( 0xFD == get_serial_byte()) {
188 return 1;
189 }
190 }
191 }
192 return 0;
193}
194
195uint8_t palm_reset(void) {
196 print("@");
197 rts_reset(); // shouldn't need to power cycle.
198
199 if ( palm_handshake() ) {
200 last_activity = timer_read();
201 return 1;
202 } else {
203 print("failed reset");
204 return 0;
205 }
206
207}
208
209uint8_t handspring_handshake(void) {
210 // should be sent 15 ms after power up.
211 // listen for up to 4 packets before giving up.
212 static uint8_t codeA=0;
213
214 for (uint8_t i=0; i < 5; i++) {
215 codeA=get_serial_byte();
216 if ( 0xF9 == codeA) {
217 if( 0xFB == get_serial_byte()) {
218 return 1;
219 }
220 }
221 }
222 return 0;
223}
224
225uint8_t handspring_reset(void) {
226 writePinLow(VCC_PIN);
227 _delay_ms(5);
228 writePinHigh(VCC_PIN);
229
230 if ( handspring_handshake() ) {
231 last_activity = timer_read();
232 disconnect_counter=0;
233 return 1;
234 } else {
235 print("-HSreset");
236 return 0;
237 }
238}
239
240void matrix_init(void)
241{
242 debug_enable = true;
243 //debug_matrix =true;
244
245 serial_init(); // arguments all #defined
246
247#if (HANDSPRING == 0)
248 pins_init(); // set all inputs and outputs.
249#endif
250
251 print("power up\n");
252 writePinHigh(VCC_PIN);
253
254 // wait for DCD strobe from keyboard - it will do this
255 // up to 3 times, then the board needs the RTS toggled to try again
256
257#if ( HANDSPRING == 1)
258 if ( handspring_handshake() ) {
259 last_activity = timer_read();
260 } else {
261 print("failed handshake");
262 _delay_ms(1000);
263 //BUG /should/ power cycle or toggle RTS & reset, but this usually works.
264 }
265
266#else /// Palm / HP device with DCD
267 while( !readPin(DCD_PIN) ) {;}
268 print("dcd\n");
269
270 rts_reset(); // at this point the keyboard should think all is well.
271
272 if ( palm_handshake() ) {
273 last_activity = timer_read();
274 } else {
275 print("failed handshake");
276 _delay_ms(1000);
277 //BUG /should/ power cycle or toggle RTS & reset, but this usually works.
278 }
279
280#endif
281
282 // initialize matrix state: all keys off
283 for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
284
285 matrix_init_quantum();
286 return;
287
288
289}
290
291
292uint8_t matrix_scan(void)
293{
294 uint8_t code;
295 code = serial_recv();
296 if (!code) {
297/*
298 disconnect_counter ++;
299 if (disconnect_counter > MAXDROP) {
300 // set all keys off
301 for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
302 }
303*/
304 // check if the keyboard is asleep.
305 if (timer_elapsed(last_activity) > SLEEP_TIMEOUT) {
306#if(HANDSPRING ==0 )
307 palm_reset();
308#else
309 handspring_reset();
310#endif
311 return 0;
312 }
313
314 }
315
316 last_activity = timer_read();
317 disconnect_counter=0; // if we are getting serial data, we're connected.
318
319 debug_hex(code); debug(" ");
320
321
322 switch (code) {
323 case 0xFD: // unexpected reset byte 2
324 print("rstD ");
325 return 0;
326 case 0xFA: // unexpected reset
327 print("rstA ");
328 return 0;
329 }
330
331 if (KEYUP(code)) {
332 if (code == last_upKey) {
333 // all keys are not pressed.
334 // Manual says to disable all modifiers left open now.
335 // but that could defeat sticky keys.
336 // BUG? dropping this byte.
337 last_upKey=0;
338 return 0;
339 }
340 // release
341 if (matrix_is_on(ROW(code), COL(code))) {
342 matrix[ROW(code)] &= ~(1<<COL(code));
343 last_upKey=code;
344 }
345 } else {
346 // press
347 if (!matrix_is_on(ROW(code), COL(code))) {
348 matrix[ROW(code)] |= (1<<COL(code));
349
350 }
351 }
352
353 matrix_scan_quantum();
354 return code;
355}
356
357bool matrix_is_modified(void)
358{
359 return is_modified;
360}
361
362inline
363bool matrix_has_ghost(void)
364{
365 return false;
366}
367
368inline
369bool matrix_is_on(uint8_t row, uint8_t col)
370{
371 return (matrix[row] & (1<<col));
372}
373
374inline
375uint8_t matrix_get_row(uint8_t row)
376{
377 return matrix[row];
378}
379
380void matrix_print(void)
381{
382 print("\nr/c 01234567\n");
383 for (uint8_t row = 0; row < matrix_rows(); row++) {
384 print_hex8(row); print(": ");
385 print_bin_reverse8(matrix_get_row(row));
386 print("\n");
387 }
388}
389
390uint8_t matrix_key_count(void)
391{
392 uint8_t count = 0;
393 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
394 count += bitpop(matrix[i]);
395 }
396 return count;
397}