From d2068d878c2ef6c4a68e85215d9d4a3b376089c2 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Wed, 9 Sep 2009 04:18:37 +0000 Subject: [PATCH] Finish Still Image Host class driver. --- .../StillImageHost/StillImageHost.c | 10 ++- LUFA/Drivers/USB/Class/Common/StillImage.h | 2 +- LUFA/Drivers/USB/Class/Host/HIDParser.c | 2 +- LUFA/Drivers/USB/Class/Host/StillImage.c | 34 +++++--- LUFA/Drivers/USB/Class/Host/StillImage.h | 87 +++++++++++++++++-- 5 files changed, 113 insertions(+), 22 deletions(-) diff --git a/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c b/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c index ef073abd51..20648563d4 100644 --- a/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c +++ b/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c @@ -111,7 +111,15 @@ int main(void) } printf("Turning off Device...\r\n"); - SImage_Host_SendCommand(&DigitalCamera_SI_Interface, 0x1013, 0, 0, 0, 0, NULL); + + SImage_Host_SendCommand(&DigitalCamera_SI_Interface, 0x1013, 0, NULL); + if (SImage_Host_ReceiveResponse(&DigitalCamera_SI_Interface)) + { + printf("Could not turn off device.\r\n"); + USB_HostState = HOST_STATE_WaitForDeviceRemoval; + break; + } + printf("Device Off.\r\n"); printf("Closing Session...\r\n"); diff --git a/LUFA/Drivers/USB/Class/Common/StillImage.h b/LUFA/Drivers/USB/Class/Common/StillImage.h index 690b1bb189..23fd79b1f0 100644 --- a/LUFA/Drivers/USB/Class/Common/StillImage.h +++ b/LUFA/Drivers/USB/Class/Common/StillImage.h @@ -117,7 +117,7 @@ uint16_t Type; /**< Container type, a value from the PIMA_Container_Types_t enum */ uint16_t Code; /**< Command, event or response code of the container */ uint32_t TransactionID; /**< Unique container ID to link blocks together */ - uint32_t Params[3]; /**< Block parameters to be issued along with the block code (command blocks only) */ + uint32_t Params[5]; /**< Block parameters to be issued along with the block code (command blocks only) */ } SI_PIMA_Container_t; /* Disable C linkage for C++ Compilers: */ diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.c b/LUFA/Drivers/USB/Class/Host/HIDParser.c index accb8f36b6..5174b59f93 100644 --- a/LUFA/Drivers/USB/Class/Host/HIDParser.c +++ b/LUFA/Drivers/USB/Class/Host/HIDParser.c @@ -37,7 +37,7 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID { HID_StateTable_t StateTable[HID_STATETABLE_STACK_DEPTH]; HID_StateTable_t* CurrStateTable = &StateTable[0]; - HID_CollectionPath_t* CurrCollectionPath = NULL; + HID_CollectionPath_t* CurrCollectionPath = NULL; uint16_t UsageStack[HID_USAGE_STACK_DEPTH]; uint8_t UsageStackSize = 0; uint16_t BitOffsetIn = 0; diff --git a/LUFA/Drivers/USB/Class/Host/StillImage.c b/LUFA/Drivers/USB/Class/Host/StillImage.c index ecaed3a890..7e3be8a81c 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) { @@ -238,7 +236,7 @@ static uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfa return PIPE_RWSTREAM_NoError; } -static uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes) +uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes) { uint8_t ErrorCode; @@ -253,7 +251,7 @@ static uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, vo return ErrorCode; } -static uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes) +uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes) { uint8_t ErrorCode; @@ -267,7 +265,7 @@ static uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, vo return ErrorCode; } -static bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo) +bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo) { bool IsEventReceived = false; @@ -282,7 +280,7 @@ static bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo return IsEventReceived; } -static uint8_t SImage_Host_ReceiveEventHeader(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; @@ -318,6 +316,9 @@ uint8_t SImage_Host_OpenSession(USB_ClassInfo_SI_Host_t* SIInterfaceInfo) 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; @@ -353,8 +354,8 @@ uint8_t SImage_Host_CloseSession(USB_ClassInfo_SI_Host_t* SIInterfaceInfo) return PIPE_RWSTREAM_NoError; } -uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t Operation, uint8_t UsedParams, - uint32_t Param1, uint32_t Param2, uint32_t Param3, void* DataBuff) +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; @@ -363,21 +364,30 @@ uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16 SI_PIMA_Container_t PIMABlock = (SI_PIMA_Container_t) { - .DataLength = PIMA_COMMAND_SIZE(UsedParams), + .DataLength = PIMA_COMMAND_SIZE(TotalParams), .Type = CType_CommandBlock, .Code = Operation, - .Params = {Param1, Param2, Param3}, }; + 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; } diff --git a/LUFA/Drivers/USB/Class/Host/StillImage.h b/LUFA/Drivers/USB/Class/Host/StillImage.h index 75f76eb8e5..0e14469785 100644 --- a/LUFA/Drivers/USB/Class/Host/StillImage.h +++ b/LUFA/Drivers/USB/Class/Host/StillImage.h @@ -126,11 +126,89 @@ uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t ConfigDescriptorLength, uint8_t* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1, 3); + /** Opens a new PIMA session with the attached device. This should be used before any session-orientated PIMA commands + * are issued to the device. Only one session can be open at the one time. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device + * returned a logical command failure + */ uint8_t SImage_Host_OpenSession(USB_ClassInfo_SI_Host_t* SIInterfaceInfo); + + /** Closes an already opened PIMA session with the attached device. This should be used after all session-orientated + * PIMA commands have been issued to the device. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device + * returned a logical command failure + */ uint8_t SImage_Host_CloseSession(USB_ClassInfo_SI_Host_t* SIInterfaceInfo); - uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t Operation, uint8_t UsedParams, - uint32_t Param1, uint32_t Param2, uint32_t Param3, void* DataBuff); + /** Sends a given PIMA command to the attached device, filling out the PIMA command header automatically as required. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state + * \param[in] Operation PIMA operation code to issue to the device + * \param[in] TotalParams Total number of 32-bit parameters to send to the device in the issued command block + * \param[in] Params Pointer to an array of 32-bit values containing the parameters to send in the command block + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device + * returned a logical command failure + */ + uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t Operation, uint8_t TotalParams, + uint32_t* Params); + + /** Receives and checks a response block from the attached PIMA device, once a command has been issued and all data + * associated with the command has been transferred. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device + * returned a logical command failure + */ + uint8_t SImage_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* SIInterfaceInfo); + + /** Indicates if the device has issued a PIMA event block to the host via the asynchronous events pipe. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state + * + * \return Boolean true if an event is waiting to be read, false otherwise + */ + bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo); + + /** Receives an asynchronous event block from the device via the asynchronous events pipe. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state + * \param[out] SI_PIMA_Container_t Pointer to a PIMA container structure where the event should be stored + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device + * returned a logical command failure + */ + uint8_t SImage_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, + SI_PIMA_Container_t* PIMAHeader); + + /** Sends arbitrary data to the attached device, for use in the data phase of PIMA commands which require data + * transfer beyond the regular PIMA command block parameters. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state + * \param[in] Buffer Pointer to a buffer where the data to send has been stored + * \param[in] Bytes Length in bytes of the data in the buffer to send to the attached device + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum + */ + uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes); + + /** Receives arbitrary data from the attached device, for use in the data phase of PIMA commands which require data + * transfer beyond the regular PIMA command block parameters. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state + * \param[out] Buffer Pointer to a buffer where the received data is to be stored + * \param[in] Bytes Length in bytes of the data to read + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum + */ + uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes); /* Private Interface - For use in library only: */ #if !defined(__DOXYGEN__) @@ -154,11 +232,6 @@ SI_PIMA_Container_t* PIMAHeader); static uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, SI_PIMA_Container_t* PIMAHeader); - static uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes); - static uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, void* Buffer, uint16_t Bytes); - static bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo); - static uint8_t SImage_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, - SI_PIMA_Container_t* PIMAHeader); #endif #endif