3      Copyright (C) Dean Camera, 2010. 
   5   dean [at] fourwalledcubicle [dot] com 
  10   Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com) 
  12   Permission to use, copy, modify, distribute, and sell this 
  13   software and its documentation for any purpose is hereby granted 
  14   without fee, provided that the above copyright notice appear in 
  15   all copies and that both that the copyright notice and this 
  16   permission notice and warranty disclaimer appear in supporting 
  17   documentation, and that the name of the author not be used in 
  18   advertising or publicity pertaining to distribution of the 
  19   software without specific, written prior permission. 
  21   The author disclaim all warranties with regard to this 
  22   software, including all implied warranties of merchantability 
  23   and fitness.  In no event shall the author be liable for any 
  24   special, indirect or consequential damages or any damages 
  25   whatsoever resulting from loss of use, data or profits, whether 
  26   in an action of contract, negligence or other tortious action, 
  27   arising out of or in connection with the use or performance of 
  31 #define  __INCLUDE_FROM_USB_DRIVER 
  34 #if defined(USB_CAN_BE_DEVICE) 
  36 #define  __INCLUDE_FROM_DEVICESTDREQ_C 
  37 #include "DeviceStandardReq.h" 
  39 uint8_t USB_ConfigurationNumber
; 
  41 #if !defined(NO_DEVICE_SELF_POWER) 
  42 bool    USB_CurrentlySelfPowered
; 
  45 #if !defined(NO_DEVICE_REMOTE_WAKEUP) 
  46 bool    USB_RemoteWakeupEnabled
; 
  49 void USB_Device_ProcessControlRequest(void) 
  51         uint8_t* RequestHeader  
= (uint8_t*)&USB_ControlRequest
; 
  53         for (uint8_t RequestHeaderByte 
= 0; RequestHeaderByte 
< sizeof(USB_Request_Header_t
); RequestHeaderByte
++) 
  54           *(RequestHeader
++) = Endpoint_Read_Byte(); 
  56         EVENT_USB_Device_ControlRequest(); 
  58         if (Endpoint_IsSETUPReceived()) 
  60                 uint8_t bmRequestType 
= USB_ControlRequest
.bmRequestType
; 
  62                 switch (USB_ControlRequest
.bRequest
) 
  65                                 if ((bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) || 
  66                                         (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
))) 
  68                                         USB_Device_GetStatus(); 
  72                         case REQ_ClearFeature
: 
  74                                 if ((bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) || 
  75                                         (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
))) 
  77                                         USB_Device_ClearSetFeature(); 
  82                                 if (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
  83                                   USB_Device_SetAddress(); 
  86                         case REQ_GetDescriptor
: 
  87                                 if ((bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) || 
  88                                         (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_INTERFACE
))) 
  90                                         USB_Device_GetDescriptor(); 
  94                         case REQ_GetConfiguration
: 
  95                                 if (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
  96                                   USB_Device_GetConfiguration(); 
  99                         case REQ_SetConfiguration
: 
 100                                 if (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
 101                                   USB_Device_SetConfiguration(); 
 107         if (Endpoint_IsSETUPReceived()) 
 109                 Endpoint_StallTransaction(); 
 110                 Endpoint_ClearSETUP(); 
 114 static void USB_Device_SetAddress(void) 
 116         uint8_t DeviceAddress 
= (USB_ControlRequest
.wValue 
& 0x7F); 
 118         ATOMIC_BLOCK(ATOMIC_RESTORESTATE
) 
 120                 Endpoint_ClearSETUP(); 
 122                 Endpoint_ClearStatusStage(); 
 124                 while (!(Endpoint_IsINReady())); 
 126                 USB_DeviceState 
= (DeviceAddress
) ? DEVICE_STATE_Addressed 
: DEVICE_STATE_Default
; 
 128                 USB_Device_SetDeviceAddress(DeviceAddress
); 
 132 static void USB_Device_SetConfiguration(void) 
 134         #if defined(FIXED_NUM_CONFIGURATIONS) 
 135         if ((uint8_t)USB_ControlRequest
.wValue 
> FIXED_NUM_CONFIGURATIONS
) 
 138         USB_Descriptor_Device_t
* DevDescriptorPtr
; 
 140         #if defined(USE_FLASH_DESCRIPTORS) 
 141                 #define MemoryAddressSpace  MEMSPACE_FLASH 
 142         #elif defined(USE_EEPROM_DESCRIPTORS) 
 143                 #define MemoryAddressSpace  MEMSPACE_EEPROM 
 144         #elif defined(USE_SRAM_DESCRIPTORS) 
 145                 #define MemoryAddressSpace  MEMSPACE_SRAM 
 147                 uint8_t MemoryAddressSpace
; 
 150         if (CALLBACK_USB_GetDescriptor((DTYPE_Device 
<< 8), 0, (void*)&DevDescriptorPtr
 
 151         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 152                                        , &MemoryAddressSpace
 
 159         if (MemoryAddressSpace 
== MEMSPACE_FLASH
) 
 161                 if (((uint8_t)USB_ControlRequest
.wValue 
> pgm_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 164         else if (MemoryAddressSpace 
== MEMSPACE_EEPROM
) 
 166                 if (((uint8_t)USB_ControlRequest
.wValue 
> eeprom_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 171                 if ((uint8_t)USB_ControlRequest
.wValue 
> DevDescriptorPtr
->NumberOfConfigurations
) 
 176         Endpoint_ClearSETUP(); 
 178         USB_ConfigurationNumber 
= (uint8_t)USB_ControlRequest
.wValue
; 
 180         Endpoint_ClearStatusStage(); 
 182         if (USB_ConfigurationNumber
) 
 183           USB_DeviceState 
= DEVICE_STATE_Configured
; 
 185           USB_DeviceState 
= (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured 
: DEVICE_STATE_Powered
; 
 187         EVENT_USB_Device_ConfigurationChanged(); 
 190 static void USB_Device_GetConfiguration(void) 
 192         Endpoint_ClearSETUP(); 
 194         Endpoint_Write_Byte(USB_ConfigurationNumber
); 
 197         Endpoint_ClearStatusStage(); 
 200 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) 
 201 static char USB_Device_NibbleToASCII(uint8_t Nibble
) 
 204         return (Nibble 
>= 10) ? 
(('A' - 10) + Nibble
) : ('0' + Nibble
); 
 207 static void USB_Device_GetInternalSerialDescriptor(void) 
 211                 USB_Descriptor_Header_t Header
; 
 212                 wchar_t                 UnicodeString
[20]; 
 213         } SignatureDescriptor
; 
 215         SignatureDescriptor
.Header
.Type 
= DTYPE_String
; 
 216         SignatureDescriptor
.Header
.Size 
= sizeof(SignatureDescriptor
); 
 218         ATOMIC_BLOCK(ATOMIC_RESTORESTATE
) 
 220                 uint8_t SigReadAddress 
= 0x0E; 
 222                 for (uint8_t SerialCharNum 
= 0; SerialCharNum 
< 20; SerialCharNum
++) 
 224                         uint8_t SerialByte 
= boot_signature_byte_get(SigReadAddress
); 
 226                         if (SerialCharNum 
& 0x01) 
 232                         SignatureDescriptor
.UnicodeString
[SerialCharNum
] = USB_Device_NibbleToASCII(SerialByte
); 
 236         Endpoint_ClearSETUP(); 
 238         Endpoint_Write_Control_Stream_LE(&SignatureDescriptor
, sizeof(SignatureDescriptor
)); 
 244 static void USB_Device_GetDescriptor(void) 
 246         const void* DescriptorPointer
; 
 247         uint16_t    DescriptorSize
; 
 249         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 250         uint8_t DescriptorAddressSpace
; 
 253         #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) 
 254         if (USB_ControlRequest
.wValue 
== ((DTYPE_String 
<< 8) | USE_INTERNAL_SERIAL
)) 
 256                 USB_Device_GetInternalSerialDescriptor(); 
 261         if ((DescriptorSize 
= CALLBACK_USB_GetDescriptor(USB_ControlRequest
.wValue
, USB_ControlRequest
.wIndex
, 
 263         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 264                                                          , &DescriptorAddressSpace
 
 271         Endpoint_ClearSETUP(); 
 273         #if defined(USE_RAM_DESCRIPTORS) 
 274         Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
); 
 275         #elif defined(USE_EEPROM_DESCRIPTORS) 
 276         Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
); 
 277         #elif defined(USE_FLASH_DESCRIPTORS) 
 278         Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
); 
 280         if (DescriptorAddressSpace 
== MEMSPACE_FLASH
) 
 281           Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
); 
 282         else if (DescriptorAddressSpace 
== MEMSPACE_EEPROM
) 
 283           Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
); 
 285           Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
); 
 291 static void USB_Device_GetStatus(void) 
 293         uint8_t CurrentStatus 
= 0; 
 295         switch (USB_ControlRequest
.bmRequestType
) 
 297                 #if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP) 
 298                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
): 
 299                         #if !defined(NO_DEVICE_SELF_POWER) 
 300                         if (USB_CurrentlySelfPowered
) 
 301                           CurrentStatus 
|= FEATURE_SELFPOWERED_ENABLED
; 
 304                         #if !defined(NO_DEVICE_REMOTE_WAKEUP) 
 305                         if (USB_RemoteWakeupEnabled
) 
 306                           CurrentStatus 
|= FEATURE_REMOTE_WAKEUP_ENABLED
; 
 310                 #if !defined(CONTROL_ONLY_DEVICE) 
 311                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
): 
 312                         Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest
.wIndex 
& ENDPOINT_EPNUM_MASK
); 
 314                         CurrentStatus 
= Endpoint_IsStalled(); 
 316                         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
); 
 324         Endpoint_ClearSETUP(); 
 326         Endpoint_Write_Word_LE(CurrentStatus
); 
 329         Endpoint_ClearStatusStage(); 
 332 static void USB_Device_ClearSetFeature(void) 
 334         switch (USB_ControlRequest
.bmRequestType 
& CONTROL_REQTYPE_RECIPIENT
) 
 336                 #if !defined(NO_DEVICE_REMOTE_WAKEUP) 
 338                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_SEL_DeviceRemoteWakeup
) 
 339                           USB_RemoteWakeupEnabled 
= (USB_ControlRequest
.bRequest 
== REQ_SetFeature
); 
 345                 #if !defined(CONTROL_ONLY_DEVICE) 
 346                 case REQREC_ENDPOINT
: 
 347                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_SEL_EndpointHalt
) 
 349                                 uint8_t EndpointIndex 
= ((uint8_t)USB_ControlRequest
.wIndex 
& ENDPOINT_EPNUM_MASK
); 
 351                                 if (EndpointIndex 
== ENDPOINT_CONTROLEP
) 
 354                                 Endpoint_SelectEndpoint(EndpointIndex
); 
 356                                 if (Endpoint_IsEnabled()) 
 358                                         if (USB_ControlRequest
.bRequest 
== REQ_SetFeature
) 
 360                                                 Endpoint_StallTransaction(); 
 364                                                 Endpoint_ClearStall(); 
 365                                                 Endpoint_ResetFIFO(EndpointIndex
); 
 366                                                 Endpoint_ResetDataToggle(); 
 377         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
); 
 379         Endpoint_ClearSETUP(); 
 381         Endpoint_ClearStatusStage();