-/*\r
- LUFA Library\r
- Copyright (C) Dean Camera, 2010.\r
- \r
- dean [at] fourwalledcubicle [dot] com\r
- www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
- Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
- Permission to use, copy, modify, distribute, and sell this \r
- software and its documentation for any purpose is hereby granted\r
- without fee, provided that the above copyright notice appear in \r
- all copies and that both that the copyright notice and this\r
- permission notice and warranty disclaimer appear in supporting \r
- documentation, and that the name of the author not be used in \r
- advertising or publicity pertaining to distribution of the \r
- software without specific, written prior permission.\r
-\r
- The author disclaim all warranties with regard to this\r
- software, including all implied warranties of merchantability\r
- and fitness. In no event shall the author be liable for any\r
- special, indirect or consequential damages or any damages\r
- whatsoever resulting from loss of use, data or profits, whether\r
- in an action of contract, negligence or other tortious action,\r
- arising out of or in connection with the use or performance of\r
- this software.\r
-*/\r
-\r
-#define __INCLUDE_FROM_USB_DRIVER\r
-#include "../HighLevel/USBMode.h"\r
-\r
-#if defined(USB_CAN_BE_DEVICE)\r
-\r
-#define __INCLUDE_FROM_DEVCHAPTER9_C\r
-#include "DevChapter9.h"\r
-\r
-uint8_t USB_ConfigurationNumber;\r
-\r
-#if !defined(NO_DEVICE_SELF_POWER)\r
-bool USB_CurrentlySelfPowered;\r
-#endif\r
-\r
-#if !defined(NO_DEVICE_REMOTE_WAKEUP)\r
-bool USB_RemoteWakeupEnabled;\r
-#endif\r
-\r
-void USB_Device_ProcessControlRequest(void)\r
-{\r
- bool RequestHandled = false;\r
- uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest;\r
- \r
- for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)\r
- *(RequestHeader++) = Endpoint_Read_Byte();\r
- \r
- uint8_t bmRequestType = USB_ControlRequest.bmRequestType;\r
- \r
- switch (USB_ControlRequest.bRequest)\r
- {\r
- case REQ_GetStatus:\r
- if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||\r
- (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))\r
- {\r
- USB_Device_GetStatus();\r
- RequestHandled = true;\r
- }\r
-\r
- break;\r
- case REQ_ClearFeature:\r
- case REQ_SetFeature:\r
- if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||\r
- (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))\r
- {\r
- USB_Device_ClearSetFeature();\r
- RequestHandled = true;\r
- }\r
-\r
- break;\r
- case REQ_SetAddress:\r
- if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))\r
- {\r
- USB_Device_SetAddress();\r
- RequestHandled = true;\r
- }\r
-\r
- break;\r
- case REQ_GetDescriptor:\r
- if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||\r
- (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))\r
- {\r
- USB_Device_GetDescriptor();\r
- RequestHandled = true;\r
- }\r
- \r
- break;\r
- case REQ_GetConfiguration:\r
- if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))\r
- {\r
- USB_Device_GetConfiguration();\r
- RequestHandled = true;\r
- }\r
-\r
- break;\r
- case REQ_SetConfiguration:\r
- if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))\r
- {\r
- USB_Device_SetConfiguration();\r
- RequestHandled = true;\r
- }\r
-\r
- break;\r
- }\r
-\r
- if (!(RequestHandled))\r
- EVENT_USB_Device_UnhandledControlRequest();\r
- \r
- if (Endpoint_IsSETUPReceived())\r
- {\r
- Endpoint_StallTransaction();\r
- Endpoint_ClearSETUP(); \r
- }\r
-}\r
-\r
-static void USB_Device_SetAddress(void)\r
-{\r
- uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F);\r
-\r
- Endpoint_ClearSETUP();\r
- \r
- Endpoint_ClearStatusStage();\r
- \r
- while (!(Endpoint_IsINReady()))\r
- {\r
- if (USB_DeviceState == DEVICE_STATE_Unattached)\r
- return;\r
- }\r
-\r
- USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;\r
-\r
- UDADDR = ((1 << ADDEN) | DeviceAddress);\r
-\r
- return;\r
-}\r
-\r
-static void USB_Device_SetConfiguration(void)\r
-{\r
- if (USB_DeviceState != DEVICE_STATE_Addressed)\r
- return;\r
- \r
-#if defined(FIXED_NUM_CONFIGURATIONS)\r
- if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)\r
- return;\r
-#else\r
- #if defined(USE_FLASH_DESCRIPTORS)\r
- #define MemoryAddressSpace MEMSPACE_FLASH\r
- #elif defined(USE_EEPROM_DESCRIPTORS)\r
- #define MemoryAddressSpace MEMSPACE_EEPROM\r
- #elif defined(USE_SRAM_DESCRIPTORS)\r
- #define MemoryAddressSpace MEMSPACE_SRAM\r
- #else\r
- uint8_t MemoryAddressSpace;\r
- #endif\r
- \r
- USB_Descriptor_Device_t* DevDescriptorPtr;\r
-\r
- if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr\r
- #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)\r
- , &MemoryAddressSpace\r
- #endif\r
- ) == NO_DESCRIPTOR)\r
- {\r
- return;\r
- }\r
- \r
- if (MemoryAddressSpace == MEMSPACE_FLASH)\r
- {\r
- if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))\r
- return;\r
- }\r
- else if (MemoryAddressSpace == MEMSPACE_EEPROM)\r
- {\r
- if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))\r
- return;\r
- }\r
- else\r
- {\r
- if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)\r
- return;\r
- }\r
-#endif\r
- \r
- Endpoint_ClearSETUP();\r
-\r
- USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;\r
-\r
- Endpoint_ClearStatusStage();\r
-\r
- USB_DeviceState = (USB_ConfigurationNumber) ? DEVICE_STATE_Configured : DEVICE_STATE_Addressed;\r
-\r
- EVENT_USB_Device_ConfigurationChanged();\r
-}\r
-\r
-void USB_Device_GetConfiguration(void)\r
-{\r
- Endpoint_ClearSETUP();\r
-\r
- Endpoint_Write_Byte(USB_ConfigurationNumber);\r
- Endpoint_ClearIN();\r
-\r
- Endpoint_ClearStatusStage();\r
-}\r
-\r
-#if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))\r
-static char USB_Device_NibbleToASCII(uint8_t Nibble)\r
-{\r
- Nibble = ((Nibble & 0x0F) + '0');\r
- return (Nibble > '9') ? (Nibble + ('A' - '9' - 1)) : Nibble;\r
-}\r
-\r
-static void USB_Device_GetInternalSerialDescriptor(void)\r
-{\r
- struct\r
- {\r
- USB_Descriptor_Header_t Header;\r
- int16_t UnicodeString[20];\r
- } SignatureDescriptor;\r
-\r
- SignatureDescriptor.Header.Type = DTYPE_String;\r
- SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor);\r
- \r
- uint8_t SigReadAddress = 0x0E;\r
-\r
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE)\r
- {\r
- for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)\r
- {\r
- uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);\r
- \r
- if (SerialCharNum & 0x01)\r
- {\r
- SerialByte >>= 4;\r
- SigReadAddress++;\r
- }\r
- \r
- SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte);\r
- }\r
- }\r
- \r
- Endpoint_ClearSETUP();\r
-\r
- Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));\r
-\r
- Endpoint_ClearOUT();\r
-}\r
-#endif\r
-\r
-static void USB_Device_GetDescriptor(void)\r
-{\r
- void* DescriptorPointer;\r
- uint16_t DescriptorSize;\r
- \r
- #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)\r
- uint8_t DescriptorAddressSpace;\r
- #endif\r
- \r
- #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))\r
- if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))\r
- {\r
- USB_Device_GetInternalSerialDescriptor();\r
- return;\r
- }\r
- #endif\r
- \r
- if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,\r
- &DescriptorPointer\r
- #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)\r
- , &DescriptorAddressSpace\r
- #endif\r
- )) == NO_DESCRIPTOR)\r
- {\r
- return;\r
- }\r
- \r
- Endpoint_ClearSETUP();\r
-\r
- #if defined(USE_RAM_DESCRIPTORS)\r
- Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);\r
- #elif defined(USE_EEPROM_DESCRIPTORS)\r
- Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);\r
- #elif defined(USE_FLASH_DESCRIPTORS)\r
- Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize); \r
- #else\r
- if (DescriptorAddressSpace == MEMSPACE_FLASH)\r
- Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize); \r
- else if (DescriptorAddressSpace == MEMSPACE_EEPROM)\r
- Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);\r
- else\r
- Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize); \r
- #endif\r
-\r
- Endpoint_ClearOUT();\r
-}\r
-\r
-static void USB_Device_GetStatus(void)\r
-{\r
- uint8_t CurrentStatus = 0;\r
-\r
- switch (USB_ControlRequest.bmRequestType)\r
- {\r
-#if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP) \r
- case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):\r
- #if !defined(NO_DEVICE_SELF_POWER)\r
- if (USB_CurrentlySelfPowered)\r
- CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;\r
- #endif\r
-\r
- #if !defined(NO_DEVICE_REMOTE_WAKEUP) \r
- if (USB_RemoteWakeupEnabled)\r
- CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;\r
- #endif\r
- break;\r
-#endif\r
-#if !defined(CONTROL_ONLY_DEVICE)\r
- case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):\r
- Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);\r
-\r
- CurrentStatus = Endpoint_IsStalled();\r
-\r
- Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); \r
-\r
- break;\r
-#endif\r
- default:\r
- return;\r
- }\r
-\r
- Endpoint_ClearSETUP();\r
-\r
- Endpoint_Write_Word_LE(CurrentStatus);\r
- Endpoint_ClearIN();\r
- \r
- Endpoint_ClearStatusStage();\r
-}\r
-\r
-static void USB_Device_ClearSetFeature(void)\r
-{\r
- switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)\r
- {\r
-#if !defined(NO_DEVICE_REMOTE_WAKEUP) \r
- case REQREC_DEVICE:\r
- if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)\r
- USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);\r
- else\r
- return;\r
- \r
- break; \r
-#endif\r
-#if !defined(CONTROL_ONLY_DEVICE)\r
- case REQREC_ENDPOINT:\r
- if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)\r
- {\r
- uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);\r
- \r
- if (EndpointIndex == ENDPOINT_CONTROLEP)\r
- return;\r
-\r
- Endpoint_SelectEndpoint(EndpointIndex);\r
-\r
- if (!(Endpoint_IsEnabled()))\r
- return;\r
-\r
- if (USB_ControlRequest.bRequest == REQ_SetFeature)\r
- {\r
- Endpoint_StallTransaction();\r
- }\r
- else\r
- {\r
- Endpoint_ClearStall();\r
- Endpoint_ResetFIFO(EndpointIndex);\r
- Endpoint_ResetDataToggle();\r
- }\r
- }\r
- \r
- break;\r
-#endif\r
- default:\r
- return;\r
- }\r
-\r
- Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);\r
-\r
- Endpoint_ClearSETUP();\r
-\r
- Endpoint_ClearStatusStage();\r
-}\r
-\r
-#endif\r
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../HighLevel/USBMode.h"
+
+#if defined(USB_CAN_BE_DEVICE)
+
+#define __INCLUDE_FROM_DEVCHAPTER9_C
+#include "DevChapter9.h"
+
+uint8_t USB_ConfigurationNumber;
+
+#if !defined(NO_DEVICE_SELF_POWER)
+bool USB_CurrentlySelfPowered;
+#endif
+
+#if !defined(NO_DEVICE_REMOTE_WAKEUP)
+bool USB_RemoteWakeupEnabled;
+#endif
+
+void USB_Device_ProcessControlRequest(void)
+{
+ bool RequestHandled = false;
+ uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest;
+
+ for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)
+ *(RequestHeader++) = Endpoint_Read_Byte();
+
+ uint8_t bmRequestType = USB_ControlRequest.bmRequestType;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_GetStatus:
+ if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
+ (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
+ {
+ USB_Device_GetStatus();
+ RequestHandled = true;
+ }
+
+ break;
+ case REQ_ClearFeature:
+ case REQ_SetFeature:
+ if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||
+ (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))
+ {
+ USB_Device_ClearSetFeature();
+ RequestHandled = true;
+ }
+
+ break;
+ case REQ_SetAddress:
+ if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
+ {
+ USB_Device_SetAddress();
+ RequestHandled = true;
+ }
+
+ break;
+ case REQ_GetDescriptor:
+ if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
+ (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))
+ {
+ USB_Device_GetDescriptor();
+ RequestHandled = true;
+ }
+
+ break;
+ case REQ_GetConfiguration:
+ if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
+ {
+ USB_Device_GetConfiguration();
+ RequestHandled = true;
+ }
+
+ break;
+ case REQ_SetConfiguration:
+ if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
+ {
+ USB_Device_SetConfiguration();
+ RequestHandled = true;
+ }
+
+ break;
+ }
+
+ if (!(RequestHandled))
+ EVENT_USB_Device_UnhandledControlRequest();
+
+ if (Endpoint_IsSETUPReceived())
+ {
+ Endpoint_StallTransaction();
+ Endpoint_ClearSETUP();
+ }
+}
+
+static void USB_Device_SetAddress(void)
+{
+ uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F);
+
+ Endpoint_ClearSETUP();
+
+ Endpoint_ClearStatusStage();
+
+ while (!(Endpoint_IsINReady()))
+ {
+ if (USB_DeviceState == DEVICE_STATE_Unattached)
+ return;
+ }
+
+ USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
+
+ UDADDR = ((1 << ADDEN) | DeviceAddress);
+
+ return;
+}
+
+static void USB_Device_SetConfiguration(void)
+{
+ if (USB_DeviceState != DEVICE_STATE_Addressed)
+ return;
+
+#if defined(FIXED_NUM_CONFIGURATIONS)
+ if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
+ return;
+#else
+ #if defined(USE_FLASH_DESCRIPTORS)
+ #define MemoryAddressSpace MEMSPACE_FLASH
+ #elif defined(USE_EEPROM_DESCRIPTORS)
+ #define MemoryAddressSpace MEMSPACE_EEPROM
+ #elif defined(USE_SRAM_DESCRIPTORS)
+ #define MemoryAddressSpace MEMSPACE_SRAM
+ #else
+ uint8_t MemoryAddressSpace;
+ #endif
+
+ USB_Descriptor_Device_t* DevDescriptorPtr;
+
+ if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
+ #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
+ , &MemoryAddressSpace
+ #endif
+ ) == NO_DESCRIPTOR)
+ {
+ return;
+ }
+
+ if (MemoryAddressSpace == MEMSPACE_FLASH)
+ {
+ if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
+ return;
+ }
+ else if (MemoryAddressSpace == MEMSPACE_EEPROM)
+ {
+ if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
+ return;
+ }
+ else
+ {
+ if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
+ return;
+ }
+#endif
+
+ Endpoint_ClearSETUP();
+
+ USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
+
+ Endpoint_ClearStatusStage();
+
+ USB_DeviceState = (USB_ConfigurationNumber) ? DEVICE_STATE_Configured : DEVICE_STATE_Addressed;
+
+ EVENT_USB_Device_ConfigurationChanged();
+}
+
+void USB_Device_GetConfiguration(void)
+{
+ Endpoint_ClearSETUP();
+
+ Endpoint_Write_Byte(USB_ConfigurationNumber);
+ Endpoint_ClearIN();
+
+ Endpoint_ClearStatusStage();
+}
+
+#if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
+static char USB_Device_NibbleToASCII(uint8_t Nibble)
+{
+ Nibble = ((Nibble & 0x0F) + '0');
+ return (Nibble > '9') ? (Nibble + ('A' - '9' - 1)) : Nibble;
+}
+
+static void USB_Device_GetInternalSerialDescriptor(void)
+{
+ struct
+ {
+ USB_Descriptor_Header_t Header;
+ int16_t UnicodeString[20];
+ } SignatureDescriptor;
+
+ SignatureDescriptor.Header.Type = DTYPE_String;
+ SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor);
+
+ uint8_t SigReadAddress = 0x0E;
+
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+ {
+ for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
+ {
+ uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
+
+ if (SerialCharNum & 0x01)
+ {
+ SerialByte >>= 4;
+ SigReadAddress++;
+ }
+
+ SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte);
+ }
+ }
+
+ Endpoint_ClearSETUP();
+
+ Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
+
+ Endpoint_ClearOUT();
+}
+#endif
+
+static void USB_Device_GetDescriptor(void)
+{
+ void* DescriptorPointer;
+ uint16_t DescriptorSize;
+
+ #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
+ uint8_t DescriptorAddressSpace;
+ #endif
+
+ #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
+ if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
+ {
+ USB_Device_GetInternalSerialDescriptor();
+ return;
+ }
+ #endif
+
+ if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
+ &DescriptorPointer
+ #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
+ , &DescriptorAddressSpace
+ #endif
+ )) == NO_DESCRIPTOR)
+ {
+ return;
+ }
+
+ Endpoint_ClearSETUP();
+
+ #if defined(USE_RAM_DESCRIPTORS)
+ Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
+ #elif defined(USE_EEPROM_DESCRIPTORS)
+ Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
+ #elif defined(USE_FLASH_DESCRIPTORS)
+ Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
+ #else
+ if (DescriptorAddressSpace == MEMSPACE_FLASH)
+ Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
+ else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
+ Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
+ else
+ Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
+ #endif
+
+ Endpoint_ClearOUT();
+}
+
+static void USB_Device_GetStatus(void)
+{
+ uint8_t CurrentStatus = 0;
+
+ switch (USB_ControlRequest.bmRequestType)
+ {
+#if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
+ case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
+ #if !defined(NO_DEVICE_SELF_POWER)
+ if (USB_CurrentlySelfPowered)
+ CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
+ #endif
+
+ #if !defined(NO_DEVICE_REMOTE_WAKEUP)
+ if (USB_RemoteWakeupEnabled)
+ CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
+ #endif
+ break;
+#endif
+#if !defined(CONTROL_ONLY_DEVICE)
+ case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
+ Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
+
+ CurrentStatus = Endpoint_IsStalled();
+
+ Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
+
+ break;
+#endif
+ default:
+ return;
+ }
+
+ Endpoint_ClearSETUP();
+
+ Endpoint_Write_Word_LE(CurrentStatus);
+ Endpoint_ClearIN();
+
+ Endpoint_ClearStatusStage();
+}
+
+static void USB_Device_ClearSetFeature(void)
+{
+ switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
+ {
+#if !defined(NO_DEVICE_REMOTE_WAKEUP)
+ case REQREC_DEVICE:
+ if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
+ USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
+ else
+ return;
+
+ break;
+#endif
+#if !defined(CONTROL_ONLY_DEVICE)
+ case REQREC_ENDPOINT:
+ if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
+ {
+ uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
+
+ if (EndpointIndex == ENDPOINT_CONTROLEP)
+ return;
+
+ Endpoint_SelectEndpoint(EndpointIndex);
+
+ if (!(Endpoint_IsEnabled()))
+ return;
+
+ if (USB_ControlRequest.bRequest == REQ_SetFeature)
+ {
+ Endpoint_StallTransaction();
+ }
+ else
+ {
+ Endpoint_ClearStall();
+ Endpoint_ResetFIFO(EndpointIndex);
+ Endpoint_ResetDataToggle();
+ }
+ }
+
+ break;
+#endif
+ default:
+ return;
+ }
+
+ Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
+
+ Endpoint_ClearSETUP();
+
+ Endpoint_ClearStatusStage();
+}
+
+#endif