]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/MBC-55X/scan_loop.c
MBC-55x support virtually complete.
[kiibohd-controller.git] / Scan / MBC-55X / scan_loop.c
1 /* Copyright (C) 2013 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
39 // ----- Macros -----
40
41 // Make sure we haven't overflowed the buffer
42 #define bufferAdd(byte) \
43                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
44                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
45
46
47
48 // ----- Variables -----
49
50 // Buffer used to inform the macro processing module which keys have been detected as pressed
51 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
52 volatile uint8_t KeyIndex_BufferUsed;
53
54
55
56 // ----- Function Declarations -----
57
58 void processKeyValue( uint8_t valueType );
59 void  removeKeyValue( uint8_t keyValue );
60
61
62
63 // ----- Interrupt Functions -----
64
65 // UART Receive Buffer Full Interrupt
66 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
67 ISR(USART1_RX_vect)
68 #elif defined(_mk20dx128_) // ARM
69 void uart0_status_isr(void)
70 #endif
71 {
72         cli(); // Disable Interrupts
73
74         // Variable for UART data read
75         uint8_t keyValue = 0x00;
76
77 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
78         keyValue = UDR1;
79 #elif defined(_mk20dx128_) // ARM
80         // UART0_S1 must be read for the interrupt to be cleared
81         if ( UART0_S1 & UART_S1_RDRF )
82         {
83                 // Only doing single byte FIFO here
84                 keyValue = UART0_D;
85         }
86 #endif
87
88         // Debug
89         char tmpStr[6];
90         hexToStr( keyValue, tmpStr );
91         dPrintStrs( tmpStr, " " ); // Debug
92
93         // Decipher scan value
94         processKeyValue( keyValue );
95
96         sei(); // Re-enable Interrupts
97 }
98
99
100
101 // ----- Functions -----
102
103 // Setup
104 inline void scan_setup()
105 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
106 {
107         // Setup the the USART interface for keyboard data input
108
109         // Setup baud rate - 1205 Baud
110         // 16 MHz / ( 16 * Baud ) = UBRR
111         // Baud: 1205 -> 16 MHz / ( 16 * 1205 ) = 829.8755
112         // Thus baud setting = 830
113         uint16_t baud = 830; // Max setting of 4095
114         UBRR1H = (uint8_t)(baud >> 8);
115         UBRR1L = (uint8_t)baud;
116
117         // Enable the receiver, and RX Complete Interrupt
118         UCSR1B = 0x90;
119
120         // Set frame format: 8 data, 1 stop bit, even parity
121         // Asynchrounous USART mode
122         UCSR1C = 0x26;
123
124         // Reset the keyboard before scanning, we might be in a wierd state
125         scan_resetKeyboard();
126 }
127 #elif defined(_mk20dx128_) // ARM
128 {
129         // Setup the the UART interface for keyboard data input
130         SIM_SCGC4 |= SIM_SCGC4_UART0; // Disable clock gating
131
132         // Pin Setup for UART0
133         PORTB_PCR16 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); // RX Pin
134         PORTB_PCR17 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); // TX Pin
135
136         // Setup baud rate - 1205 Baud
137         // 48 MHz / ( 16 * Baud ) = BDH/L
138         // Baud: 1205 -> 48 MHz / ( 16 * 1205 ) = 2489.6266
139         // Thus baud setting = 2490
140         // NOTE: If finer baud adjustment is needed see UARTx_C4 -> BRFA in the datasheet
141         uint16_t baud = 2490; // Max setting of 8191
142         UART0_BDH = (uint8_t)(baud >> 8);
143         UART0_BDL = (uint8_t)baud;
144
145         // 8 bit, Even Parity, Idle Character bit after stop
146         // NOTE: For 8 bit with Parity you must enable 9 bit transmission (pg. 1065)
147         //       You only need to use UART0_D for 8 bit reading/writing though
148         // UART_C1_M UART_C1_PE UART_C1_PT UART_C1_ILT
149         UART0_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT;
150
151         // Number of bytes in FIFO before TX Interrupt
152         UART0_TWFIFO = 1;
153
154         // Number of bytes in FIFO before RX Interrupt
155         UART0_RWFIFO = 1;
156
157         // TX FIFO Disabled, TX FIFO Size 1 (Max 8 datawords), RX FIFO Enabled, RX FIFO Size 1 (Max 8 datawords)
158         // TX/RX FIFO Size:
159         //  0x0 - 1 dataword
160         //  0x1 - 4 dataword
161         //  0x2 - 8 dataword
162         //UART0_PFIFO = UART_PFIFO_TXFE | /*TXFIFOSIZE*/ (0x0 << 4) | UART_PFIFO_RXFE | /*RXFIFOSIZE*/ (0x0);
163
164         // Reciever Inversion Disabled, LSBF
165         // UART_S2_RXINV UART_S2_MSBF
166         UART0_S2 |= 0x00;
167
168         // Transmit Inversion Disabled
169         // UART_C3_TXINV
170         UART0_C3 |= 0x00;
171
172         // TX Disabled, RX Enabled, RX Interrupt Enabled
173         // UART_C2_TE UART_C2_RE UART_C2_RIE
174         UART0_C2 = UART_C2_RE | UART_C2_RIE;
175
176         // Add interrupt to the vector table
177         NVIC_ENABLE_IRQ( IRQ_UART0_STATUS );
178
179         // Reset the keyboard before scanning, we might be in a wierd state
180         scan_resetKeyboard();
181 }
182 #endif
183
184
185 // Main Detection Loop
186 inline uint8_t scan_loop()
187 {
188         return 0;
189 }
190
191 void processKeyValue( uint8_t keyValue )
192 {
193         // XXX NOTE: The key processing is not complete for this keyboard
194         //           Mostly due to laziness, and that the keyboard can't really be useful on a modern computer
195         //           Basic typing will work, but some of the keys and the Graph mode changes things around
196
197         // Add key(s) to processing buffer
198         // First split out Shift and Ctrl
199         //  Reserved Codes:
200         //   Shift - 0xF5
201         //   Ctrl  - 0xF6
202         switch ( keyValue )
203         {
204         // - Ctrl Keys -
205         // Exception keys
206         case 0x08: // ^H
207         case 0x09: // ^I
208         case 0x0D: // ^M
209         case 0x1B: // ^[
210                 bufferAdd( keyValue );
211                 break;
212         // 0x40 Offset Keys
213         // Add Ctrl key and offset to the lower alphabet
214         case 0x00: // ^@
215         case 0x1C: // "^\"
216         case 0x1D: // ^]
217         case 0x1E: // ^^
218         case 0x1F: // ^_
219                 bufferAdd( 0xF6 );
220                 bufferAdd( keyValue + 0x40 );
221                 break;
222
223         // - Add Shift key and offset to non-shifted key -
224         // 0x10 Offset Keys
225         case 0x21: // !
226         case 0x23: // #
227         case 0x24: // $
228         case 0x25: // %
229                 bufferAdd( 0xF5 );
230                 bufferAdd( keyValue + 0x10 );
231                 break;
232         // 0x11 Offset Keys
233         case 0x26: // &
234         case 0x28: // (
235                 bufferAdd( 0xF5 );
236                 bufferAdd( keyValue + 0x11 );
237                 break;
238         // 0x07 Offset Keys
239         case 0x29: // )
240                 bufferAdd( 0xF5 );
241                 bufferAdd( keyValue + 0x07 );
242                 break;
243         // -0x0E Offset Keys
244         case 0x40: // @
245                 bufferAdd( 0xF5 );
246                 bufferAdd( keyValue - 0x0E );
247                 break;
248         // 0x0E Offset Keys
249         case 0x2A: // *
250                 bufferAdd( 0xF5 );
251                 bufferAdd( keyValue + 0x0E );
252                 break;
253         // 0x12 Offset Keys
254         case 0x2B: // +
255                 bufferAdd( 0xF5 );
256                 bufferAdd( keyValue + 0x12 );
257                 break;
258         // 0x05 Offset Keys
259         case 0x22: // "
260                 bufferAdd( 0xF5 );
261                 bufferAdd( keyValue + 0x05 );
262                 break;
263         // 0x01 Offset Keys
264         case 0x3A: // :
265                 bufferAdd( 0xF5 );
266                 bufferAdd( keyValue + 0x01 );
267                 break;
268         // -0x10 Offset Keys
269         case 0x3C: // <
270         case 0x3E: // >
271         case 0x3F: // ?
272                 bufferAdd( 0xF5 );
273                 bufferAdd( keyValue - 0x10 );
274                 break;
275         // -0x28 Offset Keys
276         case 0x5E: // ^
277                 bufferAdd( 0xF5 );
278                 bufferAdd( keyValue - 0x28 );
279                 break;
280         // -0x32 Offset Keys
281         case 0x5F: // _
282                 bufferAdd( 0xF5 );
283                 bufferAdd( keyValue - 0x32 );
284                 break;
285         // -0x20 Offset Keys
286         case 0x7B: // {
287         case 0x7C: // |
288         case 0x7D: // }
289                 bufferAdd( 0xF5 );
290                 bufferAdd( keyValue - 0x20 );
291                 break;
292         // -0x1E Offset Keys
293         case 0x7E: // ~
294                 bufferAdd( 0xF5 );
295                 bufferAdd( keyValue - 0x1E );
296                 break;
297         // All other keys
298         default:
299                 // Ctrl Characters are from 0x00 to 0x1F, excluding:
300                 //  0x08 - Backspace
301                 //  0x09 - [Horizontal] Tab
302                 //  0x0D - [Carriage] Return
303                 //  0x1B - Escape
304                 //  0x7F - Delete (^?) (Doesn't need to be split out)
305
306                 // 0x60 Offset Keys
307                 // Add Ctrl key and offset to the lower alphabet
308                 if ( keyValue >= 0x00 && keyValue <= 0x1F )
309                 {
310                         bufferAdd( 0xF6 );
311                         bufferAdd( keyValue + 0x60 );
312                 }
313
314                 // Shift Characters are from 0x41 to 0x59
315                 //  No exceptions here :D
316                 // Add Shift key and offset to the lower alphabet
317                 else if ( keyValue >= 0x41 && keyValue <= 0x5A )
318                 {
319                         bufferAdd( 0xF5 );
320                         bufferAdd( keyValue + 0x20 );
321                 }
322
323                 // Everything else
324                 else
325                 {
326                         bufferAdd( keyValue );
327                 }
328                 break;
329         }
330 }
331
332 // Send data
333 // NOTE: Example only, MBC-55X cannot receive user data
334 uint8_t scan_sendData( uint8_t dataPayload )
335 {
336         // Debug
337         char tmpStr[6];
338         hexToStr( dataPayload, tmpStr );
339         info_dPrint( "Sending - ", tmpStr );
340
341 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
342         UDR1 = dataPayload;
343 #elif defined(_mk20dx128_) // ARM
344         UART0_D = dataPayload;
345 #endif
346
347         return 0;
348 }
349
350 // Signal KeyIndex_Buffer that it has been properly read
351 void scan_finishedWithBuffer( uint8_t sentKeys )
352 {
353 }
354
355 // Signal that the keys have been properly sent over USB
356 void scan_finishedWithUSBBuffer( uint8_t sentKeys )
357 {
358         cli(); // Disable Interrupts
359
360         // Reset the buffer counter
361         KeyIndex_BufferUsed = 0;
362
363         sei(); // Re-enable Interrupts
364 }
365
366 // Reset/Hold keyboard
367 // NOTE: Does nothing with the MBC-55x
368 void scan_lockKeyboard( void )
369 {
370 }
371
372 // NOTE: Does nothing with the MBC-55x
373 void scan_unlockKeyboard( void )
374 {
375 }
376
377 // Reset Keyboard
378 void scan_resetKeyboard( void )
379 {
380         // Not a calculated valued...
381         _delay_ms( 50 );
382
383         KeyIndex_BufferUsed = 0;
384 }
385