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_ProcessControlPacket(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_UnhandledControlPacket(); 
 111         if (Endpoint_IsSETUPReceived()) 
 113                 Endpoint_StallTransaction(); 
 114                 Endpoint_ClearSETUP();           
 118 static void USB_Device_SetAddress(void) 
 120         Endpoint_ClearSETUP(); 
 124         while (!(Endpoint_IsINReady())); 
 126         UDADDR 
= ((1 << ADDEN
) | ((uint8_t)USB_ControlRequest
.wValue 
& 0x7F)); 
 131 static void USB_Device_SetConfiguration(void) 
 133         bool AlreadyConfigured 
= (USB_ConfigurationNumber 
!= 0); 
 135 #if defined(USE_SINGLE_DEVICE_CONFIGURATION) 
 136         if ((uint8_t)USB_ControlRequest
.wValue 
> 1) 
 138         USB_Descriptor_Device_t
* DevDescriptorPtr
; 
 140         if ((CALLBACK_USB_GetDescriptor((DTYPE_Device 
<< 8), 0, (void*)&DevDescriptorPtr
) == NO_DESCRIPTOR
) || 
 141         #if defined(USE_RAM_DESCRIPTORS) 
 142             ((uint8_t)USB_ControlRequest
.wValue 
> DevDescriptorPtr
->NumberOfConfigurations
)) 
 143         #elif defined (USE_EEPROM_DESCRIPTORS) 
 144             ((uint8_t)USB_ControlRequest
.wValue 
> eeprom_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 146             ((uint8_t)USB_ControlRequest
.wValue 
> pgm_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 153         Endpoint_ClearSETUP(); 
 155         USB_ConfigurationNumber 
= (uint8_t)USB_ControlRequest
.wValue
; 
 159         if (!(AlreadyConfigured
) && USB_ConfigurationNumber
) 
 160           EVENT_USB_DeviceEnumerationComplete(); 
 162         EVENT_USB_ConfigurationChanged(); 
 165 void USB_Device_GetConfiguration(void) 
 167         Endpoint_ClearSETUP(); 
 169         Endpoint_Write_Byte(USB_ConfigurationNumber
); 
 173         while (!(Endpoint_IsOUTReceived())); 
 177 static void USB_Device_GetDescriptor(void) 
 179         void*    DescriptorPointer
; 
 180         uint16_t DescriptorSize
; 
 182         #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) 
 183         if (USB_ControlRequest
.wValue 
== ((DTYPE_String 
<< 8) | USE_INTERNAL_SERIAL
)) 
 187                         USB_Descriptor_Header_t Header
; 
 188                         int16_t                 UnicodeString
[12]; 
 189                 } SignatureDescriptor
; 
 191                 #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) 
 192                         SignatureDescriptor
.Header
.Size            
= sizeof(SignatureDescriptor
); 
 193                         SignatureDescriptor
.Header
.Type            
= DTYPE_String
; 
 195                         SignatureDescriptor
.Header
.bLength         
= sizeof(SignatureDescriptor
); 
 196                         SignatureDescriptor
.Header
.bDescriptorType 
= DTYPE_String
; 
 199                 uint8_t  SigReadAddress  
= 0x0E;                 
 200                 bool     OddRead         
= false; 
 202                 for (uint8_t SerialCharNum 
= 0; SerialCharNum 
< 12; SerialCharNum
++) 
 204                         uint8_t SerialByte 
= boot_signature_byte_get(SigReadAddress
); 
 216                         OddRead 
= !(OddRead
); 
 218                         if (SerialByte 
< 0x0A) 
 221                           SerialByte 
+= ('A' - 0x0A); 
 223                         SignatureDescriptor
.UnicodeString
[SerialCharNum
] = SerialByte
; 
 226                 Endpoint_ClearSETUP(); 
 227                 Endpoint_Write_Control_Stream_LE(&SignatureDescriptor
, sizeof(SignatureDescriptor
)); 
 234         if ((DescriptorSize 
= CALLBACK_USB_GetDescriptor(USB_ControlRequest
.wValue
, USB_ControlRequest
.wIndex
, 
 235                                                          &DescriptorPointer
)) == NO_DESCRIPTOR
) 
 240         Endpoint_ClearSETUP(); 
 242         #if defined(USE_RAM_DESCRIPTORS) 
 243         Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
); 
 247         if (USB_ControlRequest
.wLength 
> DescriptorSize
) 
 248           USB_ControlRequest
.wLength 
= DescriptorSize
; 
 250         while (USB_ControlRequest
.wLength
) 
 252                 while (!(Endpoint_IsINReady())) 
 254                         if (Endpoint_IsOUTReceived()) 
 261                 while (USB_ControlRequest
.wLength 
&& (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize
)) 
 263                         #if defined (USE_EEPROM_DESCRIPTORS) 
 264                         Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer
++));              
 266                         Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer
++)); 
 269                         USB_ControlRequest
.wLength
--; 
 272                 SendZLP 
= (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize
); 
 278                 while (!(Endpoint_IsINReady())); 
 282         while (!(Endpoint_IsOUTReceived())); 
 288 static void USB_Device_GetStatus(void) 
 290         uint8_t CurrentStatus 
= 0; 
 292         switch (USB_ControlRequest
.bmRequestType
) 
 294                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
): 
 295                         if (USB_CurrentlySelfPowered
) 
 296                           CurrentStatus 
|= FEATURE_SELFPOWERED_ENABLED
; 
 298                         if (USB_RemoteWakeupEnabled
) 
 299                           CurrentStatus 
|= FEATURE_REMOTE_WAKEUP_ENABLED
; 
 302 #if !defined(CONTROL_ONLY_DEVICE) 
 303                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
): 
 304                         Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest
.wIndex
); 
 306                         CurrentStatus 
= Endpoint_IsStalled(); 
 308                         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
);                       
 314         Endpoint_ClearSETUP(); 
 316         Endpoint_Write_Word_LE(CurrentStatus
); 
 320         while (!(Endpoint_IsOUTReceived())); 
 324 static void USB_Device_ClearSetFeature(void) 
 326         switch (USB_ControlRequest
.bmRequestType 
& CONTROL_REQTYPE_RECIPIENT
) 
 329                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_REMOTE_WAKEUP
) 
 330                           USB_RemoteWakeupEnabled 
= (USB_ControlRequest
.bRequest 
== REQ_SetFeature
); 
 335 #if !defined(CONTROL_ONLY_DEVICE) 
 336                 case REQREC_ENDPOINT
: 
 337                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_ENDPOINT_HALT
) 
 339                                 uint8_t EndpointIndex 
= ((uint8_t)USB_ControlRequest
.wIndex 
& ENDPOINT_EPNUM_MASK
); 
 341                                 if (EndpointIndex 
== ENDPOINT_CONTROLEP
) 
 344                                 Endpoint_SelectEndpoint(EndpointIndex
); 
 346                                 if (Endpoint_IsEnabled()) 
 348                                         if (USB_ControlRequest
.bRequest 
== REQ_ClearFeature
) 
 350                                                 Endpoint_ClearStall(); 
 351                                                 Endpoint_ResetFIFO(EndpointIndex
); 
 352                                                 Endpoint_ResetDataToggle(); 
 356                                                 Endpoint_StallTransaction(); 
 365         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
); 
 367         Endpoint_ClearSETUP();