]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/SonyNEWS/scan_loop.c
f2bd40db7ddf565301ad1fa91cb2e79ae774c8d1
[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 // Compiler Includes
25 #include <Lib/ScanLib.h>
26
27 // Project Includes
28 #include <led.h>
29 #include <print.h>
30
31 // Local Includes
32 #include "scan_loop.h"
33
34
35
36 // ----- Defines -----
37
38 // Pinout Defines
39 #define SPKR_PORT PORTD
40 #define SPKR_DDR   DDRD
41 #define SPKR_POS      1
42
43 #define POWR_PORT PORTC
44 #define POWR_DDR   DDRC
45 #define POWR_POS      7
46
47
48
49 // ----- Macros -----
50
51 // Make sure we haven't overflowed the buffer
52 #define bufferAdd(byte) \
53                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
54                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
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         // Set Speaker Pin to Pull-Up gives a low-volume click (XXX no other setting does, why?)
93         SPKR_DDR  &= ~(1 << SPKR_POS);
94         SPKR_PORT |= (1 << SPKR_POS);
95
96         // Set Power Pin (I've traced this back to the "Power On" Switch, but I don't really know what it's for)
97         // Configured as a Pull-up Input - This pin "can" be read as well, it will go to GND when the "Power On" switch is pressed, and will read ~5V otherwise
98         // XXX Currently not used by the controller
99         POWR_DDR  &= ~(1 << POWR_POS);
100         POWR_PORT |= (1 << POWR_POS); 
101
102         // Reset the keyboard before scanning, we might be in a wierd state
103         scan_resetKeyboard();
104 }
105
106 // Main Detection Loop
107 // Not needed for the Sony NEWS, this is just a busy loop
108 inline uint8_t scan_loop()
109 {
110         return 0;
111 }
112
113 void processKeyValue( uint8_t keyValue )
114 {
115         // Detect release condition
116         uint8_t release = keyValue & 0x80;
117
118         // Finalize output buffer
119         // Mask 8th bit
120         keyValue &= 0x7F;
121
122         // Key Release
123         if ( release )
124         {
125                 // Check for the released key, and shift the other keys lower on the buffer
126                 uint8_t c;
127                 for ( c = 0; c < KeyIndex_BufferUsed; c++ )
128                 {
129                         // Key to release found
130                         if ( KeyIndex_Buffer[c] == keyValue )
131                         {
132                                 // Shift keys from c position
133                                 for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
134                                         KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
135
136                                 // Decrement Buffer
137                                 KeyIndex_BufferUsed--;
138
139                                 break;
140                         }
141                 }
142
143                 // Error case (no key to release)
144                 if ( c == KeyIndex_BufferUsed + 1 )
145                 {
146                         errorLED( 1 );
147                         char tmpStr[6];
148                         hexToStr( keyValue, tmpStr );
149                         erro_dPrint( "Could not find key to release: ", tmpStr );
150                 }
151         }
152         // Press or Repeated Key
153         else
154         {
155                 // Make sure the key isn't already in the buffer
156                 for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
157                 {
158                         // Key isn't in the buffer yet
159                         if ( c == KeyIndex_BufferUsed )
160                         {
161                                 bufferAdd( keyValue );
162                                 break;
163                         }
164
165                         // Key already in the buffer
166                         if ( KeyIndex_Buffer[c] == keyValue )
167                                 break;
168                 }
169         }
170 }
171
172 // USART Receive Buffer Full Interrupt
173 ISR(USART1_RX_vect)
174 {
175         cli(); // Disable Interrupts
176
177         uint8_t keyValue = 0x00;
178
179         // One scancode at a time (fastest interval ~3.95 ms - recorded, should still be ok for interrupt polling)
180         // Read the raw packet from the USART
181         keyValue = UDR1;
182
183         // Debug
184         char tmpStr[6];
185         hexToStr( keyValue, tmpStr );
186         dPrintStrs( tmpStr, " " );
187
188         // Process the scancode
189         if ( keyValue != 0x00 )
190                 processKeyValue( keyValue );
191
192         sei(); // Re-enable Interrupts
193 }
194
195 // Send data to keyboard
196 uint8_t scan_sendData( uint8_t dataPayload )
197 {
198         // Debug
199         char tmpStr[6];
200         hexToStr( dataPayload, tmpStr );
201         info_dPrint( tmpStr, " " );
202
203         UDR1 = dataPayload;
204         return 0;
205 }
206
207 // Signal KeyIndex_Buffer that it has been properly read
208 // Not needed as a signal is sent to remove key-presses
209 void scan_finishedWithBuffer( uint8_t sentKeys )
210 {
211         return;
212 }
213
214 // Reset/Hold keyboard TODO
215 // Warning! This will cause the keyboard to not send any data, so you can't disable with a keypress
216 void scan_lockKeyboard( void )
217 {
218 }
219
220 void scan_unlockKeyboard( void )
221 {
222 }
223
224 // Reset Keyboard
225 void scan_resetKeyboard( void )
226 {
227         // Empty buffer, now that keyboard has been reset
228         KeyIndex_BufferUsed = 0;
229 }
230
231 void scan_finishedWithUSBBuffer( uint8_t sentKeys )
232 {
233         return;
234 }
235