static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) { uint16_t TimeoutMSRem = MS_COMMAND_DATA_TIMEOUT_MS; uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber); Pipe_Unfreeze(); while (!(Pipe_IsINReceived())) { uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); if (CurrentFrameNumber != PreviousFrameNumber) { PreviousFrameNumber = CurrentFrameNumber; if (!(TimeoutMSRem--)) return PIPE_RWSTREAM_Timeout; } Pipe_Freeze(); Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); if (Pipe_IsStalled()) { USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataOUTPipeNumber); return PIPE_RWSTREAM_PipeStalled; } Pipe_Freeze(); Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber); Pipe_Unfreeze(); if (Pipe_IsStalled()) { USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataINPipeNumber); return PIPE_RWSTREAM_PipeStalled; } if (USB_HostState == HOST_STATE_Unattached) return PIPE_RWSTREAM_DeviceDisconnected; }; Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber); Pipe_Freeze(); Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }
uint8_t Pipe_WaitUntilReady(void) { #if (USB_STREAM_TIMEOUT_MS < 0xFF) uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; #else uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; #endif uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); for (;;) { if (Pipe_GetPipeToken() == PIPE_TOKEN_IN) { if (Pipe_IsINReceived()) return PIPE_READYWAIT_NoError; } else { if (Pipe_IsOUTReady()) return PIPE_READYWAIT_NoError; } if (Pipe_IsStalled()) return PIPE_READYWAIT_PipeStalled; else if (USB_HostState == HOST_STATE_Unattached) return PIPE_READYWAIT_DeviceDisconnected; uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); if (CurrentFrameNumber != PreviousFrameNumber) { PreviousFrameNumber = CurrentFrameNumber; if (!(TimeoutMSRem--)) return PIPE_READYWAIT_Timeout; } } }
uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, PIMA_Container_t* const PIMAHeader) { uint16_t TimeoutMSRem = SI_COMMAND_DATA_TIMEOUT_MS; uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) return PIPE_RWSTREAM_DeviceDisconnected; Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber); Pipe_Unfreeze(); while (!(Pipe_IsINReceived())) { uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); if (CurrentFrameNumber != PreviousFrameNumber) { PreviousFrameNumber = CurrentFrameNumber; if (!(TimeoutMSRem--)) return PIPE_RWSTREAM_Timeout; } Pipe_Freeze(); Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); if (Pipe_IsStalled()) { USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataOUTPipeNumber); return PIPE_RWSTREAM_PipeStalled; } Pipe_Freeze(); Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber); Pipe_Unfreeze(); if (Pipe_IsStalled()) { USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataINPipeNumber); return PIPE_RWSTREAM_PipeStalled; } if (USB_HostState == HOST_STATE_Unattached) return PIPE_RWSTREAM_DeviceDisconnected; } Pipe_Read_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK); if (PIMAHeader->Type == PIMA_CONTAINER_ResponseBlock) { uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0)); if (ParamBytes) Pipe_Read_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK); Pipe_ClearIN(); } Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }
/** Function to receive a PIMA response container from the attached still image device. * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ uint8_t SImage_ReceiveBlockHeader(void) { uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS; uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); /* Unfreeze the data IN pipe */ Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE); Pipe_Unfreeze(); /* Wait until data received on the IN pipe */ while (!(Pipe_IsINReceived())) { uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); /* Check to see if a new frame has been issued (1ms elapsed) */ if (CurrentFrameNumber != PreviousFrameNumber) { /* Save the new frame number and decrement the timeout period */ PreviousFrameNumber = CurrentFrameNumber; TimeoutMSRem--; /* Check to see if the timeout period for the command has elapsed */ if (!(TimeoutMSRem)) return PIPE_RWSTREAM_Timeout; } Pipe_Freeze(); Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE); Pipe_Unfreeze(); /* Check if pipe stalled (command failed by device) */ if (Pipe_IsStalled()) { /* Clear the stall condition on the OUT pipe */ USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); /* Return error code and break out of the loop */ return PIPE_RWSTREAM_PipeStalled; } Pipe_Freeze(); Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE); Pipe_Unfreeze(); /* Check if pipe stalled (command failed by device) */ if (Pipe_IsStalled()) { /* Clear the stall condition on the IN pipe */ USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); /* Return error code */ return PIPE_RWSTREAM_PipeStalled; } /* Check to see if the device was disconnected, if so exit function */ if (USB_HostState == HOST_STATE_Unattached) return PIPE_RWSTREAM_DeviceDisconnected; } /* Load in the response from the attached device */ Pipe_Read_Stream_LE(&PIMA_ReceivedBlock, PIMA_COMMAND_SIZE(0), NULL); /* Check if the returned block type is a response block */ if (PIMA_ReceivedBlock.Type == PIMA_CONTAINER_ResponseBlock) { /* Determine the size of the parameters in the block via the data length attribute */ uint8_t ParamBytes = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0)); /* Check if the device has returned any parameters */ if (ParamBytes) { /* Read the PIMA parameters from the data IN pipe */ Pipe_Read_Stream_LE(&PIMA_ReceivedBlock.Params, ParamBytes, NULL); } /* Clear pipe bank after use */ Pipe_ClearIN(); } /* Freeze the IN pipe after use */ Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }
/** Waits until the attached device is ready to accept data following a CBW, checking * to ensure that the device has not stalled the transaction. * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ static uint8_t MassStore_WaitForDataReceived(void) { uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS; uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); /* Select the IN data pipe for data reception */ Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); Pipe_Unfreeze(); /* Wait until data received in the IN pipe */ while (!(Pipe_IsINReceived())) { uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); /* Check to see if a new frame has been issued (1ms elapsed) */ if (CurrentFrameNumber != PreviousFrameNumber) { /* Save the new frame number and decrement the timeout period */ PreviousFrameNumber = CurrentFrameNumber; TimeoutMSRem--; /* Check to see if the timeout period for the command has elapsed */ if (!(TimeoutMSRem)) return PIPE_RWSTREAM_Timeout; } Pipe_Freeze(); Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE); Pipe_Unfreeze(); /* Check if pipe stalled (command failed by device) */ if (Pipe_IsStalled()) { /* Clear the stall condition on the OUT pipe */ USB_Host_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE); return PIPE_RWSTREAM_PipeStalled; } Pipe_Freeze(); Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); Pipe_Unfreeze(); /* Check if pipe stalled (command failed by device) */ if (Pipe_IsStalled()) { /* Clear the stall condition on the IN pipe */ USB_Host_ClearPipeStall(MASS_STORE_DATA_IN_PIPE); return PIPE_RWSTREAM_PipeStalled; } /* Check to see if the device was disconnected, if so exit function */ if (USB_HostState == HOST_STATE_Unattached) return PIPE_RWSTREAM_DeviceDisconnected; }; Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); Pipe_Freeze(); Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE); Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }