1 /* Copyright (C) 2013 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 -----
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
48 // ----- Variables -----
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;
56 // ----- Function Declarations -----
58 void processKeyValue( uint8_t valueType );
59 void removeKeyValue( uint8_t keyValue );
63 // ----- Interrupt Functions -----
65 // UART Receive Buffer Full Interrupt
66 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
68 #elif defined(_mk20dx128_) // ARM
69 void uart0_status_isr(void)
72 cli(); // Disable Interrupts
74 // Variable for UART data read
75 uint8_t keyValue = 0x00;
77 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
79 #elif defined(_mk20dx128_) // ARM
80 // UART0_S1 must be read for the interrupt to be cleared
81 if ( UART0_S1 & UART_S1_RDRF )
83 // Only doing single byte FIFO here
90 hexToStr( keyValue, tmpStr );
91 dPrintStrs( tmpStr, " " ); // Debug
93 // Decipher scan value
94 processKeyValue( keyValue );
96 sei(); // Re-enable Interrupts
101 // ----- Functions -----
104 inline void scan_setup()
105 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
107 // Setup the the USART interface for keyboard data input
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;
117 // Enable the receiver, and RX Complete Interrupt
120 // Set frame format: 8 data, 1 stop bit, even parity
121 // Asynchrounous USART mode
124 // Reset the keyboard before scanning, we might be in a wierd state
125 scan_resetKeyboard();
127 #elif defined(_mk20dx128_) // ARM
129 // Setup the the UART interface for keyboard data input
130 SIM_SCGC4 |= SIM_SCGC4_UART0; // Disable clock gating
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
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;
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;
151 // Number of bytes in FIFO before TX Interrupt
154 // Number of bytes in FIFO before RX Interrupt
157 // TX FIFO Disabled, TX FIFO Size 1 (Max 8 datawords), RX FIFO Enabled, RX FIFO Size 1 (Max 8 datawords)
162 //UART0_PFIFO = UART_PFIFO_TXFE | /*TXFIFOSIZE*/ (0x0 << 4) | UART_PFIFO_RXFE | /*RXFIFOSIZE*/ (0x0);
164 // Reciever Inversion Disabled, LSBF
165 // UART_S2_RXINV UART_S2_MSBF
168 // Transmit Inversion Disabled
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;
176 // Add interrupt to the vector table
177 NVIC_ENABLE_IRQ( IRQ_UART0_STATUS );
179 // Reset the keyboard before scanning, we might be in a wierd state
180 scan_resetKeyboard();
185 // Main Detection Loop
186 inline uint8_t scan_loop()
191 void processKeyValue( uint8_t keyValue )
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
197 // Add key(s) to processing buffer
198 // First split out Shift and Ctrl
210 bufferAdd( keyValue );
213 // Add Ctrl key and offset to the lower alphabet
220 bufferAdd( keyValue + 0x40 );
223 // - Add Shift key and offset to non-shifted key -
230 bufferAdd( keyValue + 0x10 );
236 bufferAdd( keyValue + 0x11 );
241 bufferAdd( keyValue + 0x07 );
246 bufferAdd( keyValue - 0x0E );
251 bufferAdd( keyValue + 0x0E );
256 bufferAdd( keyValue + 0x12 );
261 bufferAdd( keyValue + 0x05 );
266 bufferAdd( keyValue + 0x01 );
273 bufferAdd( keyValue - 0x10 );
278 bufferAdd( keyValue - 0x28 );
283 bufferAdd( keyValue - 0x32 );
290 bufferAdd( keyValue - 0x20 );
295 bufferAdd( keyValue - 0x1E );
299 // Ctrl Characters are from 0x00 to 0x1F, excluding:
301 // 0x09 - [Horizontal] Tab
302 // 0x0D - [Carriage] Return
304 // 0x7F - Delete (^?) (Doesn't need to be split out)
307 // Add Ctrl key and offset to the lower alphabet
308 if ( keyValue >= 0x00 && keyValue <= 0x1F )
311 bufferAdd( keyValue + 0x60 );
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 )
320 bufferAdd( keyValue + 0x20 );
326 bufferAdd( keyValue );
333 // NOTE: Example only, MBC-55X cannot receive user data
334 uint8_t scan_sendData( uint8_t dataPayload )
338 hexToStr( dataPayload, tmpStr );
339 info_dPrint( "Sending - ", tmpStr );
341 #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
343 #elif defined(_mk20dx128_) // ARM
344 UART0_D = dataPayload;
350 // Signal KeyIndex_Buffer that it has been properly read
351 void scan_finishedWithBuffer( uint8_t sentKeys )
355 // Signal that the keys have been properly sent over USB
356 void scan_finishedWithUSBBuffer( uint8_t sentKeys )
358 cli(); // Disable Interrupts
360 // Reset the buffer counter
361 KeyIndex_BufferUsed = 0;
363 sei(); // Re-enable Interrupts
366 // Reset/Hold keyboard
367 // NOTE: Does nothing with the MBC-55x
368 void scan_lockKeyboard( void )
372 // NOTE: Does nothing with the MBC-55x
373 void scan_unlockKeyboard( void )
378 void scan_resetKeyboard( void )
380 // Not a calculated valued...
383 KeyIndex_BufferUsed = 0;