Invalid Sequence Error in Multi-Channel Commit Buffer - KBA218830 (ZH)

Version: **

问题: 用户在使用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_Entryfor(;;)循环中,检查该标志位是否置位。如果置位,执行以下的代码以复位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;

             }