From: Drew Fisher Date: Fri, 11 Jun 2010 06:32:37 +0000 (-0700) Subject: Recognized as a joystick, timer verified working. X-Git-Url: https://git.zarvox.org/shortlog/month?a=commitdiff_plain;h=c18d4bb915d84ff09ee45e8f1101e62c34bc813e;p=usbsnes.git Recognized as a joystick, timer verified working. Actually gets recognized and polled correctly. Increments a bitmask revealed in the button state every second. --- diff --git a/Makefile b/Makefile index fa79efa..6941d0c 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,8 @@ F_CPU = 18000000 # in Hz FUSE_L = 0xd7# see below for fuse values for particular devices FUSE_H = 0xd9 -AVRDUDE = avrdude -c stk500 -B 2 -p $(DEVICE) -P /dev/ttyACM0 # edit this line for your programmer +#AVRDUDE = avrdude -c stk500 -B 2 -p $(DEVICE) -P /dev/ttyACM0 # edit this line for your programmer +AVRDUDE = avrdude -c avrispmkII -B 10 -p $(DEVICE) -P usb # edit this line for your programmer CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o snes.o diff --git a/main.c b/main.c index e34a7cf..9e8ccb8 100644 --- a/main.c +++ b/main.c @@ -10,37 +10,48 @@ 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 @@ -52,6 +63,11 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) { /* 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 */ @@ -59,19 +75,26 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) { 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) @@ -101,14 +124,14 @@ static void initTimer() { 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 */ @@ -132,17 +155,20 @@ int main(void) //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 */ @@ -154,10 +180,12 @@ int main(void) //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)); } diff --git a/usbconfig.h b/usbconfig.h index 3363dc9..9dfeae0 100644 --- a/usbconfig.h +++ b/usbconfig.h @@ -202,7 +202,7 @@ section at the end of this file). /* define this macro to 1 if you want the function usbMeasureFrameLength() * compiled in. This function can be used to calibrate the AVR's RC oscillator. */ -#define USB_USE_FAST_CRC 1 +#define USB_USE_FAST_CRC 0 /* The assembler module has two implementations for the CRC algorithm. One is * faster, the other is smaller. This CRC routine is only used for transmitted * messages where timing is not critical. The faster routine needs 31 cycles @@ -278,7 +278,7 @@ section at the end of this file). * HID class is 3, no subclass and protocol required (but may be useful!) * CDC class is 2, use subclass 2 and protocol 1 for ACM */ -#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 28 +#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 43 /* Define this to the length of the HID report descriptor, if you implement * an HID device. Otherwise don't define it or define it to 0. * If you use this define, you must add a PROGMEM character array named