]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/Kaypro1/scan_loop.c
74485e675a3504e65e21c9ed2af4a0dc2cc828d6
[kiibohd-controller.git] / Scan / Kaypro1 / scan_loop.c
1 /* Copyright (C) 2011 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
28 // Project Includes
29 #include <led.h>
30 #include <print.h>
31
32 // Local Includes
33 #include "scan_loop.h"
34
35
36
37 // ----- Defines -----
38
39
40
41 // ----- Macros -----
42
43 // Make sure we haven't overflowed the buffer
44 #define bufferAdd(byte) \
45                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
46                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
47
48
49
50 // ----- Variables -----
51
52 // Buffer used to inform the macro processing module which keys have been detected as pressed
53 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
54 volatile uint8_t KeyIndex_BufferUsed;
55
56
57 // Known signals
58 static uint8_t cmd_clickOFF  = 0x0A; // Short beep, turns off clicker
59 static uint8_t cmd_clickON   = 0x04; // Long beep, turns on clicker
60 static uint8_t cmd_ACK_AA    = 0x10; // Keyboard will send ack (0xAA) back to PC
61
62 // Other known signals
63 // 0x02 turns on clicker but with short beep
64
65
66
67 // ----- Functions -----
68
69 // Setup
70 inline void scan_setup()
71 {
72         // Setup the the USART interface for keyboard data input
73         
74         // Setup baud rate
75         // 16 MHz / ( 16 * Baud ) = UBRR
76         // Baud <- 3.358 ms per bit, thus 1000 / 3.358 = 297.80
77         // Thus baud = 3357
78         uint16_t baud = 3357; // Max setting of 4095
79         UBRR1H = (uint8_t)(baud >> 8);
80         UBRR1L = (uint8_t)baud;
81
82         // Enable the receiver, transitter, and RX Complete Interrupt
83         UCSR1B = 0x98;
84
85         // Set frame format: 8 data, no stop bits or parity
86         // Asynchrounous USART mode
87         // Kaypro sends ASCII codes (mostly standard) with 1 start bit and 8 data bits, with no trailing stop or parity bits
88         UCSR1C = 0x06;
89 }
90
91
92 // Main Detection Loop
93 // Nothing is needed here for the Kaypro, but the function is available as part of the api to be called in a polling fashion
94 // TODO
95 //  - Add songs :D
96 inline uint8_t scan_loop()
97 {
98         // We *could* do extra offline processing here, but, it's not really needed for the Kaypro 1 keyboard
99         return 0;
100 }
101
102 // USART Receive Buffer Full Interrupt
103 ISR(USART1_RX_vect)
104 {
105         cli(); // Disable Interrupts
106
107         // Get key from USART
108         uint8_t keyValue = UDR1;
109
110 //#ifdef MAX_DEBUG
111         // Debug print key
112         char tmpStr1[6];
113         hexToStr( keyValue, tmpStr1 );
114         dPrintStrs( tmpStr1, " " );
115 //#endif
116
117         // Add key(s) to processing buffer
118         // First split out Shift and Ctrl
119         //  Reserved Codes:
120         //   Shift - 0xF5
121         //   Ctrl  - 0xF6
122         switch ( keyValue )
123         {
124         // - Ctrl Keys -
125         // Exception keys
126         case 0x08: // ^H
127         case 0x09: // ^I
128         case 0x0D: // ^M
129         case 0x1B: // ^[
130                 bufferAdd( keyValue );
131                 break;
132         // 0x40 Offset Keys
133         // Add Ctrl key and offset to the lower alphabet
134         case 0x00: // ^@
135         case 0x1C: // "^\"
136         case 0x1D: // ^]
137         case 0x1E: // ^^
138         case 0x1F: // ^_
139                 bufferAdd( 0xF6 );
140                 bufferAdd( keyValue + 0x40 );
141                 break;
142
143         // - Add Shift key and offset to non-shifted key -
144         // 0x10 Offset Keys
145         case 0x21: // !
146         case 0x23: // #
147         case 0x24: // $
148         case 0x25: // %
149                 bufferAdd( 0xF5 );
150                 bufferAdd( keyValue + 0x10 );
151                 break;
152         // 0x11 Offset Keys
153         case 0x26: // &
154         case 0x28: // (
155                 bufferAdd( 0xF5 );
156                 bufferAdd( keyValue + 0x11 );
157                 break;
158         // 0x07 Offset Keys
159         case 0x29: // )
160                 bufferAdd( 0xF5 );
161                 bufferAdd( keyValue + 0x07 );
162                 break;
163         // -0x0E Offset Keys
164         case 0x40: // @
165                 bufferAdd( 0xF5 );
166                 bufferAdd( keyValue - 0x0E );
167                 break;
168         // 0x0E Offset Keys
169         case 0x2A: // *
170                 bufferAdd( 0xF5 );
171                 bufferAdd( keyValue + 0x0E );
172                 break;
173         // 0x12 Offset Keys
174         case 0x2B: // +
175                 bufferAdd( 0xF5 );
176                 bufferAdd( keyValue + 0x12 );
177                 break;
178         // 0x05 Offset Keys
179         case 0x22: // "
180                 bufferAdd( 0xF5 );
181                 bufferAdd( keyValue + 0x05 );
182                 break;
183         // 0x01 Offset Keys
184         case 0x3A: // :
185                 bufferAdd( 0xF5 );
186                 bufferAdd( keyValue + 0x01 );
187                 break;
188         // -0x10 Offset Keys
189         case 0x3C: // <
190         case 0x3E: // >
191         case 0x3F: // ?
192                 bufferAdd( 0xF5 );
193                 bufferAdd( keyValue - 0x10 );
194                 break;
195         // -0x28 Offset Keys
196         case 0x5E: // ^
197                 bufferAdd( 0xF5 );
198                 bufferAdd( keyValue - 0x28 );
199                 break;
200         // -0x32 Offset Keys
201         case 0x5F: // _
202                 bufferAdd( 0xF5 );
203                 bufferAdd( keyValue - 0x32 );
204                 break;
205         // -0x20 Offset Keys
206         case 0x7B: // {
207         case 0x7C: // |
208         case 0x7D: // }
209                 bufferAdd( 0xF5 );
210                 bufferAdd( keyValue - 0x20 );
211                 break;
212         // -0x1E Offset Keys
213         case 0x7E: // ~
214                 bufferAdd( 0xF5 );
215                 bufferAdd( keyValue - 0x1E );
216                 break;
217         // All other keys
218         default:
219                 // Ctrl Characters are from 0x00 to 0x1F, excluding:
220                 //  0x08 - Backspace
221                 //  0x09 - [Horizontal] Tab
222                 //  0x0D - [Carriage] Return
223                 //  0x1B - Escape
224                 //  0x7F - Delete (^?) (Doesn't need to be split out)
225
226                 // 0x60 Offset Keys
227                 // Add Ctrl key and offset to the lower alphabet
228                 if ( keyValue >= 0x00 && keyValue <= 0x1F )
229                 {
230                         bufferAdd( 0xF6 );
231                         bufferAdd( keyValue + 0x60 );
232                 }
233
234                 // Shift Characters are from 0x41 to 0x59
235                 //  No exceptions here :D
236                 // Add Shift key and offset to the lower alphabet
237                 else if ( keyValue >= 0x41 && keyValue <= 0x5A )
238                 {
239                         bufferAdd( 0xF5 );
240                         bufferAdd( keyValue + 0x20 );
241                 }
242
243                 // Everything else
244                 else
245                 {
246                         bufferAdd( keyValue );
247                 }
248                 break;
249         }
250
251         // Special keys - For communication to the keyboard
252         // TODO Try to push this functionality into the macros...somehow
253         switch ( keyValue )
254         {
255         case 0xC3: // Keypad Enter
256                 print("\n");
257                 info_print("BEEEEP! - Clicker on");
258                 UDR1 = cmd_clickON;
259                 break;
260
261         case 0xB2: // Keypad Decimal
262                 print("\n");
263                 info_print("BEEP! - Clicker off");
264                 UDR1 = cmd_clickOFF;
265                 break;
266
267         case 0x0A: // Line Feed
268                 print("\n");
269                 info_print("ACK!!");
270                 UDR1 = cmd_ACK_AA;
271                 break;
272         }
273
274         sei(); // Re-enable Interrupts
275 }
276