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