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         SignatureDescriptor
.Header
.Size  
= sizeof(SignatureDescriptor
); 
 236         SignatureDescriptor
.Header
.Type  
= DTYPE_String
; 
 238         uint8_t  SigReadAddress     
= 0x0E; 
 240         for (uint8_t SerialCharNum 
= 0; SerialCharNum 
< 20; SerialCharNum
++) 
 242                 uint8_t SerialByte 
= boot_signature_byte_get(SigReadAddress
); 
 244                 if (SerialCharNum 
& 0x01) 
 250                 SignatureDescriptor
.UnicodeString
[SerialCharNum
] = USB_Device_NibbleToASCII(SerialByte
); 
 253         Endpoint_ClearSETUP(); 
 254         Endpoint_Write_Control_Stream_LE(&SignatureDescriptor
, sizeof(SignatureDescriptor
)); 
 259 static void USB_Device_GetDescriptor(void) 
 261         void*    DescriptorPointer
; 
 262         uint16_t DescriptorSize
; 
 264         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 265         uint8_t  DescriptorAddressSpace
; 
 268         #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) 
 269         if (USB_ControlRequest
.wValue 
== ((DTYPE_String 
<< 8) | USE_INTERNAL_SERIAL
)) 
 271                 USB_Device_GetInternalSerialDescriptor(); 
 276         if ((DescriptorSize 
= CALLBACK_USB_GetDescriptor(USB_ControlRequest
.wValue
, USB_ControlRequest
.wIndex
, 
 278         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 279                                                          , &DescriptorAddressSpace
 
 286         Endpoint_ClearSETUP(); 
 288         #if defined(USE_RAM_DESCRIPTORS) 
 289         Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
); 
 290         #elif defined(USE_EEPROM_DESCRIPTORS) 
 291         Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
); 
 292         #elif defined(USE_FLASH_DESCRIPTORS) 
 293         Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
);    
 295         if (DescriptorAddressSpace 
== MEMSPACE_FLASH
) 
 296           Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
);  
 297         else if (DescriptorAddressSpace 
== MEMSPACE_EEPROM
) 
 298           Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
); 
 300           Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
);   
 306 static void USB_Device_GetStatus(void) 
 308         uint8_t CurrentStatus 
= 0; 
 310         switch (USB_ControlRequest
.bmRequestType
) 
 312                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
): 
 313                         if (USB_CurrentlySelfPowered
) 
 314                           CurrentStatus 
|= FEATURE_SELFPOWERED_ENABLED
; 
 316                         if (USB_RemoteWakeupEnabled
) 
 317                           CurrentStatus 
|= FEATURE_REMOTE_WAKEUP_ENABLED
; 
 320 #if !defined(CONTROL_ONLY_DEVICE) 
 321                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
): 
 322                         Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest
.wIndex
); 
 324                         CurrentStatus 
= Endpoint_IsStalled(); 
 326                         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
);                       
 334         Endpoint_ClearSETUP(); 
 336         Endpoint_Write_Word_LE(CurrentStatus
); 
 340         while (!(Endpoint_IsOUTReceived())) 
 342                 if (USB_DeviceState 
== DEVICE_STATE_Unattached
) 
 349 static void USB_Device_ClearSetFeature(void) 
 351         switch (USB_ControlRequest
.bmRequestType 
& CONTROL_REQTYPE_RECIPIENT
) 
 354                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_REMOTE_WAKEUP
) 
 355                           USB_RemoteWakeupEnabled 
= (USB_ControlRequest
.bRequest 
== REQ_SetFeature
); 
 360 #if !defined(CONTROL_ONLY_DEVICE) 
 361                 case REQREC_ENDPOINT
: 
 362                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_ENDPOINT_HALT
) 
 364                                 uint8_t EndpointIndex 
= ((uint8_t)USB_ControlRequest
.wIndex 
& ENDPOINT_EPNUM_MASK
); 
 366                                 if (EndpointIndex 
== ENDPOINT_CONTROLEP
) 
 369                                 Endpoint_SelectEndpoint(EndpointIndex
); 
 371                                 if (Endpoint_IsEnabled()) 
 373                                         if (USB_ControlRequest
.bRequest 
== REQ_ClearFeature
) 
 375                                                 Endpoint_ClearStall(); 
 376                                                 Endpoint_ResetFIFO(EndpointIndex
); 
 377                                                 Endpoint_ResetDataToggle(); 
 381                                                 Endpoint_StallTransaction(); 
 390         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
); 
 392         Endpoint_ClearSETUP();