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