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