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 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
53 volatile uint8_t KeyIndex_BufferUsed;
57 static uint8_t cmd_clickOFF = 0x0A; // Short beep, turns off clicker
58 static uint8_t cmd_clickON = 0x04; // Long beep, turns on clicker
59 static uint8_t cmd_ACK_AA = 0x10; // Keyboard will send ack (0xAA) back to PC
61 // Other known signals
62 // 0x02 turns on clicker but with short beep
66 // ----- Functions -----
69 inline void scan_setup()
71 // Setup the the USART interface for keyboard data input
74 // 16 MHz / ( 16 * Baud ) = UBRR
75 // Baud <- 3.358 ms per bit, thus 1000 / 3.358 = 297.80
77 uint16_t baud = 3357; // Max setting of 4095
78 UBRR1H = (uint8_t)(baud >> 8);
79 UBRR1L = (uint8_t)baud;
81 // Enable the receiver, transitter, and RX Complete Interrupt
84 // Set frame format: 8 data, no stop bits or parity
85 // Asynchrounous USART mode
86 // Kaypro sends ASCII codes (mostly standard) with 1 start bit and 8 data bits, with no trailing stop or parity bits
91 // Main Detection Loop
92 // Nothing is needed here for the Kaypro, but the function is available as part of the api to be called in a polling fashion
95 inline uint8_t scan_loop()
97 // We *could* do extra offline processing here, but, it's not really needed for the Kaypro 1 keyboard
101 // USART Receive Buffer Full Interrupt
104 cli(); // Disable Interrupts
106 // Get key from USART
107 uint8_t keyValue = UDR1;
112 hexToStr( keyValue, tmpStr1 );
113 dPrintStrs( tmpStr1, " " );
116 // Add key(s) to processing buffer
117 // First split out Shift and Ctrl
129 bufferAdd( keyValue );
132 // Add Ctrl key and offset to the lower alphabet
139 bufferAdd( keyValue + 0x40 );
142 // - Add Shift key and offset to non-shifted key -
149 bufferAdd( keyValue + 0x10 );
155 bufferAdd( keyValue + 0x11 );
160 bufferAdd( keyValue + 0x07 );
165 bufferAdd( keyValue - 0x0E );
170 bufferAdd( keyValue + 0x0E );
175 bufferAdd( keyValue + 0x12 );
180 bufferAdd( keyValue + 0x05 );
185 bufferAdd( keyValue + 0x01 );
192 bufferAdd( keyValue - 0x10 );
197 bufferAdd( keyValue - 0x28 );
202 bufferAdd( keyValue - 0x32 );
209 bufferAdd( keyValue - 0x20 );
214 bufferAdd( keyValue - 0x1E );
218 // Ctrl Characters are from 0x00 to 0x1F, excluding:
220 // 0x09 - [Horizontal] Tab
221 // 0x0D - [Carriage] Return
223 // 0x7F - Delete (^?) (Doesn't need to be split out)
226 // Add Ctrl key and offset to the lower alphabet
227 if ( keyValue >= 0x00 && keyValue <= 0x1F )
230 bufferAdd( keyValue + 0x60 );
233 // Shift Characters are from 0x41 to 0x59
234 // No exceptions here :D
235 // Add Shift key and offset to the lower alphabet
236 else if ( keyValue >= 0x41 && keyValue <= 0x5A )
239 bufferAdd( keyValue + 0x20 );
245 bufferAdd( keyValue );
250 // Special keys - For communication to the keyboard
251 // TODO Try to push this functionality into the macros...somehow
254 case 0xC3: // Keypad Enter
256 info_print("BEEEEP! - Clicker on");
260 case 0xB2: // Keypad Decimal
262 info_print("BEEP! - Clicker off");
266 case 0x0A: // Line Feed
273 sei(); // Re-enable Interrupts