uint16_t pollSnes();
-PROGMEM char usbHidReportDescriptor[28] = {
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x05, // USAGE (Game Pad)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x09, 0x05, // USAGE (Game Pad)
- 0xa1, 0x00, // COLLECTION (Physical)
- 0x05, 0x09, // USAGE_PAGE (Button)
- 0x19, 0x01, // USAGE_MINIMUM (Button 1)
- 0x29, 0x10, // USAGE_MAXIMUM (Button 16)
- 0x15, 0x00, // LOGICAL MINIMUM (0)
- 0x25, 0x01, // LOGICAL MAXIMUM (1)
- 0x95, 0x10, // REPORT_COUNT (16)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x81, 0x02, // INPUT (Data, Var, Abs)
- 0xc0, // END_COLLECTION
- 0xc0 // END_COLLECTION
+PROGMEM char usbHidReportDescriptor[] = {
+ 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
+ 0x09, 0x04, // USAGE (Joystick)
+ 0xa1, 0x01, // COLLECTION (Application)
+ 0x09, 0x01, // USAGE (Pointer)
+ 0xa1, 0x00, // COLLECTION (Physical)
+// 0x85, 0x01, // REPORT_ID (1)
+ 0x09, 0x30, // USAGE (X)
+ 0x09, 0x31, // USAGE (Y)
+ 0x15, 0x00, // LOGICAL_MINIMUM (0)
+ 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
+ 0x75, 0x08, // REPORT_SIZE (8)
+ 0x95, 0x02, // REPORT_COUNT (2)
+ 0x81, 0x02, // INPUT (Data,Var,Abs)
+
+ 0x05, 0x09, // USAGE_PAGE (Button)
+ 0x19, 1, // USAGE_MINIMUM (Button 1)
+ 0x29, 8, // USAGE_MAXIMUM (Button 8)
+ 0x15, 0x00, // LOGICAL_MINIMUM (0)
+ 0x25, 0x01, // LOGICAL_MAXIMUM (1)
+ 0x75, 1, // REPORT_SIZE (1)
+ 0x95, 8, // REPORT_COUNT (8)
+ 0x81, 0x02, // INPUT (Data,Var,Abs)
+ 0xc0, // END_COLLECTION
+ 0xc0, // END_COLLECTION
};
-/*
-typedef struct {
- uchar buttons[2];
-} report_t;
-*/
+
typedef struct {
- uint16_t buttons;
+ //uchar id;
+ char x;
+ char y;
+ uchar buttons;
} report_t;
static report_t buttonState;
static report_t reportBuffer;
static uint8_t pollInProgress = 0;
+static unsigned char idleRate;
+static uint8_t interrupt_count = 0;
usbMsgLen_t usbFunctionSetup(uchar data[8]) {
+
usbRequest_t *rq = (void *)data;
/* The following requests are never used. But since they are required by
/* we only have one report type, so don't look at wValue */
usbMsgPtr = (void *)&reportBuffer;
return sizeof(reportBuffer);
+ } else if (rq->bRequest == USBRQ_HID_GET_IDLE){
+ usbMsgPtr = &idleRate;
+ return 1;
+ } else if (rq->bRequest == USBRQ_HID_SET_IDLE){
+ idleRate = rq->wValue.bytes[1];
}
}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;
+ }
}
static void initPins() {
// Enable PD3 as output high (pull-up to D-)
- DDRD |= _BV(PIND3);
- PORTD |= _BV(PIND3);
+ //DDRD |= _BV(PIND3);
+ //PORTD |= _BV(PIND3);
// Enable PC1:0 as output, and set data clock high
// Serial data is PC2 (input, hi-z)
int main(void)
{
- uchar i;
+ uchar counter = 0;
wdt_enable(WDTO_1S); // Enable watchdog with 1s reset time
/* Even if you don't use the watchdog, turn it off here. On newer devices,
* the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
*/
- cli(); // Disable interrupts
+ cli(); // Disable interrupts (technically, they're disabled on reset, but...)
//DBG1(0x00, 0, 0); /* debug output: main starts */
//odDebugInit();
usbInit();
+
usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
- i = 0;
- while(--i){ /* fake USB disconnect for > 250 ms */
+ counter = 0;
+ while(--counter){ /* fake USB disconnect for > 250 ms */
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();
+
sei(); // Enable interrupts (after device reconnect)
//DBG1(0x01, 0, 0); /* debug output: main loop starts */
-
- uchar counter = 0;
+ reportBuffer.x = 0;
+ reportBuffer.y = 0;
+ reportBuffer.buttons = 0;
for(;;){ /* main event loop */
//DBG1(0x02, 0, 0); /* debug output: main loop iterates */
//reportBuffer.buttons = buttonState.buttons;
// Testing USB reports - change button state every second, incrementing the report buffer by 1.
- if(counter++ == 60) {
- reportBuffer.buttons++;
- counter = 0;
- }
+ //if(counter++ == 10) {
+ // reportBuffer.buttons = 'a';
+ // reportBuffer.buttons2 = 'a';
+ // reportBuffer.buttons3 = 'a';
+ // counter = 0;
+ //}
//DBG1(0x03, 0, 0); /* debug output: interrupt report prepared */
usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
}