]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/BETKB/scan_loop.c
Adding API changes introduced by the FACOM converter
[kiibohd-controller.git] / Scan / BETKB / scan_loop.c
1 /* Copyright (C) 2012 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 // AVR Includes
25 #include <avr/interrupt.h>
26 #include <avr/io.h>
27 #include <util/delay.h>
28
29 // Project Includes
30 #include <led.h>
31 #include <print.h>
32
33 // Local Includes
34 #include "scan_loop.h"
35
36
37
38 // ----- Defines -----
39
40 // Pinout Defines
41 #define HOLD_PORT PORTD
42 #define HOLD_DDR   DDRD
43 #define HOLD_PIN      3
44
45
46 // ----- Macros -----
47
48 // Make sure we haven't overflowed the buffer
49 #define bufferAdd(byte) \
50                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
51                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
52
53
54
55 // ----- Variables -----
56
57 // Buffer used to inform the macro processing module which keys have been detected as pressed
58 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
59 volatile uint8_t KeyIndex_BufferUsed;
60 volatile uint8_t KeyIndex_Add_InputSignal; // Used to pass the (click/input value) to the keyboard for the clicker
61
62
63 // Buffer Signals
64 volatile uint8_t BufferReadyToClear;
65
66
67
68 // ----- Function Declarations -----
69
70 void processKeyValue( uint8_t keyValue );
71 void  removeKeyValue( uint8_t keyValue );
72
73
74
75 // ----- Interrupt Functions -----
76
77 // USART Receive Buffer Full Interrupt
78 ISR(USART1_RX_vect)
79 {
80         cli(); // Disable Interrupts
81
82         uint8_t keyValue = 0x00;
83         uint8_t keyState = 0x00;
84
85         // Read the scancode packet from the USART (1st to 8th bits)
86         keyValue = UDR1;
87
88         // Read the release/press bit (9th bit) XXX Unnecessary, and wrong it seems, parity bit? or something else?
89         keyState = UCSR1B & 0x02;
90
91         // High bit of keyValue, also represents press/release
92         keyState = keyValue & 0x80 ? 0x00 : 0x02;
93
94         // Debug
95         char tmpStr[6];
96         hexToStr( keyValue & 0x7F, tmpStr );
97
98         // Process the scancode
99         switch ( keyState )
100         {
101         case 0x00: // Released
102                 dPrintStrs( tmpStr, "R  " ); // Debug
103
104                 // Remove key from press buffer
105                 removeKeyValue( keyValue & 0x7F );
106                 break;
107
108         case 0x02: // Pressed
109                 dPrintStrs( tmpStr, "P " ); // Debug
110
111                 // New key to process
112                 processKeyValue( keyValue & 0x7F );
113                 break;
114         }
115
116         sei(); // Re-enable Interrupts
117 }
118
119
120
121 // ----- Functions -----
122
123 // Setup
124 inline void scan_setup()
125 {
126         // Setup the the USART interface for keyboard data input
127         // NOTE: The input data signal needs to be inverted for the Teensy USART to properly work
128         
129         // Setup baud rate
130         // 16 MHz / ( 16 * Baud ) = UBRR
131         // Baud <- 0.823284 ms per bit, thus 1000 / 0.823284 = 1214.65004 -> 823.2824
132         // Thus baud setting = 823
133         uint16_t baud = 823; // Max setting of 4095
134         UBRR1H = (uint8_t)(baud >> 8);
135         UBRR1L = (uint8_t)baud;
136
137         // Enable the receiver, and RX Complete Interrupt as well as 9 bit data
138         UCSR1B = 0x94;
139
140         // The transmitter is only to be enabled when needed
141         // Set the pin to be pull-up otherwise (use the lowered voltage inverter in order to sink)
142         HOLD_DDR  &= ~(1 << HOLD_PIN);
143         HOLD_PORT |=  (1 << HOLD_PIN);
144
145         // Set frame format: 9 data, 1 stop bit, no parity
146         // Asynchrounous USART mode
147         UCSR1C = 0x06;
148
149         // Initially buffer doesn't need to be cleared (it's empty...)
150         BufferReadyToClear = 0;
151
152         // InputSignal is off by default
153         KeyIndex_Add_InputSignal = 0x00;
154
155         // Reset the keyboard before scanning, we might be in a wierd state
156         scan_resetKeyboard();
157 }
158
159
160 // Main Detection Loop
161 // Not needed for the BETKB, this is just a busy loop
162 inline uint8_t scan_loop()
163 {
164         return 0;
165 }
166
167 void processKeyValue( uint8_t keyValue )
168 {
169         // Interpret scan code
170         switch ( keyValue )
171         {
172         case 0x00: // Break code from input?
173                 break;
174         default:
175                 // Make sure the key isn't already in the buffer
176                 for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
177                 {
178                         // Key isn't in the buffer yet
179                         if ( c == KeyIndex_BufferUsed )
180                         {
181                                 bufferAdd( keyValue );
182
183                                 // Only send data if enabled
184                                 if ( KeyIndex_Add_InputSignal )
185                                         scan_sendData( KeyIndex_Add_InputSignal );
186                                 break;
187                         }
188
189                         // Key already in the buffer
190                         if ( KeyIndex_Buffer[c] == keyValue )
191                                 break;
192                 }
193                 break;
194         }
195 }
196
197 void removeKeyValue( uint8_t keyValue )
198 {
199         // Check for the released key, and shift the other keys lower on the buffer
200         uint8_t c;
201         for ( c = 0; c < KeyIndex_BufferUsed; c++ )
202         {
203                 // Key to release found
204                 if ( KeyIndex_Buffer[c] == keyValue )
205                 {
206                         // Shift keys from c position
207                         for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
208                                 KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
209
210                         // Decrement Buffer
211                         KeyIndex_BufferUsed--;
212
213                         break;
214                 }
215         }
216
217         // Error case (no key to release)
218         if ( c == KeyIndex_BufferUsed + 1 )
219         {
220                 errorLED( 1 );
221                 char tmpStr[6];
222                 hexToStr( keyValue, tmpStr );
223                 erro_dPrint( "Could not find key to release: ", tmpStr );
224         }
225 }
226
227 // Send data 
228 uint8_t scan_sendData( uint8_t dataPayload )
229 {
230         // Enable the USART Transmitter
231         UCSR1B |=  (1 << 3);
232
233         // Debug
234         char tmpStr[6];
235         hexToStr( dataPayload, tmpStr );
236         info_dPrint( "Sending - ", tmpStr );
237
238         UDR1 = dataPayload;
239
240         // Wait for the payload
241         _delay_us( 800 );
242
243         // Disable the USART Transmitter
244         UCSR1B &= ~(1 << 3);
245
246         return 0;
247 }
248
249 // Signal KeyIndex_Buffer that it has been properly read
250 void scan_finishedWithBuffer( uint8_t sentKeys )
251 {
252 }
253
254 // Signal that the keys have been properly sent over USB
255 void scan_finishedWithUSBBuffer( uint8_t sentKeys )
256 {
257 }
258
259 // Reset/Hold keyboard
260 // NOTE: Does nothing with the BETKB
261 void scan_lockKeyboard( void )
262 {
263 }
264
265 // NOTE: Does nothing with the BETKB
266 void scan_unlockKeyboard( void )
267 {
268 }
269
270 // Reset Keyboard
271 void scan_resetKeyboard( void )
272 {
273         // Not a calculated valued...
274         _delay_ms( 50 );
275 }
276