2011-03-04 00:38:32 +00:00
/* Copyright (C) 2011 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 .
*/
2011-09-30 05:22:19 +00:00
// ----- Includes -----
// AVR Includes
2011-03-04 00:38:32 +00:00
# include <avr/io.h>
# include <avr/interrupt.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 -----
# define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
// ----- 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
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 ;
2011-03-10 06:49:34 +00:00
}
2011-03-20 08:17:19 +00:00
2011-09-30 05:22:19 +00:00
int main ( void )
2011-03-04 00:38:32 +00:00
{
2011-03-17 05:43:33 +00:00
// Setup with 16 MHz clock
2011-03-04 00:38:32 +00:00
CPU_PRESCALE ( 0 ) ;
// 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
// Set to 256 * 1024 (8 bit timer with Clock/1024 prescalar) timer
TCCR0A = 0x00 ;
TCCR0B = 0x03 ;
TIMSK0 = ( 1 < < TOIE0 ) ;
2011-03-13 01:45:51 +00:00
2011-03-04 00:38:32 +00:00
// Main Detection Loop
2011-09-30 08:30:34 +00:00
uint8_t ledTimer = 15 ; // Enable LED for a short time
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
2011-11-13 10:04:44 +00:00
// USB Keyboard Data Send Counter Interrupt
2011-03-17 05:43:33 +00:00
ISR ( TIMER0_OVF_vect )
{
sendKeypressCounter + + ;
if ( sendKeypressCounter > USB_TRANSFER_DIVIDER ) {
sendKeypressCounter = 0 ;
sendKeypresses = 1 ;
}
}