* \note Restrictions apply on the number, size and type of endpoints which can be used\r
* when running in low speed mode - refer to the USB 2.0 specification.\r
*/\r
- #define USB_DEVICE_OPT_LOWSPEED (1 << 0)\r
+ #define USB_DEVICE_OPT_LOWSPEED (1 << 0)\r
\r
/** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the\r
* USB interface should be initialized in full speed (12Mb/s) mode.\r
*/\r
- #define USB_DEVICE_OPT_FULLSPEED (0 << 0)\r
+ #define USB_DEVICE_OPT_FULLSPEED (0 << 0)\r
//@}\r
\r
/** String descriptor index for the device's unique serial number string descriptor within the device.\r
* On unsupported devices, this will evaluate to \ref NO_DESCRIPTOR and so will force the host to create a pseudo-serial\r
* number for the device.\r
*/\r
- #define USE_INTERNAL_SERIAL NO_DESCRIPTOR\r
+ #define USE_INTERNAL_SERIAL 0xDC\r
\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 0\r
+ #define INTERNAL_SERIAL_LENGTH_BITS 112\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 0 \r
+ #define INTERNAL_SERIAL_START_ADDRESS 0x08\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 void USB_Device_SetLowSpeed(void) ATTR_ALWAYS_INLINE;\r
static inline void USB_Device_SetLowSpeed(void)\r
{\r
- // TODO\r
+ USB.CTRLA &= ~USB_SPEED_bm;\r
}\r
\r
static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE;\r
static inline void USB_Device_SetFullSpeed(void)\r
{\r
- // TODO\r
+ USB.CTRLA |= USB_SPEED_bm;\r
}\r
\r
static inline void USB_Device_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE;\r
static inline void USB_Device_SetDeviceAddress(const uint8_t Address)\r
{\r
- // TODO\r
+ USB.ADDR = Address;\r
}\r
\r
static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;\r
static inline bool USB_Device_IsAddressSet(void)\r
{\r
- return false; // TODO\r
+ return ((USB.ADDR != 0) ? true : false);\r
}\r
\r
- #if (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)\r
static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) ATTR_NON_NULL_PTR_ARG(1);\r
static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString)\r
{\r
- // TODO\r
+ uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();\r
+ GlobalInterruptDisable();\r
+ \r
+ uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS;\r
+\r
+ for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++)\r
+ { \r
+ uint8_t SerialByte;\r
+\r
+ NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;\r
+ SerialByte = pgm_read_byte(SigReadAddress);\r
+\r
+ if (SerialCharNum & 0x01)\r
+ {\r
+ SerialByte >>= 4;\r
+ SigReadAddress++;\r
+ }\r
+\r
+ SerialByte &= 0x0F;\r
+\r
+ UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ?\r
+ (('A' - 10) + SerialByte) : ('0' + SerialByte));\r
+ }\r
+ \r
+ SetGlobalInterruptMask(CurrentGlobalInt);\r
+\r
+\r
}\r
- #endif\r
\r
#endif\r
\r
/* Private Interface - For use in library only: */\r
#if !defined(__DOXYGEN__)\r
/* Macros: */\r
- #define _ENDPOINT_GET_MAXSIZE(EPIndex) _ENDPOINT_GET_MAXSIZE2(ENDPOINT_DETAILS_EP ## EPIndex)\r
- #define _ENDPOINT_GET_MAXSIZE2(EPDetails) _ENDPOINT_GET_MAXSIZE3(EPDetails)\r
- #define _ENDPOINT_GET_MAXSIZE3(MaxSize, Banks) (MaxSize)\r
-\r
- #define _ENDPOINT_GET_BANKS(EPIndex) _ENDPOINT_GET_BANKS2(ENDPOINT_DETAILS_EP ## EPIndex)\r
- #define _ENDPOINT_GET_BANKS2(EPDetails) _ENDPOINT_GET_BANKS3(EPDetails)\r
- #define _ENDPOINT_GET_BANKS3(MaxSize, Banks) (Banks)\r
-\r
- #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)\r
- #define ENDPOINT_DETAILS_MAXEP 7\r
-\r
- #define ENDPOINT_DETAILS_EP0 64, 1\r
- #define ENDPOINT_DETAILS_EP1 256, 2\r
- #define ENDPOINT_DETAILS_EP2 64, 2\r
- #define ENDPOINT_DETAILS_EP3 64, 2\r
- #define ENDPOINT_DETAILS_EP4 64, 2\r
- #define ENDPOINT_DETAILS_EP5 64, 2\r
- #define ENDPOINT_DETAILS_EP6 64, 2\r
- #else\r
- #define ENDPOINT_DETAILS_MAXEP 5\r
+ #define _ENDPOINT_GET_MAXSIZE(EPIndex) 1023\r
+ #define _ENDPOINT_GET_BANKS(EPIndex) 2\r
\r
- #define ENDPOINT_DETAILS_EP0 64, 1\r
- #define ENDPOINT_DETAILS_EP1 64, 1\r
- #define ENDPOINT_DETAILS_EP2 64, 1\r
- #define ENDPOINT_DETAILS_EP3 64, 2\r
- #define ENDPOINT_DETAILS_EP4 64, 2\r
- #endif\r
+ #define ENDPOINT_DETAILS_MAXEP 16\r
\r
/* Inline Functions: */\r
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST\r
/** Endpoint data direction mask for \ref Endpoint_ConfigureEndpoint(). This indicates that the endpoint\r
* should be initialized in the OUT direction - i.e. data flows from host to device.\r
*/\r
- #define ENDPOINT_DIR_OUT (0 << EPDIR)\r
+ #define ENDPOINT_DIR_OUT 0 // TODO\r
\r
/** Endpoint data direction mask for \ref Endpoint_ConfigureEndpoint(). This indicates that the endpoint\r
* should be initialized in the IN direction - i.e. data flows from device to host.\r
*/\r
- #define ENDPOINT_DIR_IN (1 << EPDIR)\r
+ #define ENDPOINT_DIR_IN 0 // TODO\r
//@}\r
\r
/** \name Endpoint Bank Mode Masks */\r
* in slower transfers as only one USB device (the AVR or the host) can access the endpoint's\r
* bank at the one time.\r
*/\r
- #define ENDPOINT_BANK_SINGLE (0 << EPBK0)\r
+ #define ENDPOINT_BANK_SINGLE 0 // TODO\r
\r
/** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates\r
* that the endpoint should have two banks, which requires more USB FIFO memory but results\r
* in faster transfers as one USB device (the AVR or the host) can access one bank while the other\r
* accesses the second bank.\r
*/\r
- #define ENDPOINT_BANK_DOUBLE (1 << EPBK0)\r
+ #define ENDPOINT_BANK_DOUBLE 0 // TODO\r
//@}\r
\r
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))\r
#endif\r
)\r
{\r
- // TODO\r
+ #if !defined(USE_STATIC_OPTIONS)\r
+ USB_Options = Options;\r
+ #endif\r
+ \r
+ USB_IsInitialized = true;\r
+\r
+ USB_ResetInterface(); \r
}\r
\r
void USB_Disable(void)\r
{\r
- // TODO\r
+ USB_INT_DisableAllInterrupts();\r
+ USB_INT_ClearAllInterrupts();\r
+\r
+ USB_Detach();\r
+ USB_Controller_Disable();\r
+\r
+ USB_IsInitialized = false; \r
}\r
\r
void USB_ResetInterface(void)\r
{\r
- // TODO\r
+ USB_INT_DisableAllInterrupts();\r
+ USB_INT_ClearAllInterrupts();\r
+\r
+ USB_Controller_Reset();\r
+ USB_Init_Device();\r
}\r
\r
#if defined(USB_CAN_BE_DEVICE)\r
static void USB_Init_Device(void)\r
{\r
- // TODO\r
+ USB_DeviceState = DEVICE_STATE_Unattached;\r
+ USB_Device_ConfigurationNumber = 0;\r
+\r
+ #if !defined(NO_DEVICE_REMOTE_WAKEUP)\r
+ USB_Device_RemoteWakeupEnabled = false;\r
+ #endif\r
+\r
+ #if !defined(NO_DEVICE_SELF_POWER)\r
+ USB_Device_CurrentlySelfPowered = false;\r
+ #endif\r
+\r
+ #if !defined(FIXED_CONTROL_ENDPOINT_SIZE)\r
+ USB_Descriptor_Device_t* DeviceDescriptorPtr;\r
+ \r
+ #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \\r
+ !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))\r
+ uint8_t DescriptorAddressSpace;\r
+\r
+ if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr, &DescriptorAddressSpace) != NO_DESCRIPTOR)\r
+ {\r
+ if (DescriptorAddressSpace == MEMSPACE_FLASH)\r
+ USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);\r
+ else if (DescriptorAddressSpace == MEMSPACE_EEPROM)\r
+ USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);\r
+ else\r
+ USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;\r
+ }\r
+ #else\r
+ if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR)\r
+ {\r
+ #if defined(USE_RAM_DESCRIPTORS)\r
+ USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;\r
+ #elif defined(USE_EEPROM_DESCRIPTORS)\r
+ USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);\r
+ #else\r
+ USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);\r
+ #endif\r
+ } \r
+ #endif\r
+ #endif\r
+\r
+ if (USB_Options & USB_DEVICE_OPT_LOWSPEED)\r
+ USB_Device_SetLowSpeed();\r
+ else\r
+ USB_Device_SetFullSpeed();\r
+\r
+ Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,\r
+ ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,\r
+ ENDPOINT_BANK_SINGLE);\r
+\r
+ USB_Attach();\r
}\r
#endif\r
#endif\r
\r
/* Public Interface - May be used in end-application: */\r
- /* Macros: */\r
- /** \name USB Controller Option Masks */\r
- //@{\r
- /** Regulator disable option mask for \ref USB_Init(). This indicates that the internal 3.3V USB data pad\r
- * regulator should be disabled and the AVR's VCC level used for the data pads.\r
- *\r
- * \note See USB AVR data sheet for more information on the internal pad regulator.\r
- */\r
- #define USB_OPT_REG_DISABLED (1 << 1)\r
-\r
- /** Regulator enable option mask for \ref USB_Init(). This indicates that the internal 3.3V USB data pad\r
- * regulator should be enabled to regulate the data pin voltages from the VBUS level down to a level within\r
- * the range allowable by the USB standard.\r
- *\r
- * \note See USB AVR data sheet for more information on the internal pad regulator.\r
- */\r
- #define USB_OPT_REG_ENABLED (0 << 1)\r
-\r
- /** Manual PLL control option mask for \ref USB_Init(). This indicates to the library that the user application\r
- * will take full responsibility for controlling the AVR's PLL (used to generate the high frequency clock\r
- * that the USB controller requires) and ensuring that it is locked at the correct frequency for USB operations.\r
- */\r
- #define USB_OPT_MANUAL_PLL (1 << 2)\r
-\r
- /** Automatic PLL control option mask for \ref USB_Init(). This indicates to the library that the library should\r
- * take full responsibility for controlling the AVR's PLL (used to generate the high frequency clock\r
- * that the USB controller requires) and ensuring that it is locked at the correct frequency for USB operations.\r
- */\r
- #define USB_OPT_AUTO_PLL (0 << 2)\r
- //@}\r
- \r
+ /* Macros: */ \r
/** \name Endpoint/Pipe Type Masks */\r
//@{\r
/** Mask for a CONTROL type endpoint or pipe.\r
*\r
* \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions.\r
*/\r
- #define EP_TYPE_CONTROL 0x00\r
+ #define EP_TYPE_CONTROL 0x00\r
\r
/** Mask for an ISOCHRONOUS type endpoint or pipe.\r
*\r
* \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions.\r
*/\r
- #define EP_TYPE_ISOCHRONOUS 0x01\r
+ #define EP_TYPE_ISOCHRONOUS 0x01\r
\r
/** Mask for a BULK type endpoint or pipe.\r
*\r
* \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions.\r
*/\r
- #define EP_TYPE_BULK 0x02\r
+ #define EP_TYPE_BULK 0x02\r
\r
/** Mask for an INTERRUPT type endpoint or pipe.\r
*\r
* \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions.\r
*/\r
- #define EP_TYPE_INTERRUPT 0x03\r
+ #define EP_TYPE_INTERRUPT 0x03\r
//@}\r
\r
#if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__)\r
#endif\r
\r
/* Inline Functions: */\r
- /** Determines if the VBUS line is currently high (i.e. the USB host is supplying power).\r
- *\r
- * \note This function is not available on some AVR models which do not support hardware VBUS monitoring.\r
- *\r
- * \return Boolean \c true if the VBUS line is currently detecting power from a host, \c false otherwise.\r
- */\r
- static inline bool USB_VBUS_GetStatus(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;\r
- static inline bool USB_VBUS_GetStatus(void)\r
- {\r
- return 0; // TODO\r
- }\r
-\r
/** Detaches the device from the USB bus. This has the effect of removing the device from any\r
* attached host, ceasing USB communications. If no host is present, this prevents any host from\r
* enumerating the device once attached until \ref USB_Attach() is called.\r
static inline void USB_Detach(void) ATTR_ALWAYS_INLINE;\r
static inline void USB_Detach(void)\r
{\r
- // TODO\r
+ USB.CTRLB &= ~USB_ATTACH_bm;\r
}\r
\r
/** Attaches the device to the USB bus. This announces the device's presence to any attached\r
static inline void USB_Attach(void) ATTR_ALWAYS_INLINE;\r
static inline void USB_Attach(void)\r
{\r
- // TODO\r
+ USB.CTRLB |= USB_ATTACH_bm;\r
}\r
\r
/* Function Prototypes: */\r
#endif\r
\r
/* Inline Functions: */\r
- static inline void USB_REG_On(void) ATTR_ALWAYS_INLINE;\r
- static inline void USB_REG_On(void)\r
- {\r
- // TODO\r
- }\r
-\r
- static inline void USB_REG_Off(void) ATTR_ALWAYS_INLINE;\r
- static inline void USB_REG_Off(void)\r
- {\r
- // TODO\r
- }\r
-\r
- static inline void USB_CLK_Freeze(void) ATTR_ALWAYS_INLINE;\r
- static inline void USB_CLK_Freeze(void)\r
- {\r
- // TODO\r
- }\r
-\r
- static inline void USB_CLK_Unfreeze(void) ATTR_ALWAYS_INLINE;\r
- static inline void USB_CLK_Unfreeze(void)\r
- {\r
- // TODO\r
- }\r
-\r
static inline void USB_Controller_Enable(void) ATTR_ALWAYS_INLINE;\r
static inline void USB_Controller_Enable(void)\r
{\r
- // TODO\r
+ USB.CTRLA |= (USB_ENABLE_bm | USB_STFRNUM_bm | USB_MAXEP_gm);\r
}\r
\r
static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE;\r
static inline void USB_Controller_Disable(void)\r
{\r
- // TODO\r
+ USB.CTRLA &= ~USB_ENABLE_bm;\r
}\r
\r
static inline void USB_Controller_Reset(void) ATTR_ALWAYS_INLINE;\r
static inline void USB_Controller_Reset(void)\r
{\r
- // TODO\r
+ USB.CTRLA &= ~USB_ENABLE_bm;\r
+ USB.CTRLA |= USB_ENABLE_bm;\r
}\r
\r
#endif\r