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.

AM6442: BCDMA

Genius 13655 points
Part Number: AM6442

Hello Champs,

Customer modified the mcu_plus_sdk_am64x_08_03_00_18\examples\drivers\udma\udma_memcpy_interrupt\am64x-evm\r5fss0-0_nortos example, he wants to move the data from uint32_t srcData = 10 to uint32_t destData = 0; and prints the result. App_udmaTrpdInit(chHandle, trpdMem, destBuf, srcBuf, length) is the same to the example without modification. The result is printed by DebugP_log("destData = %d\r\n",destData), but the destData = 0. The function void DMAMemcpy(uint32_t *srcBuf,uint32_t *destBuf,uint32_t length) and while(!gDataSendFinishFlag) can run successfully. 
Why the destData isn't updated. 

Below is his code. 

#include <stdio.h>
#include <kernel/dpl/DebugP.h>
#include "ti_drivers_config.h"
#include "ti_drivers_open_close.h"
#include "ti_board_open_close.h"

/*
 * µ±¸ø¶¨Ô´µØÖ·ºÍÄ¿±êµØÖ·ÒÔ¼°³¤¶È
 * ´Ëº¯Êý½«Æô¶¯DMA°áÔËÁ½¸öµØÖ·µÄÊý¾Ý
 */

#define UDMA_TEST_TRPD_SIZE             (UDMA_GET_TRPD_TR15_SIZE(1U))

uint8_t gDataSendFinishFlag = 0;

/**/
uint8_t gUdmaTestTrpdMem[UDMA_TEST_TRPD_SIZE] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));

/*ÉùÃ÷º¯Êý*/
void App_udmaEventCb(Udma_EventHandle eventHandle, uint32_t eventType, void *appData);
static void App_udmaTrpdInit(Udma_ChHandle chHandle,uint8_t *trpdMem, const void *destBuf, const void *srcBuf, uint32_t length);

void DMAMemcpy(uint32_t *srcBuf,uint32_t *destBuf,uint32_t length)
{
    uint32_t        trRespStatus;
    int32_t         retVal = UDMA_SOK;
    uint64_t        pDesc;
    Udma_ChHandle   chHandle;
    uint8_t        *trpdMem = &gUdmaTestTrpdMem[0U];
    uint64_t        trpdMemPhy = (uint64_t) Udma_defaultVirtToPhyFxn(trpdMem, 0U, NULL);

    /*»ñȡͨµÀ²Ù×÷¾ä±ú*/
    chHandle = gConfigUdma0BlkCopyChHandle[0];

    /*ʹÄÜͨµÀ*/
    retVal = Udma_chEnable(chHandle);
    DebugP_assert(UDMA_SOK == retVal);

    /*³õʼ»¯TRÃèÊö·û*/
    App_udmaTrpdInit(chHandle, trpdMem, destBuf, srcBuf, length);

    /*½«ÃèÊö·ûÌá½»¸øÍ¨µÀ¿ªÊ¼Êý¾ÝµÄ´«Êä*/
    retVal = Udma_ringQueueRaw(Udma_chGetFqRingHandle(chHandle), trpdMemPhy);
    DebugP_assert(UDMA_SOK == retVal);

    /*µÈ´ýÊý¾Ý´«ÊäÍê³É£¬»Øµ÷º¯Êý¸ü¸Ä±ê־λ*/
    while(!gDataSendFinishFlag);

    /*½«ÃèÊö·û´Ó»·Öе¯³ö*/
    retVal = Udma_ringDequeueRaw(Udma_chGetCqRingHandle(chHandle), &pDesc);
    DebugP_assert(UDMA_SOK == retVal);

    /*¼ì²âTR»ØÓ¦×´Ì¬*/
    CacheP_inv(trpdMem, UDMA_TEST_TRPD_SIZE, CacheP_TYPE_ALLD);
    trRespStatus = UdmaUtils_getTrpdTr15Response(trpdMem, 1U, 0U);
    DebugP_assert(CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE == trRespStatus);
}


void empty_main(void *args)
{
    uint32_t srcData = 10;
    uint32_t destData = 0;

    /* Open drivers to open the UART driver for console */
    Drivers_open();
    Board_driversOpen();

    DMAMemcpy(&srcData,&destData,1024);
    while(1){
        DebugP_log("destData = %d\r\n",destData);
    }

    Board_driversClose();
    Drivers_close();
}

/*Êý¾Ý´«ÊäÍê³ÉµÄÖжϻص÷º¯Êý*/
void MyDMACallback(Udma_EventHandle eventHandle, uint32_t eventType, void *appData)
{
    gDataSendFinishFlag = 1;
}

static void App_udmaTrpdInit(Udma_ChHandle chHandle,uint8_t *trpdMem,const void *destBuf,const void *srcBuf,uint32_t length)
{
    CSL_UdmapTR15  *pTr;
    uint32_t        cqRingNum = Udma_chGetCqRingNum(chHandle);

    /* Make TRPD with TR15 TR type */
    UdmaUtils_makeTrpdTr15(trpdMem, 1U, cqRingNum);

    /* Setup TR */
    pTr = UdmaUtils_getTrpdTr15Pointer(trpdMem, 0U);
    pTr->flags    = CSL_FMK(UDMAP_TR_FLAGS_TYPE, CSL_UDMAP_TR_FLAGS_TYPE_4D_BLOCK_MOVE_REPACKING_INDIRECTION);
    pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_STATIC, 0U);
    pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_EOL, CSL_UDMAP_TR_FLAGS_EOL_MATCH_SOL_EOL);
    pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_EVENT_SIZE, CSL_UDMAP_TR_FLAGS_EVENT_SIZE_COMPLETION);
    pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
    pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0_TYPE, CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL);
    pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
    pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1_TYPE, CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL);
    pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_CMD_ID, 0x25U);  /* This will come back in TR response */
    pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_SA_INDIRECT, 0U);
    pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_DA_INDIRECT, 0U);
    pTr->flags   |= CSL_FMK(UDMAP_TR_FLAGS_EOP, 1U);
    pTr->icnt0    = length;
    pTr->icnt1    = 1U;
    pTr->icnt2    = 1U;
    pTr->icnt3    = 1U;
    pTr->dim1     = pTr->icnt0;
    pTr->dim2     = (pTr->icnt0 * pTr->icnt1);
    pTr->dim3     = (pTr->icnt0 * pTr->icnt1 * pTr->icnt2);
    pTr->addr     = (uint64_t) Udma_defaultVirtToPhyFxn(srcBuf, 0U, NULL);
    pTr->fmtflags = 0x00000000U;    /* ÏßÐÔѰַ, 1 byte per elem */
    pTr->dicnt0   = length;
    pTr->dicnt1   = 1U;
    pTr->dicnt2   = 1U;
    pTr->dicnt3   = 1U;
    pTr->ddim1    = pTr->dicnt0;
    pTr->ddim2    = (pTr->dicnt0 * pTr->dicnt1);
    pTr->ddim3    = (pTr->dicnt0 * pTr->dicnt1 * pTr->dicnt2);
    pTr->daddr    = (uint64_t) Udma_defaultVirtToPhyFxn(destBuf, 0U, NULL);

    /* »º´æ»ØÐ´ */
    CacheP_wb(trpdMem, UDMA_TEST_TRPD_SIZE, CacheP_TYPE_ALLD);

    return;
}


Thanks
Regards
Shine

  • Hello Shine,

    Please add the below line after the 56th line in the above code. So, it works.

    You are not doing cache_invalidation for the destination buffer. So, data is not visible on the destination buffer.

    Please close the thread if this helps your query.

    /* Invalidate destination buffer */
    CacheP_inv(destBuf, length, CacheP_TYPE_ALLD);

    Regards,

    S.Anil.

  • Hi S.Anil.,

    Thank you very much for your great support. 

    Customer added CacheP_inv(destBuf, length, CacheP_TYPE_ALLD); after the 56th line , but it prompted below error when executing retVal = Udma_eventRegister(drvHandle, cqEventHandle, &cqEventPrms);
    DebugP_assert(UDMA_SOK == retVal);




    Thanks
    Regards
    Shine

  • Hello Shine,

    I am trying to understand why the customer added Udma_eventRegister(drvHandle, cqEventHandle, and cqEventPrms) function call in the customer Application.

    Customer is trying to do any SW trigger in the above example?

    I have fixed some bugs in the customer code and tested it on my side, and now the example is working fine.

    Please copy the udma_memcpy_interrupt.c file into the customer application and test it.

    Please close this thread if this helps your query.

    I have modified the code and tested it on 8.4 MCU+SDK, and the same code should be integrated into the udma_memcpy_interrupt.c file in the customer application.

    udma_memcpy_interrupt_am64x-evm_r5fss0-0_freertos_ti-arm-clang.zip

    Regards,

    S.Anil.

  • Hi S.Anil.,

    It works. Thank you very much.

    As for the void App_udmaEventCb(Udma_EventHandle eventHandle, uint32_t eventType, void *appData) function, can customer define the void *appData parameter? If yes, where to configure it and what kind of parameters can be configured?

    Regards
    Shine

  • Hello Shine,

    The App_udmaEventCb function callback name should be given by the user from syscfg, and please look at the image below. But the user can't modify arguments in the callback function.

    Regards,

    S.Anil.