CX3 DMA Channel

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
waxi_4600311
Level 1
Level 1

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);

     }

     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);

}

0 Likes
1 Solution
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

Hi,

CY_U3P_UIB_SOCKET_CONS_X corresponds to IN-Endpoint number X and CY_U3P_UIB_SOCKET_PROD_X corresponds to OUT-Endpoint number X.

You are committing the video data to IN-Endpoint 3 and committing leader and trailer to IN-Endpoint 4.

Regards,

Hemanth

Hemanth

View solution in original post

0 Likes
3 Replies
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

Hi,

CY_U3P_UIB_SOCKET_CONS_X corresponds to IN-Endpoint number X and CY_U3P_UIB_SOCKET_PROD_X corresponds to OUT-Endpoint number X.

You are committing the video data to IN-Endpoint 3 and committing leader and trailer to IN-Endpoint 4.

Regards,

Hemanth

Hemanth
0 Likes

Hello,

   Can the same dma producer or consumer socket register for different DMA channel ?

0 Likes
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

Hi,

No, it is not possible. To send trailer and leader at the end of the frame, to the same endpoint to which video data is sent, you will have to use CyU3PDmaMultiChannelSetupSendBuffer() as discussed in CX3 GPIFII modify​ (response dated Dec 6, 2019)

Regards,

Hemanth

Hemanth
0 Likes