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         uint8_t bmRequestType  
= Endpoint_Read_Byte(); 
  45         uint8_t bRequest       
= Endpoint_Read_Byte(); 
  46         bool    RequestHandled 
= false;  
  51                         if ((bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) || 
  52                             (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
))) 
  54                                 USB_Device_GetStatus(bmRequestType
); 
  55                                 RequestHandled 
= true; 
  59 #if !defined(FEATURELESS_CONTROL_ONLY_DEVICE) 
  60                 case REQ_ClearFeature
: 
  62                         if (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
)) 
  64                                 USB_Device_ClearSetFeature(bRequest
, bmRequestType
); 
  65                                 RequestHandled 
= true; 
  71                         if (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
  73                                 USB_Device_SetAddress(); 
  74                                 RequestHandled 
= true; 
  78                 case REQ_GetDescriptor
: 
  79                         if ((bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) || 
  80                             (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_INTERFACE
))) 
  82                                 USB_Device_GetDescriptor(); 
  83                                 RequestHandled 
= true; 
  87                 case REQ_GetConfiguration
: 
  88                         if (bmRequestType 
== (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
  90                                 USB_Device_GetConfiguration(); 
  91                                 RequestHandled 
= true; 
  95                 case REQ_SetConfiguration
: 
  96                         if (bmRequestType 
== (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
)) 
  98                                 USB_Device_SetConfiguration(); 
  99                                 RequestHandled 
= true; 
 105         if (!(RequestHandled
)) 
 106           RAISE_EVENT(USB_UnhandledControlPacket
, bRequest
, bmRequestType
); 
 108         if (Endpoint_IsSetupReceived()) 
 110                 Endpoint_StallTransaction(); 
 111                 Endpoint_ClearSetupReceived();           
 115 static void USB_Device_SetAddress(void) 
 117         uint8_t wValue_LSB 
= Endpoint_Read_Byte(); 
 119         Endpoint_ClearSetupReceived(); 
 121         while (!(Endpoint_IsSetupINReady())); 
 123         Endpoint_ClearSetupIN(); 
 125         while (!(Endpoint_IsSetupINReady())); 
 127         UDADDR 
= ((1 << ADDEN
) | (wValue_LSB 
& 0x7F)); 
 132 static void USB_Device_SetConfiguration(void) 
 134         uint8_t wValue_LSB        
= Endpoint_Read_Byte(); 
 135         bool    AlreadyConfigured 
= (USB_ConfigurationNumber 
!= 0); 
 137 #if defined(USE_SINGLE_DEVICE_CONFIGURATION) 
 140         USB_Descriptor_Device_t
* DevDescriptorPtr
; 
 142         if ((USB_GetDescriptor((DTYPE_Device 
<< 8), 0, (void*)&DevDescriptorPtr
) == NO_DESCRIPTOR
) || 
 143         #if defined(USE_RAM_DESCRIPTORS) 
 144             (wValue_LSB 
> DevDescriptorPtr
->NumberOfConfigurations
)) 
 145         #elif defined (USE_EEPROM_DESCRIPTORS) 
 146             (wValue_LSB 
> eeprom_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 148             (wValue_LSB 
> pgm_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))) 
 155         Endpoint_ClearSetupReceived(); 
 157         USB_ConfigurationNumber 
= wValue_LSB
; 
 159         Endpoint_ClearSetupIN(); 
 161         if (!(AlreadyConfigured
) && USB_ConfigurationNumber
) 
 162           RAISE_EVENT(USB_DeviceEnumerationComplete
); 
 164         RAISE_EVENT(USB_ConfigurationChanged
); 
 167 void USB_Device_GetConfiguration(void) 
 169         Endpoint_ClearSetupReceived();   
 171         Endpoint_Write_Byte(USB_ConfigurationNumber
); 
 173         Endpoint_ClearSetupIN(); 
 175         while (!(Endpoint_IsSetupOUTReceived())); 
 176         Endpoint_ClearSetupOUT(); 
 179 static void USB_Device_GetDescriptor(void) 
 181         uint16_t wValue  
= Endpoint_Read_Word_LE(); 
 182         uint16_t wIndex  
= Endpoint_Read_Word_LE(); 
 183         uint16_t wLength 
= Endpoint_Read_Word_LE(); 
 185         void*    DescriptorPointer
; 
 186         uint16_t DescriptorSize
; 
 190         if ((DescriptorSize 
= USB_GetDescriptor(wValue
, wIndex
, &DescriptorPointer
)) == NO_DESCRIPTOR
) 
 193         Endpoint_ClearSetupReceived(); 
 195         if (wLength 
> DescriptorSize
) 
 196           wLength 
= DescriptorSize
; 
 200                 while (!(Endpoint_IsSetupINReady())) 
 202                         if (Endpoint_IsSetupOUTReceived()) 
 204                                 Endpoint_ClearSetupOUT(); 
 209                 while (wLength 
&& (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize
)) 
 211                         #if defined(USE_RAM_DESCRIPTORS) 
 212                         Endpoint_Write_Byte(*((uint8_t*)DescriptorPointer
++)); 
 213                         #elif defined (USE_EEPROM_DESCRIPTORS) 
 214                         Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer
++));                      
 216                         Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer
++)); 
 222                 SendZLP 
= (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize
); 
 223                 Endpoint_ClearSetupIN(); 
 228                 while (!(Endpoint_IsSetupINReady())); 
 229                 Endpoint_ClearSetupIN(); 
 232         while (!(Endpoint_IsSetupOUTReceived())); 
 233         Endpoint_ClearSetupOUT(); 
 236 static void USB_Device_GetStatus(const uint8_t bmRequestType
) 
 238         uint8_t CurrentStatus 
= 0; 
 240         Endpoint_Discard_Word(); 
 242 #if !defined(FEATURELESS_CONTROL_ONLY_DEVICE) 
 243         uint8_t wIndex_LSB 
= Endpoint_Read_Byte(); 
 246         switch (bmRequestType
) 
 248                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
): 
 249                         if (USB_CurrentlySelfPowered
) 
 250                           CurrentStatus 
|= FEATURE_SELFPOWERED_ENABLED
; 
 252                         if (USB_RemoteWakeupEnabled
) 
 253                           CurrentStatus 
|= FEATURE_REMOTE_WAKEUP_ENABLED
; 
 256 #if !defined(FEATURELESS_CONTROL_ONLY_DEVICE) 
 257                 case (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_ENDPOINT
): 
 258                         Endpoint_SelectEndpoint(wIndex_LSB
); 
 260                         CurrentStatus 
= Endpoint_IsStalled(); 
 266         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
);                       
 267         Endpoint_ClearSetupReceived(); 
 268         Endpoint_Write_Word_LE(CurrentStatus
); 
 270         Endpoint_ClearSetupIN(); 
 272         while (!(Endpoint_IsSetupOUTReceived())); 
 273         Endpoint_ClearSetupOUT(); 
 276 #if !defined(FEATURELESS_CONTROL_ONLY_DEVICE) 
 277 static void USB_Device_ClearSetFeature(const uint8_t bRequest
, const uint8_t bmRequestType
) 
 279         uint16_t wValue 
= Endpoint_Read_Word_LE(); 
 280         uint16_t wIndex 
= Endpoint_Read_Word_LE(); 
 282         switch (bmRequestType 
& CONTROL_REQTYPE_RECIPIENT
) 
 284                 case REQREC_ENDPOINT
: 
 285                         if (wValue 
== FEATURE_ENDPOINT_HALT
) 
 287                                 uint8_t EndpointIndex 
= (wIndex 
& ENDPOINT_EPNUM_MASK
); 
 289                                 if (EndpointIndex 
!= ENDPOINT_CONTROLEP
) 
 291                                         Endpoint_SelectEndpoint(EndpointIndex
); 
 293                                         if (Endpoint_IsEnabled()) 
 295                                                 if (bRequest 
== REQ_ClearFeature
) 
 297                                                         Endpoint_ClearStall(); 
 298                                                         Endpoint_ResetFIFO(EndpointIndex
); 
 299                                                         Endpoint_ResetDataToggle(); 
 303                                                         Endpoint_StallTransaction();                                             
 307                                         Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
); 
 308                                         Endpoint_ClearSetupReceived(); 
 309                                         Endpoint_ClearSetupIN();