//uchar id;
char x;
char y;
- uchar buttons;
+ uchar buttons; // Note: bitstream goes [8...1]
} report_t;
static report_t buttonState;
static uint8_t pollInProgress = 0;
static unsigned char idleRate;
static uint8_t interrupt_count = 0;
+static uint8_t readyToPollSnes = 0;
usbMsgLen_t usbFunctionSetup(uchar data[8]) {
} else if (rq->bRequest == USBRQ_HID_SET_IDLE){
idleRate = rq->wValue.bytes[1];
}
- }else{
+ } else {
/* no vendor specific requests implemented */
}
return 0; /* default for not implemented requests: return no data back to host */
ISR(TIMER1_COMPA_vect) {
-/*
- if(pollInProgress) // Mutex, to prevent infinite recursion if terribly many USB interrupts (shouldn't happen, but safety net)
- return; // We've already started polling the SNES controller, return up the stack so that the original ISR can finish
- pollInProgress = 1; // Acquire lock
- sei(); // Allow for nested interrupts - namely, USB interrupts.
- buttonState.buttons = pollSnes();
- pollInProgress = 0; // Release lock
-*/
- if (interrupt_count++ == 60) {
- reportBuffer.buttons++;
- interrupt_count = 0;
+ readyToPollSnes = 1; // Set flag for mainloop to poll SNES (better not to do this in an ISR)
+}
+
+static void getButtons() { // Poll the SNES for the button states, arrange bytes appropriately for the descriptor
+ uint16_t temp= 0x0000;
+ uint8_t counter = 16;
+
+ PORTC |= _BV(PINC1);
+ _delay_us(12);
+
+ PORTC &= ~_BV(PINC1);
+
+ for(counter = 0; counter != 16; counter++) {
+ _delay_us(6);
+ temp = temp << 1 ;
+ temp |= (PINC & _BV(PINC2)) ? 0 : 1;
+ PORTC &= ~_BV(PINC0);
+ _delay_us(6);
+ PORTC |= _BV(PINC0);
}
+
+ if (temp & 0x0800)
+ buttonState.y = -127;
+ //buttonState.x = 127;
+ else if (temp & 0x0400)
+ buttonState.y = 127;
+ //buttonState.x = -127;
+ else buttonState.y = 0;
+
+ if (temp & 0x0200)
+ buttonState.x = -127;
+ else if (temp & 0x0100)
+ buttonState.x = 127;
+ else buttonState.x = 0;
+ buttonState.buttons = ((temp & 0xf000) >> 8) | ((temp & 0x00f0) >> 4) ;
+ readyToPollSnes = 0;
}
static void initPins() {
//DBG1(0x02, 0, 0); /* debug output: main loop iterates */
wdt_reset();
usbPoll();
+ if(readyToPollSnes) {
+ getButtons();
+ }
if(usbInterruptIsReady()){
/* called after every poll of the interrupt endpoint */
// Actual code to be executed - updates the HID report with the status of the SNES controller
- //reportBuffer.buttons = buttonState.buttons;
+ reportBuffer.x = buttonState.x;
+ reportBuffer.y = buttonState.y;
+ reportBuffer.buttons = buttonState.buttons;
// Testing USB reports - change button state every second, incrementing the report buffer by 1.
//if(counter++ == 10) {