X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=main.c;h=dd8b8e0983ffdc8f705fc4c729082f7dd017fbaf;hb=85dd7f5c52e73c98ac09478da504efbf44b1dcbb;hp=2b5494835f06e53440afa5d12e1bcaee6429cbc3;hpb=1bee2a6dc966993075ad75d88fd7f7e5baea233c;p=kiibohd-controller.git diff --git a/main.c b/main.c index 2b54948..dd8b8e0 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 by Jacob Alexander +/* Copyright (C) 2011-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 @@ -19,115 +19,194 @@ * THE SOFTWARE. */ -#include -#include -#include -#include -#include "usb_keyboard.h" +// ----- Includes ----- +// Compiler Includes +#include + +// Project Includes +#include +#include +#include + +#include +#include + + + +// ----- Defines ----- + +// Verified Keypress Defines +#define USB_TRANSFER_DIVIDER 10 // 1024 == 1 Send of keypresses per second, 1 == 1 Send of keypresses per ~1 millisecond + + + +// ----- Macros ----- +#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) +#endif -#define PRE_DRIVE_SLEEP -#define POST_DRIVE_SLEEP - - -#define DRIVE_reg_1 PORTB -#define DRIVE_reg_2 PORTB -#define DRIVE_reg_3 PORTB -#define DRIVE_reg_4 PORTC -#define DRIVE_reg_5 PORTE -#define DRIVE_reg_6 PORTE -#define DRIVE_reg_7 PORTF -#define DRIVE_reg_8 PORTF -#define DRIVE_reg_9 PORTF -#define DRIVE_reg_10 -#define DRIVE_reg_11 -#define DRIVE_reg_12 - -#define DRIVE_pin_1 0 -#define DRIVE_pin_2 1 -#define DRIVE_pin_3 2 -#define DRIVE_pin_4 7 -#define DRIVE_pin_5 6 -#define DRIVE_pin_6 7 -#define DRIVE_pin_7 0 -#define DRIVE_pin_8 4 -#define DRIVE_pin_9 5 -#define DRIVE_pin_10 -#define DRIVE_pin_11 -#define DRIVE_pin_12 - -#define DETECT_group_1 0 -#define DETECT_group_2 0 -#define DETECT_group_3 0 -#define DETECT_group_4 0 -#define DETECT_group_5 0 -#define DETECT_group_6 0 -#define DETECT_group_7 0 -#define DETECT_group_8 0 -#define DETECT_group_9 0 -#define DETECT_group_10 -#define DETECT_group_11 -#define DETECT_group_12 - -// Change number of ORDs if number of lines differ -#define DD_LOOP \ - for ( int c = 0;; c++ ) { \ - switch ( c ) { \ - DD_CASE_ORD(1) \ - DD_CASE_ORD(2) \ - DD_CASE_ORD(3) \ - DD_CASE_ORD(4) \ - DD_CASE_ORD(5) \ - DD_CASE_ORD(6) \ - DD_CASE_ORD(7) \ - DD_CASE_ORD(8) \ - DD_CASE_END(9,c) \ - } \ - } - -#define DRIVE_DETECT(reg,pin,group) \ - reg |= (1 << pin);\ - detection(group);\ - reg &= (0 << pin); - -#define DD_CASE(number) \ - case number:\ - DRIVE_DETECT(DRIVE_reg##_##number, DRIVE_pin##_##number, DETECT_group##_##number) - -#define DD_CASE_ORD(number) \ - DD_CASE(number) \ - break; - -#define DD_CASE_END(number,var) \ - DD_CASE(number) \ - default: \ - var = -1; \ - break; -int main(void) + +// ----- 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; + + + +// ----- Functions ----- + +// Initial Pin Setup, make sure they are sane +inline void pinSetup(void) { - // set for 16 MHz clock + +// AVR +#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) + + // For each pin, 0=input, 1=output +#if defined(__AVR_AT90USB1286__) + DDRA = 0x00; +#endif + DDRB = 0x00; + DDRC = 0x00; + DDRD = 0x00; + DDRE = 0x00; + DDRF = 0x00; + + + // Setting pins to either high or pull-up resistor +#if defined(__AVR_AT90USB1286__) + PORTA = 0x00; +#endif + PORTB = 0x00; + PORTC = 0x00; + PORTD = 0x00; + PORTE = 0x00; + PORTF = 0x00; + +// ARM +#elif defined(_mk20dx128_) + // TODO - Should be cleared, but not that necessary due to the pin layout +#endif +} + + +inline void usbTimerSetup(void) +{ +// AVR +#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) + + // Setup with 16 MHz clock CPU_PRESCALE( 0 ); + // 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_) + // 48 MHz clock by default + + // System Clock Gating Register Disable + SIM_SCGC6 |= SIM_SCGC6_PIT; + + // 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 + + // Insert the required vector for Timer 0 + NVIC_ENABLE_IRQ( IRQ_PIT_CH0 ); +#endif +} + + +int main(void) +{ // Configuring Pins + pinSetup(); + init_errorLED(); - // TODO + // Setup Output Module + output_setup(); - // Initialize the USB, and then wait for the host to set configuration. - // If the Teensy is powered without a PC connected to the USB port, - // this will wait forever. - usb_init(); - while ( !usb_configured() ) /* wait */ ; + // Enable CLI + init_cli(); - // Wait an extra second for the PC's operating system to load drivers - // and do whatever it does to actually be ready for input - _delay_ms(1000); + // Setup ISR Timer for flagging a kepress send to USB + usbTimerSetup(); // Main Detection Loop - DD_LOOP + uint8_t ledTimer = F_CPU / 1000000; // Enable LED for a short time + while ( 1 ) + { + // Setup the scanning module + scan_setup(); + + while ( 1 ) + { + // Acquire Key Indices + // Loop continuously until scan_loop returns 0 + cli(); + while ( scan_loop() ); + sei(); + + // Run Macros over Key Indices and convert to USB Keys + process_macros(); + + // Send keypresses over USB if the ISR has signalled that it's time + if ( !sendKeypresses ) + continue; + + // Send USB Data + usb_send(); + + // Clear sendKeypresses Flag + sendKeypresses = 0; + + // Indicate Error, if valid + errorLED( ledTimer ); + + if ( ledTimer > 0 ) + ledTimer--; + } + + // Loop should never get here (indicate error) + ledTimer = 255; + + // HID Debug Error message + erro_print("Detection loop error, this is very bad...bug report!"); + } +} + - // usb_keyboard_press(KEY_B, KEY_SHIFT); - return 0; +// ----- Interrupts ----- + +// USB Keyboard Data Send Counter Interrupt +#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR +ISR( TIMER0_OVF_vect ) +#elif defined(_mk20dx128_) // ARM +void pit0_isr(void) +#endif +{ + sendKeypressCounter++; + if ( sendKeypressCounter > USB_TRANSFER_DIVIDER ) { + sendKeypressCounter = 0; + sendKeypresses = 1; + } + +#if defined(_mk20dx128_) // ARM + // Clear the interrupt flag + PIT_TFLG0 = 1; +#endif }