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