1 /* Copyright (C) 2013,2014 by Jacob Alexander
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:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
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
22 // ----- Includes -----
25 #include <Lib/ScanLib.h>
32 #include "scan_loop.h"
36 // ----- Defines -----
43 // ----- Variables -----
45 // Buffer used to inform the macro processing module which keys have been detected as pressed
46 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
47 volatile uint8_t KeyIndex_BufferUsed;
51 // ----- Function Declarations -----
53 void processKeyValue( uint8_t valueType );
54 void removeKeyValue( uint8_t keyValue );
58 // ----- Interrupt Functions -----
60 // UART Receive Buffer Full Interrupt
61 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
63 #elif defined(_mk20dx128_) // ARM
64 void uart0_status_isr(void)
67 cli(); // Disable Interrupts
69 // Variable for UART data read
70 uint8_t keyValue = 0x00;
72 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
74 #elif defined(_mk20dx128_) // ARM
75 // UART0_S1 must be read for the interrupt to be cleared
76 if ( UART0_S1 & UART_S1_RDRF )
78 // Only doing single byte FIFO here
85 hexToStr( keyValue, tmpStr );
86 dPrintStrs( tmpStr, " " ); // Debug
88 // Decipher scan value
89 processKeyValue( keyValue );
91 sei(); // Re-enable Interrupts
96 // ----- Functions -----
99 inline void Scan_setup()
100 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
102 // Setup the the USART interface for keyboard data input
104 // Setup baud rate - 1205 Baud
105 // 16 MHz / ( 16 * Baud ) = UBRR
106 // Baud: 1205 -> 16 MHz / ( 16 * 1205 ) = 829.8755
107 // Thus baud setting = 830
108 uint16_t baud = 830; // Max setting of 4095
109 UBRR1H = (uint8_t)(baud >> 8);
110 UBRR1L = (uint8_t)baud;
112 // Enable the receiver, and RX Complete Interrupt
115 // Set frame format: 8 data, 1 stop bit, even parity
116 // Asynchrounous USART mode
119 // Reset the keyboard before scanning, we might be in a wierd state
120 scan_resetKeyboard();
122 #elif defined(_mk20dx128_) // ARM
124 // Setup the the UART interface for keyboard data input
125 SIM_SCGC4 |= SIM_SCGC4_UART0; // Disable clock gating
127 // Pin Setup for UART0
128 PORTB_PCR16 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); // RX Pin
129 PORTB_PCR17 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); // TX Pin
131 // Setup baud rate - 1205 Baud
132 // 48 MHz / ( 16 * Baud ) = BDH/L
133 // Baud: 1205 -> 48 MHz / ( 16 * 1205 ) = 2489.6266
134 // Thus baud setting = 2490
135 // NOTE: If finer baud adjustment is needed see UARTx_C4 -> BRFA in the datasheet
136 uint16_t baud = 2490; // Max setting of 8191
137 UART0_BDH = (uint8_t)(baud >> 8);
138 UART0_BDL = (uint8_t)baud;
140 // 8 bit, Even Parity, Idle Character bit after stop
141 // NOTE: For 8 bit with Parity you must enable 9 bit transmission (pg. 1065)
142 // You only need to use UART0_D for 8 bit reading/writing though
143 // UART_C1_M UART_C1_PE UART_C1_PT UART_C1_ILT
144 UART0_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT;
146 // Number of bytes in FIFO before TX Interrupt
149 // Number of bytes in FIFO before RX Interrupt
152 // TX FIFO Disabled, TX FIFO Size 1 (Max 8 datawords), RX FIFO Enabled, RX FIFO Size 1 (Max 8 datawords)
157 //UART0_PFIFO = UART_PFIFO_TXFE | /*TXFIFOSIZE*/ (0x0 << 4) | UART_PFIFO_RXFE | /*RXFIFOSIZE*/ (0x0);
159 // Reciever Inversion Disabled, LSBF
160 // UART_S2_RXINV UART_S2_MSBF
163 // Transmit Inversion Disabled
167 // TX Disabled, RX Enabled, RX Interrupt Enabled
168 // UART_C2_TE UART_C2_RE UART_C2_RIE
169 UART0_C2 = UART_C2_RE | UART_C2_RIE;
171 // Add interrupt to the vector table
172 NVIC_ENABLE_IRQ( IRQ_UART0_STATUS );
174 // Reset the keyboard before scanning, we might be in a wierd state
175 scan_resetKeyboard();
180 // Main Detection Loop
181 inline uint8_t Scan_loop()
186 void processKeyValue( uint8_t keyValue )
188 // XXX NOTE: The key processing is not complete for this keyboard
189 // Mostly due to laziness, and that the keyboard can't really be useful on a modern computer
190 // Basic typing will work, but some of the keys and the Graph mode changes things around
192 // Add key(s) to processing buffer
193 // First split out Shift and Ctrl
205 Macro_bufferAdd( keyValue );
208 // Add Ctrl key and offset to the lower alphabet
214 Macro_bufferAdd( 0xF6 );
215 Macro_bufferAdd( keyValue + 0x40 );
218 // - Add Shift key and offset to non-shifted key -
224 Macro_bufferAdd( 0xF5 );
225 Macro_bufferAdd( keyValue + 0x10 );
230 Macro_bufferAdd( 0xF5 );
231 Macro_bufferAdd( keyValue + 0x11 );
235 Macro_bufferAdd( 0xF5 );
236 Macro_bufferAdd( keyValue + 0x07 );
240 Macro_bufferAdd( 0xF5 );
241 Macro_bufferAdd( keyValue - 0x0E );
245 Macro_bufferAdd( 0xF5 );
246 Macro_bufferAdd( keyValue + 0x0E );
250 Macro_bufferAdd( 0xF5 );
251 Macro_bufferAdd( keyValue + 0x12 );
255 Macro_bufferAdd( 0xF5 );
256 Macro_bufferAdd( keyValue + 0x05 );
260 Macro_bufferAdd( 0xF5 );
261 Macro_bufferAdd( keyValue + 0x01 );
267 Macro_bufferAdd( 0xF5 );
268 Macro_bufferAdd( keyValue - 0x10 );
272 Macro_bufferAdd( 0xF5 );
273 Macro_bufferAdd( keyValue - 0x28 );
277 Macro_bufferAdd( 0xF5 );
278 Macro_bufferAdd( keyValue - 0x32 );
284 Macro_bufferAdd( 0xF5 );
285 Macro_bufferAdd( keyValue - 0x20 );
289 Macro_bufferAdd( 0xF5 );
290 Macro_bufferAdd( keyValue - 0x1E );
294 // Ctrl Characters are from 0x00 to 0x1F, excluding:
296 // 0x09 - [Horizontal] Tab
297 // 0x0D - [Carriage] Return
299 // 0x7F - Delete (^?) (Doesn't need to be split out)
302 // Add Ctrl key and offset to the lower alphabet
303 if ( keyValue >= 0x00 && keyValue <= 0x1F )
305 Macro_bufferAdd( 0xF6 );
306 Macro_bufferAdd( keyValue + 0x60 );
309 // Shift Characters are from 0x41 to 0x59
310 // No exceptions here :D
311 // Add Shift key and offset to the lower alphabet
312 else if ( keyValue >= 0x41 && keyValue <= 0x5A )
314 Macro_bufferAdd( 0xF5 );
315 Macro_bufferAdd( keyValue + 0x20 );
321 Macro_bufferAdd( keyValue );
328 // NOTE: Example only, MBC-55X cannot receive user data
329 uint8_t Scan_sendData( uint8_t dataPayload )
333 hexToStr( dataPayload, tmpStr );
334 info_dPrint( "Sending - ", tmpStr );
336 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
338 #elif defined(_mk20dx128_) // ARM
339 UART0_D = dataPayload;
345 // Signal KeyIndex_Buffer that it has been properly read
346 void Scan_finishedWithBuffer( uint8_t sentKeys )
350 // Signal that the keys have been properly sent over USB
351 void Scan_finishedWithUSBBuffer( uint8_t sentKeys )
353 cli(); // Disable Interrupts
355 // Reset the buffer counter
356 KeyIndex_BufferUsed = 0;
358 sei(); // Re-enable Interrupts
361 // Reset/Hold keyboard
362 // NOTE: Does nothing with the MBC-55x
363 void Scan_lockKeyboard( void )
367 // NOTE: Does nothing with the MBC-55x
368 void Scan_unlockKeyboard( void )
373 void Scan_resetKeyboard( void )
375 // Not a calculated valued...
378 KeyIndex_BufferUsed = 0;