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 defined(FIXED_NUM_CONFIGURATIONS) 
 149         if ((uint8_t)USB_ControlRequest
.wValue 
> FIXED_NUM_CONFIGURATIONS
) 
 152         #if defined(USE_FLASH_DESCRIPTORS) 
 153                 #define MemoryAddressSpace  MEMSPACE_FLASH 
 154         #elif defined(USE_EEPROM_DESCRIPTORS) 
 155                 #define MemoryAddressSpace  MEMSPACE_EEPROM 
 156         #elif defined(USE_SRAM_DESCRIPTORS) 
 157                 #define MemoryAddressSpace  MEMSPACE_SRAM 
 159                 uint8_t MemoryAddressSpace
; 
 162         USB_Descriptor_Device_t
* DevDescriptorPtr
; 
 164         if (CALLBACK_USB_GetDescriptor((DTYPE_Device 
<< 8), 0, (void*)&DevDescriptorPtr
 
 165         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 166                                        , &MemoryAddressSpace
 
 173         if (MemoryAddressSpace 
== MEMSPACE_FLASH
) 
 175                 if (((uint8_t)USB_ControlRequest
.wValue 
> pgm_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 178         else if (MemoryAddressSpace 
== MEMSPACE_EEPROM
) 
 180                 if (((uint8_t)USB_ControlRequest
.wValue 
> eeprom_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 185                 if ((uint8_t)USB_ControlRequest
.wValue 
> DevDescriptorPtr
->NumberOfConfigurations
) 
 190         Endpoint_ClearSETUP(); 
 192         USB_ConfigurationNumber 
= (uint8_t)USB_ControlRequest
.wValue
; 
 194         Endpoint_ClearStatusStage(); 
 196         USB_DeviceState 
= (USB_ConfigurationNumber
) ? DEVICE_STATE_Configured 
: DEVICE_STATE_Addressed
; 
 198         EVENT_USB_Device_ConfigurationChanged(); 
 201 void USB_Device_GetConfiguration(void) 
 203         Endpoint_ClearSETUP(); 
 205         Endpoint_Write_Byte(USB_ConfigurationNumber
); 
 208         Endpoint_ClearStatusStage(); 
 211 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) 
 212 static char USB_Device_NibbleToASCII(uint8_t Nibble
) 
 214         Nibble 
= ((Nibble 
& 0x0F) + '0'); 
 215         return (Nibble 
> '9') ? 
(Nibble 
+ ('A' - '9' - 1)) : Nibble
; 
 218 static void USB_Device_GetInternalSerialDescriptor(void) 
 222                 USB_Descriptor_Header_t Header
; 
 223                 int16_t                 UnicodeString
[20]; 
 224         } SignatureDescriptor
; 
 226         SignatureDescriptor
.Header
.Type 
= DTYPE_String
; 
 227         SignatureDescriptor
.Header
.Size 
= sizeof(SignatureDescriptor
); 
 229         uint8_t SigReadAddress 
= 0x0E; 
 231         ATOMIC_BLOCK(ATOMIC_RESTORESTATE
) 
 233                 for (uint8_t SerialCharNum 
= 0; SerialCharNum 
< 20; SerialCharNum
++) 
 235                         uint8_t SerialByte 
= boot_signature_byte_get(SigReadAddress
); 
 237                         if (SerialCharNum 
& 0x01) 
 243                         SignatureDescriptor
.UnicodeString
[SerialCharNum
] = USB_Device_NibbleToASCII(SerialByte
); 
 247         Endpoint_ClearSETUP(); 
 249         Endpoint_Write_Control_Stream_LE(&SignatureDescriptor
, sizeof(SignatureDescriptor
)); 
 255 static void USB_Device_GetDescriptor(void) 
 257         void*    DescriptorPointer
; 
 258         uint16_t DescriptorSize
; 
 260         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 261         uint8_t  DescriptorAddressSpace
; 
 264         #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) 
 265         if (USB_ControlRequest
.wValue 
== ((DTYPE_String 
<< 8) | USE_INTERNAL_SERIAL
)) 
 267                 USB_Device_GetInternalSerialDescriptor(); 
 272         if ((DescriptorSize 
= CALLBACK_USB_GetDescriptor(USB_ControlRequest
.wValue
, USB_ControlRequest
.wIndex
, 
 274         #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS) 
 275                                                          , &DescriptorAddressSpace
 
 282         Endpoint_ClearSETUP(); 
 284         #if defined(USE_RAM_DESCRIPTORS) 
 285         Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
); 
 286         #elif defined(USE_EEPROM_DESCRIPTORS) 
 287         Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
); 
 288         #elif defined(USE_FLASH_DESCRIPTORS) 
 289         Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
);    
 291         if (DescriptorAddressSpace 
== MEMSPACE_FLASH
) 
 292           Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
);  
 293         else if (DescriptorAddressSpace 
== MEMSPACE_EEPROM
) 
 294           Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
); 
 296           Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
);   
 302 static void USB_Device_GetStatus(void) 
 304         uint8_t CurrentStatus 
= 0; 
 306         switch (USB_ControlRequest
.bmRequestType
) 
 308 #if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)  
 309                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
): 
 310         #if !defined(NO_DEVICE_SELF_POWER) 
 311                         if (USB_CurrentlySelfPowered
) 
 312                           CurrentStatus 
|= FEATURE_SELFPOWERED_ENABLED
; 
 315         #if !defined(NO_DEVICE_REMOTE_WAKEUP)                    
 316                         if (USB_RemoteWakeupEnabled
) 
 317                           CurrentStatus 
|= FEATURE_REMOTE_WAKEUP_ENABLED
; 
 321 #if !defined(CONTROL_ONLY_DEVICE) 
 322                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
): 
 323                         Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest
.wIndex 
& ENDPOINT_EPNUM_MASK
); 
 325                         CurrentStatus 
= Endpoint_IsStalled(); 
 327                         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
);                       
 335         Endpoint_ClearSETUP(); 
 337         Endpoint_Write_Word_LE(CurrentStatus
); 
 340         Endpoint_ClearStatusStage(); 
 343 static void USB_Device_ClearSetFeature(void) 
 345         switch (USB_ControlRequest
.bmRequestType 
& CONTROL_REQTYPE_RECIPIENT
) 
 347 #if !defined(NO_DEVICE_REMOTE_WAKEUP)                    
 349                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_REMOTE_WAKEUP
) 
 350                           USB_RemoteWakeupEnabled 
= (USB_ControlRequest
.bRequest 
== REQ_SetFeature
); 
 356 #if !defined(CONTROL_ONLY_DEVICE) 
 357                 case REQREC_ENDPOINT
: 
 358                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_ENDPOINT_HALT
) 
 360                                 uint8_t EndpointIndex 
= ((uint8_t)USB_ControlRequest
.wIndex 
& ENDPOINT_EPNUM_MASK
); 
 362                                 if (EndpointIndex 
== ENDPOINT_CONTROLEP
) 
 365                                 Endpoint_SelectEndpoint(EndpointIndex
); 
 367                                 if (!(Endpoint_IsEnabled())) 
 370                                 if (USB_ControlRequest
.bRequest 
== REQ_SetFeature
) 
 372                                         Endpoint_StallTransaction(); 
 376                                         Endpoint_ClearStall(); 
 377                                         Endpoint_ResetFIFO(EndpointIndex
); 
 378                                         Endpoint_ResetDataToggle(); 
 388         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
); 
 390         Endpoint_ClearSETUP(); 
 392         Endpoint_ClearStatusStage();