2013-01-26 20:05:28 +00:00
/* Copyright (C) 2011-2013 by Jacob Alexander
2011-03-04 00:38:32 +00:00
*
* 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 .
*/
2011-09-30 05:22:19 +00:00
// ----- Includes -----
2013-01-26 20:05:28 +00:00
// Compiler Includes
# include <Lib/MainLib.h>
2011-09-30 05:22:19 +00:00
// Project Includes
2011-09-30 08:30:34 +00:00
# include <macro.h>
# include <scan_loop.h>
# include <usb_com.h>
2011-03-10 06:49:34 +00:00
2011-09-30 08:30:34 +00:00
# include <led.h>
# include <print.h>
2011-03-04 00:38:32 +00:00
2011-03-17 05:43:33 +00:00
2011-09-30 05:22:19 +00:00
// ----- Defines -----
2011-03-17 05:43:33 +00:00
// Verified Keypress Defines
# define USB_TRANSFER_DIVIDER 10 // 1024 == 1 Send of keypresses per second, 1 == 1 Send of keypresses per ~1 millisecond
2011-03-07 18:42:32 +00:00
2011-03-10 06:49:34 +00:00
2011-09-30 05:22:19 +00:00
// ----- Macros -----
2013-01-26 20:05:28 +00:00
# if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_)
2011-09-30 05:22:19 +00:00
# define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
2013-01-26 20:05:28 +00:00
# endif
2011-09-30 05:22:19 +00:00
// ----- Variables -----
// Timer Interrupt for flagging a send of the sampled key detection data to the USB host
uint16_t sendKeypressCounter = 0 ;
// Flag generated by the timer interrupt
volatile uint8_t sendKeypresses = 0 ;
2011-09-23 06:33:56 +00:00
2011-09-30 05:22:19 +00:00
// ----- Functions -----
// Initial Pin Setup, make sure they are sane
2011-03-17 05:43:33 +00:00
inline void pinSetup ( void )
2011-03-10 06:49:34 +00:00
{
2011-10-16 03:01:46 +00:00
2013-01-26 20:05:28 +00:00
// AVR
# if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_)
2011-03-10 06:49:34 +00:00
// For each pin, 0=input, 1=output
2011-10-16 03:01:46 +00:00
# if defined(__AVR_AT90USB1286__)
2011-03-10 06:49:34 +00:00
DDRA = 0x00 ;
2011-10-16 03:01:46 +00:00
# endif
2011-03-14 02:57:22 +00:00
DDRB = 0x00 ;
DDRC = 0x00 ;
2011-09-30 05:22:19 +00:00
DDRD = 0x00 ;
2011-09-23 06:33:56 +00:00
DDRE = 0x00 ;
2011-03-14 02:57:22 +00:00
DDRF = 0x00 ;
2011-03-10 06:49:34 +00:00
2011-03-17 05:43:33 +00:00
2011-03-10 06:49:34 +00:00
// Setting pins to either high or pull-up resistor
2011-10-16 03:01:46 +00:00
# if defined(__AVR_AT90USB1286__)
2011-09-23 06:33:56 +00:00
PORTA = 0x00 ;
2011-10-16 03:01:46 +00:00
# endif
2011-09-23 06:33:56 +00:00
PORTB = 0x00 ;
PORTC = 0x00 ;
2011-09-30 05:22:19 +00:00
PORTD = 0x00 ;
2011-09-23 06:33:56 +00:00
PORTE = 0x00 ;
PORTF = 0x00 ;
2013-01-26 20:05:28 +00:00
// ARM
# elif defined(_mk20dx128_)
2013-01-31 00:20:42 +00:00
// TODO - Should be cleared, but not that necessary due to the pin layout
2013-01-26 20:05:28 +00:00
# endif
2011-03-10 06:49:34 +00:00
}
2011-03-20 08:17:19 +00:00
2013-01-26 20:05:28 +00:00
inline void usbTimerSetup ( void )
2011-03-04 00:38:32 +00:00
{
2013-01-26 20:05:28 +00:00
// AVR
# if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_)
2011-03-17 05:43:33 +00:00
// Setup with 16 MHz clock
2011-03-04 00:38:32 +00:00
CPU_PRESCALE ( 0 ) ;
2013-01-26 20:05:28 +00:00
// Setup ISR Timer for flagging a kepress send to USB
// Set to 256 * 1024 (8 bit timer with Clock/1024 prescalar) timer
TCCR0A = 0x00 ;
TCCR0B = 0x03 ;
TIMSK0 = ( 1 < < TOIE0 ) ;
// ARM
# elif defined(_mk20dx128_)
2013-01-27 06:47:52 +00:00
// 48 MHz clock by default
2013-01-31 00:20:42 +00:00
// System Clock Gating Register Disable
SIM_SCGC6 | = SIM_SCGC6_PIT ;
2013-01-27 06:47:52 +00:00
// Enable Timers
PIT_MCR = 0x00 ;
// Setup ISR Timer for flagging a kepress send to USB
// 1 ms / (1 / 48 MHz) - 1 = 47999 cycles -> 0xBB7F
PIT_LDVAL0 = 0x0000BB7F ;
PIT_TCTRL0 = 0x3 ; // Enable Timer 0 interrupts, and Enable Timer 0
2013-01-31 00:20:42 +00:00
// Insert the required vector for Timer 0
NVIC_ENABLE_IRQ ( IRQ_PIT_CH0 ) ;
2013-01-26 20:05:28 +00:00
# endif
}
int main ( void )
{
2011-03-04 00:38:32 +00:00
// Configuring Pins
2011-03-10 06:49:34 +00:00
pinSetup ( ) ;
2011-09-30 08:30:34 +00:00
init_errorLED ( ) ;
2011-03-04 00:38:32 +00:00
2011-09-30 05:22:19 +00:00
// Setup USB Module
usb_setup ( ) ;
2011-03-04 00:38:32 +00:00
2011-03-17 05:43:33 +00:00
// Setup ISR Timer for flagging a kepress send to USB
2013-01-26 20:05:28 +00:00
usbTimerSetup ( ) ;
2011-03-13 01:45:51 +00:00
2011-03-04 00:38:32 +00:00
// Main Detection Loop
2013-01-31 00:20:42 +00:00
uint8_t ledTimer = F_CPU / 1000000 ; // Enable LED for a short time
2011-09-30 08:30:34 +00:00
while ( 1 )
{
2011-10-01 07:54:18 +00:00
// Setup the scanning module
scan_setup ( ) ;
2011-09-30 08:30:34 +00:00
while ( 1 )
{
// Acquire Key Indices
2011-10-01 07:54:18 +00:00
// Loop continuously until scan_loop returns 0
cli ( ) ;
while ( scan_loop ( ) ) ;
sei ( ) ;
2011-09-23 06:33:56 +00:00
2011-10-16 03:01:46 +00:00
// Run Macros over Key Indices and convert to USB Keys
process_macros ( ) ;
2011-09-30 08:30:34 +00:00
// Send keypresses over USB if the ISR has signalled that it's time
if ( ! sendKeypresses )
continue ;
2011-09-23 06:33:56 +00:00
2011-09-30 08:30:34 +00:00
// Send USB Data
usb_send ( ) ;
2011-09-30 05:22:19 +00:00
2011-09-30 08:30:34 +00:00
// Clear sendKeypresses Flag
sendKeypresses = 0 ;
2011-09-30 05:22:19 +00:00
2011-09-30 08:30:34 +00:00
// Indicate Error, if valid
errorLED ( ledTimer ) ;
2011-10-01 07:54:18 +00:00
if ( ledTimer > 0 )
ledTimer - - ;
2011-09-30 08:30:34 +00:00
}
2011-09-30 05:22:19 +00:00
2011-09-30 08:30:34 +00:00
// Loop should never get here (indicate error)
ledTimer = 255 ;
// HID Debug Error message
erro_print ( " Detection loop error, this is very bad...bug report! " ) ;
2011-09-23 06:33:56 +00:00
}
}
2011-03-04 00:38:32 +00:00
2013-01-26 20:05:28 +00:00
// ----- Interrupts -----
2013-01-27 06:47:52 +00:00
// USB Keyboard Data Send Counter Interrupt
# if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
2011-03-17 05:43:33 +00:00
ISR ( TIMER0_OVF_vect )
2013-01-27 06:47:52 +00:00
# elif defined(_mk20dx128_) // ARM
void pit0_isr ( void )
# endif
2011-03-17 05:43:33 +00:00
{
sendKeypressCounter + + ;
if ( sendKeypressCounter > USB_TRANSFER_DIVIDER ) {
sendKeypressCounter = 0 ;
sendKeypresses = 1 ;
}
2013-01-31 00:20:42 +00:00
# if defined(_mk20dx128_) // ARM
// Clear the interrupt flag
PIT_TFLG0 = 1 ;
# endif
2011-03-17 05:43:33 +00:00
}