]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/FACOM6684/scan_loop.c
Updating AVR abstraction to be compatible with ARM, nearly ready for ARM files
[kiibohd-controller.git] / Scan / FACOM6684 / scan_loop.c
1 /* Copyright (C) 2013 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
39 // ----- Macros -----
40
41 // Make sure we haven't overflowed the buffer
42 #define bufferAdd(byte) \
43                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
44                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
45
46
47
48 // ----- Variables -----
49
50 // Buffer used to inform the macro processing module which keys have been detected as pressed
51 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
52 volatile uint8_t KeyIndex_BufferUsed;
53
54 volatile uint8_t KeyBufferRemove[6];
55 volatile uint8_t KeyBufferRemoveCount = 0;
56
57 static uint8_t KeyBuffer[3];
58 volatile static uint8_t KeyBufferCount = 0;
59
60
61
62 // ----- Function Declarations -----
63
64 void processKeyValue( uint8_t valueType, uint8_t keyValue );
65 void  removeKeyValue( uint8_t keyValue );
66
67
68
69 // ----- Interrupt Functions -----
70
71 // USART Receive Buffer Full Interrupt
72 ISR(USART1_RX_vect)
73 {
74         cli(); // Disable Interrupts
75
76         // Read part of the scan code (3 8bit chunks) from USART
77         KeyBuffer[KeyBufferCount] = UDR1;
78
79         if ( KeyBufferCount >= 2 )
80         {
81                 // Debug
82                 for ( uint8_t c = 0; c <= 2; c++ )
83                 {
84                         // Debug
85                         char tmpStr[6];
86                         hexToStr( KeyBuffer[c], tmpStr );
87                         dPrintStrs( tmpStr, " " ); // Debug
88                 }
89                 print("\n");
90
91                 processKeyValue( KeyBuffer[1], KeyBuffer[2] );
92
93                 KeyBufferCount = 0;
94         }
95         else
96         {
97                 KeyBufferCount++;
98         }
99
100         sei(); // Re-enable Interrupts
101 }
102
103
104
105 // ----- Functions -----
106
107 // Setup
108 inline void scan_setup()
109 {
110         // Setup the the USART interface for keyboard data input
111         
112         // Setup baud rate
113         // 16 MHz / ( 16 * Baud ) = UBRR
114         // Baud: 4817 -> 16 MHz / ( 16 * 4817 ) = 207.5981
115         // Thus baud setting = 208
116         uint16_t baud = 208; // Max setting of 4095
117         UBRR1H = (uint8_t)(baud >> 8);
118         UBRR1L = (uint8_t)baud;
119
120         // Enable the receiver, transmitter, and RX Complete Interrupt
121         UCSR1B = 0x98;
122
123         // Set frame format: 8 data, 1 stop bit, odd parity
124         // Asynchrounous USART mode
125         UCSR1C = 0x36;
126
127         // Reset the keyboard before scanning, we might be in a wierd state
128         scan_resetKeyboard();
129 }
130
131
132 // Main Detection Loop
133 inline uint8_t scan_loop()
134 {
135         // Remove any "released keys", this is delayed due to buffer release synchronization issues
136         for ( uint8_t c = 0; c < KeyBufferRemoveCount; c++ )
137         {
138                 removeKeyValue( KeyBufferRemove[c] );
139         }
140
141         KeyBufferRemoveCount = 0;
142
143         return 0;
144 }
145
146 void processKeyValue( uint8_t valueType, uint8_t keyValue )
147 {
148         switch ( valueType )
149         {
150         // Single Key Press
151         case 0x00:
152                 break;
153         // Repeated Key Press
154         case 0x01:
155                 break;
156         // Modifier Key Release
157         case 0x02:
158                 KeyBufferRemove[KeyBufferRemoveCount++] = keyValue;
159                 return;
160         }
161
162         // Make sure the key isn't already in the buffer
163         for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
164         {
165                 // Key isn't in the buffer yet
166                 if ( c == KeyIndex_BufferUsed )
167                 {
168                         bufferAdd( keyValue );
169                         break;
170                 }
171
172                 // Key already in the buffer
173                 if ( KeyIndex_Buffer[c] == keyValue )
174                         break;
175         }
176 }
177
178 void removeKeyValue( uint8_t keyValue )
179 {
180         // Check for the released key, and shift the other keys lower on the buffer
181         uint8_t c;
182         for ( c = 0; c < KeyIndex_BufferUsed; c++ )
183         {
184                 // Key to release found
185                 if ( KeyIndex_Buffer[c] == keyValue )
186                 {
187                         // Shift keys from c position
188                         for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
189                                 KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
190
191                         // Decrement Buffer
192                         KeyIndex_BufferUsed--;
193
194                         break;
195                 }
196         }
197
198         // Error case (no key to release)
199         if ( c == KeyIndex_BufferUsed + 1 )
200         {
201                 errorLED( 1 );
202                 char tmpStr[6];
203                 hexToStr( keyValue, tmpStr );
204                 erro_dPrint( "Could not find key to release: ", tmpStr );
205         }
206 }
207
208 // Send data 
209 uint8_t scan_sendData( uint8_t dataPayload )
210 {
211         // Debug
212         char tmpStr[6];
213         hexToStr( dataPayload, tmpStr );
214         info_dPrint( "Sending - ", tmpStr );
215
216         UDR1 = dataPayload;
217
218         return 0;
219 }
220
221 // Signal KeyIndex_Buffer that it has been properly read
222 void scan_finishedWithBuffer( uint8_t sentKeys )
223 {
224         // Make sure we aren't in the middle of a receiving a new scancode
225         while ( KeyBufferCount != 0 );
226
227         cli(); // Disable Interrupts
228
229         // Count for number of modifiers to maintain in the buffer
230         uint8_t filled = 0;
231         uint8_t latched = 0;
232         uint8_t latchBuffer[13]; // There are only 13 keys that can possibly be latched at the same time...
233         uint8_t normal = 0;
234         uint8_t prevBuffer = KeyIndex_BufferUsed;
235
236         // Clean out all keys except "special" keys (designated modifiers)
237         uint8_t key;
238         for ( key = 0; key < sentKeys; key++ )
239         {
240                 switch ( KeyIndex_Buffer[key] )
241                 {
242                 // Dedicated Modifier Keys
243                 // NOTE: Both shifts are represented as the same scan code
244                 case 0x04:
245                 case 0x05:
246                 case 0x12:
247                         KeyIndex_Buffer[filled++] = KeyIndex_Buffer[key];
248                         break;
249                 // Latched Keys, only released if a non-modifier is pressed along with it
250                 // NOTE: This keys do not have a built in repeating
251                 case 0x00:
252                 case 0x01:
253                 case 0x03:
254                 //case 0x0B: // XXX Being used as an alternate Enter, since it is labelled as such
255                 case 0x22:
256                 case 0x10:
257                 case 0x11:
258                 case 0x20:
259                 case 0x21:
260                 case 0x30:
261                 case 0x31:
262                 case 0x40:
263                 //case 0x41: // XXX Being used as ESC
264                         latchBuffer[latched++] = KeyIndex_Buffer[key];
265                         break;
266                 // Allow the scancode to be removed, normal keys
267                 default:
268                         normal++;
269                         break;
270                 }
271         }
272
273         // Reset the buffer counter
274         KeyIndex_BufferUsed = filled;
275
276         // Add back lost keys, so they are processed on the next USB send
277         for ( ; key < prevBuffer; key++ )
278         {
279                 bufferAdd( KeyIndex_Buffer[key] );
280                 info_print("Re-appending lost key after USB send...");
281         }
282
283         // Only "re-add" the latched keys if they weren't used
284         if ( latched > 0 && normal == 0 )
285         {
286                 for ( uint8_t c = 0; c < latched; c++ )
287                 {
288                         bufferAdd( latchBuffer[c] );
289                 }
290         }
291
292         sei(); // Re-enable Interrupts
293 }
294
295 // Signal that the keys have been properly sent over USB
296 void scan_finishedWithUSBBuffer( uint8_t sentKeys )
297 {
298 }
299
300 // Reset/Hold keyboard
301 // NOTE: Does nothing with the FACOM6684
302 void scan_lockKeyboard( void )
303 {
304 }
305
306 // NOTE: Does nothing with the FACOM6684
307 void scan_unlockKeyboard( void )
308 {
309 }
310
311 // Reset Keyboard
312 void scan_resetKeyboard( void )
313 {
314         // Not a calculated valued...
315         _delay_ms( 50 );
316
317         KeyBufferCount = 0;
318         KeyBufferRemoveCount = 0;
319         KeyIndex_BufferUsed = 0;
320 }
321