1 /* Copyright (C) 2011 by Jacob Alexander
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:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
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
22 // ----- Includes -----
25 #include <avr/interrupt.h>
33 #include "scan_loop.h"
37 // ----- Defines -----
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
50 // ----- Variables -----
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;
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
62 // Other known signals
63 // 0x02 turns on clicker but with short beep
67 // ----- Functions -----
70 inline void scan_setup()
72 // Setup the the USART interface for keyboard data input
75 // 16 MHz / ( 16 * Baud ) = UBRR
76 // Baud <- 3.358 ms per bit, thus 1000 / 3.358 = 297.80
78 uint16_t baud = 3357; // Max setting of 4095
79 UBRR1H = (uint8_t)(baud >> 8);
80 UBRR1L = (uint8_t)baud;
82 // Enable the receiver, transitter, and RX Complete Interrupt
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
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
96 inline uint8_t scan_loop()
98 // We *could* do extra offline processing here, but, it's not really needed for the Kaypro 1 keyboard
102 // USART Receive Buffer Full Interrupt
105 cli(); // Disable Interrupts
107 // Get key from USART
108 uint8_t keyValue = UDR1;
113 hexToStr( keyValue, tmpStr1 );
114 dPrintStrs( tmpStr1, " " );
117 // Add key(s) to processing buffer
118 // First split out Shift and Ctrl
130 bufferAdd( keyValue );
133 // Add Ctrl key and offset to the lower alphabet
140 bufferAdd( keyValue + 0x40 );
143 // - Add Shift key and offset to non-shifted key -
150 bufferAdd( keyValue + 0x10 );
156 bufferAdd( keyValue + 0x11 );
161 bufferAdd( keyValue + 0x07 );
166 bufferAdd( keyValue - 0x0E );
171 bufferAdd( keyValue + 0x0E );
176 bufferAdd( keyValue + 0x12 );
181 bufferAdd( keyValue + 0x05 );
186 bufferAdd( keyValue + 0x01 );
193 bufferAdd( keyValue - 0x10 );
198 bufferAdd( keyValue - 0x28 );
203 bufferAdd( keyValue - 0x32 );
210 bufferAdd( keyValue - 0x20 );
215 bufferAdd( keyValue - 0x1E );
219 // Ctrl Characters are from 0x00 to 0x1F, excluding:
221 // 0x09 - [Horizontal] Tab
222 // 0x0D - [Carriage] Return
224 // 0x7F - Delete (^?) (Doesn't need to be split out)
227 // Add Ctrl key and offset to the lower alphabet
228 if ( keyValue >= 0x00 && keyValue <= 0x1F )
231 bufferAdd( keyValue + 0x60 );
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 )
240 bufferAdd( keyValue + 0x20 );
246 bufferAdd( keyValue );
251 // Special keys - For communication to the keyboard
252 // TODO Try to push this functionality into the macros...somehow
255 case 0xC3: // Keypad Enter
257 info_print("BEEEEP! - Clicker on");
261 case 0xB2: // Keypad Decimal
263 info_print("BEEP! - Clicker off");
267 case 0x0A: // Line Feed
274 sei(); // Re-enable Interrupts