1 /* Copyright (C) 2011,2014 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 <Lib/ScanLib.h>
32 #include "scan_loop.h"
36 // ----- Defines -----
39 #define RESET_PORT PORTB
40 #define RESET_DDR DDRD
46 #define UNSET_RESET() RESET_DDR &= ~(1 << RESET_PIN)
47 #define SET_RESET() RESET_DDR |= (1 << RESET_PIN)
51 // ----- Variables -----
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;
59 volatile uint8_t BufferReadyToClear;
63 // ----- Functions -----
66 inline void Scan_setup()
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
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;
79 // Enable the receiver, transitter, and RX Complete Interrupt
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
88 // Initially buffer doesn't need to be cleared (it's empty...)
89 BufferReadyToClear = 0;
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
97 // Main Detection Loop
98 // Not needed for the Micro Switch 8304, this is just a busy loop
99 inline uint8_t Scan_loop()
104 void processKeyValue( uint8_t keyValue )
106 // Finalize output buffer
110 // Interpret scan code
113 case 0x40: // Clear buffer command
114 info_print("CLEAR!");
116 BufferReadyToClear = 1;
121 scan_unlockKeyboard();
124 // Make sure the key isn't already in the buffer
125 for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
127 // Key isn't in the buffer yet
128 if ( c == KeyIndex_BufferUsed )
130 Macro_bufferAdd( keyValue );
134 // Key already in the buffer
135 if ( KeyIndex_Buffer[c] == keyValue )
142 // USART Receive Buffer Full Interrupt
145 cli(); // Disable Interrupts
147 uint8_t keyValue = 0x00;
149 // The interrupt is always for the first item of the packet set, reset the buffer
150 KeyIndex_BufferUsed = 0;
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
155 // Interrupts are too slow for the rest of the packet set, poll for the rest
158 // Read the raw packet from the USART
163 hexToStr( keyValue, tmpStr );
164 dPrintStrs( tmpStr, " " );
166 // Process the scancode
167 processKeyValue( keyValue );
169 // Last packet of the set
170 if ( keyValue & 0x80 )
176 // Delay enough so we don't run into the same packet (or the previous buffered packet)
180 sei(); // Re-enable Interrupts
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 )
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 )
202 // We received a Clear code from the 8304, clear the buffer now that we've used it
203 if ( BufferReadyToClear )
205 KeyIndex_BufferUsed = 0;
206 BufferReadyToClear = 0;
210 // Signal that the keys have been properly sent over USB
211 void Scan_finishedWithUSBBuffer( uint8_t sentKeys )
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 )
223 void Scan_unlockKeyboard( void )
229 void Scan_resetKeyboard( void )
231 // Reset command for the 8304
232 scan_sendData( 0x92 );