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 ((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 ((DescriptorSize 
= USB_GetDescriptor(USB_ControlRequest
.wValue
, USB_ControlRequest
.wIndex
, &DescriptorPointer
)) == NO_DESCRIPTOR
) 
 185         Endpoint_ClearSETUP(); 
 187         #if defined(USE_RAM_DESCRIPTORS) 
 188         Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
); 
 192         if (USB_ControlRequest
.wLength 
> DescriptorSize
) 
 193           USB_ControlRequest
.wLength 
= DescriptorSize
; 
 195         while (USB_ControlRequest
.wLength
) 
 197                 while (!(Endpoint_IsINReady())) 
 199                         if (Endpoint_IsOUTReceived()) 
 206                 while (USB_ControlRequest
.wLength 
&& (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize
)) 
 208                         #if defined (USE_EEPROM_DESCRIPTORS) 
 209                         Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer
++));                      
 211                         Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer
++)); 
 214                         USB_ControlRequest
.wLength
--; 
 217                 SendZLP 
= (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize
); 
 223                 while (!(Endpoint_IsINReady())); 
 227         while (!(Endpoint_IsOUTReceived())); 
 233 static void USB_Device_GetStatus(void) 
 235         uint8_t CurrentStatus 
= 0; 
 237         switch (USB_ControlRequest
.bmRequestType
) 
 239                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
): 
 240                         if (USB_CurrentlySelfPowered
) 
 241                           CurrentStatus 
|= FEATURE_SELFPOWERED_ENABLED
; 
 243                         if (USB_RemoteWakeupEnabled
) 
 244                           CurrentStatus 
|= FEATURE_REMOTE_WAKEUP_ENABLED
; 
 247 #if !defined(CONTROL_ONLY_DEVICE) 
 248                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
): 
 249                         Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest
.wIndex
); 
 251                         CurrentStatus 
= Endpoint_IsStalled(); 
 253                         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
);                       
 259         Endpoint_ClearSETUP(); 
 261         Endpoint_Write_Word_LE(CurrentStatus
); 
 265         while (!(Endpoint_IsOUTReceived())); 
 269 static void USB_Device_ClearSetFeature(void) 
 271         switch (USB_ControlRequest
.bmRequestType 
& CONTROL_REQTYPE_RECIPIENT
) 
 274                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_REMOTE_WAKEUP
) 
 275                           USB_RemoteWakeupEnabled 
= (USB_ControlRequest
.bRequest 
== REQ_SetFeature
); 
 280 #if !defined(CONTROL_ONLY_DEVICE) 
 281                 case REQREC_ENDPOINT
: 
 282                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_ENDPOINT_HALT
) 
 284                                 uint8_t EndpointIndex 
= ((uint8_t)USB_ControlRequest
.wIndex 
& ENDPOINT_EPNUM_MASK
); 
 286                                 if (EndpointIndex 
== ENDPOINT_CONTROLEP
) 
 289                                 Endpoint_SelectEndpoint(EndpointIndex
); 
 291                                 if (Endpoint_IsEnabled()) 
 293                                         if (USB_ControlRequest
.bRequest 
== REQ_ClearFeature
) 
 295                                                 Endpoint_ClearStall(); 
 296                                                 Endpoint_ResetFIFO(EndpointIndex
); 
 297                                                 Endpoint_ResetDataToggle(); 
 301                                                 Endpoint_StallTransaction(); 
 310         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
); 
 312         Endpoint_ClearSETUP();