3      Copyright (C) Dean Camera, 2009. 
   5   dean [at] fourwalledcubicle [dot] com 
   6       www.fourwalledcubicle.com 
  10   Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com) 
  12   Permission to use, copy, modify, and distribute this software 
  13   and its documentation for any purpose and without fee is hereby 
  14   granted, provided that the above copyright notice appear in all 
  15   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 #include "../HighLevel/USBMode.h" 
  33 #if defined(USB_CAN_BE_DEVICE) 
  35 #define  INCLUDE_FROM_DEVCHAPTER9_C 
  36 #include "DevChapter9.h" 
  38 uint8_t USB_ConfigurationNumber
; 
  39 bool    USB_RemoteWakeupEnabled
; 
  40 bool    USB_CurrentlySelfPowered
; 
  42 void USB_Device_ProcessControlRequest(void) 
  44         bool     RequestHandled 
= false; 
  45         uint8_t* RequestHeader  
= (uint8_t*)&USB_ControlRequest
; 
  47         for (uint8_t RequestHeaderByte 
= 0; RequestHeaderByte 
< sizeof(USB_Request_Header_t
); RequestHeaderByte
++) 
  48           *(RequestHeader
++) = Endpoint_Read_Byte(); 
  50         uint8_t bmRequestType 
= USB_ControlRequest
.bmRequestType
; 
  52         switch (USB_ControlRequest
.bRequest
) 
  55                         if ((bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) || 
  56                             (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
))) 
  58                                 USB_Device_GetStatus(); 
  59                                 RequestHandled 
= true; 
  63                 case REQ_ClearFeature
: 
  65                         if ((bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) || 
  66                             (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
))) 
  68                                 USB_Device_ClearSetFeature(); 
  69                                 RequestHandled 
= true; 
  74                         if (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
  76                                 USB_Device_SetAddress(); 
  77                                 RequestHandled 
= true; 
  81                 case REQ_GetDescriptor
: 
  82                         if ((bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) || 
  83                             (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_INTERFACE
))) 
  85                                 USB_Device_GetDescriptor(); 
  86                                 RequestHandled 
= true; 
  90                 case REQ_GetConfiguration
: 
  91                         if (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
  93                                 USB_Device_GetConfiguration(); 
  94                                 RequestHandled 
= true; 
  98                 case REQ_SetConfiguration
: 
  99                         if (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
 101                                 USB_Device_SetConfiguration(); 
 102                                 RequestHandled 
= true; 
 108         if (!(RequestHandled
)) 
 109           EVENT_USB_Device_UnhandledControlRequest(); 
 111         if (Endpoint_IsSETUPReceived()) 
 113                 Endpoint_StallTransaction(); 
 114                 Endpoint_ClearSETUP();           
 118 static void USB_Device_SetAddress(void) 
 120         uint8_t DeviceAddress 
= (USB_ControlRequest
.wValue 
& 0x7F); 
 122         Endpoint_ClearSETUP(); 
 126         while (!(Endpoint_IsINReady())) 
 128                 if (USB_DeviceState 
== DEVICE_STATE_Unattached
) 
 132         UDADDR 
= ((1 << ADDEN
) | DeviceAddress
); 
 135           USB_DeviceState 
= DEVICE_STATE_Addressed
; 
 140 static void USB_Device_SetConfiguration(void) 
 142 #if defined(FIXED_NUM_CONFIGURATIONS) 
 143         if ((uint8_t)USB_ControlRequest
.wValue 
> FIXED_NUM_CONFIGURATIONS
) 
 146         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 147         uint8_t MemoryAddressSpace
; 
 150         USB_Descriptor_Device_t
* DevDescriptorPtr
; 
 152         if (CALLBACK_USB_GetDescriptor((DTYPE_Device 
<< 8), 0, (void*)&DevDescriptorPtr
 
 153         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 154                                        , &MemoryAddressSpace
 
 161         #if defined(USE_RAM_DESCRIPTORS) 
 162         if ((uint8_t)USB_ControlRequest
.wValue 
> DevDescriptorPtr
->NumberOfConfigurations
) 
 164         #elif defined (USE_EEPROM_DESCRIPTORS) 
 165         if ((uint8_t)USB_ControlRequest
.wValue 
> eeprom_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
)) 
 167         #elif defined (USE_FLASH_DESCRIPTORS) 
 168         if ((uint8_t)USB_ControlRequest
.wValue 
> pgm_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
)) 
 171         if (MemoryAddressSpace 
== MEMSPACE_FLASH
) 
 173                 if (((uint8_t)USB_ControlRequest
.wValue 
> pgm_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 176         else if (MemoryAddressSpace 
== MEMSPACE_EEPROM
) 
 178                 if (((uint8_t)USB_ControlRequest
.wValue 
> eeprom_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 183                 if ((uint8_t)USB_ControlRequest
.wValue 
> DevDescriptorPtr
->NumberOfConfigurations
) 
 189         Endpoint_ClearSETUP(); 
 191         USB_ConfigurationNumber 
= (uint8_t)USB_ControlRequest
.wValue
; 
 195         if (USB_ConfigurationNumber
) 
 196           USB_DeviceState 
= DEVICE_STATE_Configured
; 
 198           USB_DeviceState 
= DEVICE_STATE_Addressed
; 
 200         EVENT_USB_Device_ConfigurationChanged(); 
 203 void USB_Device_GetConfiguration(void) 
 205         Endpoint_ClearSETUP(); 
 207         Endpoint_Write_Byte(USB_ConfigurationNumber
); 
 211         while (!(Endpoint_IsOUTReceived())) 
 213                 if (USB_DeviceState 
== DEVICE_STATE_Unattached
) 
 220 #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) 
 221 static char USB_Device_NibbleToASCII(uint8_t Nibble
) 
 223         Nibble 
= ((Nibble 
& 0x0F) + '0'); 
 224         return (Nibble 
> '9') ? 
(Nibble 
+ ('A' - '9' - 1)) : Nibble
; 
 227 static void USB_Device_GetInternalSerialDescriptor(void) 
 231                 USB_Descriptor_Header_t Header
; 
 232                 int16_t                 UnicodeString
[20]; 
 233         } SignatureDescriptor
; 
 235         #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) 
 236                 SignatureDescriptor
.Header
.Size            
= sizeof(SignatureDescriptor
); 
 237                 SignatureDescriptor
.Header
.Type            
= DTYPE_String
; 
 239                 SignatureDescriptor
.Header
.bLength         
= sizeof(SignatureDescriptor
); 
 240                 SignatureDescriptor
.Header
.bDescriptorType 
= DTYPE_String
; 
 243         uint8_t  SigReadAddress     
= 0x0E; 
 245         for (uint8_t SerialCharNum 
= 0; SerialCharNum 
< 20; SerialCharNum
++) 
 247                 uint8_t SerialByte 
= boot_signature_byte_get(SigReadAddress
); 
 249                 if (SerialCharNum 
& 0x01) 
 255                 SignatureDescriptor
.UnicodeString
[SerialCharNum
] = USB_Device_NibbleToASCII(SerialByte
); 
 258         Endpoint_ClearSETUP(); 
 259         Endpoint_Write_Control_Stream_LE(&SignatureDescriptor
, sizeof(SignatureDescriptor
)); 
 264 static void USB_Device_GetDescriptor(void) 
 266         void*    DescriptorPointer
; 
 267         uint16_t DescriptorSize
; 
 269         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 270         uint8_t  DescriptorAddressSpace
; 
 273         #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) 
 274         if (USB_ControlRequest
.wValue 
== ((DTYPE_String 
<< 8) | USE_INTERNAL_SERIAL
)) 
 276                 USB_Device_GetInternalSerialDescriptor(); 
 281         if ((DescriptorSize 
= CALLBACK_USB_GetDescriptor(USB_ControlRequest
.wValue
, USB_ControlRequest
.wIndex
, 
 283         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 284                                                          , &DescriptorAddressSpace
 
 291         Endpoint_ClearSETUP(); 
 293         #if defined(USE_RAM_DESCRIPTORS) 
 294         Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
); 
 295         #elif defined(USE_EEPROM_DESCRIPTORS) 
 296         Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
); 
 297         #elif defined(USE_FLASH_DESCRIPTORS) 
 298         Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
);    
 300         if (DescriptorAddressSpace 
== MEMSPACE_FLASH
) 
 301           Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
);  
 302         else if (DescriptorAddressSpace 
== MEMSPACE_EEPROM
) 
 303           Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
); 
 305           Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
);   
 311 static void USB_Device_GetStatus(void) 
 313         uint8_t CurrentStatus 
= 0; 
 315         switch (USB_ControlRequest
.bmRequestType
) 
 317                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
): 
 318                         if (USB_CurrentlySelfPowered
) 
 319                           CurrentStatus 
|= FEATURE_SELFPOWERED_ENABLED
; 
 321                         if (USB_RemoteWakeupEnabled
) 
 322                           CurrentStatus 
|= FEATURE_REMOTE_WAKEUP_ENABLED
; 
 325 #if !defined(CONTROL_ONLY_DEVICE) 
 326                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
): 
 327                         Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest
.wIndex
); 
 329                         CurrentStatus 
= Endpoint_IsStalled(); 
 331                         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
);                       
 337         Endpoint_ClearSETUP(); 
 339         Endpoint_Write_Word_LE(CurrentStatus
); 
 343         while (!(Endpoint_IsOUTReceived())) 
 345                 if (USB_DeviceState 
== DEVICE_STATE_Unattached
) 
 352 static void USB_Device_ClearSetFeature(void) 
 354         switch (USB_ControlRequest
.bmRequestType 
& CONTROL_REQTYPE_RECIPIENT
) 
 357                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_REMOTE_WAKEUP
) 
 358                           USB_RemoteWakeupEnabled 
= (USB_ControlRequest
.bRequest 
== REQ_SetFeature
); 
 363 #if !defined(CONTROL_ONLY_DEVICE) 
 364                 case REQREC_ENDPOINT
: 
 365                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_ENDPOINT_HALT
) 
 367                                 uint8_t EndpointIndex 
= ((uint8_t)USB_ControlRequest
.wIndex 
& ENDPOINT_EPNUM_MASK
); 
 369                                 if (EndpointIndex 
== ENDPOINT_CONTROLEP
) 
 372                                 Endpoint_SelectEndpoint(EndpointIndex
); 
 374                                 if (Endpoint_IsEnabled()) 
 376                                         if (USB_ControlRequest
.bRequest 
== REQ_ClearFeature
) 
 378                                                 Endpoint_ClearStall(); 
 379                                                 Endpoint_ResetFIFO(EndpointIndex
); 
 380                                                 Endpoint_ResetDataToggle(); 
 384                                                 Endpoint_StallTransaction(); 
 393         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
); 
 395         Endpoint_ClearSETUP();