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>
27 #include <util/delay.h>
34 #include "scan_loop.h"
38 // ----- Defines -----
41 #define RESET_PORT PORTB
42 #define RESET_DDR DDRD
48 // Make sure we haven't overflowed the buffer
49 #define bufferAdd(byte) \
50 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
51 KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
53 #define UNSET_RESET() RESET_DDR &= ~(1 << RESET_PIN)
54 #define SET_RESET() RESET_DDR |= (1 << RESET_PIN)
58 // ----- Variables -----
60 // Buffer used to inform the macro processing module which keys have been detected as pressed
61 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
62 volatile uint8_t KeyIndex_BufferUsed;
66 volatile uint8_t BufferReadyToClear;
70 // ----- Functions -----
73 inline void scan_setup()
75 // Setup the the USART interface for keyboard data input
76 // NOTE: The input data signal needs to be inverted for the Teensy USART to properly work
79 // 16 MHz / ( 16 * Baud ) = UBRR
80 // Baud <- 0.82020 ms per bit, thus 1000 / 0.82020 = 1219.2
82 uint16_t baud = 820; // Max setting of 4095
83 UBRR1H = (uint8_t)(baud >> 8);
84 UBRR1L = (uint8_t)baud;
86 // Enable the receiver, transitter, and RX Complete Interrupt
89 // Set frame format: 8 data, no stop bits or parity
90 // Asynchrounous USART mode
91 // 8304 sends encoded scancodes (for example Alphanumeric 0-9 follows their keypad encoding scheme)
92 // Separate line is for reset
95 // Initially buffer doesn't need to be cleared (it's empty...)
96 BufferReadyToClear = 0;
100 // Main Detection Loop
101 // Not needed for the Micro Switch 8304, this is just a busy loop
102 inline uint8_t scan_loop()
107 void processKeyValue( uint8_t keyValue )
109 // Finalize output buffer
113 // Interpret scan code
116 case 0x40: // Clear buffer command
117 info_print("CLEAR!");
119 BufferReadyToClear = 1;
124 scan_unlockKeyboard();
127 // Make sure the key isn't already in the buffer
128 for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
130 // Key isn't in the buffer yet
131 if ( c == KeyIndex_BufferUsed )
133 bufferAdd( keyValue );
137 // Key already in the buffer
138 if ( KeyIndex_Buffer[c] == keyValue )
145 // USART Receive Buffer Full Interrupt
148 cli(); // Disable Interrupts
150 uint8_t keyValue = 0x00;
152 // The interrupt is always for the first item of the packet set, reset the buffer
153 KeyIndex_BufferUsed = 0;
155 // Only the first 7 bits have scancode data
156 // The last packet of the packet set has the 8th bit high, all the others are low
158 // Interrupts are too slow for the rest of the packet set, poll for the rest
161 // Read the raw packet from the USART
166 hexToStr( keyValue, tmpStr );
167 dPrintStrs( tmpStr, " " );
169 // Process the scancode
170 processKeyValue( keyValue );
172 // Last packet of the set
173 if ( keyValue & 0x80 )
179 // Delay enough so we don't run into the same packet (or the previous buffered packet)
183 sei(); // Re-enable Interrupts
188 // Keyboard Input Guide for Micro Switch 8304
189 // 0xBX is for LED F1,F2,Over Type,Lock
190 // 0xAX is for LED F3,F8,F9,F10
191 // 0x92 resets keyboard (LED off, echo scancode mode off)
192 // 0x9E sets echo scancode mode from (0x81 to 0xFF; translates to 0x01 to 0x7F)
193 // Other echos: 0x15~0x19 send 0x15~0x19, 0x40 sends 0x40 (as well as 0x44,0x45, 0x80)
194 // 0x8C Acks the keyboard and gets 0x70 sent back (delayed)
195 uint8_t scan_sendData( uint8_t dataPayload )
201 // Signal KeyIndex_Buffer that it has been properly read
202 // In the case of the Micro Switch 8304, we leave the buffer alone until more scancode data comes in
203 void scan_finishedWithBuffer( void )
205 // We received a Clear code from the 8304, clear the buffer now that we've used it
206 if ( BufferReadyToClear )
208 KeyIndex_BufferUsed = 0;
209 BufferReadyToClear = 0;
213 // Reset/Hold keyboard
214 // Warning! This will cause the keyboard to not send any data, so you can't disable with a keypress
215 // The Micro Switch 8304 has a dedicated reset line
216 void scan_lockKeyboard( void )
221 void scan_unlockKeyboard( void )