Fix XMEGA core USB driver so that device mode enumerates correctly on the host PC.
authorDean Camera <dean@fourwalledcubicle.com>
Mon, 31 Oct 2011 02:26:21 +0000 (02:26 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Mon, 31 Oct 2011 02:26:21 +0000 (02:26 +0000)
LUFA/DoxygenPages/LUFAPoweredProjects.txt
LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h
LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c
LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h
LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c
LUFA/Platform/XMEGA/ClockManagement.h

index df72cbc..4b85285 100644 (file)
@@ -56,6 +56,7 @@
  *  - Gamecube controller to USB adapter: https://www.facebook.com/media/set/?set=a.10150202447076304.310536.688776303&l=df53851c50 
  *  - Garmin GPS USB to NMEA standard serial sentence translator: http://github.com/nall/garmin-transmogrifier/tree/master
  *  - Generic HID Device Creator: http://generichid.sourceforge.net/
  *  - Gamecube controller to USB adapter: https://www.facebook.com/media/set/?set=a.10150202447076304.310536.688776303&l=df53851c50 
  *  - Garmin GPS USB to NMEA standard serial sentence translator: http://github.com/nall/garmin-transmogrifier/tree/master
  *  - Generic HID Device Creator: http://generichid.sourceforge.net/
+ *  - Generic HID Open Source Framework: http://www.waitingforfriday.com/index.php/USB_Generic_HID_Open_Source_Framework_for_Atmel_AVR_and_Windows
  *  - Ghetto Drum, a MIDI drum controller: http://noisybox.net/art/gdrum/
  *  - Hiduino, a USB-MIDI replacement firmware for the Arduino Uno: http://code.google.com/p/hiduino/
  *  - Ikea RGB LED USB modification: http://slashhome.se/p/projects/id/ikea_dioder_usb/#project
  *  - Ghetto Drum, a MIDI drum controller: http://noisybox.net/art/gdrum/
  *  - Hiduino, a USB-MIDI replacement firmware for the Arduino Uno: http://code.google.com/p/hiduino/
  *  - Ikea RGB LED USB modification: http://slashhome.se/p/projects/id/ikea_dioder_usb/#project
index df6823a..1c128dc 100644 (file)
 
                                        NVM.CMD    = NVM_CMD_READ_CALIB_ROW_gc;
                                        SerialByte = pgm_read_byte(SigReadAddress);
 
                                        NVM.CMD    = NVM_CMD_READ_CALIB_ROW_gc;
                                        SerialByte = pgm_read_byte(SigReadAddress);
+                                       NVM.CMD    = 0;
 
                                        if (SerialCharNum & 0x01)
                                        {
 
                                        if (SerialCharNum & 0x01)
                                        {
index 3c9ba27..604427f 100644 (file)
@@ -53,7 +53,7 @@ bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Number,
        Endpoint_SelectEndpoint(Number | Direction);
        
        USB_Endpoint_SelectedHandle->CTRL      = 0;
        Endpoint_SelectEndpoint(Number | Direction);
        
        USB_Endpoint_SelectedHandle->CTRL      = 0;
-       USB_Endpoint_SelectedHandle->STATUS    = (Direction == ENDPOINT_DIR_IN) ? (USB_EP_BUSNACK0_bm | USB_EP_TRNCOMPL0_bm) : USB_EP_BUSNACK0_bm;
+       USB_Endpoint_SelectedHandle->STATUS    = (Direction == ENDPOINT_DIR_IN) ? USB_EP_BUSNACK0_bm : 0;
        USB_Endpoint_SelectedHandle->CTRL      = Config;
        USB_Endpoint_SelectedHandle->CNT       = 0;
        USB_Endpoint_SelectedHandle->DATAPTR   = (intptr_t)&USB_Endpoint_SelectedFIFO->Data[0];
        USB_Endpoint_SelectedHandle->CTRL      = Config;
        USB_Endpoint_SelectedHandle->CNT       = 0;
        USB_Endpoint_SelectedHandle->DATAPTR   = (intptr_t)&USB_Endpoint_SelectedFIFO->Data[0];
@@ -72,13 +72,26 @@ void Endpoint_ClearEndpoints(void)
 
 void Endpoint_ClearStatusStage(void)
 {
 
 void Endpoint_ClearStatusStage(void)
 {
-       while (!(Endpoint_IsOUTReceived()))
+       if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST)
        {
        {
-               if (USB_DeviceState == DEVICE_STATE_Unattached)
-                 return;
+               while (!(Endpoint_IsOUTReceived()))
+               {
+                       if (USB_DeviceState == DEVICE_STATE_Unattached)
+                         return;
+               }
+
+               Endpoint_ClearOUT();
        }
        }
+       else
+       {
+               while (!(Endpoint_IsINReady()))
+               {
+                       if (USB_DeviceState == DEVICE_STATE_Unattached)
+                         return;
+               }
 
 
-       Endpoint_ClearOUT();
+               Endpoint_ClearIN();
+       }
 }
 
 #if !defined(CONTROL_ONLY_DEVICE)
 }
 
 #if !defined(CONTROL_ONLY_DEVICE)
index c26f7e5..2ba1356 100644 (file)
                        {
                                Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN);
                                
                        {
                                Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN);
                                
-                               return ((USB_Endpoint_SelectedHandle->STATUS & USB_EP_TRNCOMPL0_bm) ? true : false);
+                               return ((USB_Endpoint_SelectedHandle->STATUS & USB_EP_BUSNACK0_bm) ? true : false);
                        }
 
                        /** Determines if the selected OUT endpoint has received new packet from the host.
                        }
 
                        /** Determines if the selected OUT endpoint has received new packet from the host.
                        static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearSETUP(void)
                        {
                        static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_ClearSETUP(void)
                        {
-                               USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm);
+                               USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_SETUP_bm | USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm);
+
+                               USB_Endpoint_SelectedHandle->STATUS |= USB_EP_TOGGLE_bm;
+                               USB_Endpoint_SelectedFIFO->Position  = 0;
+
+                               Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN);
+                               USB_Endpoint_SelectedHandle->STATUS |= USB_EP_TOGGLE_bm;
                                USB_Endpoint_SelectedFIFO->Position  = 0;
                        }
 
                                USB_Endpoint_SelectedFIFO->Position  = 0;
                        }
 
                        static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_StallTransaction(void)
                        {
                        static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE;
                        static inline void Endpoint_StallTransaction(void)
                        {
-                               USB_Endpoint_SelectedHandle->CTRL |=  USB_EP_STALL_bm;
+                               USB_Endpoint_SelectedHandle->CTRL |= USB_EP_STALL_bm;
+                               
+                               if ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_TYPE_gm) == USB_EP_TYPE_CONTROL_gc)
+                               {
+                                       Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint |  ENDPOINT_DIR_IN);
+                                       USB_Endpoint_SelectedHandle->STATUS |= USB_EP_STALL_bm;
+                                       Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN);
+                               }
                        }
 
                        /** Clears the STALL condition on the currently selected endpoint.
                        }
 
                        /** Clears the STALL condition on the currently selected endpoint.
                        static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsStalled(void)
                        {
                        static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
                        static inline bool Endpoint_IsStalled(void)
                        {
-                               return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_STALL_bm) ? true : false);
+                               return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_STALLF_bm) ? true : false);
                        }
 
                        /** Resets the data toggle of the currently selected endpoint. */
                        }
 
                        /** Resets the data toggle of the currently selected endpoint. */
index 58d1b76..3b77930 100644 (file)
@@ -69,8 +69,8 @@ void USB_Init(
 
        NVM.CMD  = NVM_CMD_READ_CALIB_ROW_gc;
        USB.CAL0 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL0));
 
        NVM.CMD  = NVM_CMD_READ_CALIB_ROW_gc;
        USB.CAL0 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL0));
-       NVM.CMD  = NVM_CMD_READ_CALIB_ROW_gc;
        USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1));
        USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1));
+       NVM.CMD  = 0;
        
        USB.EPPTR = (intptr_t)&USB_EndpointTable;
        USB.CTRLA = (USB_STFRNUM_bm | USB_MAXEP_gm);
        
        USB.EPPTR = (intptr_t)&USB_EndpointTable;
        USB.CTRLA = (USB_STFRNUM_bm | USB_MAXEP_gm);
index 357ed7b..1305d0e 100644 (file)
                                                {
                                                        NVM.CMD        = NVM_CMD_READ_CALIB_ROW_gc;
                                                        DFLLRC32M.CALA = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSCA));
                                                {
                                                        NVM.CMD        = NVM_CMD_READ_CALIB_ROW_gc;
                                                        DFLLRC32M.CALA = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSCA));
-                                                       NVM.CMD        = NVM_CMD_READ_CALIB_ROW_gc;
                                                        DFLLRC32M.CALB = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSC));
                                                        DFLLRC32M.CALB = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSC));
+                                                       NVM.CMD        = 0;
                                                }
 
                                                DFLLRC32M.CTRL  = DFLL_ENABLE_bm;
                                                }
 
                                                DFLLRC32M.CTRL  = DFLL_ENABLE_bm;
                                GlobalInterruptDisable();
 
                                CCP      = CCP_IOREG_gc;
                                GlobalInterruptDisable();
 
                                CCP      = CCP_IOREG_gc;
-                               CLK.CTRL = ClockSourceMask;
+                               CLK_CTRL = ClockSourceMask;
                                
                                SetGlobalInterruptMask(CurrentGlobalInt);
                                
                                
                                SetGlobalInterruptMask(CurrentGlobalInt);