Invalid Sequence Error in Multi-Channel Commit Buffer - KBA218830 (ZH)
Version: **
Translation - Japanese: マルチチャネル コミットバッファでの無効なシーケンスエラー – KBA218830 - Community Translated (JA)
问题: 用户在使用FX3进行视频传输的时候会在UART终端中看到“Error in CyU3PDmaMultiChannelCommitBuffer: code 71”的错误信息。导致这个错误的原因是什么?如何从此错误中恢复?
回答: 当DMA buffer发生溢出的时候,用户会看到“Error in CyU3PDmaMultiChannelCommitBuffer: code 71”的出错信息。其中,error code 71对应 “CY_U3P_ERROR_INVALID_SEQUENCE”的错误。当主机端的UVC应用软件不能足够快速地向设备发送IN令牌,从而不能清空DMA buffer的时候,会发生这样的错误。
从error code 71中恢复的方法:
I) 在固件中增大分配给DMA buffer的空间。
II) 同AN75779,执行以下的代码:
1. 当CyU3PDmaMultiChannelCommitBuffer()没有返回CY_U3P_SUCCESS时,在CyFxUvcApplnDmaCallback()函数里设置一个标志位(例如,commit_buffer_failure)。
2. 在UVCAppThread_Entry的for(;;)循环中,检查该标志位是否置位。如果置位,执行以下的代码以复位DMA通道并且重启GPIF II状态机。
if (commit_buffer_failure == 1)
{
commit_buffer_failure = 0;
/* Stop the GPIF state machine to stop data transfers through FX3 */
CyU3PGpifDisable (CyFalse);
streamingStarted = CyFalse;
/* Place the Endpoint in NAK mode before cleaning up the pipe. */
apiRetStatus = CyU3PUsbSetEpNak (CY_FX_EP_BULK_VIDEO, CyTrue);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\r EP_NAK=%d\n", apiRetStatus);
}
/* Reset the DMA channel and flush the endpoint pipe. */
apiRetStatus = CyU3PDmaMultiChannelReset (&glChHandleUVCStream);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\r DMA_RESET=%d\n", apiRetStatus);
}
apiRetStatus = CyU3PUsbFlushEp (CY_FX_EP_BULK_VIDEO);
if(apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\r EP_FLUSH=%d\n", apiRetStatus);
}
apiRetStatus = CyU3PDmaMultiChannelSetXfer (&glChHandleUVCStream, 0, 0);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\r DMA_XFER = %d\n", apiRetStatus);
}
apiRetStatus = CyU3PUsbSetEpNak (CY_FX_EP_BULK_VIDEO, CyFalse);
if(apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "\r EP_ACK=%d\n", apiRetStatus);
}
apiRetStatus = CyU3PGpifSMStart (START_SCK0, ALPHA_START_SCK0);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PGpifSMStart = %d\n", apiRetStatus);
}
apiRetStatus = CyU3PGpifSMSwitch (257, 0, 257, 0, 2);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PGpifSMSwitch = %d\n", apiRetStatus);
}
streamingStarted = CyTrue;
}