int main(void) { CPU_PRESCALE(CPU_16MHz); SPI_SlaveInit(); InitWEnc(); u08 main_msg; // Start keeping track of position at 0 WE_wheel_0 = 0; while(!WE_wheel_0); WE_position = 0; // Loop indefinitely while(1) { // obtain command from main uC main_msg = SPI_SlaveReceive(); switch(main_msg) { case SPI_WHEEL_POS: SPI_SlaveReceiveX(WE_position); break; case SPI_WHEEL_RPM: SPI_SlaveReceiveX(WE_RPM); break; default: break; } } }
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++; } }