Automatically load in the USB calibration bytes from the User Signature Row on start-up.
Create internal SRAM variable for the endpoint control and status register table, used by the XMEGA USB controller hardware.
\r
void USB_INT_DisableAllInterrupts(void)\r
{\r
- AVR32_USBB.USBCON.vbuste = false;\r
- AVR32_USBB.USBCON.idte = false;\r
+ AVR32_USBB.USBCON.vbuste = false;\r
+ AVR32_USBB.USBCON.idte = false;\r
\r
- AVR32_USBB.uhinteclr = -1;\r
- AVR32_USBB.udinteclr = -1;\r
+ AVR32_USBB.uhinteclr = -1;\r
+ AVR32_USBB.udinteclr = -1;\r
}\r
\r
void USB_INT_ClearAllInterrupts(void)\r
AVR32_USBB.USBSTACLR.vbustic = true;\r
AVR32_USBB.USBSTACLR.idtic = true;\r
\r
- AVR32_USBB.uhintclr = -1;\r
- AVR32_USBB.udintclr = -1;\r
+ AVR32_USBB.uhintclr = -1;\r
+ AVR32_USBB.udintclr = -1;\r
}\r
\r
ISR(USB_GEN_vect)\r
\r
/* Includes: */\r
#include "../../../../Common/Common.h"\r
+ #include "../USBController.h"\r
#include "../StdDescriptors.h"\r
#include "../USBInterrupt.h"\r
#include "../Endpoint.h"\r
/** Length of the device's unique internal serial number, in bits, if present on the selected microcontroller\r
* model.\r
*/\r
- #define INTERNAL_SERIAL_LENGTH_BITS 112\r
+ #define INTERNAL_SERIAL_LENGTH_BITS (8 * (1 + (offsetof(NVM_PROD_SIGNATURES_t, COORDY1) - offsetof(NVM_PROD_SIGNATURES_t, LOTNUM0))))\r
\r
/** Start address of the internal serial number, in the appropriate address space, if present on the selected microcontroller\r
* model.\r
*/\r
- #define INTERNAL_SERIAL_START_ADDRESS 0x08\r
+ #define INTERNAL_SERIAL_START_ADDRESS offsetof(NVM_PROD_SIGNATURES_t, LOTNUM0)\r
\r
/* Function Prototypes: */\r
/** Sends a Remote Wakeup request to the host. This signals to the host that the device should\r
static inline uint16_t USB_Device_GetFrameNumber(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;\r
static inline uint16_t USB_Device_GetFrameNumber(void)\r
{\r
- return 0; // TODO\r
+ return (((uint16_t)USB_EndpointTable.FRAMENUMH << 8) | USB_EndpointTable.FRAMENUML);\r
}\r
\r
#if !defined(NO_SOF_EVENTS)\r
static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE;\r
static inline void USB_Device_EnableSOFEvents(void)\r
{\r
- // TODO\r
+ USB.INTCTRLA |= USB_SOFIE_bm;\r
}\r
\r
/** Disables the device mode Start Of Frame events. When disabled, this stops the firing of the\r
static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE;\r
static inline void USB_Device_DisableSOFEvents(void)\r
{\r
- // TODO\r
+ USB.INTCTRLA &= ~USB_SOFIE_bm;\r
}\r
#endif\r
\r
}\r
\r
SetGlobalInterruptMask(CurrentGlobalInt);\r
-\r
-\r
}\r
\r
#endif\r
CheckBytes <<= 1;\r
}\r
\r
- return (MaskVal << USB_EP_SIZE_gp);\r
+ return (MaskVal << USB_EP_BUFSIZE_gp);\r
}\r
\r
/* Function Prototypes: */\r
volatile uint8_t USB_Options;\r
#endif\r
\r
+USB_EP_TABLE_t USB_EndpointTable ATTR_ALIGNED(2);\r
+\r
void USB_Init(\r
#if defined(USB_CAN_BE_BOTH)\r
const uint8_t Mode\r
#endif\r
\r
USB_IsInitialized = true;\r
+ \r
+ uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();\r
+ GlobalInterruptDisable();\r
+\r
+ NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;\r
+ USB.CAL0 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL0));\r
+ NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;\r
+ USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1));\r
+ \r
+ SetGlobalInterruptMask(CurrentGlobalInt);\r
\r
USB_ResetInterface(); \r
}\r
void USB_ResetInterface(void)\r
{\r
if (USB_Options & USB_DEVICE_OPT_LOWSPEED)\r
- CLK.USBCTRL = ((((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_PLL_gc | CLK_USBEN_bm);\r
+ CLK.USBCTRL = ((((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_PLL_gc | CLK_USBSEN_bm);\r
else\r
- CLK.USBCTRL = ((((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_PLL_gc | CLK_USBEN_bm);\r
+ CLK.USBCTRL = ((((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp) | CLK_USBSRC_PLL_gc | CLK_USBSEN_bm);\r
\r
USB_INT_DisableAllInterrupts();\r
USB_INT_ClearAllInterrupts();\r
\r
+ // TODO: Config define for priority\r
+ USB.INTCTRLA = (2 << USB_INTLVL_gp);\r
+ PMIC.CTRL |= (1 << PMIC_MEDLVLEX_bp);\r
+\r
USB_Controller_Reset();\r
USB_Init_Device();\r
}\r
ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,\r
ENDPOINT_BANK_SINGLE);\r
\r
+ USB_INT_Enable(USB_INT_BUSEVENTI);\r
+\r
USB_Attach();\r
}\r
#endif\r
#include "../USBTask.h"\r
#include "../USBInterrupt.h"\r
\r
+ /* Private Interface - For use in library only: */\r
+ #if !defined(__DOXYGEN__)\r
+ /* External Variables: */\r
+ extern USB_EP_TABLE_t USB_EndpointTable;\r
+ #endif\r
+ \r
+ /* Includes: */\r
#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)\r
#include "../Device.h"\r
#include "../Endpoint.h"\r
\r
void USB_INT_DisableAllInterrupts(void)\r
{\r
- // TODO\r
+ USB.INTCTRLA = 0;\r
+ USB.INTCTRLB = 0;\r
}\r
\r
void USB_INT_ClearAllInterrupts(void)\r
{\r
- // TODO\r
+ USB.INTFLAGSACLR = 0xFF;\r
+ USB.INTFLAGSBCLR = 0xFF;\r
}\r
\r
-// TODO: USB ISR\r
+ISR(USB_BUSEVENT_vect)\r
+{\r
+ #if !defined(NO_SOF_EVENTS)\r
+ if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI))\r
+ {\r
+ USB_INT_Clear(USB_INT_SOFI);\r
+\r
+ EVENT_USB_Device_StartOfFrame();\r
+ }\r
+ #endif\r
+\r
+ if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Suspend))\r
+ {\r
+ USB_INT_Clear(USB_INT_BUSEVENTI_Suspend);\r
+\r
+ #if !defined(NO_LIMITED_CONTROLLER_CONNECT)\r
+ USB_DeviceState = DEVICE_STATE_Unattached;\r
+ EVENT_USB_Device_Disconnect();\r
+ #else\r
+ USB_DeviceState = DEVICE_STATE_Suspended;\r
+ EVENT_USB_Device_Suspend();\r
+ #endif\r
+ }\r
+\r
+ if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Resume))\r
+ {\r
+ USB_INT_Clear(USB_INT_BUSEVENTI_Resume);\r
+ \r
+ if (USB_Device_ConfigurationNumber)\r
+ USB_DeviceState = DEVICE_STATE_Configured;\r
+ else\r
+ USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;\r
+\r
+ #if !defined(NO_LIMITED_CONTROLLER_CONNECT)\r
+ EVENT_USB_Device_Connect();\r
+ #else\r
+ EVENT_USB_Device_WakeUp();\r
+ #endif\r
+ }\r
+\r
+ if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Reset))\r
+ {\r
+ USB_INT_Clear(USB_INT_BUSEVENTI_Reset);\r
+ \r
+ USB_DeviceState = DEVICE_STATE_Default;\r
+ USB_Device_ConfigurationNumber = 0;\r
+\r
+ Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,\r
+ ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,\r
+ ENDPOINT_BANK_SINGLE);\r
+\r
+ EVENT_USB_Device_Reset();\r
+ }\r
+}\r
\r
/* Enums: */\r
enum USB_Interrupts_t\r
{\r
- USB_INT_NONE = 0, // TODO\r
+ USB_INT_BUSEVENTI = 1,\r
+ USB_INT_BUSEVENTI_Suspend = 2,\r
+ USB_INT_BUSEVENTI_Resume = 3,\r
+ USB_INT_BUSEVENTI_Reset = 4,\r
+ USB_INT_SOFI = 5,\r
};\r
\r
/* Inline Functions: */\r
static inline void USB_INT_Enable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE;\r
static inline void USB_INT_Enable(const uint8_t Interrupt)\r
{\r
- // TODO\r
+ switch (Interrupt)\r
+ {\r
+ case USB_INT_BUSEVENTI:\r
+ USB.INTCTRLA |= USB_BUSEVIE_bm;\r
+ return;\r
+ case USB_INT_SOFI:\r
+ USB.INTCTRLA |= USB_SOFIE_bm; \r
+ return; \r
+ }\r
}\r
\r
static inline void USB_INT_Disable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE;\r
static inline void USB_INT_Disable(const uint8_t Interrupt)\r
{\r
- // TODO\r
+ switch (Interrupt)\r
+ {\r
+ case USB_INT_BUSEVENTI:\r
+ USB.INTCTRLA &= ~USB_BUSEVIE_bm;\r
+ return;\r
+ case USB_INT_SOFI:\r
+ USB.INTCTRLA &= ~USB_SOFIE_bm; \r
+ return; \r
+ }\r
}\r
\r
static inline void USB_INT_Clear(const uint8_t Interrupt) ATTR_ALWAYS_INLINE;\r
static inline void USB_INT_Clear(const uint8_t Interrupt)\r
{\r
- // TODO\r
+ switch (Interrupt)\r
+ {\r
+ case USB_INT_BUSEVENTI_Suspend:\r
+ USB.INTFLAGSACLR = USB_SUSPENDIF_bm;\r
+ return;\r
+ case USB_INT_BUSEVENTI_Resume:\r
+ USB.INTFLAGSACLR = USB_RESUMEIF_bm;\r
+ return;\r
+ case USB_INT_BUSEVENTI_Reset:\r
+ USB.INTFLAGSACLR = USB_RSTIF_bm;\r
+ return;\r
+ case USB_INT_SOFI:\r
+ USB.INTFLAGSACLR = USB_SOFIF_bm; \r
+ return; \r
+ }\r
}\r
\r
static inline bool USB_INT_IsEnabled(const uint8_t Interrupt) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;\r
static inline bool USB_INT_IsEnabled(const uint8_t Interrupt)\r
{\r
- return false; // TODO\r
+ switch (Interrupt)\r
+ {\r
+ case USB_INT_BUSEVENTI:\r
+ return (USB.INTCTRLA & USB_BUSEVIE_bm);\r
+ case USB_INT_SOFI:\r
+ return (USB.INTCTRLA & USB_SOFIE_bm);\r
+ }\r
+ \r
+ return false;\r
}\r
\r
static inline bool USB_INT_HasOccurred(const uint8_t Interrupt) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;\r
static inline bool USB_INT_HasOccurred(const uint8_t Interrupt)\r
{\r
- return false; // TODO\r
+ switch (Interrupt)\r
+ {\r
+ case USB_INT_BUSEVENTI_Suspend:\r
+ return (USB.INTFLAGSACLR & USB_SUSPENDIF_bm);\r
+ case USB_INT_BUSEVENTI_Resume:\r
+ return (USB.INTFLAGSACLR & USB_RESUMEIF_bm);\r
+ case USB_INT_BUSEVENTI_Reset:\r
+ return (USB.INTFLAGSACLR & USB_RSTIF_bm);\r
+ case USB_INT_SOFI:\r
+ return (USB.INTFLAGSACLR & USB_SOFIF_bm);\r
+ }\r
+ \r
+ return false;\r
}\r
\r
/* Includes: */\r