int main(void) { int8_t r; struct teensy_msg msg; // set for 16 MHz clock CPU_PRESCALE(0); // 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 */ ; // 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); // Set up Timer 1 for PWM control. // P&F Correct, Runs 5KHz. Divide 16Mhz clock by 8, cycle = 200. // Make OCR1A & B outputs. DDRB |= ((1<<PORTB5) | (1<<PORTB6)); //TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0); TCCR1A = (1<<COM1A1) | (1<<COM1B1) ; TCCR1B = (1<<WGM13) | (1<<CS11); ICR1 = 200; OCR1A = 0; // Should stay low to start OCR1B = 0; // Set up Control Signals. PD6&7 for OCR1B; PC6&7 for OCR1A. DDRD |= (1<<PORTD6) | (1<<PORTD7); DDRC |= (1<<PORTC6) | (1<<PORTC7); PORTD &= ~((1<<PORTD6) | (1<<PORTD7)); // take low to start (off) PORTC &= ~((1<<PORTC6) | (1<<PORTC7)); // Timer 0 is not necessary - leave code in case we later want it. // Configure timer 0 to generate a timer overflow interrupt every // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock // TCCR0A = 0x00; // TCCR0B = 0x05; // TIMSK0 = (1<<TOIE0); // give a blink at the start // Loop for debug //while (1){ DDRD |= (1<<PORTD3); PORTD |= (1<<PORTD3); _delay_ms(500); PORTD &= ~(1<<PORTD3); _delay_ms(500); //} while (1) { // if received data, do something with it r = usb_rawhid_recv(buffer, 0); if (r > 0) { // give a blink on packet received - uncomment for debug /* DDRD |= (1<<PORTD3); PORTD |= (1<<PORTD3); _delay_ms(500); PORTD &= ~(1<<PORTD3); _delay_ms(500); */ msg = unpack(buffer); switch(msg.destination){ case 'a': handle_adc(msg); break; case 'm': handle_mc(msg); break; default: fail_spectacularly(); break; } free(msg.buf); // _delay_ms(50); } } }
static void cb_adc_available(void) { static uint8_t led_count = 0; static uint32_t timestamp_counter = 0; static uint32_t timestamp_last_frame = 0; static uint16_t missed_adc = 0; static uint16_t high_adc = 0; static uint16_t low_adc = 0xffff; uint16_t missed; uint16_t adc_value; uint16_t dxdt; uint32_t timestamp_ms; uint8_t send_adc_only = 0; #if FPS_SEND_ADC_ONLY send_adc_only = 1; #endif // Get ADC reading for light sensor sc_adc_channel_get(&adc_value, ×tamp_ms); // Check if we missed an ADC reading ++timestamp_counter; missed = timestamp_ms - timestamp_counter; timestamp_counter = timestamp_ms; missed_adc += missed; led_count += missed; if (led_count++ > 100) { led_count = 0; sc_led_toggle(); } // Store lowest and highest values for debugging if (adc_value > high_adc) { high_adc = adc_value; } if (adc_value < low_adc) { low_adc = adc_value; } if (handle_adc(adc_value, timestamp_ms, &dxdt) || send_adc_only) { uint8_t buf[64]; uint8_t len; if (send_adc_only) { len = create_adc_msg(buf, 64, adc_value, timestamp_ms); } else { len = create_message(buf, 64, timestamp_ms, timestamp_ms - timestamp_last_frame, missed_adc, low_adc, high_adc, dxdt); } sc_uart_send_msg(SC_UART_LAST, buf, len); high_adc = 0; low_adc = 0xffff; timestamp_last_frame = timestamp_ms; missed_adc = 0; } }