X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=main.c;h=3b48941dfca0ed1e647378b51b8998fa1138362c;hb=0013d7a4f31d35ad054369037e20b683085c6116;hp=b6eb0e5285c075e0802c577096075f91caa4042b;hpb=35ae82fff78557083febfa23044a5c1ba7a71b47;p=kiibohd-controller.git diff --git a/main.c b/main.c index b6eb0e5..3b48941 100644 --- a/main.c +++ b/main.c @@ -35,335 +35,41 @@ -// ----- 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 - - - -// ----- Function Declarations ----- - -void cliFunc_distRead ( char* args ); -void cliFunc_free ( char* args ); -void cliFunc_gaugeHelp ( char* args ); -void cliFunc_single ( char* args ); -void cliFunc_start ( char* args ); -void cliFunc_zeroForce ( char* args ); -void cliFunc_zeroPosition( char* args ); - - - -// ----- 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) +int main() { - -// AVR + // AVR - Teensy Set Clock speed to 16 MHz #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 + CLKPR = 0x80; + CLKPR = 0x00; #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(); - - // Setup Output Module - output_setup(); // Enable CLI - init_cli(); + CLI_init(); - // Setup ISR Timer for flagging a kepress send to USB - usbTimerSetup(); + // Setup Modules + Output_setup(); + Macro_setup(); + Scan_setup(); // Main Detection 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!"); - } -} - - -// ----- 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 -} - - -// ----- CLI Command Functions ----- - -uint32_t readDistanceGauge() -{ - // Setup distance read parameters for iGaging Distance Scale - // freq = 9kHz - // duty_cycle = 20% - // high_delay = (1/freq) * (duty_cycle/100) - // low_delay = (1/freq) * ((100-duty_cycle)/100) - uint8_t bits = 21; // 21 clock pulses, for 21 bits - uint32_t high_delay = 22; // Clock high time per pulse - uint32_t low_delay = 89; // Clock low time per pulse - - // Data - uint32_t distInput = 0; - - // Make sure clock is low initially - GPIOC_PCOR |= (1<<2); // Set Clock low - - // Scan each of the bits - for ( uint8_t bit = 0; bit < bits; bit++ ) - { - // Begin clock pulse - GPIOC_PSOR |= (1<<2); // Set Clock high - - // Delay for duty cycle - delayMicroseconds( high_delay ); + // Process CLI + CLI_process(); - // End clock pulse - GPIOC_PCOR |= (1<<2); // Set Clock low + // Acquire Key Indices + // Loop continuously until scan_loop returns 0 + cli(); + while ( Scan_loop() ); + sei(); - // Read Data Bit - distInput |= GPIOC_PDIR & (1<<1) ? (1 << bit) : 0; + // Run Macros over Key Indices and convert to USB Keys + Macro_process(); - // Delay for duty cycle - delayMicroseconds( low_delay ); + // Sends USB data only if changed + Output_send(); } - - return distInput; -} - -void cliFunc_distRead( char* args ) -{ - // Parse number from argument - // NOTE: Only first argument is used - char* arg1Ptr; - char* arg2Ptr; - argumentIsolation_cli( args, &arg1Ptr, &arg2Ptr ); - - // Convert the argument into an int - int read_count = decToInt( arg1Ptr ) + 1; - - // If no argument specified, default to 1 read - if ( *arg1Ptr == '\0' ) - { - read_count = 2; - } - - // Repeat reading as many times as specified in the argument - print( NL ); - while ( --read_count > 0 ) - { - // Prepare to print output - info_msg("Distance: "); - - // Data - uint32_t distInput = readDistanceGauge(); - - // Output result - printInt32( distInput ); - - // Convert to mm - // As per http://www.shumatech.com/web/21bit_protocol?page=0,1 - // 21 bits is 2560 CPI (counts per inch) (C/inch) - // 1 inch is 25.4 mm - // 2560 / 25.4 = 100.7874016... CPMM (C/mm) - // Or - // 1 count is 1/2560 = 0.000390625... inches - // 1 count is (1/2560) * 25.4 = 0.00992187500000000 mm = 9.92187500000000 um = 9921.87500000000 nm - // Since there are 21 bits (2 097 152 positions) converting to um is possible by multiplying by 1000 - // which is 2 097 152 000, and within 32 bits (4 294 967 295). - // However, um is still not convenient, so 64 bits (18 446 744 073 709 551 615) is a more accurate alternative. - // For each nm there are 2 097 152 000 000 positions. - // And for shits: - // mm is 2 097 152 : 0.009 921 875 000 mm : 32 bit - // um is 2 097 152 000 : 9.921 875 000 um : 32 bit (ideal acc. for 32 bit) - // nm is 2 097 152 000 000 : 9 921.875 000 nm : 64 bit - // pm is 2 097 152 000 000 000 : 9 921 875.000 pm : 64 bit (ideal acc. for 64 bit) - - // XXX Apparently shumatech was sorta wrong about the 21 bits of usage - // Yes there are 21 bits, but the values only go from ~338 to ~30681 which is less than 16 bits... - // This means that the conversion at NM can use 32 bits :D - // It's been noted that the multiplier should be 100.6 (and that it could vary from scale to scale) - uint32_t distNM = distInput * 9921;; - uint32_t distUM = distNM / 1000; - uint32_t distMM = distUM / 1000; - - print(" "); - printInt32( distMM ); - print(" mm "); - printInt32( distUM ); - print(" um "); - printInt32( distNM ); - print(" nm "); - - print( NL ); - - // Only delay if still counting - if ( read_count > 1 ) - delay( 50 ); - } -} - - -void cliFunc_free( char* args ) -{ -} - - -void cliFunc_gaugeHelp( char* args ) -{ -} - - -void cliFunc_single( char* args ) -{ -} - - -void cliFunc_start( char* args ) -{ -} - - -void cliFunc_zeroForce( char* args ) -{ -} - - -void cliFunc_zeroPosition( char* args ) -{ }