diff --git a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h index 3fbd3ff2f0..0667f67040 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h +++ b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h @@ -231,8 +231,10 @@ ((EndpointNumber & ENDPOINT_DIR_IN) ? 0x01 : 0); Endpoint_SelectedEndpoint = EndpointNumber; - Endpoint_SelectedEndpointHandle = &((USB_EP_t*)&USB_EndpointTable.Endpoints)[EPTableIndex]; Endpoint_SelectedEndpointAux = &Endpoint_AuxData[EPTableIndex]; + Endpoint_SelectedEndpointHandle = (EndpointNumber & ENDPOINT_DIR_IN) ? + &USB_EndpointTable.Endpoints[EndpointNumber & ENDPOINT_EPNUM_MASK].IN : + &USB_EndpointTable.Endpoints[EndpointNumber & ENDPOINT_EPNUM_MASK].OUT; } /** Configures the specified endpoint number with the given endpoint type, direction, bank size diff --git a/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c b/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c index 8c6f46cad2..58d1b768b1 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c +++ b/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c @@ -101,10 +101,15 @@ void USB_Disable(void) void USB_ResetInterface(void) { if (USB_Options & USB_DEVICE_OPT_LOWSPEED) - CLK.USBCTRL = ((((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_PLL_gc | CLK_USBSEN_bm); + CLK.USBCTRL = (((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp); else - CLK.USBCTRL = ((((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_PLL_gc | CLK_USBSEN_bm); + CLK.USBCTRL = (((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp); + if (USB_Options & USB_OPT_PLLCLKSRC) + CLK.USBCTRL |= (CLK_USBSRC_PLL_gc | CLK_USBSEN_bm); + else + CLK.USBCTRL |= (CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm); + USB_Device_SetDeviceAddress(0); USB_INT_DisableAllInterrupts(); diff --git a/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h index abaf0578aa..0d39258af7 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h +++ b/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h @@ -60,12 +60,12 @@ /* Type Defines: */ typedef struct { - uint16_t FrameNum; struct { USB_EP_t OUT; USB_EP_t IN; } Endpoints[16]; + uint16_t FrameNum; } ATTR_PACKED USB_EndpointTable_t; /* External Variables: */ @@ -113,6 +113,12 @@ * and resume events, bus reset events and other events related to the management of the USB bus. */ #define USB_OPT_BUSEVENT_PRIHIGH ((1 << 2) | (0 << 1)) + + /** Sets the USB controller to source its clock from the internal RC 32MHz clock, once it has been DFLL calibrated to 48MHz. */ + #define USB_OPT_RC32MCLKSRC (0 << 3) + + /** Sets the USB controller to source its clock from the internal PLL. */ + #define USB_OPT_PLLCLKSRC (1 << 3) //@} #if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__) diff --git a/LUFA/Platform/XMEGA/ClockManagement.h b/LUFA/Platform/XMEGA/ClockManagement.h index 07ba0e73c8..357ed7b327 100644 --- a/LUFA/Platform/XMEGA/ClockManagement.h +++ b/LUFA/Platform/XMEGA/ClockManagement.h @@ -263,14 +263,7 @@ const uint8_t Reference, const uint32_t Frequency) { - uint16_t DFLLCompare = (Frequency / 1024); - uint16_t DFFLCal = 0; - - if (Reference == DFLL_REF_INT_USBSOF) - { - NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; - DFFLCal = ((0x00 << 8) | pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSC))); - } + uint16_t DFLLCompare = (Frequency / 1000); switch (Source) { @@ -278,16 +271,21 @@ OSC.DFLLCTRL |= (Reference << OSC_RC2MCREF_bp); DFLLRC2M.COMP1 = (DFLLCompare & 0xFF); DFLLRC2M.COMP2 = (DFLLCompare >> 8); - DFLLRC2M.CALA = (DFFLCal & 0xFF); - DFLLRC2M.CALB = (DFFLCal >> 8); DFLLRC2M.CTRL = DFLL_ENABLE_bm; break; case CLOCK_SRC_INT_RC32MHZ: OSC.DFLLCTRL |= (Reference << OSC_RC32MCREF_gp); DFLLRC32M.COMP1 = (DFLLCompare & 0xFF); DFLLRC32M.COMP2 = (DFLLCompare >> 8); - DFLLRC32M.CALA = (DFFLCal & 0xFF); - DFLLRC32M.CALB = (DFFLCal >> 8); + + if (Reference == DFLL_REF_INT_USBSOF) + { + 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.CTRL = DFLL_ENABLE_bm; break; default: