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 // ----- Functions -----
69 inline void scan_setup()
71 // Setup the the USART interface for keyboard data input
74 // 16 MHz / ( 16 * Baud ) = UBRR
75 // Baud <- 0.10450 ms per bit, thus 1000 / 0.10450 = 9569.4
77 // To deal with the 0.5, setting to double speed, which means UBRR = 209
78 uint16_t baud = 209; // Max setting of 4095
79 UBRR1H = (uint8_t)(baud >> 8);
80 UBRR1L = (uint8_t)baud;
82 // Enable Double Read Speed
85 // Enable the receiver, transitter, and RX Complete Interrupt
88 // Set frame format: 8 data, no stop bits or parity
89 // Asynchrounous USART mode
92 // Reset the keyboard before scanning, we might be in a wierd state
97 // Main Detection Loop
98 // Not needed for the Sony NEWS, this is just a busy loop
99 inline uint8_t scan_loop()
104 void processKeyValue( uint8_t keyValue )
106 // Detect release condition
107 uint8_t release = keyValue & 0x80;
109 // Finalize output buffer
116 // Check for the released key, and shift the other keys lower on the buffer
118 for ( c = 0; c < KeyIndex_BufferUsed; c++ )
120 // Key to release found
121 if ( KeyIndex_Buffer[c] == keyValue )
123 // Shift keys from c position
124 for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
125 KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
128 KeyIndex_BufferUsed--;
134 // Error case (no key to release)
135 if ( c == KeyIndex_BufferUsed + 1 )
139 hexToStr( keyValue, tmpStr );
140 erro_dPrint( "Could not find key to release: ", tmpStr );
143 // Press or Repeat Rate
146 // Make sure the key isn't already in the buffer
147 for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
149 // Key isn't in the buffer yet
150 if ( c == KeyIndex_BufferUsed )
152 bufferAdd( keyValue );
156 // Key already in the buffer
157 if ( KeyIndex_Buffer[c] == keyValue )
163 // USART Receive Buffer Full Interrupt
166 cli(); // Disable Interrupts
168 uint8_t keyValue = 0x00;
170 // One scancode at a time (fastest interval ~3.95 ms - recorded, should still be ok for interrupt polling)
171 // Read the raw packet from the USART
176 hexToStr( keyValue, tmpStr );
177 dPrintStrs( tmpStr, " " );
179 // Process the scancode
180 processKeyValue( keyValue );
182 sei(); // Re-enable Interrupts
187 // Keyboard Input Guide for Micro Switch 8304
188 // 0xBX is for LED F1,F2,Over Type,Lock
189 // 0xAX is for LED F3,F8,F9,F10
190 // 0x92 resets keyboard (LED off, echo scancode mode off)
191 // 0x9E sets echo scancode mode from (0x81 to 0xFF; translates to 0x01 to 0x7F)
192 // Other echos: 0x15~0x19 send 0x15~0x19, 0x40 sends 0x40 (as well as 0x44,0x45, 0x80)
193 // 0x8C Acks the keyboard and gets 0x70 sent back (delayed)
194 uint8_t scan_sendData( uint8_t dataPayload )
200 // Signal KeyIndex_Buffer that it has been properly read
201 // Not needed as a signal is sent to remove key-presses
202 void scan_finishedWithBuffer( void )
207 // Reset/Hold keyboard TODO
208 // Warning! This will cause the keyboard to not send any data, so you can't disable with a keypress
209 // The Micro Switch 8304 has a dedicated reset line
210 void scan_lockKeyboard( void )
215 void scan_unlockKeyboard( void )
220 // Reset Keyboard TODO
221 void scan_resetKeyboard( void )
223 // Reset command for the 8304
224 //scan_sendData( 0x92 );
226 // Empty buffer, now that keyboard has been reset
227 KeyIndex_BufferUsed = 0;