X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/0e2ffebb82af721299f2df9089f66f9da68e1e1e..0d5e30e69fdd10cc75f62e550c32ab4baf9b0005:/LUFA/Drivers/USB/Class/Host/StillImage.c?ds=sidebyside diff --git a/LUFA/Drivers/USB/Class/Host/StillImage.c b/LUFA/Drivers/USB/Class/Host/StillImage.c index 40ef4f23e..7e3be8a81 100644 --- a/LUFA/Drivers/USB/Class/Host/StillImage.c +++ b/LUFA/Drivers/USB/Class/Host/StillImage.c @@ -34,8 +34,6 @@ #define INCLUDE_FROM_SI_CLASS_HOST_C #include "StillImage.h" -#warning The Still Image Host mode Class driver is currently incomplete and is for preview purposes only. - uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t ConfigDescriptorLength, uint8_t* DeviceConfigDescriptor) { @@ -99,6 +97,7 @@ uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_ } } + SIInterfaceInfo->State.IsActive = true; return SI_ENUMERROR_NoError; } @@ -148,27 +147,33 @@ void SI_Host_USBTask(USB_ClassInfo_SI_Host_t* SIInterfaceInfo) } -void SImage_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader) +static uint8_t SImage_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader) { + uint8_t ErrorCode; + + PIMAHeader->TransactionID = SIInterfaceInfo->State.TransactionID++; + Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); - Pipe_Write_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK); + if ((ErrorCode = Pipe_Write_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError) + return ErrorCode; - if (PIMAHeader->Type == CType_CommandBlock) - { - uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0)); + uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0)); - if (ParamBytes) - Pipe_Write_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK); - - Pipe_ClearOUT(); + if (ParamBytes) + { + if ((ErrorCode = Pipe_Write_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError) + return ErrorCode; } - + + Pipe_ClearOUT(); Pipe_Freeze(); + + return PIPE_RWSTREAM_NoError; } -uint8_t SImage_Host_RecieveBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader) +static uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader) { uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS; @@ -275,7 +280,7 @@ bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo) return IsEventReceived; } -uint8_t SImage_Host_RecieveEventHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader) +uint8_t SImage_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader) { uint8_t ErrorCode; @@ -290,4 +295,100 @@ uint8_t SImage_Host_RecieveEventHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, return ErrorCode; } +uint8_t SImage_Host_OpenSession(USB_ClassInfo_SI_Host_t* SIInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnect; + + uint8_t ErrorCode; + + SI_PIMA_Container_t PIMABlock = (SI_PIMA_Container_t) + { + .DataLength = PIMA_COMMAND_SIZE(0), + .Type = CType_CommandBlock, + .Code = 0x1002, + .Params = {}, + }; + + if ((ErrorCode = SImage_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + if ((ErrorCode = SImage_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001)) + return SI_ERROR_LOGICAL_CMD_FAILED; + + SIInterfaceInfo->State.TransactionID = 0; + SIInterfaceInfo->State.IsSessionOpen = true; + + return PIPE_RWSTREAM_NoError; +} + +uint8_t SImage_Host_CloseSession(USB_ClassInfo_SI_Host_t* SIInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnect; + + uint8_t ErrorCode; + + SI_PIMA_Container_t PIMABlock = (SI_PIMA_Container_t) + { + .DataLength = PIMA_COMMAND_SIZE(0), + .Type = CType_CommandBlock, + .Code = 0x1003, + .Params = {}, + }; + + if ((ErrorCode = SImage_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + if ((ErrorCode = SImage_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + SIInterfaceInfo->State.IsSessionOpen = false; + + if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001)) + return SI_ERROR_LOGICAL_CMD_FAILED; + + return PIPE_RWSTREAM_NoError; +} + +uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t Operation, + uint8_t TotalParams, uint32_t* Params) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnect; + + uint8_t ErrorCode; + + SI_PIMA_Container_t PIMABlock = (SI_PIMA_Container_t) + { + .DataLength = PIMA_COMMAND_SIZE(TotalParams), + .Type = CType_CommandBlock, + .Code = Operation, + }; + + memcpy(&PIMABlock.Params, Params, sizeof(uint32_t) * TotalParams); + + if ((ErrorCode = SImage_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + return PIPE_RWSTREAM_NoError; +} + +uint8_t SImage_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* SIInterfaceInfo) +{ + uint8_t ErrorCode; + SI_PIMA_Container_t PIMABlock; + + if ((ErrorCode = SImage_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001)) + return SI_ERROR_LOGICAL_CMD_FAILED; + + return PIPE_RWSTREAM_NoError; +} + #endif