This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMDS64EVM: How to start BCDMA from the second time onwards

Part Number: TMDS64EVM

Dear TI support team,

Looking at the BCDMA sample code (udma_memcpy_interrupt_am64x-evm_a53ss0-0_nortos_gcc-aarch64:udma_memcpy_interrupt.c ), DMA is started using the following steps.

////

Drivers_udmaConfigUdma0BlkCopyOpen()
    UdmaChPrms_init
    Udma_chOpen
    UdmaChTxPrms_init
    Udma_chConfigTx
    UdmaChRxPrms_init
    Udma_chConfigRx
    UdmaEventPrms_init
    Udma_eventRegister
    Udma_chEnable
App_udmaInitBuf
App_udmaTrpdInit
Udma_ringQueueRaw --> DMA start transfer !
////

Then, a DMA transfer end interrupt occurs.

Next, I would like to start BCDMA by changing srcBuf and destBuf.
Which API should I call?

I thought that if I called App_udmaTrpdInit and Udma_ringQueueRaw as shown below, DMA would start, but it doesn't.

////
App_udmaInitBuf
App_udmaTrpdInit
Udma_ringQueueRaw --> DMA start transfer!
SemaphoreP_pend(&gUdmaTestDoneSem, SystemP_WAIT_FOREVER); // --> wait transfer end interrupt.
App_udmaInitBuf <-- add code
App_udmaTrpdInit <-- add code
Udma_ringQueueRaw <-- add code
(Buf DMA is NOT started !)
////

I would like to know as soon as possible how I can start a second DMA.

Could you please teach me?

Best reagrds,

Kiyomasa Imaizumi

  • P.S.
    I don't want to call Drivers_udmaConfigUdma0BlkCopyOpen again to start DMA for the second time.

  • Hello Kiyomasa Imaizumi,

    I am looking at your queries, and you may expect a reply by today.

    Regards,

    S.Anil.

  • Hello Kiyomasa Imaizumi,

    Can you please share your requirements?

    So, based on the above question, you wanted to trigger DMA on the same channel multiple times?

    You wanted to change the source and destination addresses for every DMA completion?

    I need the above details to better assist you.

    Regards,

    S.Anil.

  • Hello Swargam Anil.

    What I want to do is as follows.

    Data is transferred from DDR to FPGA via GPMC using BCDMA.

    1. Generates a GPMC interrupt, masks the GPMC interrupt within the interrupt, and starts BCDMA (data transfer from DDR to FPGA)
    2. Enable GPMC interrupt with BCDMA transfer end interrupt
    3. Generate GPMC interrupt again, start DMA within the interrupt (data transfer from DDR to FPGA)
    same as below


    DMA is performed multiple times as long as there is data to send on the same channel.
    The src address (DDR) changes every time DMA is completed. The dest address (FPGA) is fixed.

    Best Regards,

    Kiyomasa Imaizumi

  • P.S.

    The reason I don't want to call Drivers_udmaConfigUdma0BlkCopyOpen is because the processing time takes hundreds of microseconds.

    I want to configure the next DMA within several tens of microseconds.

  • Hello Kiyomasa Imaizumi,

    Thanks for sharing your requirements.

    In the above use case, every time you wanted to trigger data from DDR to FPGA,. In this use case, the source address is changed and the destination address is fixed. To achieve your requirement, you have to follow the below steps.

     

    Steps :

    1. App_udmaTrpdInit(chHandle, trpdMem, destBuf, srcBuf, length); in this API, you have to update your source address and length value if you are changing the length value.

     2. Next call the Udma_ringQueueRaw function to start DMA triggers.

     3. Next call the Udma_ringDequeueRaw function to check whether the DMA completion event is completed or not.

     

    The above steps need to be taken for every data transfer.

    Drivers_udmaConfigUdma0BlkCopyOpen

    You don't need to call the above function every time. This should be called only once.

    Regards,

    S.Anil.

  • Hello Swargam Anil.

    Thank you for your reply.
    I understood most of it.

    Is it safe to call the Udma_ringDequeueRaw function within the DMA transfer end interrupt?

    Also, is it necessary to check the status (CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE) with UdmaUtils_getTrpdTr15Response after the DMA transfer is completed?

    Best regards,
    Kiyomasa Imaizumi.

  • Hello Kiyomasa Imaizumi,

    Is it safe to call the Udma_ringDequeueRaw function within the DMA transfer end interrupt?

    You can do it, but the problem is that you need to stay on the same interrupt until the Udma_ringDequeueRaw function returns status OK.

    My suggestion is that at that end of the interrupt, just set the one flag, poll that flag, and if this flag is set, call the Udma_ringDequeueRaw function.

    Also, is it necessary to check the status (CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE) with UdmaUtils_getTrpdTr15Response after the DMA transfer is completed?

    Yes, you need to perform.

     

    Is there any concern while performing the above conditions?

    Regards,

    S.Anil.

  • Hello Swargam Anil.

    Thank you for your reply.

    Does Udma_ringDequeueRaw return OK on DMA transfer end interrupt?
    What does it mean that Udma_ringDequeueRaw returns something other than OK?

    On DMA transfer end interrupt, UdmaUtils_getTrpdTr15Response returns CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE?
    What does it mean that UdmaUtils_getTrpdTr15Response returns something other than COMPLETE?

    If the Udma_ringDequeueRaw function returns a status other than OK, should I keep waiting for OK?
    Also, if UdmaUtils_getTrpdTr15Response returns something other than COMPLETE, do I need to keep waiting for COMPLETE?

    Best regards,

    Kiyomasa Imaizumi.

  • P.S.

    If I get an error other than OK or COMPLETE, what should I do next? For example, do I need to call UDMA Driver Channel APIs such as Udma_chDisable?

  • Hello Kiyomasa Imaizumi,

    Please look at my answers to the above queries.

    After DMA completion ends,: "The DMA controllers do not actually write anything back to completion queues but instead just increment the reverse occupancy." This operation would be done in the dequeraw function. So, in simple words, after the DMA completion event in the dequeraw function, we will be setting one flag. If this flag is set, it means the total DMA completion event is completed.

    UdmaUtils_getTrpdTr15Response :

    Please look at the below image, and currently, when you are calling UdmaUtils_getTrpdTr15Response, it gives the information of status type (0:3 bits).

    In your current application, you are triggering a DMA event for the completion of an event type. In some use cases, you need to trigger some bytes of transfer by the DMA. In those cases, the response will be different.

     

    Based on the above information, when you got the DMA interrupt, the next calling of the Dequeraw function gave the status OK after a few CPU clock cycles.

    Next, you are checking the TR response status, which tells you exactly whether your application reads all data or if any processing data is there.

    After completion of the DMA end interrupt, you mostly get these statuses as ok or complete, but if any case doesn't come, just re-trigger DMA. Before retriggering DMA, just do the teardown DMA process.

    call the udma_ch_disable and the udma_close functions. And open udma_open and udma_ch_enable .

    Regards,

    S.Anil.