]> git.zarvox.org Git - usbsnes.git/commitdiff
Recognized as a joystick, timer verified working.
authorDrew Fisher <drew.m.fisher@gmail.com>
Fri, 11 Jun 2010 06:32:37 +0000 (23:32 -0700)
committerDrew Fisher <drew.m.fisher@gmail.com>
Fri, 11 Jun 2010 06:32:37 +0000 (23:32 -0700)
Actually gets recognized and polled correctly.  Increments a bitmask revealed in the button state every second.

Makefile
main.c
usbconfig.h

index fa79efa81625ab6d8ad83a59f134c6a46ff6d6ee..6941d0c1a50b650efe1d4c8e0cd908ff846a3297 100644 (file)
--- 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 e34a7cfd49065207d1806b2088330a3552cd7cdd..9e8ccb8a580b82c09532d158ef62c78f82a56a93 100644 (file)
--- a/main.c
+++ b/main.c
 
 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));
                }
index 3363dc9d5aecf0fe4df4dc702d78da12a83ae092..9dfeae0d7c0cbf0abd58dad7b94e43e3f40277ba 100644 (file)
@@ -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