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(USB_ClassInfo_CDC_Host_t
* CDCInterfaceInfo
) 
  39         uint8_t* ConfigDescriptorData
; 
  40         uint16_t ConfigDescriptorSize
; 
  41         uint8_t  FoundEndpoints 
= 0; 
  43         if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize
, NULL
) != HOST_SENDCONTROL_Successful
) 
  44           return CDC_ENUMERROR_ControlError
; 
  46         if (ConfigDescriptorSize 
> 512) 
  47           return CDC_ENUMERROR_DescriptorTooLarge
; 
  49         ConfigDescriptorData 
= alloca(ConfigDescriptorSize
); 
  51         USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize
, ConfigDescriptorData
); 
  53         if (DESCRIPTOR_TYPE(ConfigDescriptorData
) != DTYPE_Configuration
) 
  54           return CDC_ENUMERROR_InvalidConfigDataReturned
; 
  56         if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
, 
  57                                       DComp_CDC_Host_NextCDCControlInterface
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  59                 return CDC_ENUMERROR_NoCDCInterfaceFound
; 
  62         while (FoundEndpoints 
!= (CDC_FOUND_DATAPIPE_IN 
| CDC_FOUND_DATAPIPE_OUT 
| CDC_FOUND_DATAPIPE_NOTIFICATION
)) 
  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 
& CDC_FOUND_DATAPIPE_NOTIFICATION
) 
  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                                         return CDC_ENUMERROR_NoCDCInterfaceFound
; 
  81                                 Pipe_SelectPipe(CDCInterfaceInfo
->Config
.DataINPipeNumber
); 
  83                                 Pipe_SelectPipe(CDCInterfaceInfo
->Config
.DataOUTPipeNumber
); 
  85                                 Pipe_SelectPipe(CDCInterfaceInfo
->Config
.NotificationPipeNumber
); 
  88                                 if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
, 
  89                                                               DComp_CDC_Host_NextCDCControlInterface
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  91                                         return CDC_ENUMERROR_NoCDCInterfaceFound
; 
  95                         if (USB_GetNextDescriptorComp(&ConfigDescriptorSize
, &ConfigDescriptorData
, 
  96                                                       DComp_CDC_Host_NextInterfaceCDCDataEndpoint
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  98                                 return CDC_ENUMERROR_NoEndpointFound
; 
 102                 USB_Descriptor_Endpoint_t
* EndpointData 
= DESCRIPTOR_PCAST(ConfigDescriptorData
, USB_Descriptor_Endpoint_t
); 
 104                 if ((EndpointData
->Attributes 
& EP_TYPE_MASK
) == EP_TYPE_INTERRUPT
) 
 106                         if (EndpointData
->EndpointAddress 
& ENDPOINT_DESCRIPTOR_DIR_IN
) 
 108                                 Pipe_ConfigurePipe(CDCInterfaceInfo
->Config
.NotificationPipeNumber
, EP_TYPE_INTERRUPT
, PIPE_TOKEN_IN
, 
 109                                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
, PIPE_BANK_SINGLE
); 
 110                                 CDCInterfaceInfo
->State
.NotificationPipeSize 
= EndpointData
->EndpointSize
; 
 112                                 Pipe_SetInterruptPeriod(EndpointData
->PollingIntervalMS
); 
 114                                 FoundEndpoints 
|= CDC_FOUND_DATAPIPE_NOTIFICATION
; 
 119                         if (EndpointData
->EndpointAddress 
& ENDPOINT_DESCRIPTOR_DIR_IN
) 
 121                                 Pipe_ConfigurePipe(CDCInterfaceInfo
->Config
.DataINPipeNumber
, EP_TYPE_BULK
, PIPE_TOKEN_IN
, 
 122                                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
, PIPE_BANK_SINGLE
); 
 123                                 CDCInterfaceInfo
->State
.DataINPipeSize 
= EndpointData
->EndpointSize
; 
 125                                 FoundEndpoints 
|= CDC_FOUND_DATAPIPE_IN
; 
 129                                 Pipe_ConfigurePipe(CDCInterfaceInfo
->Config
.DataOUTPipeNumber
, EP_TYPE_BULK
, PIPE_TOKEN_OUT
, 
 130                                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
, PIPE_BANK_SINGLE
); 
 131                                 CDCInterfaceInfo
->State
.DataOUTPipeSize 
= EndpointData
->EndpointSize
; 
 133                                 FoundEndpoints 
|= CDC_FOUND_DATAPIPE_OUT
; 
 138         return CDC_ENUMERROR_NoError
; 
 141 static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* CurrentDescriptor
) 
 143         if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Interface
) 
 145                 USB_Descriptor_Interface_t
* CurrentInterface 
= DESCRIPTOR_PCAST(CurrentDescriptor
, 
 146                                                                                 USB_Descriptor_Interface_t
); 
 148                 if ((CurrentInterface
->Class    
== CDC_CONTROL_CLASS
)    && 
 149                     (CurrentInterface
->SubClass 
== CDC_CONTROL_SUBCLASS
) && 
 150                         (CurrentInterface
->Protocol 
== CDC_CONTROL_PROTOCOL
)) 
 152                         return DESCRIPTOR_SEARCH_Found
; 
 156         return DESCRIPTOR_SEARCH_NotFound
; 
 159 static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* CurrentDescriptor
) 
 161         if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Interface
) 
 163                 USB_Descriptor_Interface_t
* CurrentInterface 
= DESCRIPTOR_PCAST(CurrentDescriptor
, 
 164                                                                                 USB_Descriptor_Interface_t
); 
 166                 if ((CurrentInterface
->Class    
== CDC_DATA_CLASS
)    && 
 167                     (CurrentInterface
->SubClass 
== CDC_DATA_SUBCLASS
) && 
 168                         (CurrentInterface
->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                 USB_Descriptor_Endpoint_t
* CurrentEndpoint 
= DESCRIPTOR_PCAST(CurrentDescriptor
, 
 182                                                                               USB_Descriptor_Endpoint_t
) 
 184                 uint8_t EndpointType 
= (CurrentEndpoint
->Attributes 
& EP_TYPE_MASK
); 
 186                 if ((EndpointType 
== EP_TYPE_BULK
) || (EndpointType 
== EP_TYPE_INTERRUPT
)) 
 187                   return DESCRIPTOR_SEARCH_Found
; 
 189         else if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Interface
) 
 191                 return DESCRIPTOR_SEARCH_Fail
; 
 194         return DESCRIPTOR_SEARCH_NotFound
; 
 197 void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t
* CDCInterfaceInfo
) 
 201         switch (USB_HostState
) 
 203                 case HOST_STATE_Addressed
: 
 204                         if ((ErrorCode 
= CDC_Host_ProcessConfigDescriptor(CDCInterfaceInfo
)) != CDC_ENUMERROR_NoError
) 
 206                                 USB_HostState 
= HOST_STATE_Unattached
; 
 209                         if ((ErrorCode 
= USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful
) 
 211                                 USB_HostState 
= HOST_STATE_Unattached
; 
 214                         USB_HostState 
= HOST_STATE_Configured
; 
 216                 case HOST_STATE_Configured
: 
 217                         USB_HostState 
= HOST_STATE_Ready
;