]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/SonyNEWS/scan_loop.c
Final SonyNEWS commit before sending device back
[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 SPKR_PORT PORTD
42 #define SPKR_DDR   DDRD
43 #define SPKR_POS      1
44
45 #define POWR_PORT PORTC
46 #define POWR_DDR   DDRC
47 #define POWR_POS      7
48
49
50
51 // ----- Macros -----
52
53 // Make sure we haven't overflowed the buffer
54 #define bufferAdd(byte) \
55                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
56                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
57
58
59
60 // ----- Variables -----
61
62 // Buffer used to inform the macro processing module which keys have been detected as pressed
63 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
64 volatile uint8_t KeyIndex_BufferUsed;
65
66
67
68 // ----- Functions -----
69
70 // Setup
71 inline void scan_setup()
72 {
73         // Setup the the USART interface for keyboard data input
74         
75         // Setup baud rate
76         // 16 MHz / ( 16 * Baud ) = UBRR
77         // Baud <- 0.10450 ms per bit, thus 1000 / 0.10450 = 9569.4
78         // Thus UBRR = 104.50
79         // To deal with the 0.5, setting to double speed, which means UBRR = 209
80         uint16_t baud = 209; // Max setting of 4095
81         UBRR1H = (uint8_t)(baud >> 8);
82         UBRR1L = (uint8_t)baud;
83
84         // Enable Double Read Speed
85         UCSR1A = 0x02;
86
87         // Enable the receiver, transitter, and RX Complete Interrupt
88         UCSR1B = 0x98;
89
90         // Set frame format: 8 data, no stop bits or parity
91         // Asynchrounous USART mode
92         UCSR1C = 0x06;
93
94         // Set Speaker Pin to Pull-Up gives a low-volume click (XXX no other setting does, why?)
95         SPKR_DDR  &= ~(1 << SPKR_POS);
96         SPKR_PORT |= (1 << SPKR_POS);
97
98         // Set Power Pin (I've traced this back to the "Power On" Switch, but I don't really know what it's for)
99         // 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
100         // XXX Currently not used by the controller
101         POWR_DDR  &= ~(1 << POWR_POS);
102         POWR_PORT |= (1 << POWR_POS); 
103
104         // Reset the keyboard before scanning, we might be in a wierd state
105         scan_resetKeyboard();
106 }
107
108 // Main Detection Loop
109 // Not needed for the Sony NEWS, this is just a busy loop
110 inline uint8_t scan_loop()
111 {
112         return 0;
113 }
114
115 void processKeyValue( uint8_t keyValue )
116 {
117         // Detect release condition
118         uint8_t release = keyValue & 0x80;
119
120         // Finalize output buffer
121         // Mask 8th bit
122         keyValue &= 0x7F;
123
124         // Key Release
125         if ( release )
126         {
127                 // Check for the released key, and shift the other keys lower on the buffer
128                 uint8_t c;
129                 for ( c = 0; c < KeyIndex_BufferUsed; c++ )
130                 {
131                         // Key to release found
132                         if ( KeyIndex_Buffer[c] == keyValue )
133                         {
134                                 // Shift keys from c position
135                                 for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
136                                         KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
137
138                                 // Decrement Buffer
139                                 KeyIndex_BufferUsed--;
140
141                                 break;
142                         }
143                 }
144
145                 // Error case (no key to release)
146                 if ( c == KeyIndex_BufferUsed + 1 )
147                 {
148                         errorLED( 1 );
149                         char tmpStr[6];
150                         hexToStr( keyValue, tmpStr );
151                         erro_dPrint( "Could not find key to release: ", tmpStr );
152                 }
153         }
154         // Press or Repeated Key
155         else
156         {
157                 // Make sure the key isn't already in the buffer
158                 for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
159                 {
160                         // Key isn't in the buffer yet
161                         if ( c == KeyIndex_BufferUsed )
162                         {
163                                 bufferAdd( keyValue );
164                                 break;
165                         }
166
167                         // Key already in the buffer
168                         if ( KeyIndex_Buffer[c] == keyValue )
169                                 break;
170                 }
171         }
172 }
173
174 // USART Receive Buffer Full Interrupt
175 ISR(USART1_RX_vect)
176 {
177         cli(); // Disable Interrupts
178
179         uint8_t keyValue = 0x00;
180
181         // One scancode at a time (fastest interval ~3.95 ms - recorded, should still be ok for interrupt polling)
182         // Read the raw packet from the USART
183         keyValue = UDR1;
184
185         // Debug
186         char tmpStr[6];
187         hexToStr( keyValue, tmpStr );
188         dPrintStrs( tmpStr, " " );
189
190         // Process the scancode
191         if ( keyValue != 0x00 )
192                 processKeyValue( keyValue );
193
194         sei(); // Re-enable Interrupts
195 }
196
197 // Send data to keyboard
198 uint8_t scan_sendData( uint8_t dataPayload )
199 {
200         // Debug
201         char tmpStr[6];
202         hexToStr( dataPayload, tmpStr );
203         info_dPrint( tmpStr, " " );
204
205         UDR1 = dataPayload;
206         return 0;
207 }
208
209 // Signal KeyIndex_Buffer that it has been properly read
210 // Not needed as a signal is sent to remove key-presses
211 void scan_finishedWithBuffer( void )
212 {
213         return;
214 }
215
216 // Reset/Hold keyboard TODO
217 // Warning! This will cause the keyboard to not send any data, so you can't disable with a keypress
218 void scan_lockKeyboard( void )
219 {
220 }
221
222 void scan_unlockKeyboard( void )
223 {
224 }
225
226 // Reset Keyboard
227 void scan_resetKeyboard( void )
228 {
229         // Empty buffer, now that keyboard has been reset
230         KeyIndex_BufferUsed = 0;
231 }
232
233 void scan_finishedWithUSBBuffer( void )
234 {
235         return;
236 }
237