]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/MicroSwitch8304/scan_loop.c
Fix whitespace
[kiibohd-controller.git] / Scan / MicroSwitch8304 / scan_loop.c
1 /* Copyright (C) 2011,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 #define RESET_PORT PORTB
40 #define RESET_DDR   DDRD
41 #define RESET_PIN      0
42
43
44 // ----- Macros -----
45
46 #define UNSET_RESET()   RESET_DDR &= ~(1 << RESET_PIN)
47 #define   SET_RESET()   RESET_DDR |=  (1 << RESET_PIN)
48
49
50
51 // ----- Variables -----
52
53 // Buffer used to inform the macro processing module which keys have been detected as pressed
54 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
55 volatile uint8_t KeyIndex_BufferUsed;
56
57
58 // Buffer Signals
59 volatile uint8_t BufferReadyToClear;
60
61
62
63 // ----- Functions -----
64
65 // Setup
66 inline void Scan_setup()
67 {
68         // Setup the the USART interface for keyboard data input
69         // NOTE: The input data signal needs to be inverted for the Teensy USART to properly work
70
71         // Setup baud rate
72         // 16 MHz / ( 16 * Baud ) = UBRR
73         // Baud <- 0.82020 ms per bit, thus 1000 / 0.82020 = 1219.2
74         // Thus baud setting = 820
75         uint16_t baud = 820; // Max setting of 4095
76         UBRR1H = (uint8_t)(baud >> 8);
77         UBRR1L = (uint8_t)baud;
78
79         // Enable the receiver, transitter, and RX Complete Interrupt
80         UCSR1B = 0x98;
81
82         // Set frame format: 8 data, no stop bits or parity
83         // Asynchrounous USART mode
84         // 8304 sends encoded scancodes (for example Alphanumeric 0-9 follows their keypad encoding scheme)
85         // Separate line is for reset
86         UCSR1C = 0x06;
87
88         // Initially buffer doesn't need to be cleared (it's empty...)
89         BufferReadyToClear = 0;
90
91         // Reset the keyboard before scanning, we might be in a wierd state
92         // Note: This should be run asap, but we need the USART setup to run this command on the 8304
93         scan_resetKeyboard();
94 }
95
96
97 // Main Detection Loop
98 // Not needed for the Micro Switch 8304, this is just a busy loop
99 inline uint8_t Scan_loop()
100 {
101         return 0;
102 }
103
104 void processKeyValue( uint8_t keyValue )
105 {
106         // Finalize output buffer
107         // Mask 8th bit
108         keyValue &= 0x7F;
109
110         // Interpret scan code
111         switch ( keyValue )
112         {
113         case 0x40: // Clear buffer command
114                 info_print("CLEAR!");
115
116                 BufferReadyToClear = 1;
117                 break;
118         case 0x7F:
119                 scan_lockKeyboard();
120                 _delay_ms(3000);
121                 scan_unlockKeyboard();
122
123         default:
124                 // Make sure the key isn't already in the buffer
125                 for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
126                 {
127                         // Key isn't in the buffer yet
128                         if ( c == KeyIndex_BufferUsed )
129                         {
130                                 Macro_bufferAdd( keyValue );
131                                 break;
132                         }
133
134                         // Key already in the buffer
135                         if ( KeyIndex_Buffer[c] == keyValue )
136                                 break;
137                 }
138                 break;
139         }
140 }
141
142 // USART Receive Buffer Full Interrupt
143 ISR(USART1_RX_vect)
144 {
145         cli(); // Disable Interrupts
146
147         uint8_t keyValue = 0x00;
148
149         // The interrupt is always for the first item of the packet set, reset the buffer
150         KeyIndex_BufferUsed = 0;
151
152         // Only the first 7 bits have scancode data
153         // The last packet of the packet set has the 8th bit high, all the others are low
154         //
155         // Interrupts are too slow for the rest of the packet set, poll for the rest
156         while ( 1 )
157         {
158                 // Read the raw packet from the USART
159                 keyValue = UDR1;
160
161                 // Debug
162                 char tmpStr[6];
163                 hexToStr( keyValue, tmpStr );
164                 dPrintStrs( tmpStr, " " );
165
166                 // Process the scancode
167                 processKeyValue( keyValue );
168
169                 // Last packet of the set
170                 if ( keyValue & 0x80 )
171                 {
172                         dPrintStrs( "**" );
173                         break;
174                 }
175
176                 // Delay enough so we don't run into the same packet (or the previous buffered packet)
177                 _delay_us(10000);
178         }
179
180         sei(); // Re-enable Interrupts
181 }
182
183 // Send data
184 //
185 // Keyboard Input Guide for Micro Switch 8304
186 // 0xBX is for LED F1,F2,Over Type,Lock
187 // 0xAX is for LED F3,F8,F9,F10
188 // 0x92 resets keyboard (LED off, echo scancode mode off)
189 // 0x9E sets echo scancode mode from (0x81 to 0xFF; translates to 0x01 to 0x7F)
190 // Other echos: 0x15~0x19 send 0x15~0x19, 0x40 sends 0x40 (as well as 0x44,0x45, 0x80)
191 // 0x8C Acks the keyboard and gets 0x70 sent back (delayed)
192 uint8_t Scan_sendData( uint8_t dataPayload )
193 {
194         UDR1 = dataPayload;
195         return 0;
196 }
197
198 // Signal KeyIndex_Buffer that it has been properly read
199 // In the case of the Micro Switch 8304, we leave the buffer alone until more scancode data comes in
200 void Scan_finishedWithBuffer( uint8_t sentKeys )
201 {
202         // We received a Clear code from the 8304, clear the buffer now that we've used it
203         if ( BufferReadyToClear )
204         {
205                 KeyIndex_BufferUsed = 0;
206                 BufferReadyToClear = 0;
207         }
208 }
209
210 // Signal that the keys have been properly sent over USB
211 void Scan_finishedWithUSBBuffer( uint8_t sentKeys )
212 {
213 }
214
215 // Reset/Hold keyboard
216 // Warning! This will cause the keyboard to not send any data, so you can't disable with a keypress
217 // The Micro Switch 8304 has a dedicated reset line
218 void Scan_lockKeyboard( void )
219 {
220         UNSET_RESET();
221 }
222
223 void Scan_unlockKeyboard( void )
224 {
225         SET_RESET();
226 }
227
228 // Reset Keyboard
229 void Scan_resetKeyboard( void )
230 {
231         // Reset command for the 8304
232         scan_sendData( 0x92 );
233 }
234