3 Replies Latest reply on Dec 15, 2019 11:14 PM by HemanthR_06

    CX3 DMA Channel

    waxi_4600311

      Hello,

         I use cyusb3065 and 0v5640 to tranmit image data by DMA. I config stream dma as CY_U3P_DMA_TYPE_MANUAL_MANY_TO_ONE dma, and commit data buffer in its dma callback. And I want to send leader before payload and send trailer after payload. I creat another CY_U3P_DMA_TYPE_MANUAL_OUT dma channel to send leader and trailer. I sent trailer and leader when stream dma callback get a short packet.But when I debug my code, I can see Leader and trailer dma get buffer and commit  buffer successful, but I can't catch leader and trailer in bushound.What's my problem?

       

         And I confuse how dma channel connet with end point? For example, I commit a buffer in stream dma callback, why dma can send the buffer to stream end point?How dma channel match the end point?

       

      my code:

      Stream DMA init:

      {

          /* Create a DMA Manual OUT channel for streaming data */

          /* Video streaming Channel is not active till a stream request is received */

      stDmaCfg.size                 = 32768;

      stDmaCfg.count                = 2;

      stDmaCfg.validSckCount        = 2;

      stDmaCfg.prodSckId[0]         = CY_U3P_PIB_SOCKET_0;

      stDmaCfg.prodSckId[1]         = CY_U3P_PIB_SOCKET_1;

      stDmaCfg.consSckId[0]         = CY_U3P_UIB_SOCKET_CONS_3;

      stDmaCfg.dmaMode              = CY_U3P_DMA_MODE_BYTE;

      stDmaCfg.notification         = CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_CONS_EVENT | CY_U3P_DMA_CB_SEND_CPLT;

      stDmaCfg.cb                   = CyCx3UvcAppDmaCallback;

      stDmaCfg.prodHeader           = 0;

      stDmaCfg.prodFooter           = 0;

      stDmaCfg.consHeader           = 0;

      stDmaCfg.prodAvailCount       = 0;

       

      ui32Status = CyU3PDmaMultiChannelCreate (&g_stParameterSetVariable.stDMAHandleStreamIn,

                  CY_U3P_DMA_TYPE_MANUAL_MANY_TO_ONE , &stDmaCfg);

          if (ui32Status != CY_U3P_SUCCESS)

          {

              CyU3PDebugPrint (4, "\n\rAppInit:DmaMultiChannelCreate1 Err = 0x%x", ui32Status);

          }

          CyU3PThreadSleep(100);

       

          ui32Status = CyU3PDmaMultiChannelReset(&g_stParameterSetVariable.stDMAHandleStreamIn);

          if (ui32Status != CY_U3P_SUCCESS)

          {

              CyU3PDebugPrint (4,"\n\rAppInit:MultiChannelReset1 Err = 0x%x", ui32Status);

          }

      }

       

      Stream DMA Callback:CyCx3UvcAppDmaCallback

      {

      ...

          if(type ==CY_U3P_DMA_CB_SEND_CPLT )

          {

              status = CyU3PDmaMultiChannelSetXfer (&g_stParameterSetVariable.stDMAHandleStreamIn, 0, 0);

              if (status != CY_U3P_SUCCESS)

              {

                  CyU3PDebugPrint (4, "\n\rAplnStrt:SetXfer Err = 0x%x", status);

              }

       

       

          CyU3PGpifSMSwitch(CX3_INVALID_GPIF_STATE, CX3_START_SCK0, CX3_INVALID_GPIF_STATE, ALPHA_CX3_START_SCK0, CX3_GPIF_SWITCH_TIMEOUT);

           CyU3PMipicsiWakeup();

          if (status != CY_U3P_SUCCESS)

                  {

                 CyU3PDeviceReset(CyFalse);

                      CyU3PDebugPrint (4, "\n\rAplnStrt:SetXfer Err = 0x%x", status);

                  }

          CyCx3_ImageSensor_Wakeup();

          }

          if (type == CY_U3P_DMA_CB_PROD_EVENT)

          {

              /* This is a produce event notification to the CPU. This notification is

               * received upon reception of every buffer. The buffer will not be sent

               * out unless it is explicitly committed. The call shall fail if there

               * is a bus reset / usb disconnect or if there is any application error. */

              status = CyU3PDmaMultiChannelGetBuffer(chHandle, &dmaBuffer, CYU3P_NO_WAIT);

              while (status == CY_U3P_SUCCESS)

              {

              ui32DataCount = ui32DataCount + dmaBuffer.count;

                  /* Add Headers*/

                  if (dmaBuffer.count < CX3_UVC_DATA_BUF_SIZE)

                  {

                      EOF = CyTrue;

                  }

       

                  status = CyU3PDmaMultiChannelCommitBuffer (chHandle, dmaBuffer.count, 0);

                  if (status != CY_U3P_SUCCESS)

                  {

                  CyU3PDebugPrint(4, "\r\nCommit Error:0x%x\r\n", status);

                      CyU3PEventSet(&glCx3Event, CX3_DMA_RESET_EVENT, CYU3P_EVENT_OR);

                      break;

                  }

                 status = CyU3PDmaMultiChannelGetBuffer(chHandle, &dmaBuffer, CYU3P_NO_WAIT);

              }

          }

          else if (type == CY_U3P_DMA_CB_CONS_EVENT)

          {

              if(EOF == CyTrue)

              {

              EOF = CyFalse;

               status = CyU3PMipicsiSleep();

               status = CyCx3_ImageSensor_Sleep();

               CyU3PBusyWait (1000);

       

              //Fill Trailer

               __SetTrailerBuffer(&stTrailer);

              //Send Trailer

              SendDMAMessage(&stTrailer, sizeof(IMAGE_TRAILER));

       

              //Fill Leader

              __SetLeaderBuffer(&stLeader);

       

              //Send Leader

              SendDMAMessage(&stLeader, sizeof(IMAGE_LEADER));

          }

      ...

      }

       

      Leader Trailer DMA init

      {

         stEP1OutDmaCfg.size  = 1024;

         stEP1OutDmaCfg.count = 3;

         stEP1OutDmaCfg.prodSckId = CY_U3P_CPU_SOCKET_PROD;

         stEP1OutDmaCfg.consSckId = CY_U3P_UIB_SOCKET_CONS_4;

         stEP1OutDmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;

         stEP1OutDmaCfg.notification = 0;

         stEP1OutDmaCfg.cb = 0;

         stEP1OutDmaCfg.prodHeader = 0;

         stEP1OutDmaCfg.prodFooter = 0;

         stEP1OutDmaCfg.consHeader = 0;

         stEP1OutDmaCfg.prodAvailCount = 0;

       

          ui32Status = CyU3PDmaChannelCreate (&g_stParameterSetVariable.stLeaderTrailer,

                  CY_U3P_DMA_TYPE_MANUAL_OUT, &stEP1OutDmaCfg);

          if (ui32Status != DH_STATUS_SUCCESS)

          {

          CyU3PDebugPrint (4, "LeaderTrailerDma Error: 0x%x\n\r", ui32Status);

          g_testparam = ui32Status;

          return ui32Status;

          }

          else

          {

          CyU3PDebugPrint(4, "\r\n LeaderTrailerDma success\r\n");

          }

       

          // 设置DMA通道传输大小

          ui32Status = CyU3PDmaChannelSetXfer (&g_stParameterSetVariable.stLeaderTrailer, 0);

          if (ui32Status != DH_STATUS_SUCCESS)

          {

          return ui32Status;

          }

      }

       

      Send Leader and Trailer function:

      void SendDMAMessage(uint8_t* buffer, uint8_t len)

      {

          unsigned int ui32Status = 0;

           CyU3PDmaBuffer_t buf_p;

          CyU3PDmaBuffer_t stOutBuffer;

       

           ui32Status = CyU3PDmaChannelGetBuffer(&g_stParameterSetVariable.stLeaderTrailer, &stOutBuffer, 0);

           if (ui32Status != CY_U3P_SUCCESS)

           {

                CyU3PDebugPrint (4, "\r\nGetBuffer Fail = %d\n", ui32Status);

           }

           else

           {

                CyU3PDebugPrint (4, "\r\nGetBuffer success\r\n");

           }

       

           CyU3PMemCopy(stOutBuffer.buffer, buffer, len);

           for (i = 0; i < len; i++)

           {

                  CyU3PDebugPrint(4, "0x%x\r\n", stOutBuffer.buffer[i]);

           }

       

           ui32Status = CyU3PDmaChannelCommitBuffer(&g_stParameterSetVariable.stLeaderTrailer, len, 0);

           if(ui32Status != CY_U3P_SUCCESS)

           {

                CyU3PDebugPrint (4, "\r\nSendBuffer Fail = %d\n", ui32Status);

           }

           else

            {

                CyU3PDebugPrint (4, "\r\nSendBuffer success\r\n");

            }

       

           ui32Status = CyU3PDmaChannelDiscardBuffer (&g_stParameterSetVariable.stLeaderTrailer);

      }