2013-01-27 06:47:52 +00:00
/* Copyright (C) 2013 by Jacob Alexander
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
// ----- Includes -----
// Compiler Includes
# include <Lib/ScanLib.h>
// Project Includes
# include <led.h>
# include <print.h>
// Local Includes
# include "scan_loop.h"
// ----- Defines -----
// ----- Macros -----
// Make sure we haven't overflowed the buffer
# define bufferAdd(byte) \
if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
KeyIndex_Buffer [ KeyIndex_BufferUsed + + ] = byte
// ----- Variables -----
// Buffer used to inform the macro processing module which keys have been detected as pressed
volatile uint8_t KeyIndex_Buffer [ KEYBOARD_BUFFER ] ;
volatile uint8_t KeyIndex_BufferUsed ;
// ----- Function Declarations -----
void processKeyValue ( uint8_t valueType ) ;
void removeKeyValue ( uint8_t keyValue ) ;
// ----- Interrupt Functions -----
// UART Receive Buffer Full Interrupt
# if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
ISR ( USART1_RX_vect )
# elif defined(_mk20dx128_) // ARM
void uart0_status_isr ( void )
# endif
{
cli ( ) ; // Disable Interrupts
2013-02-01 20:10:58 +00:00
// Variable for UART data read
2013-02-01 21:49:32 +00:00
uint8_t keyValue = 0x00 ;
2013-02-01 20:10:58 +00:00
2013-01-27 06:47:52 +00:00
# if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
2013-02-01 21:49:32 +00:00
keyValue = UDR1 ;
2013-01-27 06:47:52 +00:00
# elif defined(_mk20dx128_) // ARM
2013-02-01 20:10:58 +00:00
// UART0_S1 must be read for the interrupt to be cleared
if ( UART0_S1 & UART_S1_RDRF )
2013-01-31 04:43:41 +00:00
{
2013-02-01 20:10:58 +00:00
// Only doing single byte FIFO here
2013-02-01 21:49:32 +00:00
keyValue = UART0_D ;
2013-01-31 04:43:41 +00:00
}
2013-01-27 06:47:52 +00:00
# endif
// Debug
char tmpStr [ 6 ] ;
2013-02-01 21:49:32 +00:00
hexToStr ( keyValue , tmpStr ) ;
2013-02-01 20:10:58 +00:00
dPrintStrs ( tmpStr , " " ) ; // Debug
2013-01-27 06:47:52 +00:00
2013-02-01 21:49:32 +00:00
// Decipher scan value
processKeyValue ( keyValue ) ;
2013-01-27 06:47:52 +00:00
sei ( ) ; // Re-enable Interrupts
}
// ----- Functions -----
// Setup
inline void scan_setup ( )
# if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
{
// Setup the the USART interface for keyboard data input
2013-01-31 04:43:41 +00:00
// Setup baud rate - 1205 Baud
2013-01-27 06:47:52 +00:00
// 16 MHz / ( 16 * Baud ) = UBRR
2013-01-31 04:43:41 +00:00
// Baud: 1205 -> 16 MHz / ( 16 * 1205 ) = 829.8755
// Thus baud setting = 830
uint16_t baud = 830 ; // Max setting of 4095
2013-01-27 06:47:52 +00:00
UBRR1H = ( uint8_t ) ( baud > > 8 ) ;
UBRR1L = ( uint8_t ) baud ;
2013-02-01 21:49:32 +00:00
// Enable the receiver, and RX Complete Interrupt
UCSR1B = 0x90 ;
2013-01-27 06:47:52 +00:00
2013-02-01 21:49:32 +00:00
// Set frame format: 8 data, 1 stop bit, even parity
2013-01-27 06:47:52 +00:00
// Asynchrounous USART mode
2013-02-01 21:49:32 +00:00
UCSR1C = 0x26 ;
2013-01-27 06:47:52 +00:00
// Reset the keyboard before scanning, we might be in a wierd state
scan_resetKeyboard ( ) ;
}
# elif defined(_mk20dx128_) // ARM
{
// Setup the the UART interface for keyboard data input
2013-01-31 04:43:41 +00:00
SIM_SCGC4 | = SIM_SCGC4_UART0 ; // Disable clock gating
2013-01-27 06:47:52 +00:00
2013-01-31 04:43:41 +00:00
// Pin Setup for UART0
PORTB_PCR16 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX ( 3 ) ; // RX Pin
PORTB_PCR17 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX ( 3 ) ; // TX Pin
// Setup baud rate - 1205 Baud
// 48 MHz / ( 16 * Baud ) = BDH/L
// Baud: 1205 -> 48 MHz / ( 16 * 1205 ) = 2489.6266
// Thus baud setting = 2490
// NOTE: If finer baud adjustment is needed see UARTx_C4 -> BRFA in the datasheet
uint16_t baud = 2490 ; // Max setting of 8191
UART0_BDH = ( uint8_t ) ( baud > > 8 ) ;
UART0_BDL = ( uint8_t ) baud ;
// 8 bit, Even Parity, Idle Character bit after stop
2013-02-01 20:10:58 +00:00
// NOTE: For 8 bit with Parity you must enable 9 bit transmission (pg. 1065)
// You only need to use UART0_D for 8 bit reading/writing though
// UART_C1_M UART_C1_PE UART_C1_PT UART_C1_ILT
UART0_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT ;
2013-01-31 04:43:41 +00:00
// Number of bytes in FIFO before TX Interrupt
UART0_TWFIFO = 1 ;
// Number of bytes in FIFO before RX Interrupt
UART0_RWFIFO = 1 ;
// TX FIFO Disabled, TX FIFO Size 1 (Max 8 datawords), RX FIFO Enabled, RX FIFO Size 1 (Max 8 datawords)
// TX/RX FIFO Size:
// 0x0 - 1 dataword
// 0x1 - 4 dataword
// 0x2 - 8 dataword
2013-02-01 20:10:58 +00:00
//UART0_PFIFO = UART_PFIFO_TXFE | /*TXFIFOSIZE*/ (0x0 << 4) | UART_PFIFO_RXFE | /*RXFIFOSIZE*/ (0x0);
2013-01-31 04:43:41 +00:00
2013-02-01 17:17:52 +00:00
// Reciever Inversion Disabled, LSBF
2013-02-01 20:10:58 +00:00
// UART_S2_RXINV UART_S2_MSBF
UART0_S2 | = 0x00 ;
2013-01-31 04:43:41 +00:00
// Transmit Inversion Disabled
2013-02-01 20:10:58 +00:00
// UART_C3_TXINV
UART0_C3 | = 0x00 ;
2013-01-31 04:43:41 +00:00
2013-02-01 17:17:52 +00:00
// TX Disabled, RX Enabled, RX Interrupt Enabled
2013-02-01 20:10:58 +00:00
// UART_C2_TE UART_C2_RE UART_C2_RIE
2013-02-01 21:49:32 +00:00
UART0_C2 = UART_C2_RE | UART_C2_RIE ;
2013-02-01 17:17:52 +00:00
2013-01-31 04:43:41 +00:00
// Add interrupt to the vector table
NVIC_ENABLE_IRQ ( IRQ_UART0_STATUS ) ;
2013-01-27 06:47:52 +00:00
// Reset the keyboard before scanning, we might be in a wierd state
scan_resetKeyboard ( ) ;
}
# endif
// Main Detection Loop
inline uint8_t scan_loop ( )
{
return 0 ;
}
void processKeyValue ( uint8_t keyValue )
{
2013-02-01 21:49:32 +00:00
// XXX NOTE: The key processing is not complete for this keyboard
// Mostly due to laziness, and that the keyboard can't really be useful on a modern computer
// Basic typing will work, but some of the keys and the Graph mode changes things around
// Add key(s) to processing buffer
// First split out Shift and Ctrl
// Reserved Codes:
// Shift - 0xF5
// Ctrl - 0xF6
switch ( keyValue )
2013-01-27 06:47:52 +00:00
{
2013-02-01 21:49:32 +00:00
// - Ctrl Keys -
// Exception keys
case 0x08 : // ^H
case 0x09 : // ^I
case 0x0D : // ^M
case 0x1B : // ^[
bufferAdd ( keyValue ) ;
break ;
// 0x40 Offset Keys
// Add Ctrl key and offset to the lower alphabet
case 0x00 : // ^@
case 0x1C : // "^\"
case 0x1D : // ^]
case 0x1E : // ^^
case 0x1F : // ^_
bufferAdd ( 0xF6 ) ;
bufferAdd ( keyValue + 0x40 ) ;
break ;
// - Add Shift key and offset to non-shifted key -
// 0x10 Offset Keys
case 0x21 : // !
case 0x23 : // #
case 0x24 : // $
case 0x25 : // %
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue + 0x10 ) ;
break ;
// 0x11 Offset Keys
case 0x26 : // &
case 0x28 : // (
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue + 0x11 ) ;
break ;
// 0x07 Offset Keys
case 0x29 : // )
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue + 0x07 ) ;
break ;
// -0x0E Offset Keys
case 0x40 : // @
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue - 0x0E ) ;
break ;
// 0x0E Offset Keys
case 0x2A : // *
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue + 0x0E ) ;
break ;
// 0x12 Offset Keys
case 0x2B : // +
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue + 0x12 ) ;
break ;
// 0x05 Offset Keys
case 0x22 : // "
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue + 0x05 ) ;
break ;
// 0x01 Offset Keys
case 0x3A : // :
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue + 0x01 ) ;
break ;
// -0x10 Offset Keys
case 0x3C : // <
case 0x3E : // >
case 0x3F : // ?
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue - 0x10 ) ;
break ;
// -0x28 Offset Keys
case 0x5E : // ^
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue - 0x28 ) ;
break ;
// -0x32 Offset Keys
case 0x5F : // _
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue - 0x32 ) ;
break ;
// -0x20 Offset Keys
case 0x7B : // {
case 0x7C : // |
case 0x7D : // }
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue - 0x20 ) ;
break ;
// -0x1E Offset Keys
case 0x7E : // ~
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue - 0x1E ) ;
break ;
// All other keys
default :
// Ctrl Characters are from 0x00 to 0x1F, excluding:
// 0x08 - Backspace
// 0x09 - [Horizontal] Tab
// 0x0D - [Carriage] Return
// 0x1B - Escape
// 0x7F - Delete (^?) (Doesn't need to be split out)
// 0x60 Offset Keys
// Add Ctrl key and offset to the lower alphabet
if ( keyValue > = 0x00 & & keyValue < = 0x1F )
2013-01-27 06:47:52 +00:00
{
2013-02-01 21:49:32 +00:00
bufferAdd ( 0xF6 ) ;
bufferAdd ( keyValue + 0x60 ) ;
2013-01-27 06:47:52 +00:00
}
2013-02-01 21:49:32 +00:00
// Shift Characters are from 0x41 to 0x59
// No exceptions here :D
// Add Shift key and offset to the lower alphabet
else if ( keyValue > = 0x41 & & keyValue < = 0x5A )
2013-01-27 06:47:52 +00:00
{
2013-02-01 21:49:32 +00:00
bufferAdd ( 0xF5 ) ;
bufferAdd ( keyValue + 0x20 ) ;
2013-01-27 06:47:52 +00:00
}
2013-02-01 21:49:32 +00:00
// Everything else
else
{
bufferAdd ( keyValue ) ;
}
break ;
2013-01-27 06:47:52 +00:00
}
}
2013-01-31 04:43:41 +00:00
// Send data
// NOTE: Example only, MBC-55X cannot receive user data
2013-01-27 06:47:52 +00:00
uint8_t scan_sendData ( uint8_t dataPayload )
{
// Debug
char tmpStr [ 6 ] ;
hexToStr ( dataPayload , tmpStr ) ;
info_dPrint ( " Sending - " , tmpStr ) ;
# if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
UDR1 = dataPayload ;
# elif defined(_mk20dx128_) // ARM
2013-01-31 04:43:41 +00:00
UART0_D = dataPayload ;
2013-01-27 06:47:52 +00:00
# endif
return 0 ;
}
// Signal KeyIndex_Buffer that it has been properly read
void scan_finishedWithBuffer ( uint8_t sentKeys )
{
}
// Signal that the keys have been properly sent over USB
void scan_finishedWithUSBBuffer ( uint8_t sentKeys )
{
2013-02-01 21:49:32 +00:00
cli ( ) ; // Disable Interrupts
// Reset the buffer counter
KeyIndex_BufferUsed = 0 ;
sei ( ) ; // Re-enable Interrupts
2013-01-27 06:47:52 +00:00
}
// Reset/Hold keyboard
2013-02-01 21:49:32 +00:00
// NOTE: Does nothing with the MBC-55x
2013-01-27 06:47:52 +00:00
void scan_lockKeyboard ( void )
{
}
2013-02-01 21:49:32 +00:00
// NOTE: Does nothing with the MBC-55x
2013-01-27 06:47:52 +00:00
void scan_unlockKeyboard ( void )
{
}
// Reset Keyboard
void scan_resetKeyboard ( void )
{
// Not a calculated valued...
_delay_ms ( 50 ) ;
KeyIndex_BufferUsed = 0 ;
}