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 ((DescriptorSize 
= CALLBACK_USB_GetDescriptor(USB_ControlRequest
.wValue
, USB_ControlRequest
.wIndex
, 
 183                                                          &DescriptorPointer
)) == NO_DESCRIPTOR
) 
 188         Endpoint_ClearSETUP(); 
 190         #if defined(USE_RAM_DESCRIPTORS) 
 191         Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
); 
 195         if (USB_ControlRequest
.wLength 
> DescriptorSize
) 
 196           USB_ControlRequest
.wLength 
= DescriptorSize
; 
 198         while (USB_ControlRequest
.wLength
) 
 200                 while (!(Endpoint_IsINReady())) 
 202                         if (Endpoint_IsOUTReceived()) 
 209                 while (USB_ControlRequest
.wLength 
&& (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize
)) 
 211                         #if defined (USE_EEPROM_DESCRIPTORS) 
 212                         Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer
++));              
 214                         Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer
++)); 
 217                         USB_ControlRequest
.wLength
--; 
 220                 SendZLP 
= (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize
); 
 226                 while (!(Endpoint_IsINReady())); 
 230         while (!(Endpoint_IsOUTReceived())); 
 236 static void USB_Device_GetStatus(void) 
 238         uint8_t CurrentStatus 
= 0; 
 240         switch (USB_ControlRequest
.bmRequestType
) 
 242                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
): 
 243                         if (USB_CurrentlySelfPowered
) 
 244                           CurrentStatus 
|= FEATURE_SELFPOWERED_ENABLED
; 
 246                         if (USB_RemoteWakeupEnabled
) 
 247                           CurrentStatus 
|= FEATURE_REMOTE_WAKEUP_ENABLED
; 
 250 #if !defined(CONTROL_ONLY_DEVICE) 
 251                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
): 
 252                         Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest
.wIndex
); 
 254                         CurrentStatus 
= Endpoint_IsStalled(); 
 256                         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
);                       
 262         Endpoint_ClearSETUP(); 
 264         Endpoint_Write_Word_LE(CurrentStatus
); 
 268         while (!(Endpoint_IsOUTReceived())); 
 272 static void USB_Device_ClearSetFeature(void) 
 274         switch (USB_ControlRequest
.bmRequestType 
& CONTROL_REQTYPE_RECIPIENT
) 
 277                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_REMOTE_WAKEUP
) 
 278                           USB_RemoteWakeupEnabled 
= (USB_ControlRequest
.bRequest 
== REQ_SetFeature
); 
 283 #if !defined(CONTROL_ONLY_DEVICE) 
 284                 case REQREC_ENDPOINT
: 
 285                         if ((uint8_t)USB_ControlRequest
.wValue 
== FEATURE_ENDPOINT_HALT
) 
 287                                 uint8_t EndpointIndex 
= ((uint8_t)USB_ControlRequest
.wIndex 
& ENDPOINT_EPNUM_MASK
); 
 289                                 if (EndpointIndex 
== ENDPOINT_CONTROLEP
) 
 292                                 Endpoint_SelectEndpoint(EndpointIndex
); 
 294                                 if (Endpoint_IsEnabled()) 
 296                                         if (USB_ControlRequest
.bRequest 
== REQ_ClearFeature
) 
 298                                                 Endpoint_ClearStall(); 
 299                                                 Endpoint_ResetFIFO(EndpointIndex
); 
 300                                                 Endpoint_ResetDataToggle(); 
 304                                                 Endpoint_StallTransaction(); 
 313         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
); 
 315         Endpoint_ClearSETUP();