Fix XMEGA core USB driver so that device mode enumerates correctly on the host PC.

pull/1469/head
Dean Camera 13 years ago
parent eb5b8a32e4
commit 0304916356

@ -56,6 +56,7 @@
* - Gamecube controller to USB adapter: https://www.facebook.com/media/set/?set=a.10150202447076304.310536.688776303&l=df53851c50 * - 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 * - 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 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/ * - 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/ * - 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 * - Ikea RGB LED USB modification: http://slashhome.se/p/projects/id/ikea_dioder_usb/#project

@ -211,6 +211,7 @@
NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
SerialByte = pgm_read_byte(SigReadAddress); SerialByte = pgm_read_byte(SigReadAddress);
NVM.CMD = 0;
if (SerialCharNum & 0x01) if (SerialCharNum & 0x01)
{ {

@ -53,7 +53,7 @@ bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Number,
Endpoint_SelectEndpoint(Number | Direction); Endpoint_SelectEndpoint(Number | Direction);
USB_Endpoint_SelectedHandle->CTRL = 0; 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->CTRL = Config;
USB_Endpoint_SelectedHandle->CNT = 0; USB_Endpoint_SelectedHandle->CNT = 0;
USB_Endpoint_SelectedHandle->DATAPTR = (intptr_t)&USB_Endpoint_SelectedFIFO->Data[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) while (!(Endpoint_IsOUTReceived()))
return; {
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)

@ -433,7 +433,7 @@
{ {
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.
@ -486,7 +486,13 @@
static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE; static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ClearSETUP(void) 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;
} }
@ -529,7 +535,14 @@
static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE; static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_StallTransaction(void) 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.
@ -551,7 +564,7 @@
static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; 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)
{ {
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. */

@ -69,8 +69,8 @@ void USB_Init(
NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
USB.CAL0 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL0)); 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.EPPTR = (intptr_t)&USB_EndpointTable;
USB.CTRLA = (USB_STFRNUM_bm | USB_MAXEP_gm); USB.CTRLA = (USB_STFRNUM_bm | USB_MAXEP_gm);

@ -282,8 +282,8 @@
{ {
NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
DFLLRC32M.CALA = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSCA)); 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;
@ -359,7 +359,7 @@
GlobalInterruptDisable(); GlobalInterruptDisable();
CCP = CCP_IOREG_gc; CCP = CCP_IOREG_gc;
CLK.CTRL = ClockSourceMask; CLK_CTRL = ClockSourceMask;
SetGlobalInterruptMask(CurrentGlobalInt); SetGlobalInterruptMask(CurrentGlobalInt);

Loading…
Cancel
Save