3      Copyright (C) Dean Camera, 2010. 
   5   dean [at] fourwalledcubicle [dot] com 
   6       www.fourwalledcubicle.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 
  32 #include "../HighLevel/USBMode.h" 
  34 #if defined(USB_CAN_BE_DEVICE) 
  36 #define  __INCLUDE_FROM_DEVCHAPTER9_C 
  37 #include "DevChapter9.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         bool     RequestHandled 
= false; 
  52         uint8_t* RequestHeader  
= (uint8_t*)&USB_ControlRequest
; 
  54         for (uint8_t RequestHeaderByte 
= 0; RequestHeaderByte 
< sizeof(USB_Request_Header_t
); RequestHeaderByte
++) 
  55           *(RequestHeader
++) = Endpoint_Read_Byte(); 
  57         uint8_t bmRequestType 
= USB_ControlRequest
.bmRequestType
; 
  59         switch (USB_ControlRequest
.bRequest
) 
  62                         if ((bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) || 
  63                             (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
))) 
  65                                 USB_Device_GetStatus(); 
  66                                 RequestHandled 
= true; 
  70                 case REQ_ClearFeature
: 
  72                         if ((bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) || 
  73                             (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
))) 
  75                                 USB_Device_ClearSetFeature(); 
  76                                 RequestHandled 
= true; 
  81                         if (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
  83                                 USB_Device_SetAddress(); 
  84                                 RequestHandled 
= true; 
  88                 case REQ_GetDescriptor
: 
  89                         if ((bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) || 
  90                             (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_INTERFACE
))) 
  92                                 USB_Device_GetDescriptor(); 
  93                                 RequestHandled 
= true; 
  97                 case REQ_GetConfiguration
: 
  98                         if (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
 100                                 USB_Device_GetConfiguration(); 
 101                                 RequestHandled 
= true; 
 105                 case REQ_SetConfiguration
: 
 106                         if (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
 108                                 USB_Device_SetConfiguration(); 
 109                                 RequestHandled 
= true; 
 115         if (!(RequestHandled
)) 
 116           EVENT_USB_Device_UnhandledControlRequest(); 
 118         if (Endpoint_IsSETUPReceived()) 
 120                 Endpoint_StallTransaction(); 
 121                 Endpoint_ClearSETUP();           
 125 static void USB_Device_SetAddress(void) 
 127         uint8_t DeviceAddress 
= (USB_ControlRequest
.wValue 
& 0x7F); 
 129         Endpoint_ClearSETUP(); 
 131         Endpoint_ClearStatusStage(); 
 133         while (!(Endpoint_IsINReady())) 
 135                 if (USB_DeviceState 
== DEVICE_STATE_Unattached
) 
 139         USB_DeviceState 
= (DeviceAddress
) ? DEVICE_STATE_Addressed 
: DEVICE_STATE_Default
; 
 141         UDADDR 
= ((1 << ADDEN
) | DeviceAddress
); 
 146 static void USB_Device_SetConfiguration(void) 
 148         if (USB_DeviceState 
!= DEVICE_STATE_Addressed
) 
 151 #if defined(FIXED_NUM_CONFIGURATIONS) 
 152         if ((uint8_t)USB_ControlRequest
.wValue 
> FIXED_NUM_CONFIGURATIONS
) 
 155         #if defined(USE_FLASH_DESCRIPTORS) 
 156                 #define MemoryAddressSpace  MEMSPACE_FLASH 
 157         #elif defined(USE_EEPROM_DESCRIPTORS) 
 158                 #define MemoryAddressSpace  MEMSPACE_EEPROM 
 159         #elif defined(USE_SRAM_DESCRIPTORS) 
 160                 #define MemoryAddressSpace  MEMSPACE_SRAM 
 162                 uint8_t MemoryAddressSpace
; 
 165         USB_Descriptor_Device_t
* DevDescriptorPtr
; 
 167         if (CALLBACK_USB_GetDescriptor((DTYPE_Device 
<< 8), 0, (void*)&DevDescriptorPtr
 
 168         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 169                                        , &MemoryAddressSpace
 
 176         if (MemoryAddressSpace 
== MEMSPACE_FLASH
) 
 178                 if (((uint8_t)USB_ControlRequest
.wValue 
> pgm_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 181         else if (MemoryAddressSpace 
== MEMSPACE_EEPROM
) 
 183                 if (((uint8_t)USB_ControlRequest
.wValue 
> eeprom_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 188                 if ((uint8_t)USB_ControlRequest
.wValue 
> DevDescriptorPtr
->NumberOfConfigurations
) 
 193         Endpoint_ClearSETUP(); 
 195         USB_ConfigurationNumber 
= (uint8_t)USB_ControlRequest
.wValue
; 
 197         Endpoint_ClearStatusStage(); 
 199         USB_DeviceState 
= (USB_ConfigurationNumber
) ? DEVICE_STATE_Configured 
: DEVICE_STATE_Addressed
; 
 201         EVENT_USB_Device_ConfigurationChanged(); 
 204 void USB_Device_GetConfiguration(void) 
 206         Endpoint_ClearSETUP(); 
 208         Endpoint_Write_Byte(USB_ConfigurationNumber
); 
 211         Endpoint_ClearStatusStage(); 
 214 #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) 
 215 static char USB_Device_NibbleToASCII(uint8_t Nibble
) 
 217         Nibble 
= ((Nibble 
& 0x0F) + '0'); 
 218         return (Nibble 
> '9') ? 
(Nibble 
+ ('A' - '9' - 1)) : Nibble
; 
 221 static void USB_Device_GetInternalSerialDescriptor(void) 
 225                 USB_Descriptor_Header_t Header
; 
 226                 int16_t                 UnicodeString
[20]; 
 227         } SignatureDescriptor
; 
 229         SignatureDescriptor
.Header
.Type 
= DTYPE_String
; 
 230         SignatureDescriptor
.Header
.Size 
= sizeof(SignatureDescriptor
); 
 232         uint8_t SigReadAddress 
= 0x0E; 
 234         ATOMIC_BLOCK(ATOMIC_RESTORESTATE
) 
 236                 for (uint8_t SerialCharNum 
= 0; SerialCharNum 
< 20; SerialCharNum
++) 
 238                         uint8_t SerialByte 
= boot_signature_byte_get(SigReadAddress
); 
 240                         if (SerialCharNum 
& 0x01) 
 246                         SignatureDescriptor
.UnicodeString
[SerialCharNum
] = USB_Device_NibbleToASCII(SerialByte
); 
 250         Endpoint_ClearSETUP(); 
 252         Endpoint_Write_Control_Stream_LE(&SignatureDescriptor
, sizeof(SignatureDescriptor
)); 
 258 static void USB_Device_GetDescriptor(void) 
 260         void*    DescriptorPointer
; 
 261         uint16_t DescriptorSize
; 
 263         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 264         uint8_t  DescriptorAddressSpace
; 
 267         #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) 
 268         if (USB_ControlRequest
.wValue 
== ((DTYPE_String 
<< 8) | USE_INTERNAL_SERIAL
)) 
 270                 USB_Device_GetInternalSerialDescriptor(); 
 275         if ((DescriptorSize 
= CALLBACK_USB_GetDescriptor(USB_ControlRequest
.wValue
, USB_ControlRequest
.wIndex
, 
 277         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 278                                                          , &DescriptorAddressSpace
 
 285         Endpoint_ClearSETUP(); 
 287         #if defined(USE_RAM_DESCRIPTORS) 
 288         Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
); 
 289         #elif defined(USE_EEPROM_DESCRIPTORS) 
 290         Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
); 
 291         #elif defined(USE_FLASH_DESCRIPTORS) 
 292         Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
);    
 294         if (DescriptorAddressSpace 
== MEMSPACE_FLASH
) 
 295           Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
);  
 296         else if (DescriptorAddressSpace 
== MEMSPACE_EEPROM
) 
 297           Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
); 
 299           Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
);   
 305 static void USB_Device_GetStatus(void) 
 307         uint8_t CurrentStatus 
= 0; 
 309         switch (USB_ControlRequest
.bmRequestType
) 
 311 #if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)  
 312                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
): 
 313         #if !defined(NO_DEVICE_SELF_POWER) 
 314                         if (USB_CurrentlySelfPowered
) 
 315                           CurrentStatus 
|= FEATURE_SELFPOWERED_ENABLED
; 
 318         #if !defined(NO_DEVICE_REMOTE_WAKEUP)                    
 319                         if (USB_RemoteWakeupEnabled
) 
 320                           CurrentStatus 
|= FEATURE_REMOTE_WAKEUP_ENABLED
; 
 324 #if !defined(CONTROL_ONLY_DEVICE) 
 325                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
): 
 326                         Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest
.wIndex 
& ENDPOINT_EPNUM_MASK
); 
 328                         CurrentStatus 
= Endpoint_IsStalled(); 
 330                         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
);                       
 338         Endpoint_ClearSETUP(); 
 340         Endpoint_Write_Word_LE(CurrentStatus
); 
 343         Endpoint_ClearStatusStage(); 
 346 static void USB_Device_ClearSetFeature(void) 
 348         switch (USB_ControlRequest
.bmRequestType 
& CONTROL_REQTYPE_RECIPIENT
) 
 350 #if !defined(NO_DEVICE_REMOTE_WAKEUP)                    
 352                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_REMOTE_WAKEUP
) 
 353                           USB_RemoteWakeupEnabled 
= (USB_ControlRequest
.bRequest 
== REQ_SetFeature
); 
 359 #if !defined(CONTROL_ONLY_DEVICE) 
 360                 case REQREC_ENDPOINT
: 
 361                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_ENDPOINT_HALT
) 
 363                                 uint8_t EndpointIndex 
= ((uint8_t)USB_ControlRequest
.wIndex 
& ENDPOINT_EPNUM_MASK
); 
 365                                 if (EndpointIndex 
== ENDPOINT_CONTROLEP
) 
 368                                 Endpoint_SelectEndpoint(EndpointIndex
); 
 370                                 if (!(Endpoint_IsEnabled())) 
 373                                 if (USB_ControlRequest
.bRequest 
== REQ_SetFeature
) 
 375                                         Endpoint_StallTransaction(); 
 379                                         Endpoint_ClearStall(); 
 380                                         Endpoint_ResetFIFO(EndpointIndex
); 
 381                                         Endpoint_ResetDataToggle(); 
 391         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
); 
 393         Endpoint_ClearSETUP(); 
 395         Endpoint_ClearStatusStage();