Commit d2068d87 authored by Dean Camera's avatar Dean Camera
Browse files

Finish Still Image Host class driver.

parent 6f993a2f
...@@ -111,7 +111,15 @@ int main(void) ...@@ -111,7 +111,15 @@ int main(void)
} }
printf("Turning off Device...\r\n"); 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("Device Off.\r\n");
printf("Closing Session...\r\n"); printf("Closing Session...\r\n");
......
...@@ -117,7 +117,7 @@ ...@@ -117,7 +117,7 @@
uint16_t Type; /**< Container type, a value from the PIMA_Container_Types_t enum */ 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 */ uint16_t Code; /**< Command, event or response code of the container */
uint32_t TransactionID; /**< Unique container ID to link blocks together */ 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; } SI_PIMA_Container_t;
/* Disable C linkage for C++ Compilers: */ /* Disable C linkage for C++ Compilers: */
......
...@@ -37,7 +37,7 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID ...@@ -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 StateTable[HID_STATETABLE_STACK_DEPTH];
HID_StateTable_t* CurrStateTable = &StateTable[0]; HID_StateTable_t* CurrStateTable = &StateTable[0];
HID_CollectionPath_t* CurrCollectionPath = NULL; HID_CollectionPath_t* CurrCollectionPath = NULL;
uint16_t UsageStack[HID_USAGE_STACK_DEPTH]; uint16_t UsageStack[HID_USAGE_STACK_DEPTH];
uint8_t UsageStackSize = 0; uint8_t UsageStackSize = 0;
uint16_t BitOffsetIn = 0; uint16_t BitOffsetIn = 0;
......
...@@ -34,8 +34,6 @@ ...@@ -34,8 +34,6 @@
#define INCLUDE_FROM_SI_CLASS_HOST_C #define INCLUDE_FROM_SI_CLASS_HOST_C
#include "StillImage.h" #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 SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t ConfigDescriptorLength,
uint8_t* DeviceConfigDescriptor) uint8_t* DeviceConfigDescriptor)
{ {
...@@ -238,7 +236,7 @@ static uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfa ...@@ -238,7 +236,7 @@ static uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfa
return PIPE_RWSTREAM_NoError; 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; uint8_t ErrorCode;
...@@ -253,7 +251,7 @@ static uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, vo ...@@ -253,7 +251,7 @@ static uint8_t SImage_Host_SendData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, vo
return ErrorCode; 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; uint8_t ErrorCode;
...@@ -267,7 +265,7 @@ static uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, vo ...@@ -267,7 +265,7 @@ static uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, vo
return ErrorCode; 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; bool IsEventReceived = false;
...@@ -282,7 +280,7 @@ static bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo ...@@ -282,7 +280,7 @@ static bool SImage_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* SIInterfaceInfo
return IsEventReceived; 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; uint8_t ErrorCode;
...@@ -318,6 +316,9 @@ uint8_t SImage_Host_OpenSession(USB_ClassInfo_SI_Host_t* SIInterfaceInfo) ...@@ -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) if ((ErrorCode = SImage_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode; return ErrorCode;
if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001))
return SI_ERROR_LOGICAL_CMD_FAILED;
SIInterfaceInfo->State.TransactionID = 0; SIInterfaceInfo->State.TransactionID = 0;
SIInterfaceInfo->State.IsSessionOpen = true; SIInterfaceInfo->State.IsSessionOpen = true;
...@@ -353,8 +354,8 @@ uint8_t SImage_Host_CloseSession(USB_ClassInfo_SI_Host_t* SIInterfaceInfo) ...@@ -353,8 +354,8 @@ uint8_t SImage_Host_CloseSession(USB_ClassInfo_SI_Host_t* SIInterfaceInfo)
return PIPE_RWSTREAM_NoError; return PIPE_RWSTREAM_NoError;
} }
uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t Operation, uint8_t UsedParams, uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t Operation,
uint32_t Param1, uint32_t Param2, uint32_t Param3, void* DataBuff) uint8_t TotalParams, uint32_t* Params)
{ {
if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
return HOST_SENDCONTROL_DeviceDisconnect; return HOST_SENDCONTROL_DeviceDisconnect;
...@@ -363,21 +364,30 @@ uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16 ...@@ -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) SI_PIMA_Container_t PIMABlock = (SI_PIMA_Container_t)
{ {
.DataLength = PIMA_COMMAND_SIZE(UsedParams), .DataLength = PIMA_COMMAND_SIZE(TotalParams),
.Type = CType_CommandBlock, .Type = CType_CommandBlock,
.Code = Operation, .Code = Operation,
.Params = {Param1, Param2, Param3},
}; };
memcpy(&PIMABlock.Params, Params, sizeof(uint32_t) * TotalParams);
if ((ErrorCode = SImage_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) if ((ErrorCode = SImage_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode; 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) if ((ErrorCode = SImage_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
return ErrorCode; return ErrorCode;
if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001)) if ((PIMABlock.Type != CType_ResponseBlock) || (PIMABlock.Code != 0x2001))
return SI_ERROR_LOGICAL_CMD_FAILED; return SI_ERROR_LOGICAL_CMD_FAILED;
return PIPE_RWSTREAM_NoError; return PIPE_RWSTREAM_NoError;
} }
......
...@@ -126,11 +126,89 @@ ...@@ -126,11 +126,89 @@
uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t ConfigDescriptorLength, uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t ConfigDescriptorLength,
uint8_t* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1, 3); 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); 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_CloseSession(USB_ClassInfo_SI_Host_t* SIInterfaceInfo);
uint8_t SImage_Host_SendCommand(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, uint16_t Operation, uint8_t UsedParams, /** Sends a given PIMA command to the attached device, filling out the PIMA command header automatically as required.
uint32_t Param1, uint32_t Param2, uint32_t Param3, void* DataBuff); *
* \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: */ /* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__) #if !defined(__DOXYGEN__)
...@@ -154,11 +232,6 @@ ...@@ -154,11 +232,6 @@
SI_PIMA_Container_t* PIMAHeader); SI_PIMA_Container_t* PIMAHeader);
static uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo, static uint8_t SImage_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* SIInterfaceInfo,
SI_PIMA_Container_t* PIMAHeader); 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
#endif #endif
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment