1 Reply Latest reply on Oct 29, 2019 4:25 AM by HemanthR_06

    CyU3PDmaMultiChannelGetBuffer and CyU3PDmaMultiChannelCommitBuffer failure

    jawu_4351971

      Now I can see video at player, but only dozens of seconds the two function return Failure.and the video will be missing.

      CyU3PDmaMultiChannelGetBuffer return CY_U3P_ERROR_TIMEOUT,

      CyU3PDmaMultiChannelCommitBuffer return CY_U3P_ERROR_INVALID_SEQUENCE.

       

      Please help me,how can I solve it?

      thank you

       

      my code in CY_U3P_DMA_CB_PROD_EVENT is
      
      void DmaProducerEventCallback(CyU3PDmaMultiChannel *chHandle,
                                    CyU3PDmaCbType_t      type,
                                    CyU3PDmaCBInput_t    *input)
      {
          CyU3PDmaBuffer_t dmaBuffer;
          CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
      
          status = CyU3PDmaMultiChannelGetBuffer(chHandle, &dmaBuffer, CYU3P_NO_WAIT);
          if (status != CY_U3P_SUCCESS)
          {
              // signal the event and return
              CyU3PEventSet(&glCloverUsbEvent, CX3_DMA_GET_BUFFER_ERROR_EVENT, CYU3P_EVENT_OR);
              return;
          }
      
          for (int i = 0; ((i < 2) && (status == CY_U3P_SUCCESS)); i++)
          {
              /* Add Headers */
              if (dmaBuffer.count < CX3_APP_DATA_BUF_SIZE)
              {
                  DmaUvcDebugProbeInCallback(&dmaBuffer);
                  CyCx3AppAddHeader((dmaBuffer.buffer - UVC_DATA_BUFFER_HEADER_SIZE), CX3_APP_HEADER_EOF);
                  glCloverMipiInfo.hitFV = CyTrue;
              }
              else
              {
                  CyCx3AppAddHeader((dmaBuffer.buffer - UVC_DATA_BUFFER_HEADER_SIZE), CX3_APP_HEADER_FRAME);
              }
              /* Commit Buffer to USB */
              status = CyU3PDmaMultiChannelCommitBuffer(chHandle, (dmaBuffer.count + UVC_DATA_BUFFER_HEADER_SIZE), 0);
              if (status != CY_U3P_SUCCESS)
              {
                  CyU3PEventSet(&glCloverUsbEvent, CX3_DMA_COMMIT_BUFFER_ERRPR_EVENT, CYU3P_EVENT_OR);
                  break;
              }
      
              glCloverMipiInfo.dmaDone++;
              glCloverMipiInfo.activeSocket ^= 1; /* Toggle the Active Socket */
              status = CyU3PDmaMultiChannelGetBuffer(chHandle, &dmaBuffer, CYU3P_NO_WAIT);
          }
      }
      
      
      

      my code in CY_U3P_DMA_CB_CONS_EVENT is

       

      void DmaCustomerEventCallback(CyU3PDmaMultiChannel *chHandle,
                                    CyU3PDmaCbType_t      type,
                                    CyU3PDmaCBInput_t    *input)
      {
          if(glCloverMipiInfo.dmaDone == 0)
          {
              Cx3Err("dma done is 0\r\n");
          }
          else
          {
              glCloverMipiInfo.dmaDone--;
          }
          glCloverMipiInfo.isStreamingStarted = CyTrue;
      
          if((glCloverMipiInfo.dmaDone == 0)&&(glCloverMipiInfo.hitFV == CyTrue))
          {
              glCloverMipiInfo.hitFV = CyFalse;
              glCloverMipiInfo.dmaTxCount = 0;
      
              if(glCloverMipiInfo.activeSocket)
              {
                  CyU3PGpifSMSwitch(CX3_INVALID_GPIF_STATE, CX3_START_SCK1,
                                    CX3_INVALID_GPIF_STATE, ALPHA_CX3_START_SCK1, CX3_GPIF_SWITCH_TIMEOUT);
              }else
              {
                  CyU3PGpifSMSwitch(CX3_INVALID_GPIF_STATE, CX3_START_SCK0,
                                    CX3_INVALID_GPIF_STATE, ALPHA_CX3_START_SCK0, CX3_GPIF_SWITCH_TIMEOUT);
              }
      
          }
      }
      
      
      
      
      
      
        • 1. Re: CyU3PDmaMultiChannelGetBuffer and CyU3PDmaMultiChannelCommitBuffer failure
          HemanthR_06

          Hi,

           

          If CyU3PDmaMultiChannelGetBuffer() fails with timeout as the return status, then CyU3PDmaMultiChannelCommitBuffer() should not be called. Calling leads to Invalid Sequence error.

          If you have a look at Cypress UVC example source code, CyU3PDmaMultiChannelCommitBuffer() is called in a while loop as long as CyU3PDmaMultiChannelGetBuffer() is success.

           

          I am not sure why 'for' loop is put in the DmaCall back snippet that you have posted. Can you please change that to the way standard example handle it?

           

          Sometimes, you may get Invalid Sequence error even though Get Buffer succeeded. This happens when all your DMA buffers are full and Host has not yet consumed them. In that case you can perform the steps mentioned in the below document (which you might already be aware):

          Invalid Sequence Error in Multi-Channel Commit Buffer - KBA218830 

           

          Regards,

          Hemanth