int main(void) {
    CPU_PRESCALE(0);

    GBA_DDR &= ~(1<<MISO_BIT);
    GBA_DDR |= (1<<MOSI_BIT) | (1<<CLK_BIT);
    CLK_HIGH();

    usb_init();
    while (!usb_configured());
    _delay_ms(1000);

    INIT_TIMER();

    while (1) {
        if (usb_serial_available() >= 4) {
            uint32_t data = 0;
            data |= (uint32_t)usb_serial_getchar()<<24;
            data |= (uint32_t)usb_serial_getchar()<<16;
            data |= (uint32_t)usb_serial_getchar()<<8;
            data |= (uint32_t)usb_serial_getchar();
            xfer(&data);
            usb_serial_putchar((data>>24) & 0xff);
            usb_serial_putchar((data>>16) & 0xff);
            usb_serial_putchar((data>>8) & 0xff);
            usb_serial_putchar(data & 0xff);
            usb_serial_flush_output();
        }
    }
Exemple #2
0
// USB Input buffer available
inline unsigned int Output_availablechar()
{
#if enableVirtualSerialPort_define == 1
	return usb_serial_available();
#else
	return 0;
#endif
}
Exemple #3
0
void usb_serial_wait_for_key(void)
{
  while(usb_serial_available() == 0) {
    usb_tasks();
    service_button();
    _delay_ms(10);
  }
}
Exemple #4
0
int kbhit() {
    // return usb_serial_available() != 0;
    if(USB_SERIAL_ON && (usb_serial_available() != 0))
	return 1;
#ifdef USE_UART
    return serial_available() != 0;
#endif
    return 0;
}
Exemple #5
0
int getkey()
{
    while (!kbhit())
        ;
    // return the next character from the console input device
//    return usb_serial_getchar();
    if(USB_SERIAL_ON && (usb_serial_available() != 0)) {
	return usb_serial_getchar();
    }
#ifdef USE_UART
    return serial_getchar();
#endif
    return 0;
}
Exemple #6
0
uint16_t usb_serial_readline(char *buffer, const uint16_t buffer_size, const bool obscure_input)
{
  uint16_t end = 0;
  char c;

  while(true) {
    if(usb_serial_available() > 0) {
      c = (char)usb_serial_getchar();
      switch((char) c) {
        case '\r': // enter
          buffer[end] = 0;
          usb_serial_putchar('\n');
          usb_serial_putchar('\r');
          return end;
          break;
        case '\b': // ^H
        case 127: // backspace
          end--;
          usb_serial_write("\b \b"); // remove the last char from the display
          //usb_serial_readline_refresh(buffer, end, obscure_input);
          break;
        default:
          if(end < buffer_size-1) {
            buffer[end++] = c;
            if(obscure_input)
              usb_serial_putchar('*');
            else
              usb_serial_putchar(c);
          }
          break;
      }
    }
    usb_tasks();
    service_button();
    _delay_ms(10);
  }
  return 0; // never reached
}
// Basic command interpreter for controlling port pins
int main(void)
{
	char rx_buf[8];// the buffer to store received characters
	uint8_t n = 0;  // to store the number of bytes read from the serial port
    uint8_t counter = 0; //keep count of the number of cycles in the while loop
    // coordinates of the middle of the screen
    int x=LCD_X/2; 
    int y=LCD_Y/2;

	//set clock speed to 8MhZ
    set_clock_speed(CPU_8MHz);
    
    
    //initialise LCD and ports
	Init();

	// 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 */ ;
	  _delay_ms(1000);


   //keep looping until the character 'q' is received
	while (rx_buf[0]!='q') {
        counter++;
		// wait for the user to run their terminal emulator program
		// which sets DTR to indicate it is ready to receive.
		while (!(usb_serial_get_control() & USB_SERIAL_DTR)) /* wait */ ;

		// discard anything that was received prior.  Sometimes the
		// operating system or other software will send a modem
		// "AT command", which can still be buffered.
		usb_serial_flush_input();


		// and then listen for commands and process them
		while (1) {
            
            //send some characters to the other side
             //send_str(PSTR("> \n"));
            
            if (usb_serial_available())
			  n = recv_str(rx_buf, sizeof(rx_buf)); //read serial port
			else
			  break;	 
            
            
            parse_and_execute_command(rx_buf, n);
            
            
            clear_screen();
            draw_string(x-40,y,"receiving: ");
            show_screen();
            draw_char(x+20,y,rx_buf[0]);
            show_screen();
            
		}
		
	}	 
	return 0;
}
Exemple #8
0
//void parse_CIM_protocol(unsigned char actbyte)
void parse_CIM_protocol(void)
{
    uint32_t checksum=0;
    static uint8_t transmission_mode;
	static uint8_t reply_status_code;
	static uint8_t last_serial;
	uint8_t actbyte;

	

    while (usb_serial_available()) 
	{ //PORTD |= (1<<6);
      actbyte=usb_serial_getchar();
		

      switch (readstate) 
	  {
		  case 0: // first sync byte
		  		  reply_status_code=0;
		  		  if (actbyte=='@') readstate++; 
				  break;
		  case 1: // second sync byte
		  		  if (actbyte=='T')  readstate++;
				  else readstate=0;
				  break;

 		  // packet in sync !

		  case 2: // ARE-ID: SW-version low byte
				  ARE_frame.are_id=actbyte;  
		  		  readstate++; 
				  break;
		  case 3: // ARE-ID: SW-version high byte
		  		  ARE_frame.are_id+=((uint16_t)actbyte)<<8;  
				  if (ARE_frame.are_id < ARE_MINIMAL_VERSION)    // outdated ARE ?
				     reply_status_code |= CIM_ERROR_INVALID_ARE_VERSION;
		  		  readstate++; 
				  break;
		  case 4: // data length low byte
		  		  ARE_frame.data_size=actbyte;
				  readstate++; 
				  break;
		  case 5: // data length high byte
		  		  ARE_frame.data_size+=((uint16_t)actbyte)<<8;
				  if (ARE_frame.data_size > DATABUF_SIZE)  { // dismiss packets of excessive length
				       readstate=0;
					   //ARE_frame.data_size=0;
  				       //reply_status_code |= CIM_ERROR_INVALID_FEATURE;
				  }
				  else readstate++; 
				 
				  break;
	      case 6: // serial_number 
		  		  ARE_frame.serial_number = actbyte;
				  if (first_packet)    // don't check first serial
				      first_packet=0;
				  else if (actbyte != (last_serial+1)%0x80) // check current serial number
				     reply_status_code |= CIM_ERROR_LOST_PACKETS;

				  last_serial=actbyte;
			      readstate++;
				  break;
		  case 7: // CIM-feature low byte
		  		  ARE_frame.cim_feature= actbyte; 
		  		  readstate++; 
				  
				  break;
		  case 8: // CIM-feature high byte
		  		  ARE_frame.cim_feature+=((int)actbyte)<<8; 
		  		  readstate++; 

				  break;
		  case 9: // Request code low byte ( command )
		  		  ARE_frame.request_code=actbyte;
		  		  readstate++; 
				  break;
		  case 10:// Request code high byte (transmission mode)
		  		  transmission_mode=actbyte;  // bit 0: CRC enable
				  // reply_status_code|=(actbyte & CIM_STATUS_CRC);   
				  // remember CRC state for reply
				  
		  		  if (ARE_frame.data_size>0) {
				  	readstate++;
					datapos=0;
				  }
				  else {  // no data in packet 
				    if (transmission_mode & CIM_STATUS_CRC) 
					   readstate+=2;      // proceed with CRC 
					else readstate=FRAME_DONE;  // frame is finished here !
				  }
				  break;

		  case 11: // read out data
		  		  ARE_frame.data[datapos]=actbyte;
				  datapos++;
				  if (datapos==ARE_frame.data_size)
				  {
				     if (transmission_mode & CIM_STATUS_CRC)  // with CRC: get checksum 
 				        readstate++;  					 
					 else  readstate=FRAME_DONE; // no CRC:  frame is finished here !
				  } 
				  break;
		  case 12: // checksum byte 1
		  		  checksum=actbyte;
				  readstate++;
				  break;
		  case 13: // checksum byte 2
		  		  checksum+=((long)actbyte)<<8;
				  readstate++;
				  break;
		  case 14: // checksum byte 3
		  		  checksum+=((long)actbyte)<<16;
				  readstate++;
				  break;
		  case 15: // checksum byte 4
		  		  checksum+=((long)actbyte)<<24;	  

				  // check CRC now (currently not used):
				  // if (checksum != crc32(ARE_frame.data, ARE_frame.data_size))
				  reply_status_code |= CIM_ERROR_CRC_MISMATCH;

				  // frame finished here !  
 				  readstate=FRAME_DONE;
				  break;
		  default: readstate=0; break;
	 }		

     if (readstate==FRAME_DONE)  {  // frame finished: store command in ringbuffer
			process_ARE_frame(reply_status_code);
			readstate=0;
		}
   }
}
Exemple #9
0
/** The MAIN loop. */
int main(void) {
  // Turn off the CPU prescale.
  CLKPR = 0x80;
  CLKPR = 0x00;

  // PORTA are general purpose inputs.
  DDRA = 0x00;
  PORTA = 0xff; // pull-ups all enabled

  PORTD = 0xff;
  DDRD = 0x00; // pull-ups all enabled

  DDRF = 0x00; // These are ADC lines.
  PORTF = 0x00;

  usb_init();

  // Set up Timer 0 to match compare every 1ms.
  OCR0A = 250;
  TCCR0A = 0x02; // CTC
  TCCR0B = 0x03; // CK/64 (64 * 250 == 16000)

  sei();
  char line_buf[128] = {};
  uint8_t line_len = 0;
  uint8_t usb_ready = 0;
  while (1) {
    wdt_reset();
    g_main_loop_count++;

    if (usb_configured() && (usb_serial_get_control() & USB_SERIAL_DTR)) {
      if (!usb_ready) {
        usb_ready = 1;
        strcpy_P(line_buf, PSTR("!GNR WELCOME " DEV_VERSION EOL));
        usb_serial_write((uint8_t*)line_buf, strlen(line_buf));
        line_len = 0;
      }
    } else {
      stream_stop_all();
      usb_serial_flush_input();
      usb_ready = 0;
      line_len = 0;
      g_arm_code = 0;
    }

    if (usb_serial_available()) {
      int16_t c = usb_serial_getchar();
      if (c == '\r' || c == '\n') {
        line_buf[line_len] = 0;
        handle_line(line_buf);
        if (g_arm_code) { g_arm_timer = ARM_TIMEOUT_MS; }
        line_len = 0;
      } else {
        line_buf[line_len++] = c & 0xff;

        if ((line_len + 1) >= sizeof(line_buf)) {
          /* Clobber the first byte so that this line will be reported
             as an error. */
          line_buf[0] = MAGIC_OVERRUN_CODE;
          line_len--;
        }
      }
    }

    if (TIFR0 & (1 << OCF0A)) {
      TIFR0 |= (1 << OCF0A);
      g_timer++;
      stream_timer_update();
      hit_timer_update();

      g_main_loop_count = (uint16_t) (((uint32_t) g_main_loop_count) * 7 / 8);
    }

    stream_poll();
    usb_poll();
    hit_poll();
  }
}
Exemple #10
0
// USB Input buffer available
inline unsigned int Output_availablechar()
{
	return usb_serial_available();
}
Exemple #11
0
// Basic command interpreter for controlling port pins
int main(void)
{
	char rx_buf[8];// the buffer to store received characters
    uint8_t n=0;  //number of bytes read


	//set clock speed to 8MhZ
    set_clock_speed(CPU_8MHz);
    
    
    //initialise LCD and ports
	Init();

	// 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 */ ;
	  _delay_ms(1000);


   //keep looping until the character 'q' is received
	while (rx_buf[0]!='q') {
        
		// wait for the user to run their terminal emulator program
		// which sets DTR to indicate it is ready to receive.
		while (!(usb_serial_get_control() & USB_SERIAL_DTR)) /* wait */ ;

		// discard anything that was received prior.  Sometimes the
		// operating system or other software will send a modem
		// "AT command", which can still be buffered.
		usb_serial_flush_input();


		// and then listen for commands and process them
		while (1) {
            
            if (usb_serial_available())
            {
			   n = recv_str(rx_buf, sizeof(rx_buf)); //read serial port
			   //send a characters to the other side
               send_str(PSTR("> \n"));
			}
			else
			{
			  break;
			}	 
          	    
            //check first character of the buffer and perform an action
            if(rx_buf[0]=='a') //turn LED0 ON
                PORTB = 1<<2;
            if(rx_buf[0]=='d') //turn LED1 ON
            	PORTB = 1<<3;
            if(rx_buf[0]=='s') //turn LED0 OFF
            	PORTB = 0x00;
                         
		}
		
	}	 
	return 0;
}
Exemple #12
0
int main(void)
{	
	char cmd;
	char param1;
	char param2;
	char param3;
	
	cmd = 0;
	param1 = 0;
	param2 = 0;
	param3 = 0;

	DDRB = 0x00;
	PORTB |= 0x01;
	
	// set for 16 MHz clock, and make sure the LED is off
	CPU_PRESCALE(0);
	LED_CONFIG;
	LED_ON;

	SPI_SlaveInit();	
	ACK_CONFIG;
	ACK_HIGH;
	
	TEST_CONFIG;
		
	usb_init();
	_delay_ms(1000);

	usb_serial_flush_input();
	int flashCounter = 0;
	char LEDstate = 1;

	while (1) {

idle:
		TEST_HIGH;
		ACK_HIGH;
		SPDR = 0xff;
		if(ATT_PIN)
		{
			timeoutCounter++;
			if(timeoutCounter >= 30000)//we've been disconnected
			{
				mode = 0x41;
				motorSetting1 = 0xff;
				motorSetting2 = 0xff;
				analogEnabled = 0;
				configMode = 0;
				timeoutCounter = 0;
				flashCounter++;
				if(flashCounter > 5)
				{
					if(LEDstate == 1)
					{
						LED_OFF;
						LEDstate = 0;
					}
					else
					{
						LED_ON;
						LEDstate = 1;	
					}
					flashCounter = 0;
					
				}
			}
			if(usb_serial_available())
			{
				LED_ON;
				int c = usb_serial_getchar();
				if (c >= 0) 
				{
					switch(parseIndex)
					{
					case 0:
						if(c == 0x5A)
							parseIndex++;
						else
							usb_serial_putchar('x');
						break;
					case 1:
						buttons1 &= c;//combine this with any pending presses
						buttons1postReportState = c;
						parseIndex++;
						break;
					case 2:
						buttons2 &= c;//combine this with any pending presses
						buttons2postReportState = c;
						parseIndex++;
						break;
					case 3:
						joyRX = c;
						parseIndex++;
						break;
					case 4:
						joyRY = c;
						parseIndex++;
						break;
					case 5:
						joyLX = c;
						parseIndex++;
						break;
					case 6:
						joyLY = c;
						parseIndex = 0;
						recievedUpdate = 1;
						break;
					}
				}
				else
				{
					parseIndex = 0;
					usb_serial_putchar('x');
				}
			}
			_delay_us(1);
			goto idle;
		}
		timeoutCounter = 0;
		
		if((buttons1 & 0x10) == 0) upPressure = 0xFF; else upPressure = 0x00;
		if((buttons1 & 0x20) == 0) rightPressure = 0xFF; else rightPressure = 0x00;
		if((buttons1 & 0x40) == 0) downPressure = 0xFF; else downPressure = 0x00;
		if((buttons1 & 0x80) == 0) leftPressure = 0xFF; else leftPressure = 0x00;
		if((buttons2 & 0x01) == 0) L2Pressure = 0xFF; else L2Pressure = 0x00;
		if((buttons2 & 0x02) == 0) R2Pressure = 0xFF; else R2Pressure = 0x00;
		if((buttons2 & 0x04) == 0) L1Pressure = 0xFF; else L1Pressure = 0x00;
		if((buttons2 & 0x08) == 0) R1Pressure = 0xFF; else R1Pressure = 0x00;
		if((buttons2 & 0x10) == 0) trianglePressure = 0xFF; else trianglePressure = 0x00;
		if((buttons2 & 0x20) == 0) circlePressure = 0xFF; else circlePressure = 0x00;
		if((buttons2 & 0x40) == 0) crossPressure = 0xFF; else crossPressure = 0x00;
		if((buttons2 & 0x80) == 0) squarePressure = 0xFF; else squarePressure = 0x00;

		cli();//disable usb interrupts
		LED_ON;
		TEST_LOW;
		cmd = SPI_SlaveReceive(0xff,1);		
		TEST_HIGH;
		
		if(cmd != 0x01)
			goto finish;
		
		if(configMode)
		{
			cmd = SPI_SlaveReceive(0xF3,1);		
			SPI_SlaveReceive(0x5A,1);
			switch(cmd)
			{
				case 0x40:
					param1 = SPI_SlaveReceive(0x00,1);
//					if(param1 == 0) //lots on param1 but the reponses are all the same?
					{
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x02,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x5A,0);
					}
					break;
				case 0x41://check response data
					if(analogEnabled==1)
					{
						//button pressures byte mask, appears after 0x44 is called
						SPI_SlaveReceive(0xFF,1);//use mask instead?
						SPI_SlaveReceive(0xFF,1);
						SPI_SlaveReceive(0x03,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x5A,0);
					}
					else
					{
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x00,0);
					}
					break;
				case 0x43://exit config mode
					param1 = SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,0);
					if(param1 == 0)
					{
						configMode = 0;
					}
					break;
				case 0x44://turn on analog mode
					param1 = SPI_SlaveReceive(0x00,1);
					param2 = SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,0);
					if(param1 == 1)
					{
						mode = 0x73;//no analog button pressures
						analogEnabled = 1;
					}
					else
					{
						mode = 0x41;	
						analogEnabled = 0;
					}
					break;
				case 0x45://query model
					param1 = SPI_SlaveReceive(0x03,1);
					param2 = SPI_SlaveReceive(0x02,1);
					if(analogEnabled==1)
						SPI_SlaveReceive(0x01,1);
					else
						SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x02,1);
					SPI_SlaveReceive(0x01,1);
					SPI_SlaveReceive(0x00,0);
					break;
				case 0x46:
					param1 = SPI_SlaveReceive(0x00,1);
					if(param1 == 0)
					{
						param2 = SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x01,1);
						SPI_SlaveReceive(0x02,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x0F,0);
					}
					if(param1 == 1)
					{
						param2 = SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x01,1);
						SPI_SlaveReceive(0x01,1);
						SPI_SlaveReceive(0x01,1);
						SPI_SlaveReceive(0x0F,0);
					}
					break;
				case 0x47:
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x02,1);
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x01,1);
					SPI_SlaveReceive(0x00,0);
					break;
				case 0x4C:
					param1 = SPI_SlaveReceive(0x00,1);
					if(param1 == 0)
					{
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x04,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x00,0);
					}
					if(param1 == 1)
					{
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x07,1);
						SPI_SlaveReceive(0x00,1);
						SPI_SlaveReceive(0x00,0);
					}
					break;
				case 0x4D://setup motors
					motorSetting1 = SPI_SlaveReceive(motorSetting1,1);
					motorSetting2 = SPI_SlaveReceive(motorSetting2,1);
					SPI_SlaveReceive(0xFF,1);
					SPI_SlaveReceive(0xFF,1);
					SPI_SlaveReceive(0xFF,1);
					SPI_SlaveReceive(0xFF,0);
					break;
				case 0x4F://set pressure byte mask, extended pressures
					mode = 0x79;//analog button pressures
					param1 = SPI_SlaveReceive(0x00,1);
					param2 = SPI_SlaveReceive(0x00,1);
					param3 = SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x00,1);
					SPI_SlaveReceive(0x5A,0);
					break;
			}
		}
		else
		{
			TEST_LOW;
			cmd = SPI_SlaveReceive(mode,1);	
			
			SPI_SlaveReceive(0x5A,1);
			
			if(mode == 0x41)//digital only
			{
				param1 = SPI_SlaveReceive(buttons1,1);
				param2 = SPI_SlaveReceive(buttons2,0);
			}
			if(mode == 0x73)//digital buttons, analog joysticks
			{
				param1 = SPI_SlaveReceive(buttons1,1);
				if(param1 ==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(buttons2,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(joyRX,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(joyRY,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(joyLX,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(joyLY,0)==TIME_OUT_ERROR_CODE) goto finish;
			}
			if(mode == 0x79)//analog joysticks, analog buttons
			{
				param1 = SPI_SlaveReceive(buttons1,1);
				if(param1 ==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(buttons2,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(joyRX,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(joyRY,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(joyLX,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(joyLY,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(rightPressure,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(leftPressure,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(upPressure,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(downPressure,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(trianglePressure,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(circlePressure,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(crossPressure,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(squarePressure,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(L1Pressure,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(R1Pressure,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(L2Pressure,1)==TIME_OUT_ERROR_CODE) goto finish;
				if(SPI_SlaveReceive(R2Pressure,0)==TIME_OUT_ERROR_CODE) goto finish;
			}
			//cmd should usually be 0x42 for polling
			if(cmd == 0x43)
			{
				if(param1 == 0x01)
					configMode = 1;
			}
		}
finish:
		TEST_HIGH;
		ACK_HIGH;
		if((buttons1 == 0xff)&&(buttons2 == 0xff))
		{
			LED_OFF;
		}

		//copy queued releases into button state
		buttons1 = buttons1postReportState;
		buttons2 = buttons2postReportState;
		sei();//renable usb interrupts
		
		if(recievedUpdate == 1)
		{
			//ack the update was sent to the console
			usb_serial_putchar('k');
			recievedUpdate = 0;
		}

		while(!ATT_PIN)
		{
			_delay_us(20); //conservative so we aren't still in ATT low at the top of the loop		
		}

		
		counter++;
	}
}