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" 
  32 #if defined(USB_CAN_BE_HOST) 
  34 #define  INCLUDE_FROM_CDC_CLASS_HOST_C 
  37 static uint8_t CDC_Host_ProcessConfigDescriptor(void) 
  39         uint8_t* ConfigDescriptorData
; 
  40         uint16_t ConfigDescriptorSize
; 
  41         uint8_t  FoundEndpoints 
= 0; 
  43         if (USB_GetDeviceConfigDescriptor(&ConfigDescriptorSize
, NULL
) != HOST_SENDCONTROL_Successful
) 
  46         if (ConfigDescriptorSize 
> 512) 
  47           return DescriptorTooLarge
; 
  49         ConfigDescriptorData 
= alloca(ConfigDescriptorSize
); 
  51         USB_GetDeviceConfigDescriptor(&ConfigDescriptorSize
, ConfigDescriptorData
); 
  53         if (DESCRIPTOR_TYPE(ConfigDescriptorData
) != DTYPE_Configuration
) 
  54           return InvalidConfigDataReturned
; 
  56         if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
, 
  57                                       DComp_CDC_Host_NextCDCControlInterface
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  59                 return NoCDCInterfaceFound
; 
  62         while (FoundEndpoints 
!= ((1 << CDC_NOTIFICATIONPIPE
) | (1 << CDC_DATAPIPE_IN
) | (1 << CDC_DATAPIPE_OUT
))) 
  64                 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
, 
  65                                               DComp_CDC_Host_NextInterfaceCDCDataEndpoint
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  67                         /* Check to see if the control interface's notification pipe has been found, if so search for the data interface */ 
  68                         if (FoundEndpoints 
& (1 << CDC_NOTIFICATIONPIPE
)) 
  70                                 /* Get the next CDC data interface from the configuration descriptor (CDC class has two CDC interfaces) */ 
  71                                 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
,  
  72                                                               DComp_CDC_Host_NextCDCDataInterface
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  74                                         /* Descriptor not found, error out */ 
  75                                         return NoCDCInterfaceFound
; 
  82                                 Pipe_SelectPipe(CDC_NOTIFICATIONPIPE
); 
  84                                 Pipe_SelectPipe(CDC_DATAPIPE_IN
); 
  86                                 Pipe_SelectPipe(CDC_DATAPIPE_OUT
); 
  89                                 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
, 
  90                                                               DComp_CDC_Host_NextCDCControlInterface
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  92                                         return NoCDCInterfaceFound
; 
  96                         if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
, 
  97                                                       DComp_CDC_Host_NextInterfaceCDCDataEndpoint
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  99                                 return NoEndpointFound
; 
 103                 USB_Descriptor_Endpoint_t
* EndpointData 
= DESCRIPTOR_PCAST(ConfigDescriptorData
, USB_Descriptor_Endpoint_t
); 
 105                 if ((EndpointData
->Attributes 
& EP_TYPE_MASK
) == EP_TYPE_INTERRUPT
) 
 107                         if (EndpointData
->EndpointAddress 
& ENDPOINT_DESCRIPTOR_DIR_IN
) 
 109                                 Pipe_ConfigurePipe(CDC_NOTIFICATIONPIPE
, EP_TYPE_INTERRUPT
, PIPE_TOKEN_IN
, 
 110                                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
, PIPE_BANK_SINGLE
); 
 112                                 Pipe_SetInfiniteINRequests(); 
 113                                 Pipe_SetInterruptPeriod(EndpointData
->PollingIntervalMS
); 
 115                                 FoundEndpoints 
|= (1 << CDC_NOTIFICATIONPIPE
); 
 120                         if (EndpointData
->EndpointAddress 
& ENDPOINT_DESCRIPTOR_DIR_IN
) 
 122                                 Pipe_ConfigurePipe(CDC_DATAPIPE_IN
, EP_TYPE_BULK
, PIPE_TOKEN_IN
, 
 123                                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
, PIPE_BANK_SINGLE
); 
 125                                 Pipe_SetInfiniteINRequests(); 
 128                                 FoundEndpoints 
|= (1 << CDC_DATAPIPE_IN
); 
 132                                 Pipe_ConfigurePipe(CDC_DATAPIPE_OUT
, EP_TYPE_BULK
, PIPE_TOKEN_OUT
, 
 133                                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
, PIPE_BANK_SINGLE
); 
 137                                 FoundEndpoints 
|= (1 << CDC_DATAPIPE_OUT
); 
 142         return SuccessfulConfigRead
; 
 145 static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* CurrentDescriptor
) 
 147         if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Interface
) 
 149                 /* Check the CDC descriptor class, subclass and protocol, break out if correct control interface found */ 
 150                 if ((DESCRIPTOR_CAST(CurrentDescriptor
, USB_Descriptor_Interface_t
).Class    
== CDC_CONTROL_CLASS
)    && 
 151                     (DESCRIPTOR_CAST(CurrentDescriptor
, USB_Descriptor_Interface_t
).SubClass 
== CDC_CONTROL_SUBCLASS
) && 
 152                     (DESCRIPTOR_CAST(CurrentDescriptor
, USB_Descriptor_Interface_t
).Protocol 
== CDC_CONTROL_PROTOCOL
)) 
 154                         return DESCRIPTOR_SEARCH_Found
; 
 158         return DESCRIPTOR_SEARCH_NotFound
; 
 161 static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* CurrentDescriptor
) 
 163         if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Interface
) 
 165                 /* Check the CDC descriptor class, subclass and protocol, break out if correct data interface found */ 
 166                 if ((DESCRIPTOR_CAST(CurrentDescriptor
, USB_Descriptor_Interface_t
).Class    
== CDC_DATA_CLASS
)    && 
 167                     (DESCRIPTOR_CAST(CurrentDescriptor
, USB_Descriptor_Interface_t
).SubClass 
== CDC_DATA_SUBCLASS
) && 
 168                     (DESCRIPTOR_CAST(CurrentDescriptor
, USB_Descriptor_Interface_t
).Protocol 
== CDC_DATA_PROTOCOL
)) 
 170                         return DESCRIPTOR_SEARCH_Found
; 
 174         return DESCRIPTOR_SEARCH_NotFound
; 
 177 static uint8_t DComp_CDC_Host_NextInterfaceCDCDataEndpoint(void* CurrentDescriptor
) 
 179         if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Endpoint
) 
 181                 uint8_t EndpointType 
= (DESCRIPTOR_CAST(CurrentDescriptor
, 
 182                                                         USB_Descriptor_Endpoint_t
).Attributes 
& EP_TYPE_MASK
); 
 184                 if ((EndpointType 
== EP_TYPE_BULK
) || (EndpointType 
== EP_TYPE_INTERRUPT
)) 
 185                   return DESCRIPTOR_SEARCH_Found
; 
 187         else if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Interface
) 
 189                 return DESCRIPTOR_SEARCH_Fail
; 
 192         return DESCRIPTOR_SEARCH_NotFound
; 
 195 void CDC_Host_Task(void) 
 199         switch (USB_HostState
) 
 201                 case HOST_STATE_Addressed
: 
 202                         USB_ControlRequest 
= (USB_Request_Header_t
) 
 204                                         .bmRequestType 
= (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
), 
 205                                         .bRequest      
= REQ_SetConfiguration
, 
 211                         Pipe_SelectPipe(PIPE_CONTROLPIPE
); 
 213                         if ((ErrorCode 
= USB_Host_SendControlRequest(NULL
)) != HOST_SENDCONTROL_Successful
) 
 215                                 USB_HostState 
= HOST_STATE_Unattached
; 
 218                         USB_HostState 
= HOST_STATE_Configured
; 
 220                 case HOST_STATE_Configured
: 
 221                         if ((ErrorCode 
= CDC_Host_ProcessConfigDescriptor()) != SuccessfulConfigRead
) 
 223                                 USB_HostState 
= HOST_STATE_Unattached
; 
 226                         USB_HostState 
= HOST_STATE_Ready
;