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_SI_CLASS_HOST_C 
  35 #include "StillImage.h" 
  37 #warning The Still Image Host mode Class driver is currently incomplete and is for preview purposes only. 
  39 uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t
* SIInterfaceInfo
, uint16_t ConfigDescriptorLength
, 
  40                               uint8_t* DeviceConfigDescriptor
) 
  42         uint8_t  FoundEndpoints 
= 0; 
  44         memset(&SIInterfaceInfo
->State
, 0x00, sizeof(SIInterfaceInfo
->State
)); 
  46         if (DESCRIPTOR_TYPE(DeviceConfigDescriptor
) != DTYPE_Configuration
) 
  47           return SI_ENUMERROR_InvalidConfigDescriptor
; 
  49         if (USB_GetNextDescriptorComp(&ConfigDescriptorLength
, &DeviceConfigDescriptor
, 
  50                                       DComp_SI_Host_NextSIInterface
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  52                 return SI_ENUMERROR_NoSIInterfaceFound
; 
  55         while (FoundEndpoints 
!= (SI_FOUND_EVENTS_IN 
| SI_FOUND_DATAPIPE_IN 
| SI_FOUND_DATAPIPE_OUT
)) 
  57                 if (USB_GetNextDescriptorComp(&ConfigDescriptorLength
, &DeviceConfigDescriptor
, 
  58                                               DComp_SI_Host_NextSIInterfaceEndpoint
) != DESCRIPTOR_SEARCH_COMP_Found
) 
  60                         return SI_ENUMERROR_EndpointsNotFound
; 
  63                 USB_Descriptor_Endpoint_t
* EndpointData 
= DESCRIPTOR_PCAST(DeviceConfigDescriptor
, USB_Descriptor_Endpoint_t
); 
  65                 if ((EndpointData
->Attributes 
& EP_TYPE_MASK
) == EP_TYPE_INTERRUPT
) 
  67                         if (EndpointData
->EndpointAddress 
& ENDPOINT_DESCRIPTOR_DIR_IN
) 
  69                                 Pipe_ConfigurePipe(SIInterfaceInfo
->Config
.EventsPipeNumber
, EP_TYPE_INTERRUPT
, PIPE_TOKEN_IN
, 
  70                                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
, 
  72                                 SIInterfaceInfo
->State
.EventsPipeSize 
= EndpointData
->EndpointSize
; 
  74                                 Pipe_SetInterruptPeriod(EndpointData
->PollingIntervalMS
); 
  76                                 FoundEndpoints 
|= SI_FOUND_EVENTS_IN
; 
  81                         if (EndpointData
->EndpointAddress 
& ENDPOINT_DESCRIPTOR_DIR_IN
) 
  83                                 Pipe_ConfigurePipe(SIInterfaceInfo
->Config
.DataINPipeNumber
, EP_TYPE_BULK
, PIPE_TOKEN_IN
, 
  84                                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
, 
  86                                 SIInterfaceInfo
->State
.DataINPipeSize 
= EndpointData
->EndpointSize
; 
  88                                 FoundEndpoints 
|= SI_FOUND_DATAPIPE_IN
; 
  92                                 Pipe_ConfigurePipe(SIInterfaceInfo
->Config
.DataOUTPipeNumber
, EP_TYPE_BULK
, PIPE_TOKEN_OUT
, 
  93                                                                    EndpointData
->EndpointAddress
, EndpointData
->EndpointSize
, 
  95                                 SIInterfaceInfo
->State
.DataOUTPipeSize 
= EndpointData
->EndpointSize
; 
  97                                 FoundEndpoints 
|= SI_FOUND_DATAPIPE_OUT
; 
 102         return SI_ENUMERROR_NoError
; 
 105 uint8_t DComp_SI_Host_NextSIInterface(void* CurrentDescriptor
) 
 107         if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Interface
) 
 109                 USB_Descriptor_Interface_t
* CurrentInterface 
= DESCRIPTOR_PCAST(CurrentDescriptor
, 
 110                                                                                 USB_Descriptor_Interface_t
); 
 112                 if ((CurrentInterface
->Class    
== STILL_IMAGE_CLASS
)    && 
 113                     (CurrentInterface
->SubClass 
== STILL_IMAGE_SUBCLASS
) && 
 114                     (CurrentInterface
->Protocol 
== STILL_IMAGE_PROTOCOL
)) 
 116                         return DESCRIPTOR_SEARCH_Found
; 
 120         return DESCRIPTOR_SEARCH_NotFound
; 
 123 uint8_t DComp_SI_Host_NextSIInterfaceEndpoint(void* CurrentDescriptor
) 
 125         if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Endpoint
) 
 127                 USB_Descriptor_Endpoint_t
* CurrentEndpoint 
= DESCRIPTOR_PCAST(CurrentDescriptor
, 
 128                                                                               USB_Descriptor_Endpoint_t
); 
 130                 uint8_t EndpointType 
= (CurrentEndpoint
->Attributes 
& EP_TYPE_MASK
); 
 132                 if (((EndpointType 
== EP_TYPE_BULK
) || (EndpointType 
== EP_TYPE_INTERRUPT
)) && 
 133                     (!(Pipe_IsEndpointBound(CurrentEndpoint
->EndpointAddress
)))) 
 135                         return DESCRIPTOR_SEARCH_Found
; 
 138         else if (DESCRIPTOR_TYPE(CurrentDescriptor
) == DTYPE_Interface
) 
 140                 return DESCRIPTOR_SEARCH_Fail
; 
 143         return DESCRIPTOR_SEARCH_NotFound
; 
 146 void SI_Host_USBTask(USB_ClassInfo_SI_Host_t
* SIInterfaceInfo
) 
 151 void SImage_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t
* SIInterfaceInfo
, SI_PIMA_Container_t
* PIMAHeader
) 
 153         Pipe_SelectPipe(SIInterfaceInfo
->Config
.DataOUTPipeNumber
); 
 156         Pipe_Write_Stream_LE(PIMAHeader
, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK
); 
 158         if (PIMAHeader
->Type 
== CType_CommandBlock
) 
 160                 uint8_t ParamBytes 
= (PIMAHeader
->DataLength 
- PIMA_COMMAND_SIZE(0)); 
 163                   Pipe_Write_Stream_LE(&PIMAHeader
->Params
, ParamBytes
, NO_STREAM_CALLBACK
); 
 171 uint8_t SImage_Host_RecieveBlockHeader(USB_ClassInfo_SI_Host_t
* SIInterfaceInfo
, SI_PIMA_Container_t
* PIMAHeader
) 
 173         uint16_t TimeoutMSRem 
= COMMAND_DATA_TIMEOUT_MS
; 
 175         Pipe_SelectPipe(SIInterfaceInfo
->Config
.DataINPipeNumber
); 
 178         while (!(Pipe_IsReadWriteAllowed())) 
 180                 if (USB_INT_HasOccurred(USB_INT_HSOFI
)) 
 182                         USB_INT_Clear(USB_INT_HSOFI
); 
 187                                 return PIPE_RWSTREAM_Timeout
; 
 192                 Pipe_SelectPipe(SIInterfaceInfo
->Config
.DataOUTPipeNumber
); 
 195                 if (Pipe_IsStalled()) 
 197                         USB_Host_ClearPipeStall(SIInterfaceInfo
->Config
.DataOUTPipeNumber
); 
 198                         return PIPE_RWSTREAM_PipeStalled
; 
 202                 Pipe_SelectPipe(SIInterfaceInfo
->Config
.DataINPipeNumber
); 
 205                 if (Pipe_IsStalled()) 
 207                         USB_Host_ClearPipeStall(SIInterfaceInfo
->Config
.DataINPipeNumber
); 
 208                         return PIPE_RWSTREAM_PipeStalled
; 
 211                 if (USB_HostState 
== HOST_STATE_Unattached
) 
 212                   return PIPE_RWSTREAM_DeviceDisconnected
; 
 215         Pipe_Read_Stream_LE(PIMAHeader
, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK
); 
 217         if (PIMAHeader
->Type 
== CType_ResponseBlock
) 
 219                 uint8_t ParamBytes 
= (PIMAHeader
->DataLength 
- PIMA_COMMAND_SIZE(0)); 
 222                   Pipe_Read_Stream_LE(&PIMAHeader
->Params
, ParamBytes
, NO_STREAM_CALLBACK
); 
 229         return PIPE_RWSTREAM_NoError
; 
 232 uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t
* SIInterfaceInfo
, void* Buffer
, uint16_t Bytes
) 
 236         Pipe_SelectPipe(SIInterfaceInfo
->Config
.DataOUTPipeNumber
); 
 239         ErrorCode 
= Pipe_Write_Stream_LE(Buffer
, Bytes
, NO_STREAM_CALLBACK
); 
 247 uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t
* SIInterfaceInfo
, void* Buffer
, uint16_t Bytes
) 
 251         Pipe_SelectPipe(SIInterfaceInfo
->Config
.DataINPipeNumber
); 
 254         ErrorCode 
= Pipe_Read_Stream_LE(Buffer
, Bytes
, NO_STREAM_CALLBACK
); 
 261 bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t
* SIInterfaceInfo
) 
 263         bool IsEventReceived 
= false; 
 265         Pipe_SelectPipe(SIInterfaceInfo
->Config
.EventsPipeNumber
); 
 268         if (Pipe_BytesInPipe()) 
 269           IsEventReceived 
= true; 
 273         return IsEventReceived
; 
 276 uint8_t SImage_Host_RecieveEventHeader(USB_ClassInfo_SI_Host_t
* SIInterfaceInfo
, SI_PIMA_Container_t
* PIMAHeader
) 
 280         Pipe_SelectPipe(SIInterfaceInfo
->Config
.EventsPipeNumber
); 
 283         ErrorCode 
= Pipe_Read_Stream_LE(PIMAHeader
, sizeof(SI_PIMA_Container_t
), NO_STREAM_CALLBACK
);