Skip to content
Snippets Groups Projects
Commit a4d67bb6 authored by Dean Camera's avatar Dean Camera
Browse files

USB XMEGA support improvements; add DFLL clock platform support, ensure the...

USB XMEGA support improvements; add DFLL clock platform support, ensure the endpoint table is correctly aligned and configured in the USB controller.
parent db73b112
No related branches found
No related tags found
No related merge requests found
......@@ -40,7 +40,7 @@ volatile uint8_t USB_CurrentMode = USB_MODE_None;
volatile uint8_t USB_Options;
#endif
USB_EP_TABLE_t USB_EndpointTable ATTR_ALIGNED(2);
USB_EP_TABLE_t USB_EndpointTable ATTR_ALIGNED(4);
void USB_Init(
#if defined(USB_CAN_BE_BOTH)
......@@ -72,6 +72,8 @@ void USB_Init(
NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1));
USB.EPPTR = (intptr_t)&USB_EndpointTable;
if ((USB_Options & USB_OPT_BUSEVENT_PRIHIGH) == USB_OPT_BUSEVENT_PRIHIGH)
USB.INTCTRLA = (3 << USB_INTLVL_gp);
else if ((USB_Options & USB_OPT_BUSEVENT_PRIMED) == USB_OPT_BUSEVENT_PRIMED)
......@@ -81,7 +83,7 @@ void USB_Init(
SetGlobalInterruptMask(CurrentGlobalInt);
USB_ResetInterface();
USB_ResetInterface();
}
void USB_Disable(void)
......@@ -102,6 +104,8 @@ void USB_ResetInterface(void)
else
CLK.USBCTRL = ((((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_PLL_gc | CLK_USBSEN_bm);
USB_Device_SetDeviceAddress(0);
USB_INT_DisableAllInterrupts();
USB_INT_ClearAllInterrupts();
......
......@@ -108,6 +108,14 @@
CLOCK_SRC_PLL = 4, /**< Clock sourced from the Internal PLL clock. */
};
/** Enum for the possible DFLL clock reference sources. */
enum XMEGA_System_DFLLReference_t
{
DFLL_REF_INT_RC32KHZ = 0, /**< Reference clock sourced from the Internal 32KHz RC Oscillator clock. */
DFLL_REF_EXT_RC32KHZ = 1, /**< Reference clock sourced from the External 32KHz RC Oscillator clock connected to TOSC pins. */
DFLL_REF_INT_USBSOF = 2, /**< Reference clock sourced from the USB Start Of Frame packets. */
};
/* Inline Functions: */
/** Starts the external oscillator of the XMEGA microcontroller, with the given options. This routine blocks until
* the oscillator is ready for use.
......@@ -240,6 +248,79 @@
OSC.CTRL &= ~OSC_PLLEN_bm;
}
/** Starts the DFLL of the XMEGA microcontroller, with the given options.
*
* \param[in] Source RC Clock source for the DFLL, a value from \ref XMEGA_System_ClockSource_t.
* \param[in] Reference Reference clock source for the DFLL, an value from \ref XMEGA_System_DFLLReference_t
* \param[in] Frequency Target frequency of the DFLL's output.
*
* \return Boolean \c true if the DFLL was successfully started, \c false if invalid parameters specified.
*/
static inline bool XMEGACLK_StartDFLL(const uint8_t Source,
const uint8_t Reference,
const uint32_t Frequency) ATTR_ALWAYS_INLINE;
static inline bool XMEGACLK_StartDFLL(const uint8_t Source,
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)));
}
switch (Source)
{
case CLOCK_SRC_INT_RC2MHZ:
OSC.DFLLCTRL |= (Reference << OSC_RC32MCREF_gp);
DFLLRC2M.COMP1 = (DFLLCompare >> 8);
DFLLRC2M.COMP2 = (DFLLCompare & 0xFF);
DFLLRC2M.CALA = (DFFLCal >> 8);
DFLLRC2M.CALB = (DFFLCal & 0xFF);
DFLLRC2M.CTRL = DFLL_ENABLE_bm;
break;
case CLOCK_SRC_INT_RC32MHZ:
OSC.DFLLCTRL |= (Reference << OSC_RC32MCREF_gp);
DFLLRC32M.COMP1 = (DFLLCompare >> 8);
DFLLRC32M.COMP2 = (DFLLCompare & 0xFF);
DFLLRC32M.CALA = (DFFLCal >> 8);
DFLLRC32M.CALB = (DFFLCal & 0xFF);
DFLLRC32M.CTRL = DFLL_ENABLE_bm;
break;
default:
return false;
}
return true;
}
/** Stops the given DFLL of the XMEGA microcontroller.
*
* \param[in] Source RC Clock source for the DFLL to be stopped, a value from \ref XMEGA_System_ClockSource_t.
*
* \return Boolean \c true if the DFLL was successfully stopped, \c false if invalid parameters specified.
*/
static inline bool XMEGACLK_StopDFLL(const uint8_t Source) ATTR_ALWAYS_INLINE;
static inline bool XMEGACLK_StopDFLL(const uint8_t Source)
{
switch (Source)
{
case CLOCK_SRC_INT_RC2MHZ:
DFLLRC2M.CTRL = 0;
break;
case CLOCK_SRC_INT_RC32MHZ:
DFLLRC32M.CTRL = 0;
break;
default:
return false;
}
return true;
}
/** Sets the clock source for the main microcontroller core. The given clock source should be configured
* and ready for use before this function is called.
*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment