((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
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();
/* 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: */
* 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__)
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)
{
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: