1 /* Copyright (C) 2012 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 HOLD_PORT PORTD
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
55 // ----- Variables -----
57 // Buffer used to inform the macro processing module which keys have been detected as pressed
58 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
59 volatile uint8_t KeyIndex_BufferUsed;
60 volatile uint8_t KeyIndex_Add_InputSignal; // Used to pass the (click/input value) to the keyboard for the clicker
64 volatile uint8_t BufferReadyToClear;
68 // ----- Function Declarations -----
70 void processKeyValue( uint8_t keyValue );
71 void removeKeyValue( uint8_t keyValue );
75 // ----- Interrupt Functions -----
77 // USART Receive Buffer Full Interrupt
80 cli(); // Disable Interrupts
82 uint8_t keyValue = 0x00;
83 uint8_t keyState = 0x00;
85 // Read the scancode packet from the USART (1st to 8th bits)
88 // Read the release/press bit (9th bit) XXX Unnecessary, and wrong it seems, parity bit? or something else?
89 keyState = UCSR1B & 0x02;
91 // High bit of keyValue, also represents press/release
92 keyState = keyValue & 0x80 ? 0x00 : 0x02;
96 hexToStr( keyValue & 0x7F, tmpStr );
98 // Process the scancode
101 case 0x00: // Released
102 dPrintStrs( tmpStr, "R " ); // Debug
104 // Remove key from press buffer
105 removeKeyValue( keyValue & 0x7F );
108 case 0x02: // Pressed
109 dPrintStrs( tmpStr, "P " ); // Debug
111 // New key to process
112 processKeyValue( keyValue & 0x7F );
116 sei(); // Re-enable Interrupts
121 // ----- Functions -----
124 inline void scan_setup()
126 // Setup the the USART interface for keyboard data input
127 // NOTE: The input data signal needs to be inverted for the Teensy USART to properly work
130 // 16 MHz / ( 16 * Baud ) = UBRR
131 // Baud <- 0.823284 ms per bit, thus 1000 / 0.823284 = 1214.65004 -> 823.2824
132 // Thus baud setting = 823
133 uint16_t baud = 823; // Max setting of 4095
134 UBRR1H = (uint8_t)(baud >> 8);
135 UBRR1L = (uint8_t)baud;
137 // Enable the receiver, and RX Complete Interrupt as well as 9 bit data
140 // The transmitter is only to be enabled when needed
141 // Set the pin to be pull-up otherwise (use the lowered voltage inverter in order to sink)
142 HOLD_DDR &= ~(1 << HOLD_PIN);
143 HOLD_PORT |= (1 << HOLD_PIN);
145 // Set frame format: 9 data, 1 stop bit, no parity
146 // Asynchrounous USART mode
149 // Initially buffer doesn't need to be cleared (it's empty...)
150 BufferReadyToClear = 0;
152 // InputSignal is off by default
153 KeyIndex_Add_InputSignal = 0x00;
155 // Reset the keyboard before scanning, we might be in a wierd state
156 scan_resetKeyboard();
160 // Main Detection Loop
161 // Not needed for the BETKB, this is just a busy loop
162 inline uint8_t scan_loop()
167 void processKeyValue( uint8_t keyValue )
169 // Interpret scan code
172 case 0x00: // Break code from input?
175 // Make sure the key isn't already in the buffer
176 for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
178 // Key isn't in the buffer yet
179 if ( c == KeyIndex_BufferUsed )
181 bufferAdd( keyValue );
183 // Only send data if enabled
184 if ( KeyIndex_Add_InputSignal )
185 scan_sendData( KeyIndex_Add_InputSignal );
189 // Key already in the buffer
190 if ( KeyIndex_Buffer[c] == keyValue )
197 void removeKeyValue( uint8_t keyValue )
199 // Check for the released key, and shift the other keys lower on the buffer
201 for ( c = 0; c < KeyIndex_BufferUsed; c++ )
203 // Key to release found
204 if ( KeyIndex_Buffer[c] == keyValue )
206 // Shift keys from c position
207 for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
208 KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
211 KeyIndex_BufferUsed--;
217 // Error case (no key to release)
218 if ( c == KeyIndex_BufferUsed + 1 )
222 hexToStr( keyValue, tmpStr );
223 erro_dPrint( "Could not find key to release: ", tmpStr );
228 uint8_t scan_sendData( uint8_t dataPayload )
230 // Enable the USART Transmitter
235 hexToStr( dataPayload, tmpStr );
236 info_dPrint( "Sending - ", tmpStr );
240 // Wait for the payload
243 // Disable the USART Transmitter
249 // Signal KeyIndex_Buffer that it has been properly read
250 void scan_finishedWithBuffer( uint8_t sentKeys )
254 // Signal that the keys have been properly sent over USB
255 void scan_finishedWithUSBBuffer( uint8_t sentKeys )
259 // Reset/Hold keyboard
260 // NOTE: Does nothing with the BETKB
261 void scan_lockKeyboard( void )
265 // NOTE: Does nothing with the BETKB
266 void scan_unlockKeyboard( void )
271 void scan_resetKeyboard( void )
273 // Not a calculated valued...