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>
33 #include "scan_loop.h"
37 // ----- Defines -----
44 // ----- Variables -----
46 // Buffer used to inform the macro processing module which keys have been detected as pressed
47 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
48 volatile uint8_t KeyIndex_BufferUsed;
52 // ----- Function Declarations -----
54 void processKeyValue( uint8_t valueType );
55 void removeKeyValue( uint8_t keyValue );
59 // ----- Interrupt Functions -----
61 // UART Receive Buffer Full Interrupt
62 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
64 #elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM
65 void uart0_status_isr(void)
68 cli(); // Disable Interrupts
70 // Variable for UART data read
71 uint8_t keyValue = 0x00;
73 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
75 #elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM
76 // UART0_S1 must be read for the interrupt to be cleared
77 if ( UART0_S1 & UART_S1_RDRF )
79 // Only doing single byte FIFO here
86 hexToStr( keyValue, tmpStr );
87 dPrintStrs( tmpStr, " " ); // Debug
89 // Decipher scan value
90 processKeyValue( keyValue );
92 sei(); // Re-enable Interrupts
97 // ----- Functions -----
100 void Scan_resetKeyboard( void )
102 // Not a calculated valued...
105 KeyIndex_BufferUsed = 0;
109 inline void Scan_setup()
110 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
112 // Setup the the USART interface for keyboard data input
114 // Setup baud rate - 1205 Baud
115 // 16 MHz / ( 16 * Baud ) = UBRR
116 // Baud: 1205 -> 16 MHz / ( 16 * 1205 ) = 829.8755
117 // Thus baud setting = 830
118 uint16_t baud = 830; // Max setting of 4095
119 UBRR1H = (uint8_t)(baud >> 8);
120 UBRR1L = (uint8_t)baud;
122 // Enable the receiver, and RX Complete Interrupt
125 // Set frame format: 8 data, 1 stop bit, even parity
126 // Asynchrounous USART mode
129 // Reset the keyboard before scanning, we might be in a wierd state
130 Scan_resetKeyboard();
132 #elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM
134 // Setup the the UART interface for keyboard data input
135 SIM_SCGC4 |= SIM_SCGC4_UART0; // Disable clock gating
137 // Pin Setup for UART0
138 PORTB_PCR16 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); // RX Pin
139 PORTB_PCR17 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); // TX Pin
141 // Setup baud rate - 1205 Baud
142 // 48 MHz / ( 16 * Baud ) = BDH/L
143 // Baud: 1205 -> 48 MHz / ( 16 * 1205 ) = 2489.6266
144 // Thus baud setting = 2490
145 // NOTE: If finer baud adjustment is needed see UARTx_C4 -> BRFA in the datasheet
146 uint16_t baud = 2490; // Max setting of 8191
147 UART0_BDH = (uint8_t)(baud >> 8);
148 UART0_BDL = (uint8_t)baud;
150 // 8 bit, Even Parity, Idle Character bit after stop
151 // NOTE: For 8 bit with Parity you must enable 9 bit transmission (pg. 1065)
152 // You only need to use UART0_D for 8 bit reading/writing though
153 // UART_C1_M UART_C1_PE UART_C1_PT UART_C1_ILT
154 UART0_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT;
156 // Number of bytes in FIFO before TX Interrupt
159 // Number of bytes in FIFO before RX Interrupt
162 // TX FIFO Disabled, TX FIFO Size 1 (Max 8 datawords), RX FIFO Enabled, RX FIFO Size 1 (Max 8 datawords)
167 //UART0_PFIFO = UART_PFIFO_TXFE | /*TXFIFOSIZE*/ (0x0 << 4) | UART_PFIFO_RXFE | /*RXFIFOSIZE*/ (0x0);
169 // Reciever Inversion Disabled, LSBF
170 // UART_S2_RXINV UART_S2_MSBF
173 // Transmit Inversion Disabled
177 // TX Disabled, RX Enabled, RX Interrupt Enabled
178 // UART_C2_TE UART_C2_RE UART_C2_RIE
179 UART0_C2 = UART_C2_RE | UART_C2_RIE;
181 // Add interrupt to the vector table
182 NVIC_ENABLE_IRQ( IRQ_UART0_STATUS );
184 // Reset the keyboard before scanning, we might be in a wierd state
185 Scan_resetKeyboard();
190 // Main Detection Loop
191 inline uint8_t Scan_loop()
196 void processKeyValue( uint8_t keyValue )
198 // XXX NOTE: The key processing is not complete for this keyboard
199 // Mostly due to laziness, and that the keyboard can't really be useful on a modern computer
200 // Basic typing will work, but some of the keys and the Graph mode changes things around
202 // Add key(s) to processing buffer
203 // First split out Shift and Ctrl
215 Macro_bufferAdd( keyValue );
218 // Add Ctrl key and offset to the lower alphabet
224 Macro_bufferAdd( 0xF6 );
225 Macro_bufferAdd( keyValue + 0x40 );
228 // - Add Shift key and offset to non-shifted key -
234 Macro_bufferAdd( 0xF5 );
235 Macro_bufferAdd( keyValue + 0x10 );
240 Macro_bufferAdd( 0xF5 );
241 Macro_bufferAdd( keyValue + 0x11 );
245 Macro_bufferAdd( 0xF5 );
246 Macro_bufferAdd( keyValue + 0x07 );
250 Macro_bufferAdd( 0xF5 );
251 Macro_bufferAdd( keyValue - 0x0E );
255 Macro_bufferAdd( 0xF5 );
256 Macro_bufferAdd( keyValue + 0x0E );
260 Macro_bufferAdd( 0xF5 );
261 Macro_bufferAdd( keyValue + 0x12 );
265 Macro_bufferAdd( 0xF5 );
266 Macro_bufferAdd( keyValue + 0x05 );
270 Macro_bufferAdd( 0xF5 );
271 Macro_bufferAdd( keyValue + 0x01 );
277 Macro_bufferAdd( 0xF5 );
278 Macro_bufferAdd( keyValue - 0x10 );
282 Macro_bufferAdd( 0xF5 );
283 Macro_bufferAdd( keyValue - 0x28 );
287 Macro_bufferAdd( 0xF5 );
288 Macro_bufferAdd( keyValue - 0x32 );
294 Macro_bufferAdd( 0xF5 );
295 Macro_bufferAdd( keyValue - 0x20 );
299 Macro_bufferAdd( 0xF5 );
300 Macro_bufferAdd( keyValue - 0x1E );
304 // Ctrl Characters are from 0x00 to 0x1F, excluding:
306 // 0x09 - [Horizontal] Tab
307 // 0x0D - [Carriage] Return
309 // 0x7F - Delete (^?) (Doesn't need to be split out)
312 // Add Ctrl key and offset to the lower alphabet
313 if ( keyValue >= 0x00 && keyValue <= 0x1F )
315 Macro_bufferAdd( 0xF6 );
316 Macro_bufferAdd( keyValue + 0x60 );
319 // Shift Characters are from 0x41 to 0x59
320 // No exceptions here :D
321 // Add Shift key and offset to the lower alphabet
322 else if ( keyValue >= 0x41 && keyValue <= 0x5A )
324 Macro_bufferAdd( 0xF5 );
325 Macro_bufferAdd( keyValue + 0x20 );
331 Macro_bufferAdd( keyValue );
338 // NOTE: Example only, MBC-55X cannot receive user data
339 uint8_t Scan_sendData( uint8_t dataPayload )
343 hexToStr( dataPayload, tmpStr );
344 info_dPrint( "Sending - ", tmpStr );
346 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
348 #elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM
349 UART0_D = dataPayload;
355 // Signal KeyIndex_Buffer that it has been properly read
356 void Scan_finishedWithBuffer( uint8_t sentKeys )
360 // Signal that the keys have been properly sent over USB
361 void Scan_finishedWithUSBBuffer( uint8_t sentKeys )
363 cli(); // Disable Interrupts
365 // Reset the buffer counter
366 KeyIndex_BufferUsed = 0;
368 sei(); // Re-enable Interrupts
371 // Reset/Hold keyboard
372 // NOTE: Does nothing with the MBC-55x
373 void Scan_lockKeyboard( void )
377 // NOTE: Does nothing with the MBC-55x
378 void Scan_unlockKeyboard( void )