]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/SonyNEWS/scan_loop.c
Small macro update for debugging the Sony NEWS
[kiibohd-controller.git] / Scan / SonyNEWS / scan_loop.c
1 /* Copyright (C) 2011 by Jacob Alexander
2  * 
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:
9  * 
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  * 
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
19  * THE SOFTWARE.
20  */
21
22 // ----- Includes -----
23
24 // AVR Includes
25 #include <avr/interrupt.h>
26 #include <avr/io.h>
27 #include <util/delay.h>
28
29 // Project Includes
30 #include <led.h>
31 #include <print.h>
32
33 // Local Includes
34 #include "scan_loop.h"
35
36
37
38 // ----- Defines -----
39
40 // Pinout Defines
41 #define RESET_PORT PORTB
42 #define RESET_DDR   DDRD
43 #define RESET_PIN      0
44
45
46 // ----- Macros -----
47
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
52
53 #define UNSET_RESET()   RESET_DDR &= ~(1 << RESET_PIN)
54 #define   SET_RESET()   RESET_DDR |=  (1 << RESET_PIN)
55
56
57
58 // ----- Variables -----
59
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;
63
64
65
66 // ----- Functions -----
67
68 // Setup
69 inline void scan_setup()
70 {
71         // Setup the the USART interface for keyboard data input
72         
73         // Setup baud rate
74         // 16 MHz / ( 16 * Baud ) = UBRR
75         // Baud <- 0.10450 ms per bit, thus 1000 / 0.10450 = 9569.4
76         // Thus UBRR = 104.50
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;
81
82         // Enable Double Read Speed
83         UCSR1A = 0x02;
84
85         // Enable the receiver, transitter, and RX Complete Interrupt
86         UCSR1B = 0x98;
87
88         // Set frame format: 8 data, no stop bits or parity
89         // Asynchrounous USART mode
90         UCSR1C = 0x06;
91
92         // Reset the keyboard before scanning, we might be in a wierd state
93         scan_resetKeyboard();
94 }
95
96
97 // Main Detection Loop
98 // Not needed for the Sony NEWS, this is just a busy loop
99 inline uint8_t scan_loop()
100 {
101         return 0;
102 }
103
104 void processKeyValue( uint8_t keyValue )
105 {
106         // Detect release condition
107         uint8_t release = keyValue & 0x80;
108
109         // Finalize output buffer
110         // Mask 8th bit
111         keyValue &= 0x7F;
112
113         // Key Release
114         if ( release )
115         {
116                 // Check for the released key, and shift the other keys lower on the buffer
117                 uint8_t c;
118                 for ( c = 0; c < KeyIndex_BufferUsed; c++ )
119                 {
120                         // Key to release found
121                         if ( KeyIndex_Buffer[c] == keyValue )
122                         {
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];
126
127                                 // Decrement Buffer
128                                 KeyIndex_BufferUsed--;
129
130                                 break;
131                         }
132                 }
133
134                 // Error case (no key to release)
135                 if ( c == KeyIndex_BufferUsed + 1 )
136                 {
137                         errorLED( 1 );
138                         char tmpStr[6];
139                         hexToStr( keyValue, tmpStr );
140                         erro_dPrint( "Could not find key to release: ", tmpStr );
141                 }
142         }
143         // Press or Repeat Rate
144         else
145         {
146                 // Make sure the key isn't already in the buffer
147                 for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
148                 {
149                         // Key isn't in the buffer yet
150                         if ( c == KeyIndex_BufferUsed )
151                         {
152                                 bufferAdd( keyValue );
153                                 break;
154                         }
155
156                         // Key already in the buffer
157                         if ( KeyIndex_Buffer[c] == keyValue )
158                                 break;
159                 }
160         }
161 }
162
163 // USART Receive Buffer Full Interrupt
164 ISR(USART1_RX_vect)
165 {
166         cli(); // Disable Interrupts
167
168         uint8_t keyValue = 0x00;
169
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
172         keyValue = UDR1;
173
174         // Debug
175         char tmpStr[6];
176         hexToStr( keyValue, tmpStr );
177         dPrintStrs( tmpStr, " " );
178
179         // Process the scancode
180         if ( keyValue != 0x00 )
181         processKeyValue( keyValue );
182
183         sei(); // Re-enable Interrupts
184 }
185
186 // Send data TODO
187 //
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 )
196 {
197         // Debug
198         char tmpStr[6];
199         hexToStr( dataPayload, tmpStr );
200         info_dPrint( tmpStr, " " );
201
202         UDR1 = dataPayload;
203         return 0;
204 }
205
206 // Signal KeyIndex_Buffer that it has been properly read
207 // Not needed as a signal is sent to remove key-presses
208 void scan_finishedWithBuffer( void )
209 {
210         return;
211 }
212
213 // Reset/Hold keyboard TODO
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 )
217 {
218         //UNSET_RESET();
219 }
220
221 void scan_unlockKeyboard( void )
222 {
223         //SET_RESET();
224 }
225
226 // Reset Keyboard TODO
227 void scan_resetKeyboard( void )
228 {
229         // Reset command for the 8304
230         //scan_sendData( 0x92 );
231
232         // Empty buffer, now that keyboard has been reset
233         KeyIndex_BufferUsed = 0;
234 }
235