]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/SonyOA-S3400/scan_loop.c
Merge pull request #71 from glguy/pr-cli-history
[kiibohd-controller.git] / Scan / SonyOA-S3400 / scan_loop.c
1 /* Copyright (C) 2012,2014 by Jacob Alexander
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  */
21
22 // ----- Includes -----
23
24 // Compiler Includes
25 #include <Lib/ScanLib.h>
26
27 // Project Includes
28 #include <led.h>
29 #include <print.h>
30
31 // Local Includes
32 #include "scan_loop.h"
33
34
35
36 // ----- Defines -----
37
38 // - Pinout Defines -
39
40 // Scan Bit Pins (from keyboard)
41 // - Reads in the ASCII scancode
42 // - Shift and ShiftLock are handled internally
43 #define READSCAN_PORT PORTC
44 #define READSCAN_DDR   DDRC
45 #define READSCAN_PIN   PINC
46
47
48 // Interrupt Pins (from keyboard)
49 // - CODEINT  (Code key signal  interrupt/press)
50 //   - Normally high, low when "Code" key is pressed; separate from all other key presses
51 // - PRESSINT (Press signal     interrupt/press)
52 //   - Normally high, low when any key (or multiple except "Code") is pressed, returns to high once all keys are released
53 //   - Signal is changed BEFORE the Scan Bits are updated
54 // - PULSEINT (Key action pulse interrupt/press)
55 //   - Normally high, low pulses of 147us on key presses (depending on the combination of mode control pins)
56 //   - Pulse is guarranteed to sent after the Scan Bits are updated
57 #define CODEINT_PORT PORTE
58 #define CODEINT_DDR   DDRE
59 #define CODEINT_PIN   PINE
60 #define CODEINT_POS      7
61
62 #define PRESSINT_PORT PORTE
63 #define PRESSINT_DDR   DDRE
64 #define PRESSINT_POS      6
65
66 #define PULSEINT_PORT PORTD
67 #define PULSEINT_DDR   DDRD
68 #define PULSEINT_POS      3
69
70
71 // LED Pins (to keyboard)
72 // - 1 disable LED
73 // - 1  enable LED
74 #define LED1_PORT PORTF // [Pin 19]
75 #define LED1_DDR   DDRF
76 #define LED1_POS      6
77
78 #define LED2_PORT PORTF // [Pin 20]
79 #define LED2_DDR   DDRF
80 #define LED2_POS      7
81
82
83 // Mode Control Pins (to keyboard)
84 // - Repeat [Pin 14]
85 //   - 1 Single   pulse mode (PULSEINT)
86 //   - 0 Repeated pulse mode (PULSEINT) (1 pulse, pause, then constant pulses)
87 // - Multi  [Pin 15]
88 //   - 1 1KRO mode (typewriter compatibility mode)
89 //   - 0 NKRO mode (new pulse on each keypress - PULSEINT)
90 // - Signal [Pin 18]
91 //   - 1 disables pulse interrupt (PULSEINT)
92 //   - 0 enables  pulse interrupt (PULSEINT)
93 #define REPEAT_PORT PORTF
94 #define REPEAT_DDR   DDRF
95 #define REPEAT_POS      3
96
97 #define MULTI_PORT PORTF
98 #define MULTI_DDR   DDRF
99 #define MULTI_POS      4
100
101 #define SIGNAL_PORT PORTF
102 #define SIGNAL_DDR   DDRF
103 #define SIGNAL_POS      5
104
105
106 // Manually Scanned Keys
107 // Keys that the controller screws up, requiring a separate wire to be brought to the controller
108 // Note: Safer to route these through a NOT gate to boost the signal strength
109 //       Values below are AFTER NOT gate
110 // - Shift (both shift keys are on the same scan line)
111 //   - 0 Released
112 //   - 1 Pressed
113 // - Shift Lock
114 //   - 0 Released
115 //   - 1 Pressed
116 #define MANUAL_SCAN_KEYS 2
117
118 #define SHIFT_KEY      0
119 #define SHIFT_PORT PORTF
120 #define SHIFT_DDR   DDRF
121 #define SHIFT_PIN   PINF
122 #define SHIFT_POS      0
123
124 #define SHIFTLOCK_KEY      1
125 #define SHIFTLOCK_PORT PORTF
126 #define SHIFTLOCK_DDR   DDRF
127 #define SHIFTLOCK_PIN   PINF
128 #define SHIFTLOCK_POS      1
129
130
131 // ----- Macros -----
132
133
134
135 // ----- Variables -----
136
137 // Buffer used to inform the macro processing module which keys have been detected as pressed
138 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
139 volatile uint8_t KeyIndex_BufferUsed;
140 volatile uint8_t KeyIndex_Add_InputSignal; // Used to pass the (click/input value) to the keyboard for the clicker
141
142 volatile uint8_t KeyScan_Table[MANUAL_SCAN_KEYS]; // Used for tracking key status of manually scanned keys
143 volatile uint8_t KeyScan_Prev [MANUAL_SCAN_KEYS]; // Keeps track of key state changes
144 volatile uint8_t KeyScan_Count;
145
146
147
148 // ----- Functions -----
149
150 // Pre-declarations
151 void processKeyValue( uint8_t keyValue );
152
153
154
155 // Setup
156 inline void Scan_setup()
157 {
158         // Setup the external interrupts for
159         // - General keypresses     (INT6/E6) ->         rising edge (to detect key       release)
160         // - "Code" key             (INT7/E7) -> falling/rising edge (to detect key press/release)
161         // - General keypress pulse (INT3/D3) -> falling        edge (to detect key press        )
162         EICRA = 0x80;
163         EICRB = 0x70;
164         EIMSK = 0xC8;
165
166
167         // Setup Interrupt Pins
168         CODEINT_PORT  |=  (1 << CODEINT_POS );
169         CODEINT_DDR   &= ~(1 << CODEINT_POS );
170
171         PRESSINT_PORT |=  (1 << PRESSINT_POS);
172         PRESSINT_DDR  &= ~(1 << PRESSINT_POS);
173
174         PULSEINT_PORT |=  (1 << PULSEINT_POS);
175         PULSEINT_DDR  &= ~(1 << PULSEINT_POS);
176
177
178         // Setup LED Pins (default off)
179         LED1_PORT |= (1 << LED1_POS);
180         LED1_DDR  |= (1 << LED1_POS);
181
182         LED2_PORT |= (1 << LED2_POS);
183         LED2_DDR  |= (1 << LED2_POS);
184
185
186         // Setup READSCAN pins to read out scancode
187         READSCAN_PORT = 0xFF;
188         READSCAN_DDR  = 0x00;
189
190
191         // Setup Mode Control Pins
192         // Note: These can be changed at any time, but there is no real reason too for a USB converter
193         REPEAT_PORT |=  (1 << REPEAT_POS); // Setting high for single press mode
194         REPEAT_DDR  |=  (1 << REPEAT_POS);
195
196         MULTI_PORT  &= ~(1 << MULTI_POS ); // Setting low for multi press mode (NKRO)
197         MULTI_DDR   |=  (1 << MULTI_POS );
198
199         SIGNAL_PORT &= ~(1 << SIGNAL_POS); // Setting low to enable PULSEINT
200         SIGNAL_DDR  |=  (1 << SIGNAL_POS);
201
202
203         // Setup Troublesome Key Pins
204         SHIFT_PORT     &= ~(1 << SHIFT_POS    );
205         SHIFT_DDR      &= ~(1 << SHIFT_POS    );
206
207         SHIFTLOCK_PORT &= ~(1 << SHIFTLOCK_POS);
208         SHIFTLOCK_DDR  &= ~(1 << SHIFTLOCK_POS);
209
210
211         // Reset the keyboard before scanning, we might be in a wierd state
212         scan_resetKeyboard();
213 }
214
215 // Main Detection Loop
216 // Not needed for the Sony OA-S3400 as signals are interrupt based, thus this is a busy loop
217 // XXX Function is used for scanning troublesome keys, technically this is not needed for a pure converter
218 //     I just want proper use of the shift and shift lock keys, without having to do major rework to attach to the entire matrix
219 inline uint8_t Scan_loop()
220 {
221         // Loop through known keys
222         for ( uint8_t key = 0; key < MANUAL_SCAN_KEYS; key++ ) switch ( key )
223         {
224         case SHIFT_KEY:
225                 if ( SHIFT_PIN & (1 << SHIFT_POS) )
226                 {
227                         KeyScan_Table[SHIFT_KEY]++;
228                 }
229                 break;
230         case SHIFTLOCK_KEY:
231                 if ( SHIFTLOCK_PIN & (1 << SHIFTLOCK_POS) )
232                 {
233                         KeyScan_Table[SHIFTLOCK_KEY]++;
234                 }
235                 break;
236         default:
237                 erro_print("Invalid key scan index");
238                 break;
239         }
240
241         // Increment vote instance
242         KeyScan_Count++;
243
244         // Loop function again if not enough votes have been tallied
245         if ( KeyScan_Count < 255 )
246                 return 1;
247
248         // Clear vote data
249         KeyScan_Count = 0;
250
251         // Loop through known keys
252         for ( uint8_t key = 0; key < MANUAL_SCAN_KEYS; key++ )
253         {
254                 // Key scanned as pressed (might have been held from a previous vote)
255                 if ( KeyScan_Table[key] > 127 )
256                 {
257                         // Keypress detected
258                         if ( !KeyScan_Prev[key] )
259                         {
260                                 processKeyValue( 0x90 + key ); // Arbitrary key mapping starts at 0x90
261                                 KeyScan_Prev[key] = 1;
262                         }
263                 }
264                 // Key scanned as released
265                 else
266                 {
267                         // Keypress detected
268                         if ( KeyScan_Prev[key] )
269                         {
270                                 processKeyValue( 0xA0 + key ); // Arbitrary key mapping release starts at 0xA0
271                                 KeyScan_Prev[key] = 0;
272                         }
273                 }
274
275                 // Clear votes
276                 KeyScan_Table[key] = 0;
277         }
278
279         // End loop, process macros and USB data
280         return 0;
281 }
282
283 void processKeyValue( uint8_t keyValue )
284 {
285         // - Convert Shifted Value to non-shifted ASCII code -
286
287         // Alphabetic
288         if ( keyValue >= 0x61 && keyValue <= 0x7A )
289         {
290                 keyValue -= 0x20;
291         }
292         // Other keys with ASCII shift codes
293         else
294         {
295                 switch ( keyValue )
296                 {
297                 case 0x21: // 1
298                 case 0x23: // 3
299                 case 0x24: // 4
300                 case 0x25: // 5
301                         keyValue += 0x10;
302                         break;
303                 case 0x26: // 7
304                 case 0x28: // 9
305                         keyValue += 0x11;
306                         break;
307                 case 0x81: // 1/2
308                 case 0x3A: // ;
309                         keyValue += 0x01;
310                         break;
311                 case 0x29: // 0
312                         keyValue = 0x30;
313                         break;
314                 case 0x40: // 2
315                         keyValue = 0x32;
316                         break;
317                 case 0x80: // 6
318                         keyValue = 0x36;
319                         break;
320                 case 0x2A: // 8
321                         keyValue = 0x38;
322                         break;
323                 case 0x5F: // -
324                         keyValue = 0x2D;
325                         break;
326                 case 0x2B: // +
327                         keyValue = 0x3D;
328                         break;
329                 case 0x22: // "
330                         keyValue = 0x27;
331                         break;
332                 case 0x3F: // ?
333                         keyValue = 0x2F;
334                         break;
335                 }
336         }
337
338         // TODO Move to Macro Section
339         switch ( keyValue )
340         {
341         case 0xD3: // F11
342                 scan_sendData( 0x01 );
343                 break;
344         case 0xD4: // F12
345                 scan_sendData( 0x02 );
346                 break;
347         }
348
349         // Scan code is now finalized, and ready to add to buffer
350         // Note: Scan codes come from 3 different interrupts and a manual key scan into this function
351
352         // Debug
353         char tmpStr[6];
354         hexToStr( keyValue, tmpStr );
355         dPrintStrs( tmpStr, " " );
356
357         // Detect release condition
358         uint8_t release = 0;
359         switch ( keyValue )
360         {
361         case 0xA0:
362         case 0xA1:
363         case 0xA2:
364                 keyValue -= 0x10;
365         case 0xB0:
366                 release = 1;
367                 break;
368         }
369
370         // Key Release
371         if ( release )
372         {
373                 // Check for the released key, and shift the other keys lower on the buffer
374                 uint8_t c;
375                 for ( c = 0; c < KeyIndex_BufferUsed; c++ )
376                 {
377                         // General key buffer clear
378                         if ( keyValue == 0xB0 )
379                         {
380                                 switch ( KeyIndex_Buffer[c] )
381                                 {
382                                 // Ignore these keys on general key release (have their own release codes)
383                                 case 0x90:
384                                 case 0x91:
385                                 case 0x92:
386                                         break;
387
388                                 // Remove key from buffer
389                                 default:
390                                         // Shift keys from c position
391                                         for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
392                                                 KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
393
394                                         // Decrement Buffer
395                                         KeyIndex_BufferUsed--;
396
397                                         // Start at this position again for the next loop
398                                         c--;
399
400                                         break;
401                                 }
402                         }
403                         // Key to release found
404                         else if ( KeyIndex_Buffer[c] == keyValue )
405                         {
406                                 // Shift keys from c position
407                                 for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
408                                         KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
409
410                                 // Decrement Buffer
411                                 KeyIndex_BufferUsed--;
412
413                                 break;
414                         }
415                 }
416
417                 // Error case (no key to release)
418                 if ( c == KeyIndex_BufferUsed + 1 )
419                 {
420                         errorLED( 1 );
421                         char tmpStr[6];
422                         hexToStr( keyValue, tmpStr );
423                         erro_dPrint( "Could not find key to release: ", tmpStr );
424                 }
425         }
426         // Press or Repeated Key
427         else
428         {
429                 // Make sure the key isn't already in the buffer
430                 for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
431                 {
432                         // Key isn't in the buffer yet
433                         if ( c == KeyIndex_BufferUsed )
434                         {
435                                 Macro_bufferAdd( keyValue );
436                                 break;
437                         }
438
439                         // Key already in the buffer
440                         if ( KeyIndex_Buffer[c] == keyValue )
441                                 break;
442                 }
443         }
444 }
445
446 // Key Press Detected Interrupt
447 ISR(INT3_vect)
448 {
449         cli(); // Disable Interrupts
450
451         uint8_t keyValue = 0x00;
452
453         // Bits are flipped coming in from the keyboard
454         keyValue = ~READSCAN_PIN;
455
456         // Process the scancode
457         processKeyValue( keyValue );
458
459         sei(); // Re-enable Interrupts
460 }
461
462 // Key Release Detected Interrupt
463 ISR(INT6_vect)
464 {
465         cli(); // Disable Interrupts
466
467         // Send release code for general keys, 0xB0
468         processKeyValue( 0xB0 );
469
470         sei(); // Re-enable Interrupts
471 }
472
473 // Code Key Interrupt
474 ISR(INT7_vect)
475 {
476         cli(); // Disable Interrupts
477
478         // Code Key Released (send scancode)
479         if ( CODEINT_PIN & (1 << CODEINT_POS) )
480         {
481                 processKeyValue( 0xA2 );
482         }
483         // Code Key Pressed (send scancode)
484         else
485         {
486                 processKeyValue( 0x92 );
487         }
488
489         sei(); // Re-enable Interrupts
490 }
491
492
493 // Send data to keyboard
494 // Sony OA-S3400 has no serial/parallel dataport to send data too...
495 // Using this function for LED enable/disable
496 uint8_t Scan_sendData( uint8_t dataPayload )
497 {
498         switch ( dataPayload )
499         {
500         case 0x01:
501                 LED1_PORT ^= (1 << LED1_POS);
502                 break;
503         case 0x02:
504                 LED2_PORT ^= (1 << LED2_POS);
505                 break;
506         default:
507                 erro_print("Invalid data send attempt");
508                 break;
509         }
510         return 0;
511 }
512
513 // Signal KeyIndex_Buffer that it has been properly read
514 // Not needed as a signal is sent to remove key-presses
515 void Scan_finishedWithBuffer( uint8_t sentKeys )
516 {
517         return;
518 }
519
520 // Reset/Hold keyboard
521 // Sony OA-S3400 has no locking signals
522 void Scan_lockKeyboard( void )
523 {
524 }
525
526 void Scan_unlockKeyboard( void )
527 {
528 }
529
530 // Reset Keyboard
531 void Scan_resetKeyboard( void )
532 {
533         // Empty buffer, now that keyboard has been reset
534         KeyIndex_BufferUsed = 0;
535
536         // Clear the KeyScan table and count
537         for ( uint8_t key = 0; key < MANUAL_SCAN_KEYS; key++ )
538         {
539                 KeyScan_Table[key] = 0;
540                 KeyScan_Prev [key] = 0;
541         }
542         KeyScan_Count = 0;
543 }
544
545 // USB module is finished with buffer
546 // Not needed as a signal is sent to remove key-presses
547 void Scan_finishedWithUSBBuffer( uint8_t sentKeys )
548 {
549         return;
550 }
551