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.

[FAQ] TDA4VM: GPIO interrupt use DMA

Part Number: TDA4VM
Other Parts Discussed in Thread: SYSBIOS

dear experts:

          I want use the GPIO input calture function and use the DMA  function. can you provide us the  examble or  demo  ?

I also check the path to the example is at <SDK_PATH>/psdk_rtos_auto_j7_07_00_00_11/[pdk_jacinto_07_00_00/packages/ti/drv/gpio/test/led_blink/src/main_led_blink.c . this just only the GPIO interrupt function!

I check that datasheet which also support the GPIO dma , the content description below :

12.1.2.1 GPIO Overview

In addition, the GPIO peripheral can produce host CPU interrupts and DMA synchronization events in
different interrupt/event generation modes.

BR!

thanks!

  • Hi,

    There is no single example application for what you are looking for. You can take a look at the example "udma_sw_trigger_testapp" in pdk/packages/ti/build --> make udma_sw_trigger_testapp on how to trigger DMA using events.

    Code is under packages/ti/ti/drv/udma/application

    As described in the TRM under GPIO section, 12.1.2.4.3 GPIO Interrupt and Event Generation you need to setup the DMA triggers and route them to the DMA

    Regards

    Vineet

  • I have  same question!

  • how to setup the DMA triggers and route them to the DMA

  • I have searched the udma support the TDA4 Peripherals, it not include gpio and timer , so it means that TDA4 ' UDMA not support the gpio and timer?

  • Hi,

    Can you please provide some more details? What do you mean UDMA with GPIO/Timer??

    Regards,

    Brijesh

  • Brijesh,

    I know this customer. I guess, they want GPIO to trigger DMA, to offload CPU.

    Is it possible to trigger UDMA using GPIO rising/falling edge without R5F involve?

    Thanks & Best Regards!

    ZM

  • Hi ZM,

    Yes, it is possible.

    Regards,

    Brijesh

  • Thanks for confirmation.

    Is there any example code in PDK? So that I can guide them to integrate into MCU2_1. If not, could you please share some ideas?

    Background: This is for ultrasonic sensor capture.

    Thanks & Best Regards!

    ZM

  • Zm,

    I dont have PDK code, i wrote one on SDK7.1, it works fine. I will share you file.. 

    Regards,

    Brijesh

  • when i use app_gpio_dma.c ,During operation, there is an exception.

    ########################################################################

          This file is integrated into the vision_app basic_demos/app_tirtos, app_gpio_dma.c the file is only added in a few places to print, no other changes

    The timing of the call

                     [common/appinit.c] appInit() call appGpioInit() 

          

          

     

    log positioning failed to run to the write L2G register

          

          log output

     

    #############################################################################################

    To use CCS debugging, I moved the functions in the app_gpio_dma.c regarding gpio interrupt configuration and UDMA interrupt routing configuration to the pdk/drv/udma/example/udma_sw_trigger,. The following functions were used to configure the interrupt

    The compile (CORE=mcu2_0) runs (normal before adding changes) and is located in the same place where an exception occurs when L2G register is written

    Time to call

    app_create() end, add call

              
        

          I adjust the timing of the call elsewhere in the app_create(), and the exception is still located in the same place.

    #######################################################################################

     app_gpio_dma.c file

    ~~~

    /*
    *
    * Copyright (c) 2018 Texas Instruments Incorporated
    *
    * All rights reserved not granted herein.
    *
    * Limited License.
    *
    * Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive
    * license under copyrights and patents it now or hereafter owns or controls to make,
    * have made, use, import, offer to sell and sell ("Utilize") this software subject to the
    * terms herein. With respect to the foregoing patent license, such license is granted
    * solely to the extent that any such patent is necessary to Utilize the software alone.
    * The patent license shall not apply to any combinations which include this software,
    * other than combinations with devices manufactured by or for TI ("TI Devices").
    * No hardware patent is licensed hereunder.
    *
    * Redistributions must preserve existing copyright notices and reproduce this license
    * (including the above copyright notice and the disclaimer and (if applicable) source
    * code license limitations below) in the documentation and/or other materials provided
    * with the distribution
    *
    * Redistribution and use in binary form, without modification, are permitted provided
    * that the following conditions are met:
    *
    * * No reverse engineering, decompilation, or disassembly of this software is
    * permitted with respect to any software provided in binary form.
    *
    * * any redistribution and use are licensed by TI for use only with TI Devices.
    *
    * * Nothing shall obligate TI to provide you with source code for the software
    * licensed and provided to you in object code.
    *
    * If software source code is provided to you, modification and redistribution of the
    * source code are permitted provided that the following conditions are met:
    *
    * * any redistribution and use of the source code, including any resulting derivative
    * works, are licensed by TI for use only with TI Devices.
    *
    * * any redistribution and use of any object code compiled from the source code
    * and any resulting derivative works, are licensed by TI for use only with TI Devices.
    *
    * Neither the name of Texas Instruments Incorporated nor the names of its suppliers
    *
    * may be used to endorse or promote products derived from this software without
    * specific prior written permission.
    *
    * DISCLAIMER.
    *
    * THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS
    * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    * IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
    * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
    * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    * OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    */

    #include <stdio.h>
    #include <string.h>
    #include <xdc/runtime/Error.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>

    #include <ti/board/board.h>
    #include <ti/drv/gpio/GPIO.h>
    #include <ti/drv/gpio/soc/GPIO_soc.h>
    #include <ti/drv/gpio/src/v0/GPIO_v0.h>

    #include <ti/csl/csl_intr_router.h> /* CSL for interrupt router */
    #include <ti/osal/osal.h>
    #include <ti/drv/sciclient/sciclient.h>
    #include <ti/csl/soc/j721e/src/cslr_main_ctrl_mmr.h>
    #include <ti/csl/soc/j721e/src/cslr_soc_baseaddress.h>

    #include <utils/sciclient/include/app_sciclient_wrapper_api.h>

    #include <utils/mem/include/app_mem.h>
    #include <ti/drv/udma/udma.h>

    #include <utils/udma/include/app_udma.h>

    /* ========================================================================== */
    /* Macros & Typedefs */
    /* ========================================================================== */

    /* Test application stack size */
    #define APP_TSK_STACK_MAIN (16U * 1024U)

    /*
    * Application test parameters
    */

    #define APP_TIME_READ_CNT (20U)

    /** \brief Number of bytes to copy and buffer allocation */
    #define APP_NUM_BYTES (8U * APP_TIME_READ_CNT)
    /** \brief This ensures every channel memory is aligned */
    #define APP_BUF_SIZE_ALIGN ((APP_NUM_BYTES + UDMA_CACHELINE_ALIGNMENT) & ~(UDMA_CACHELINE_ALIGNMENT - 1U))
    /** \brief Number of channels */
    #define APP_NUM_CH (1U)

    /*
    * Ring parameters
    */
    /** \brief Number of ring entries - we can prime this much memcpy operations */
    #define APP_RING_ENTRIES (3U)
    /** \brief Size (in bytes) of each ring entry (Size of pointer - 64-bit) */
    #define APP_RING_ENTRY_SIZE (sizeof(uint64_t))
    /** \brief Total ring memory */
    #define APP_RING_MEM_SIZE (APP_RING_ENTRIES * \
    APP_RING_ENTRY_SIZE)
    /** \brief This ensures every channel memory is aligned */
    #define APP_RING_MEM_SIZE_ALIGN ((APP_RING_MEM_SIZE + UDMA_CACHELINE_ALIGNMENT) & ~(UDMA_CACHELINE_ALIGNMENT - 1U))
    /**
    * \brief UDMA TR packet descriptor memory.
    * This contains the CSL_UdmapCppi5TRPD + Padding to sizeof(CSL_UdmapTR15) +
    * one Type_15 TR (CSL_UdmapTR15) + one TR response of 4 bytes.
    * Since CSL_UdmapCppi5TRPD is less than CSL_UdmapTR15, size is just two times
    * CSL_UdmapTR15 for alignment.
    */
    #define APP_TRPD_SIZE ((sizeof(CSL_UdmapTR15) * 2U) + 4U)
    /** \brief This ensures every channel memory is aligned */
    #define APP_TRPD_SIZE_ALIGN ((APP_TRPD_SIZE + UDMA_CACHELINE_ALIGNMENT) & ~(UDMA_CACHELINE_ALIGNMENT - 1U))


    #define TRIGGER_TYPE (CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL0)

    uint32_t INTR_OFFSET = 8u;

    #define GPIOMUX_INTRTR0_OUTP_START_R5FSS0 (16u + INTR_OFFSET)

    #define GPIO_START (37)

    #define GTC_TIME_ADDR (0xA90008u)

    /* ========================================================================== */
    /* Structure Declarations */
    /* ========================================================================== */

    typedef struct
    {
    int32_t chIdx;

    struct Udma_ChObj chObj;
    struct Udma_EventObj cqEventObj;
    struct Udma_EventObj tdCqEventObj;

    Udma_ChHandle chHandle;
    Udma_EventHandle cqEventHandle;
    Udma_EventHandle tdCqEventHandle;

    Udma_DrvHandle drvHandle;
    SemaphoreP_Handle transferDoneSem;
    /**< Semaphore to indicate transfer completion */

    uint8_t *txRingMem;
    uint8_t *txCompRingMem;
    uint8_t *txTdCompRingMem;
    uint8_t *trpdMem;

    uint64_t trpd_mem_phy;
    /**< Allocated TRPD memory physical pointer */

    uint8_t *destBuf;
    } App_ChObj;

    typedef struct
    {
    Udma_DrvHandle drvHandle;
    App_ChObj appChObj[APP_NUM_CH];
    } App_Obj;

    /* ========================================================================== */
    /* Function Declarations */
    /* ========================================================================== */

    static int32_t App_GpioDmaTest(void);

    static int32_t App_gpioTriggerTest(App_Obj *appObj, uint32_t inst);

    static void App_eventDmaCb(Udma_EventHandle eventHandle,
    uint32_t eventType,
    void *appData);
    static void App_eventTdCb(Udma_EventHandle eventHandle,
    uint32_t eventType,
    void *appData);

    static int32_t App_init(App_Obj *appObj);
    static int32_t App_deinit(App_Obj *appObj);

    static int32_t App_create(App_Obj *appObj);
    static int32_t App_delete(App_Obj *appObj);

    static void App_trpdInit(App_ChObj *appChObj, uint32_t inst);

    static void App_print(const char *str);

    static void App_setupPinmux();
    static uint32_t Udma_chGetTriggerEvent(Udma_DrvHandle drvHandle,
    Udma_ChHandle chHandle,
    uint32_t trigger);
    static void App_setupL2G(App_Obj *appObj, uint32_t enable);
    static void App_setUdmaIntAMap(App_Obj *appObj, uint32_t localEvtIdx, uint32_t glblEvt, uint32_t enable);
    static void App_initGpio();
    static void App_setupGpioMuxIr();
    static void App_triggerGpio();

    static void App_cacheInv(const void * addr, int32_t size);
    static void App_cacheWb(const void *addr, int32_t size);

    static int32_t App_pause(App_Obj *appObj);
    static int32_t App_resume(App_Obj *appObj);

    /* ========================================================================== */
    /* Global Variables */
    /* ========================================================================== */

    /*
    * UDMA driver and channel objects
    */
    App_Obj gAppObj;

    #if 0
    /*
    * UDMA Memories
    */
    static uint8_t gTxRingMem[APP_NUM_CH][APP_RING_MEM_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    static uint8_t gTxCompRingMem[APP_NUM_CH][APP_RING_MEM_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    static uint8_t gTxTdCompRingMem[APP_NUM_CH][APP_RING_MEM_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    static uint8_t gUdmaTrpdMem[APP_NUM_CH][APP_TRPD_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    #endif

    #if 0
    /*
    * Application Buffers
    */
    static uint8_t gUdmaTestSrcBuf[APP_NUM_CH][APP_BUF_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    static uint8_t gUdmaTestDestBuf[APP_NUM_CH][APP_BUF_SIZE_ALIGN] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT)));
    #endif

    /* Global test pass/fail flag */
    static volatile int32_t gUdmaAppResult = UDMA_SOK;

    static volatile uint32_t gIntAggrLeviEvtId[16] = {
    68, 69, 70, 71, 72, 73, 74, 75,
    76, 77, 78, 79, 80, 81, 82, 83};

    /* Test application stack */
    //static uint8_t gAppTskStackMain[APP_TSK_STACK_MAIN] __attribute__((aligned(32)));;

    /* ========================================================================== */
    /* Function Definitions */
    /* ========================================================================== */

    static int32_t App_GpioDmaTest(void)
    {
    int32_t retVal;
    App_Obj *appObj = &gAppObj;

    retVal = App_init(appObj);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA App init failed!!\n");
    }

    App_print("Application started...\n");

    if(UDMA_SOK == retVal)
    {
    retVal = App_create(appObj);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA App create failed!!\n");
    }
    }

    if(UDMA_SOK == retVal)
    {
    retVal = App_gpioTriggerTest(appObj, 0);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA App test failed!!\n");
    }
    }

    retVal += App_delete(appObj);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA App delete failed!!\n");
    }

    retVal += App_deinit(appObj);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA App deinit failed!!\n");
    }

    if((UDMA_SOK == retVal) && (UDMA_SOK == gUdmaAppResult))
    {
    App_print("Passed!!\n");
    App_print("All tests have passed!!\n");
    }
    else
    {
    App_print("Failed!!\n");
    App_print("Some tests have failed!!\n");
    }

    return (0);
    }

    static int32_t App_gpioTriggerTest(App_Obj *appObj, uint32_t inst)
    {
    int32_t retVal = UDMA_SOK;
    int32_t chIdx;
    App_ChObj *appChObj;
    uint32_t i;
    uint8_t *destBuf;
    Udma_ChHandle chHandle;
    //uint64_t pDesc = 0;
    //uint32_t *pTrResp, trRespStatus;

    /* Reset dest buffers */
    for(chIdx = 0U; chIdx < APP_NUM_CH; chIdx++)
    {
    appChObj = &appObj->appChObj[chIdx];
    chHandle = appChObj->chHandle;
    destBuf = appChObj->destBuf;

    for(i = 0U; i < APP_NUM_BYTES; i++)
    {
    destBuf[i] = 0U;
    }
    /* Writeback destination buffer */
    App_cacheWb(appChObj->destBuf, APP_NUM_BYTES);

    /* Updated TRPD */
    App_trpdInit(appChObj, inst);

    /* Submit TRPD to channel */
    retVal = Udma_ringQueueRaw(
    Udma_chGetFqRingHandle(chHandle),
    (uint64_t) appChObj->trpd_mem_phy);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] Channel queue failed!!\n");
    break;
    }

    for (i = 0u; i < 5; i ++)
    {
    /* Now Trigger this GPIO */
    // 本身是低->高->低->高->低->高
    App_triggerGpio();
    appLogWaitMsecs(10);
    }

    App_setupL2G(appObj, 0);

    retVal = App_pause(appObj);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA App test Channel Disable Failed!!\n");
    }

    appLogWaitMsecs(1000);

    for (i = 0u; i < 5; i ++)
    {
    /* Now Trigger this GPIO */
    // 本身是高->低->高->低->高->低
    App_triggerGpio();
    }

    retVal = App_resume(appObj);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA App test Channel Enable Failed!!\n");
    }

    App_setupL2G(appObj, 1);

    for (i = 0u; i < 5; i ++)
    {
    /* Now Trigger this GPIO */
    // 本身是低->高->低->高->低->高
    App_triggerGpio();
    appLogWaitMsecs(10);
    }

    App_cacheInv(appChObj->destBuf, APP_NUM_BYTES);

    {
    uint64_t *buf = (uint64_t *)appChObj->destBuf;
    for (i = 1u; i < APP_TIME_READ_CNT; i ++)
    {
    printf ("Diff %d\n", (uint32_t)(buf[i] - buf[i-1]));
    }
    }

    }

    return (retVal);
    }

    static void App_eventDmaCb(Udma_EventHandle eventHandle,
    uint32_t eventType,
    void *appData)
    {
    App_ChObj *appChObj = (App_ChObj *) appData;

    if(appChObj != NULL)
    {
    if(UDMA_EVENT_TYPE_DMA_COMPLETION == eventType)
    {
    SemaphoreP_post(appChObj->transferDoneSem);
    }
    else
    {
    gUdmaAppResult = UDMA_EFAIL;
    }
    }
    else
    {
    gUdmaAppResult = UDMA_EFAIL;
    }

    return;
    }

    static void App_eventTdCb(Udma_EventHandle eventHandle,
    uint32_t eventType,
    void *appData)
    {
    int32_t retVal;
    CSL_UdmapTdResponse tdResp;
    App_ChObj *appChObj = (App_ChObj *) appData;

    if(appChObj != NULL)
    {
    if(UDMA_EVENT_TYPE_TEARDOWN_PACKET == eventType)
    {
    /* Response received in Teardown completion queue */
    retVal = Udma_chDequeueTdResponse(appChObj->chHandle, &tdResp);
    if(UDMA_SOK != retVal)
    {
    /* [Error] No TD response after callback!! */
    gUdmaAppResult = UDMA_EFAIL;
    }
    }
    else
    {
    gUdmaAppResult = UDMA_EFAIL;
    }
    }
    else
    {
    gUdmaAppResult = UDMA_EFAIL;
    }

    return;
    }

    static int32_t App_init(App_Obj *appObj)
    {
    int32_t retVal = UDMA_SOK;
    int32_t chIdx;
    App_ChObj *appChObj;
    Udma_DrvHandle drvHandle;

    drvHandle = appObj->drvHandle = appUdmaGetObj();

    /* Init channel parameters */
    for(chIdx = 0U; chIdx < APP_NUM_CH; chIdx++)
    {
    appChObj = &appObj->appChObj[chIdx];
    appChObj->chIdx = chIdx;

    appChObj->chHandle = &appChObj->chObj;
    appChObj->cqEventHandle = NULL;
    appChObj->tdCqEventHandle = NULL;
    appChObj->drvHandle = drvHandle;
    appChObj->transferDoneSem = NULL;
    appChObj->txRingMem = appMemAlloc(APP_MEM_HEAP_DDR, APP_RING_MEM_SIZE_ALIGN, UDMA_CACHELINE_ALIGNMENT);
    appChObj->txCompRingMem = appMemAlloc(APP_MEM_HEAP_DDR, APP_RING_MEM_SIZE_ALIGN, UDMA_CACHELINE_ALIGNMENT);
    appChObj->txTdCompRingMem = appMemAlloc(APP_MEM_HEAP_DDR, APP_RING_MEM_SIZE_ALIGN, UDMA_CACHELINE_ALIGNMENT);
    appChObj->trpdMem = appMemAlloc(APP_MEM_HEAP_DDR, APP_TRPD_SIZE_ALIGN, UDMA_CACHELINE_ALIGNMENT);

    appChObj->destBuf = appMemAlloc(APP_MEM_HEAP_DDR_NON_CACHE,
    APP_BUF_SIZE_ALIGN*10, UDMA_CACHELINE_ALIGNMENT);

    appChObj->trpd_mem_phy =
    appMemGetVirt2PhyBufPtr(
    (uint64_t) appChObj->trpdMem, APP_MEM_HEAP_DDR);
    }

    return (retVal);
    }

    static int32_t App_deinit(App_Obj *appObj)
    {
    /* Release Driver Handle */
    appObj->drvHandle = NULL;

    return (UDMA_SOK);
    }

    static int32_t App_create(App_Obj *appObj)
    {
    int32_t retVal = UDMA_SOK;
    uint32_t chType;
    Udma_ChPrms chPrms;
    Udma_ChTxPrms txPrms;
    Udma_ChRxPrms rxPrms;
    Udma_EventHandle eventHandle;
    Udma_EventPrms eventPrms;
    SemaphoreP_Params semPrms;
    int32_t chIdx;
    App_ChObj *appChObj;
    Udma_ChHandle chHandle;
    Udma_DrvHandle drvHandle = appObj->drvHandle;

    for(chIdx = 0U; chIdx < APP_NUM_CH; chIdx++)
    {
    appChObj = &appObj->appChObj[chIdx];
    chHandle = appChObj->chHandle;

    SemaphoreP_Params_init(&semPrms);
    appChObj->transferDoneSem = SemaphoreP_create(0, &semPrms);
    if(NULL == appChObj->transferDoneSem)
    {
    App_print("[Error] Sem create failed!!\n");
    retVal = UDMA_EFAIL;
    }

    if(UDMA_SOK == retVal)
    {
    /* Init channel parameters */
    chType = UDMA_CH_TYPE_TR_BLK_COPY;
    UdmaChPrms_init(&chPrms, chType);
    chPrms.fqRingPrms.ringMem = appChObj->txRingMem;
    chPrms.cqRingPrms.ringMem = appChObj->txCompRingMem;
    chPrms.tdCqRingPrms.ringMem = appChObj->txTdCompRingMem;
    chPrms.fqRingPrms.ringMemSize = APP_RING_MEM_SIZE;
    chPrms.cqRingPrms.ringMemSize = APP_RING_MEM_SIZE;
    chPrms.tdCqRingPrms.ringMemSize = APP_RING_MEM_SIZE;

    chPrms.fqRingPrms.elemCnt = APP_RING_ENTRIES;
    chPrms.cqRingPrms.elemCnt = APP_RING_ENTRIES;
    chPrms.tdCqRingPrms.elemCnt = APP_RING_ENTRIES;

    /* Open channel for block copy */
    retVal = Udma_chOpen(drvHandle, chHandle, chType, &chPrms);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA channel open failed!!\n");
    }
    }

    if(UDMA_SOK == retVal)
    {
    /* Config TX channel */
    UdmaChTxPrms_init(&txPrms, chType);
    retVal = Udma_chConfigTx(chHandle, &txPrms);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA TX channel config failed!!\n");
    }
    }

    if(UDMA_SOK == retVal)
    {
    /* Config RX channel - which is implicitly paired to TX channel in
    * block copy mode */
    UdmaChRxPrms_init(&rxPrms, chType);
    retVal = Udma_chConfigRx(chHandle, &rxPrms);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA RX channel config failed!!\n");
    }
    }

    if(UDMA_SOK == retVal)
    {
    /* Register ring completion callback - for the last channel only */
    eventHandle = &appChObj->cqEventObj;
    UdmaEventPrms_init(&eventPrms);
    eventPrms.eventType = UDMA_EVENT_TYPE_DMA_COMPLETION;
    eventPrms.eventMode = UDMA_EVENT_MODE_SHARED;
    eventPrms.chHandle = chHandle;
    eventPrms.masterEventHandle = Udma_eventGetGlobalHandle(drvHandle);
    eventPrms.eventCb = &App_eventDmaCb;
    eventPrms.appData = appChObj;
    retVal = Udma_eventRegister(drvHandle, eventHandle, &eventPrms);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA CQ event register failed!!\n");
    }
    else
    {
    appChObj->cqEventHandle = eventHandle;
    }
    }

    if(UDMA_SOK == retVal)
    {
    /* Register teardown ring completion callback */
    eventHandle = &appChObj->tdCqEventObj;
    UdmaEventPrms_init(&eventPrms);
    eventPrms.eventType = UDMA_EVENT_TYPE_TEARDOWN_PACKET;
    eventPrms.eventMode = UDMA_EVENT_MODE_SHARED;
    eventPrms.chHandle = chHandle;
    eventPrms.masterEventHandle = Udma_eventGetGlobalHandle(drvHandle);
    eventPrms.eventCb = &App_eventTdCb;
    eventPrms.appData = appChObj;
    retVal = Udma_eventRegister(drvHandle, eventHandle, &eventPrms);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA Teardown CQ event register failed!!\n");
    }
    else
    {
    appChObj->tdCqEventHandle = eventHandle;
    }
    }

    if(UDMA_SOK == retVal)
    {
    /* Channel enable */
    retVal = Udma_chEnable(chHandle);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA channel enable failed!!\n");
    }
    }

    if(UDMA_SOK != retVal)
    {
    break;
    }
    }

    /* Setup GPIO Pinmux */
    App_setupPinmux();

    /* Initialize GPIO now here */
    App_initGpio();

    /* Configure GPIO Mux to output event on Interrupt Aggregrator */
    App_setupGpioMuxIr();

    /* Setup L2G register to map local event to Global event */
    App_setupL2G(appObj, 1);

    return (retVal);
    }

    static int32_t App_resume(App_Obj *appObj)
    {
    #if 0
    int32_t retVal;
    int32_t chIdx;
    App_ChObj *appChObj;
    Udma_ChHandle chHandle;

    for(chIdx = 0U; chIdx < APP_NUM_CH; chIdx++)
    {
    appChObj = &appObj->appChObj[chIdx];
    chHandle = appChObj->chHandle;

    retVal = Udma_chResume(chHandle);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA channel disable failed!!\n");
    }
    }
    #endif

    return 0;
    }

    static int32_t App_pause(App_Obj *appObj)
    {
    #if 0
    int32_t retVal;
    int32_t chIdx;
    App_ChObj *appChObj;
    Udma_ChHandle chHandle;

    for(chIdx = 0U; chIdx < APP_NUM_CH; chIdx++)
    {
    appChObj = &appObj->appChObj[chIdx];
    chHandle = appChObj->chHandle;

    retVal = Udma_chPause(chHandle);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA channel disable failed!!\n");
    }
    }
    #endif

    return 0;
    }

    static int32_t App_delete(App_Obj *appObj)
    {
    int32_t retVal, tempRetVal;
    uint64_t pDesc;
    int32_t chIdx;
    App_ChObj *appChObj;
    Udma_ChHandle chHandle;

    for(chIdx = 0U; chIdx < APP_NUM_CH; chIdx++)
    {
    appChObj = &appObj->appChObj[chIdx];
    chHandle = appChObj->chHandle;

    retVal = Udma_chDisable(chHandle, UDMA_DEFAULT_CH_DISABLE_TIMEOUT);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA channel disable failed!!\n");
    }

    /* Flush any pending request from the free queue */
    while(1)
    {
    tempRetVal = Udma_ringFlushRaw(
    Udma_chGetFqRingHandle(chHandle), &pDesc);
    if(UDMA_ETIMEOUT == tempRetVal)
    {
    break;
    }
    }
    }

    for(chIdx = APP_NUM_CH - 1U; chIdx >=0 ; chIdx--)
    {
    appChObj = &appObj->appChObj[chIdx];
    chHandle = appChObj->chHandle;

    /* Unregister all events */
    if(NULL != appChObj->cqEventHandle)
    {
    retVal += Udma_eventUnRegister(appChObj->cqEventHandle);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA event unregister failed!!\n");
    }
    appChObj->cqEventHandle = NULL;
    }
    if(NULL != appChObj->tdCqEventHandle)
    {
    retVal += Udma_eventUnRegister(appChObj->tdCqEventHandle);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA event unregister failed!!\n");
    }
    appChObj->tdCqEventHandle = NULL;
    }

    retVal += Udma_chClose(chHandle);
    if(UDMA_SOK != retVal)
    {
    App_print("[Error] UDMA channel close failed!!\n");
    }

    if(appChObj->transferDoneSem != NULL)
    {
    SemaphoreP_delete(appChObj->transferDoneSem);
    appChObj->transferDoneSem = NULL;
    }
    }

    for(chIdx = 0U; chIdx < APP_NUM_CH; chIdx++)
    {
    appChObj = &appObj->appChObj[chIdx];

    if (NULL != appChObj->txRingMem)
    {
    appMemFree(APP_MEM_HEAP_DDR, appChObj->txRingMem, UDMA_CACHELINE_ALIGNMENT);
    appChObj->txRingMem = NULL;
    }
    if (NULL != appChObj->txCompRingMem)
    {
    appMemFree(APP_MEM_HEAP_DDR, appChObj->txCompRingMem, UDMA_CACHELINE_ALIGNMENT);
    appChObj->txCompRingMem = NULL;
    }
    if (NULL != appChObj->txTdCompRingMem)
    {
    appMemFree(APP_MEM_HEAP_DDR, appChObj->txTdCompRingMem, UDMA_CACHELINE_ALIGNMENT);
    appChObj->txTdCompRingMem = NULL;
    }
    if (NULL != appChObj->trpdMem)
    {
    appMemFree(APP_MEM_HEAP_DDR, appChObj->trpdMem, UDMA_CACHELINE_ALIGNMENT);
    appChObj->trpdMem = NULL;
    }
    if (NULL != appChObj->destBuf)
    {
    appMemFree(APP_MEM_HEAP_DDR_NON_CACHE, appChObj->destBuf, UDMA_CACHELINE_ALIGNMENT);
    appChObj->destBuf = NULL;
    }
    }

    return (retVal);
    }


    static void App_trpdInit(App_ChObj *appChObj, uint32_t inst)
    {
    CSL_UdmapCppi5TRPD *pTrpd = (CSL_UdmapCppi5TRPD *) appChObj->trpdMem;
    CSL_UdmapTR15 *pTr = (CSL_UdmapTR15 *)(appChObj->trpdMem + sizeof(CSL_UdmapTR15));
    uint32_t *pTrResp = (uint32_t *) (appChObj->trpdMem + (sizeof(CSL_UdmapTR15) * 2U));
    uint32_t cqRingNum = Udma_chGetCqRingNum(appChObj->chHandle);

    /* Make TRPD */
    UdmaUtils_makeTrpd(pTrpd, UDMA_TR_TYPE_15, 1U, cqRingNum);

    /* Reload indefinately */
    CSL_udmapCppi5TrSetReload((CSL_UdmapCppi5TRPD*)pTrpd, 0x1FF, 0U);

    /* Setup TR */
    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, 1U);
    pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EVENT_SIZE, CSL_UDMAP_TR_FLAGS_EVENT_SIZE_COMPLETION);

    #if 1
    if (TRIGGER_TYPE == CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL0)
    {
    pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0, CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL0);
    pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0_TYPE, /*CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL*/ CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ICNT1_DEC);
    }
    else
    {
    pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
    }

    if (TRIGGER_TYPE == CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL1)
    {
    pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1, CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL1);
    }
    else
    {
    pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
    }
    #else

    pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
    pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE);
    #endif

    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);
    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 = 8U;
    pTr->icnt1 = APP_TIME_READ_CNT;
    pTr->icnt2 = 1u;
    pTr->icnt3 = 1U;
    pTr->dim1 = 0;
    pTr->dim2 = 0;
    pTr->dim3 = 0;
    pTr->addr = (uint64_t) (GTC_TIME_ADDR)/*appChObj->srcBuf*/;
    pTr->fmtflags = 0x00000000U; /* Linear addressing, 1 byte per elem.
    Replace with CSL-FL API */
    pTr->dicnt0 = 8U;
    pTr->dicnt1 = APP_TIME_READ_CNT;
    pTr->dicnt2 = 1u;
    pTr->dicnt3 = 1U;
    pTr->ddim1 = pTr->dicnt0;
    pTr->ddim2 = pTr->dicnt0 * pTr->dicnt1;
    pTr->ddim3 = 0;
    pTr->daddr = (uint64_t) appChObj->destBuf;

    /* Clear TR response memory */
    *pTrResp = 0xFFFFFFFFU;

    /* Writeback cache */
    App_cacheWb(appChObj->trpdMem, APP_TRPD_SIZE_ALIGN);

    return;
    }

    static uint32_t Udma_chGetTriggerEvent(Udma_DrvHandle drvHandle,
    Udma_ChHandle chHandle,
    uint32_t trigger)
    {
    uint32_t triggerEvent = UDMA_EVENT_INVALID;

    if((CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL0 == trigger) ||
    (CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL1 == trigger))
    {
    /* Global 0/1 triggers are interleaved - so multiply by 2 */
    if(((chHandle->chType & UDMA_CH_FLAG_BLK_COPY) == UDMA_CH_FLAG_BLK_COPY) ||
    ((chHandle->chType & UDMA_CH_FLAG_TX) == UDMA_CH_FLAG_TX))
    {
    /* For block copy return the TX channel trigger */
    triggerEvent = (chHandle->txChNum * 2U);
    if(CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL1 == trigger)
    {
    triggerEvent++; /* Global1 trigger is next to global0 */
    }
    /* Add the global offset */
    triggerEvent += drvHandle->trigGemOffset;
    }
    else if((chHandle->chType & UDMA_CH_FLAG_RX) == UDMA_CH_FLAG_RX)
    {
    #if 0
    /* RX trigger is after TX channel triggers
    * Note: There is no external channel triggers - hence not
    * using rxChOffset */
    #if (UDMA_SOC_CFG_UDMAP_PRESENT == 1)
    if(UDMA_INST_TYPE_NORMAL == drvHandle->instType)
    {
    triggerEvent = (drvHandle->udmapRegs.txChanCnt * 2U);
    }
    #endif
    #if (UDMA_SOC_CFG_LCDMA_PRESENT == 1)
    if(UDMA_INST_TYPE_LCDMA_BCDMA == drvHandle->instType)
    {
    triggerEvent = (drvHandle->bcdmaRegs.txChanCnt * 2U);
    }
    else if(UDMA_INST_TYPE_LCDMA_PKTDMA == drvHandle->instType)
    {
    triggerEvent = (drvHandle->pktdmaRegs.txChanCnt * 2U);
    }
    #endif
    #endif

    triggerEvent += (chHandle->rxChNum * 2U);
    if(CSL_UDMAP_TR_FLAGS_TRIGGER_GLOBAL1 == trigger)
    {
    triggerEvent++; /* Global1 trigger is next to global0 */
    }
    /* Add the global offset */
    triggerEvent += drvHandle->trigGemOffset;
    }
    else
    {
    /* Trigger not supported for external channel -
    * return no event - already set */
    }
    }

    return (triggerEvent);
    }

    static void App_setupL2G(App_Obj *appObj, uint32_t enable)
    {
    uint32_t chIdx;
    uint32_t triggerEvent;
    App_ChObj *appChObj;
    Udma_ChHandle chHandle;

    for(chIdx = 0U; chIdx < APP_NUM_CH; chIdx++)
    {
    appChObj = &appObj->appChObj[chIdx];
    chHandle = appChObj->chHandle;

    triggerEvent =
    Udma_chGetTriggerEvent(appChObj->drvHandle,
    chHandle, TRIGGER_TYPE);

    App_setUdmaIntAMap(appObj, gIntAggrLeviEvtId[chIdx + INTR_OFFSET], triggerEvent, enable);
    }
    }

    static void App_setUdmaIntAMap(App_Obj *appObj, uint32_t localEvtIdx, uint32_t glblEvt, uint32_t enable)
    {
    uint32_t intaOffset = (CSL_NAVSS0_UDMASS_INTA0_CFG_L2G_BASE + (localEvtIdx) * 0x20u);

    if (enable)
    {
    /* Enable Rising Event */
    *((uint32_t *)intaOffset) = (1u << 31u) | (glblEvt & 0xFFFFu);
    }
    else
    {
    *((uint32_t *)intaOffset) = 0;
    }
    }

    static void App_setupPinmux()
    {
    /* Setup GPIO 37 */
    *(volatile uint32_t *)0x11c094 = 0x50007 | (2 << 4);
    *(volatile uint32_t *)0x11c098 = 0x50007 | (2 << 4);
    *(volatile uint32_t *)0x11c09C = 0x50007 | (2 << 4);
    }

    static void App_initGpio()
    {
    uint32_t chIdx, bitpos, gpio_id, bank_id;

    for (chIdx = 0; chIdx < APP_NUM_CH; chIdx ++)
    {
    gpio_id = GPIO_START + chIdx;
    bitpos = gpio_id % 32;
    bank_id = gpio_id / 16;

    *(volatile uint32_t *)0x00620044 = (1u << bitpos);
    *(volatile uint32_t *)0x00620038 &= ~(1u << bitpos);

    *(volatile uint32_t *)0x0062004C = (1u << bitpos);
    *(volatile uint32_t *)0x00620054 = (1u << bitpos);

    *(volatile uint32_t *)0x0062005C = (1u << bitpos);

    *(volatile uint32_t *)0x00620044 = (1u << bitpos);
    *(volatile uint32_t *)0x00620038 &= ~(1u << bitpos);

    *(volatile uint32_t *)0x00620008 = (1u << bank_id);

    *(volatile uint32_t *)0x0062004C = (1u << bitpos);
    *(volatile uint32_t *)0x00620054 = (1u << bitpos);
    }
    }

    static void App_setupGpioMuxIr()
    {
    int32_t status;
    uint32_t chIdx;
    struct tisci_msg_rm_irq_set_req rmIrqReq;
    struct tisci_msg_rm_irq_set_resp rmIrqResp;

    memset(&rmIrqReq, 0x0, sizeof(rmIrqReq));
    memset(&rmIrqResp, 0x0, sizeof(rmIrqResp));

    rmIrqReq.valid_params = 0U;
    rmIrqReq.global_event = 0U;
    rmIrqReq.src_id = 0U;
    rmIrqReq.src_index = 0U;
    rmIrqReq.dst_id = 0U;
    rmIrqReq.dst_host_irq = 0U;
    rmIrqReq.ia_id = 0U;
    rmIrqReq.vint = 0U;
    rmIrqReq.vint_status_bit_index = 0U;
    rmIrqReq.secondary_host = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST;

    rmIrqReq.secondary_host = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST;

    for(chIdx = 0U; chIdx < APP_NUM_CH; chIdx++)
    {
    rmIrqReq.src_id = TISCI_DEV_GPIOMUX_INTRTR0;
    rmIrqReq.src_index = GPIO_START + chIdx;

    /* Set the destination based on the core */
    rmIrqReq.dst_id = TISCI_DEV_GPIOMUX_INTRTR0;
    rmIrqReq.dst_host_irq = GPIOMUX_INTRTR0_OUTP_START_R5FSS0 + chIdx;

    /* Set the destination interrupt */
    rmIrqReq.valid_params |= TISCI_MSG_VALUE_RM_DST_ID_VALID;
    rmIrqReq.valid_params |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;

    status = Sciclient_rmIrqSetRaw(
    (const struct tisci_msg_rm_irq_set_req *)&rmIrqReq,
    &rmIrqResp,
    SCICLIENT_SERVICE_WAIT_FOREVER);

    if(status == CSL_PASS)
    {
    App_print ("Worked fine \n");
    }
    else
    {
    App_print ("Failed \n");
    }
    }
    }

    static void App_triggerGpio()
    {
    uint32_t chIdx;
    uint32_t gpio_id;
    uint32_t bitpos;
    static uint32_t iterCnt = 0;

    for (chIdx = 0; chIdx < APP_NUM_CH; chIdx ++)
    {
    gpio_id = GPIO_START + chIdx;
    bitpos = gpio_id % 32;

    if (iterCnt % 2 == 0)
    {
    /* Now set the data for both the GPIO,
    Both interrupts would be called,
    but in second loop on GPIO38 isr would be called */
    *(volatile uint32_t *)0x00620040 = (1u << bitpos);
    }
    else
    {
    /* Now set the data for both the GPIO,
    Both interrupts would be called,
    but in second loop on GPIO38 isr would be called */
    *(volatile uint32_t *)0x00620044 = (1u << bitpos);
    }
    }

    iterCnt ++;
    }

    static void App_print(const char *str)
    {
    printf("%s", str);

    return;
    }


    static void App_cacheWb(const void *addr, int32_t size)
    {
    CacheP_wb(addr, size);

    return;
    }

    static void App_cacheInv(const void * addr, int32_t size)
    {
    CacheP_Inv(addr, size);

    return;
    }


    volatile uint32_t gWait = 1;
    int32_t appGpioInit(void)
    {
    Board_initCfg boardCfg;

    boardCfg = BOARD_INIT_PINMUX_CONFIG |
    BOARD_INIT_MODULE_CLOCK |
    BOARD_INIT_UART_STDIO | BOARD_INIT_UNLOCK_MMR |
    BOARD_INIT_PLL_MCU | BOARD_INIT_MODULE_CLOCK_MCU;

    Board_init(boardCfg);


    SET_DEVICE_STATE_ON(TISCI_DEV_GPIO0);
    SET_DEVICE_STATE_ON(TISCI_DEV_GPIO1);
    SET_DEVICE_STATE_ON(TISCI_DEV_GPIO2);
    SET_DEVICE_STATE_ON(TISCI_DEV_GPIO3);
    SET_DEVICE_STATE_ON(TISCI_DEV_GPIO4);
    SET_DEVICE_STATE_ON(TISCI_DEV_GPIO5);
    SET_DEVICE_STATE_ON(TISCI_DEV_GPIO6);
    SET_DEVICE_STATE_ON(TISCI_DEV_GPIO7);

    while (gWait);

    App_GpioDmaTest();

    return 0;
    }

    ~~~

  • The Issues is can't access UDMASS_INTA0_CFG_L2G Register

  • Hi,

    Please use SDK7.3 release. This issue is fixed on SDK7.3 release. 

    Regards,

    Brijesh

  • Hi, :

    The example you provided can work on MCU2_0.

    What changes are needed if customer wants to run it on MCU2_1?

    The error log (run it on MCU2_1):

    [MCU2_1]     48.212438 s: [UDMA] 
    [MCU2_1]     48.212463 s: [Error] RM Alloc Blkcpy Ch failed!!!
    [MCU2_1]     48.212493 s: [UDMA] 
    [MCU2_1]     48.212509 s: [Error] Channel resource allocation failed!!
    [MCU2_1]     48.212555 s: [Error] UDMA  channel  open failed!
    

  • Hi Peter,

    We have less number of block copy channel on mcu2_1. If we need more channels, we need to change it resource manager.

    Regards,

    Brijesh

  • Hi,

    Would you please let us know the place where to change "the block copy channels" for MCU2_1 in resource manager?

    Thanks.

  • Hi Peter,

    Which boot flow are you using? 

    if you are using SBL, we need to change in the sciclient/soc/V1/sciclient_boardcfg_rm.c file. 

    For Linux, this requires change in the sysfw.itb file.

    Regards,

    Brijesh

  • Hi  Brijesh Jadav:

              at this moment ,we use the SPL+ u_boot to boot all r5fs and A72. we will switch to Sbl to boot the r5f  after few weeks!

    can you provide us the modifed sysfw.itb which can run MCU2_1 and if possible  can you share us the instructions on how to modify the file(sysfw.itb) and SBL (sciclient_boardcfg_rm.c) ?

    thanks !