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.

TDA4VM: GPIO+UDMA for USS Capture in MCU domain

Part Number: TDA4VM

PSDK version:ti-processor-sdk-rtos-j721e-evm-08_04_00_06

Hi,

In TDA4VM application Notes  ZHCAB72 and E2E, the patch running in MCU2_0 and SDK7.1. 

Can you provide a demo running in MCU1_0?

Thanks.

  • Hi,

    Why do you require it on mcu domain r5f? This would require many changes, and may not be work/supported. Can you please use any one of main domain r5f? 

    Regards,

    Brijesh

  • Why do you require it on mcu domain r5f?

    We want to run only USS in one mcu core. 

    If mcu domain r5f is not OK , Can you provide a demo running in MCU3_0?

  • Yes, mcu3_0 is possible. If you are using SDK8.6 release, most likely, you would just require  to change INTR_OFFSET macro to 0. That will allow 4 GPIO interrupt on mcu3_0. 

    regards,

    Brijesh 

  • We are using SDK8.4 release. And we need 12 capture for uss, does MCU3_0 support?

    And we try to apply the patch 2313.0001-reproduce-the-DMA-issue-in-EVM-and-solved-it.-but.patch in SDK8.4, but failed. Can you provide a new patch for SDK8.4 in MCU3_0?

    Thank you!

  • Yes, mcu3_0 can support 12 channels of uss. You would have to allocate them using resource manager. Please refer to below faq for allocating udma channels. 

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1097038/faq-tda4vm-workflow-and-resource-allocation-build-flow-for-sysconfig-tool

    Also changes in the patch are straight forward, can you please try applying them manually. 

    Regards,

    Brijesh

  • Hi,

    My test is as follows: the code runs on mcu2_ 0, PDK8.4

    1.e2e.ti.com/.../faq-tda4vm-gpio-dma-trigger-in-tda4-and-test-in-sdk7-1

    Do we need to take action on the second point of the link above。


    2.GPIO+UDMA cannot obtain correct data for obtaining timestamp,

    2.1.#define GPIO_START            (24)
    2.2.We use GPIO0_ 24 as GPIO input,
    
    GPIO0_ 94 Control GPIO0_ 24 input levels, pin configuration as follows
    
    GPIO_PinConfig gpioPinConfigs[] =
    {
        /* Input pin with interrupt enabled */
     GPIO_DEVICE_CONFIG(0, 24) | GPIO_CFG_IN_INT_BOTH_EDGES | GPIO_CFG_INPUT,
     GPIO_DEVICE_CONFIG(0, 94) | GPIO_CFG_OUTPUT,
    };
    
    /* GPIO Driver call back functions */
    GPIO_CallbackFxn gpioCallbackFunctions[] =
    {
        NULL,
     NULL,
    };
    
    /* GPIO Driver configuration structure */
    GPIO_v0_Config GPIO_v0_config =
    {
        gpioPinConfigs,
        gpioCallbackFunctions,
        sizeof(gpioPinConfigs) / sizeof(GPIO_PinConfig),
        sizeof(gpioCallbackFunctions) / sizeof(GPIO_CallbackFxn),
    #if (__ARM_ARCH == 7) && (__ARM_ARCH_PROFILE == 'R') /* R5F */
        0x8U
    #else
    #if defined(BUILD_C7X)
        0x01U
    #else
        0x20U
    #endif
    #endif
    };
    2.3.App_setupPinmux
    
    static void App_setupPinmux()
    {
    
    
    }
    
    2.4.App_initGpio
    static void App_initGpio()
    {
     GPIO_init();
     GPIO_enableInt(0);
    }
    
    2.5.App_triggerGpio
    void App_triggerGpio()
    {
        static uint32_t iterCnt = 0;
         if (iterCnt % 2 == 0)
        {
             GPIO_write(0,1);
        }
        else
        {
           GPIO_write(0,0);
    
        }
        iterCnt ++;
    
    }
    

    Can you provide me with some ideas。

    Thanks.

  • Hi Frank,

    Do we need to take action on the second point of the link above。

    No, this is now enabled in the latest release, so we dont need to use the tifs, which is shared in that forum.

    2.GPIO+UDMA cannot obtain correct data for obtaining timestamp,

    Did not get it. Are you getting DMA completion interrupt? Are the two consecutive timestamp matching with the GPIO toggle time? Also if the buffer is allocated from Cached memory, can you please invalidate the cache before accessing/checking timestmap? 

    Regards,

    Brijesh

  • Hi,

    1.I did not receive DMA completion interrupt.

    2."App_cacheInv(appChObj->destBuf, APP_NUM_BYTES);" has been called.

    Thanks.

  • Hi,

    Then i dont think GPIO interrupt is connected to DMA engine. Can you check if all code/APIs are passing in the above shared patch? Also are you able to register interrupt using RM API, Sciclient_rmIrqSetRaw? 

    I see you are using GPIO0, i think the same pin for GPIO0 can also be used for GPIO4, so can you try using GPIO4, instead of GPIO0?

    Regards,

    Brijesh

  • Hi,

    1.all code/APIs are passing in the above shared patch.

    2.GPIO4 is also not working properly.

    Thanks.

  • Hi,

    Can you please first try the example that has been shared on the ticket? It is for one of GPIO4 output. 

    Regards,

    Brijesh

  • Hi,

    1.Which one should I use for function Udma_chGetTriggerEvent?

    pdk_jacinto_08_04_00_21\packages\ti\drv\udma\src\udma_ch.c

    uint32_t Udma_chGetTriggerEvent(Udma_ChHandle chHandle,
                                    uint32_t trigger)
    {
        int32_t         retVal = UDMA_SOK;
        Udma_DrvHandle  drvHandle;
        uint32_t        triggerEvent = UDMA_EVENT_INVALID;
    
        /* Error check */
        if((NULL_PTR == chHandle) ||
           (chHandle->chInitDone != UDMA_INIT_DONE))
        {
            retVal = UDMA_EBADARGS;
        }
        if(UDMA_SOK == retVal)
        {
            drvHandle = chHandle->drvHandle;
            if((NULL_PTR == drvHandle) || (drvHandle->drvInitDone != UDMA_INIT_DONE))
            {
                retVal = UDMA_EFAIL;
            }
        }
    
        if(UDMA_SOK == retVal)
        {
            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)
                {
                    /* 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_BCDMA_PRESENT == 1)
                    if(UDMA_INST_TYPE_LCDMA_BCDMA == drvHandle->instType)
                    {
                        triggerEvent  = (drvHandle->bcdmaRegs.txChanCnt * 2U);
                    }
    #endif
    #if (UDMA_SOC_CFG_PKTDMA_PRESENT == 1)
                    if(UDMA_INST_TYPE_LCDMA_PKTDMA == drvHandle->instType)
                    {
                        triggerEvent  = (drvHandle->pktdmaRegs.txChanCnt * 2U);
                    }
    #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);
    }

    app_gpio_dma.c

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

    2.

    Hi,

    Can you please first try the example that has been shared on the ticket? It is for one of GPIO4 output. 

      2.1 have tried the example shared on the ticket, but there is still no UDMA interrupt generated.

      2.2 Then GPIO0_ 37 changed to GPIO0_ 90. GPIO4 cannot change the level, so I used GPIO0, but there is still no UDMA interrupt generated.

      2.3 APP_ TIME_ READ_ CNT changed from 200 to 20, function App_ EventTdCb is called, and then the program freezes.

     Do you have any good ideas?

    Thanks.

  • Hi,

    #1, please use channel trigger Event function from the udma driver ie in the file packages\ti\drv\udma\src\udma_ch.c

    #2.1, ok, this was working example, but i have not checked it recently. 

    #2.2, ok, but i think gpio0 is not allocated to mcu2_0 core, so registering interrupt for it may not work. I would suggest to use GPIO4 instead.

    #2.3, ok, can you please comment out call to CSL_udmapCppi5TrSetReload API? You might not be getting callback due to this API. 

    Also this example is doing GPIO time capture slightly differently. I guess you just want to use it to do time capture. 

    So can you please change the main loop like below?

    Replace below code

    +    for(j=0;j<5;j++)
    +    {
    +            for (i = 0u; i < 30; 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");
    +            }
    +
    +            //  add readback to verify if  the package 
    +            index1=(j+1)*30 -15;    //
    +            index2=(j+1)*30 -3;
    +
    +            App_cacheInv(appChObj->destBuf, APP_NUM_BYTES);
    +            test_readBackData[readback_index] = buf[ index1];
    +            test_readBackData[readback_index+1] =  buf[ index2];
    +            readback_index +=2;
    +            
    +
    +            for (i = 0u; i < 30; i ++)
    +            {
    +                /* Now Trigger this GPIO */
    +                App_triggerGpio();
    +                appLogWaitMsecs(10);        
    +            }
    +
    +            retVal = App_resume(appObj);
    +            if(UDMA_SOK != retVal)
    +            {
    +                App_print("[Error] UDMA App test Channel Enable Failed!!\n");
    +            }
    +
    +            App_setupL2G(appObj, 1);
    +#if 0
    +            for (i = 0u; i < 20; i ++)
    +            {
    +                /* Now Trigger this GPIO */
    +                App_triggerGpio();
    +                appLogWaitMsecs(10);
    +            }
    +#endif            
    

    With

        for (i = 0u; i < APP_TIME_READ_CNT; i ++)
        {
            /* Now Trigger this GPIO */
            App_triggerGpio();
            appLogWaitMsecs(10);
        }
        
        SemaphoreP_pend(appChObj->transferDoneSem);
    

    Essentially, just trigger GPIO for APP_TIME_READ_CNT number of times, and then wait on transferDone semaphore. You can then print the timer value as shown in below loop.

    +#if 0
    +
    +        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]));
    +            }
    +        }
    +#endif
    

    Regards,

    Brijesh

  • Hi,

    Based on your feedback, I have made changes to the code, but there have been no improvements.

    Here is my test code. Can you help analyze the code?

    /*
     *
     * 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 <ti/drv/udma/examples/udma_apputils/udma_apputils.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            (2U)
    
    /*
     * 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            (90)
    
    #define GTC_TIME_ADDR         (0xA90008u)
    #define GTC_CNTCV_HI          (0xA9000cu)
    
    #define GPIO_USE_SDK
    
    //#define GPIO01_GROUP
    //#define GPIO_DEMO_DEFAULT
    
    #ifdef GPIO01_GROUP
    /*GPIO0 And GPIO1*/
    #define GPIO_BASE          (0x00600000)
    #define GPIO_INSTANCE   0
    #else
    /*GPIO4 And GPIO5*/
    #define GPIO_BASE          (0x00620000)
    #define GPIO_INSTANCE   4
    #endif
    
    volatile unsigned long long test_readBackData[50] = {0};
    
    #include"utils/mem/include/app_mem.h"
    uint64_t appMemGetVirt2PhyBufPtr(uint64_t virtPtr, uint32_t heap_id);
    void    *appMemAlloc(uint32_t heap_id, uint32_t size, uint32_t align);
    
    /* ========================================================================== */
    /*                         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                             */
    /* ========================================================================== */
    
    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_Inner(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();
    void App_setupGpioMuxIr();
    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                                */
    /* ========================================================================== */
    
    extern void appLogPrintf(const char *pcString, ...);
    
    /*
     * UDMA driver and channel objects
     */
    App_Obj gAppObj;
    static struct Udma_DrvObj gUdmaDrvObj;
    
    #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                              */
    /* ========================================================================== */
    
    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");
        }
        else
        {
            App_print("App_init OK\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");
            }
            else
            {
                App_print("App_create OK\n");
            }
        }
    
        if(UDMA_SOK == retVal)
        {
            retVal = App_gpioTriggerTest(appObj, 0);
            if(UDMA_SOK != retVal)
            {
                App_print("[Error] UDMA App test failed!!\n");
            }
            else
            {
                App_print("App_gpioTriggerTest OK\n");
            }
        }
        
    
        
    #if 1
        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");
        }
    #endif
        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,j,index1,index2,readback_index;
        uint8_t        *destBuf;
        Udma_ChHandle   chHandle;
        //uint64_t        pDesc = 0;
        //uint32_t       *pTrResp, trRespStatus;
        
        appLogPrintf("%s %d \n", __func__, __LINE__);
    
        /* 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);
    #if 1
    
            /* 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;
            }
    #endif
            readback_index = 0;
            uint64_t *buf = (uint64_t *)appChObj->destBuf;    
            #if 1
            for(j=0;j<5;j++)
            {
        			appLogPrintf("%s %d \n", __func__, __LINE__);
                    for (i = 0u; i < 30; i ++)
                    {
                        /* Now Trigger this GPIO */
                        App_triggerGpio();
                        appLogWaitMsecs(10);
                    }
        			appLogPrintf("%s %d \n", __func__, __LINE__);
                    App_setupL2G(appObj, 0);
        			appLogPrintf("%s %d \n", __func__, __LINE__);
                    retVal = App_pause(appObj);
                    if(UDMA_SOK != retVal)
                    {
                        App_print("[Error] UDMA App test Channel Disable Failed!!\n");
                    }
        			appLogPrintf("%s %d \n", __func__, __LINE__);
                    //  add readback to verify if  the package 
                    index1=(j+1)*30 -15;    //
                    index2=(j+1)*30 -3;
    
    
                    App_cacheInv(appChObj->destBuf, APP_NUM_BYTES);
                    test_readBackData[readback_index] = buf[ index1];
                    test_readBackData[readback_index+1] =  buf[ index2];
                    readback_index +=2;
    
        			appLogPrintf("%s %d \n", __func__, __LINE__);
                    for (i = 0u; i < 30; i ++)
                    {
                        /* Now Trigger this GPIO */
                        App_triggerGpio();
                        appLogWaitMsecs(10);        
                    }
                   	appLogPrintf("%s %d \n", __func__, __LINE__);
                    retVal = App_resume(appObj);
                    if(UDMA_SOK != retVal)
                    {
                        App_print("[Error] UDMA App test Channel Enable Failed!!\n");
                    }
        			appLogPrintf("%s %d \n", __func__, __LINE__);
                    App_setupL2G(appObj, 1);
                    #if 0
                    for (i = 0u; i < 30; i ++)
                    {
                        /* Now Trigger this GPIO */
                        App_triggerGpio();
                        appLogWaitMsecs(10);
                    }
                    #endif            
            }        
            #else
            appLogPrintf("%s %d \n", __func__, __LINE__);
    
            for (i = 0u; i < APP_TIME_READ_CNT; i ++)
            {
                /* Now Trigger this GPIO */
                App_triggerGpio();
                appLogWaitMsecs(10);
            }
            appLogPrintf("%s %d \n", __func__, __LINE__);
    
            if(SemaphoreP_pend(appChObj->transferDoneSem,100) == SemaphoreP_OK)
            {
                appLogPrintf("SemaphoreP_pend Transfer OK \n");
            }
            else
            {
                appLogPrintf("SemaphoreP_pend Timerout \n");
    
            }
            #endif
    		
            #if 1
            
    		appLogPrintf("%s %d \n", __func__, __LINE__);
            App_cacheInv(appChObj->destBuf, APP_NUM_BYTES);
    
            {
                appLogPrintf("%s %u \n", __func__,*((uint64_t*)(GTC_TIME_ADDR)));
                appLogPrintf("Diff:\n ");
                uint64_t *buf = (uint64_t *)appChObj->destBuf;
                for (i = 1u; i < APP_TIME_READ_CNT; i ++)
                {
                    //appLogPrintf("Diff %d\n", (uint32_t)(buf[i] - buf[i-1]));
                    appLogPrintf("%u ", buf[i-1]);
                }
                appLogPrintf("\n");
            }
            
            appLogPrintf("%s %d \n", __func__, __LINE__);
            #endif
        }
    
        return (retVal);
    }
    
    static void App_eventDmaCb(Udma_EventHandle eventHandle,
                                   uint32_t eventType,
                                   void *appData)
    {
        App_ChObj *appChObj = (App_ChObj *) appData;
        appLogPrintf("%s %d \n", __func__, __LINE__);
    
        if(appChObj != NULL)
        {
            if(UDMA_EVENT_TYPE_DMA_COMPLETION == eventType)
            {
                SemaphoreP_post(appChObj->transferDoneSem);
            }
            else
            {
                gUdmaAppResult = UDMA_EFAIL;
            }
        }
        else
        {
            gUdmaAppResult = UDMA_EFAIL;
        }
    	appLogPrintf("%s %d \n", __func__, __LINE__);
        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;
        appLogPrintf("%s %d \n", __func__, __LINE__);
        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;
        }
        appLogPrintf("%s %d \n", __func__, __LINE__);
        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*64, UDMA_CACHELINE_ALIGNMENT);
            appChObj->destBuf = appMemAlloc(APP_MEM_HEAP_DDR_NON_CACHE, APP_BUF_SIZE_ALIGN*128, 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");
                    appLogPrintf("retVal= %d\n", retVal);
                }
            }
    
            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)
    {
        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");
            }
        }
    
        return 0;
    }
    
    static int32_t App_pause(App_Obj *appObj)
    {
        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");
            }
        }
    
        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    = 0;
        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;
    }
    #if 1
    static uint32_t Udma_chGetTriggerEvent_Inner(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);
    }
    #endif
    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_Inner(appChObj->drvHandle, chHandle, TRIGGER_TYPE);
    		triggerEvent = Udma_chGetTriggerEvent(chHandle, TRIGGER_TYPE);
            appLogPrintf("%s triggerEvent1=%d enable=%d \n",__func__,triggerEvent,enable);
            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()
    {
    #ifdef GPIO_DEMO_DEFAULT
    
        /* Setup GPIO 37 */
        *(volatile uint32_t *)0x11c094 = 0x50007 | (2 << 4);
        *(volatile uint32_t *)0x11c098 = 0x50007 | (2 << 4);
        *(volatile uint32_t *)0x11c09C = 0x50007 | (2 << 4);
    
    #else
    /* Setup GPIO0_24 */
    *(volatile uint32_t *)0x11c064 = 0x50007| (GPIO_INSTANCE << 4);
    /* Setup GPIO0_25 */
    *(volatile uint32_t *)0x11c068 = 0x50007| (GPIO_INSTANCE << 4);
    
    
    /*      GPIO0_91 */
    *(volatile uint32_t *)0x11C170 = 0x50007| (GPIO_INSTANCE << 4);	
    /*      GPIO0_90 */
    *(volatile uint32_t *)0x11C16C = 0x50007| (GPIO_INSTANCE << 4);
    #endif
    
    }
    
    
    
    
    static void App_initGpio()
    {
    #ifdef GPIO_DEMO_DEFAULT
    
    
        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);
        }
    
    
    #else
    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;
           #if 1
    		if((bank_id == 2) || (bank_id == 3))
            {
               *(volatile uint32_t *)(GPIO_BASE+0x44) = (1u << bitpos);
               *(volatile uint32_t *)(GPIO_BASE+0x38) &= ~(1u << bitpos);
    
               *(volatile uint32_t *)(GPIO_BASE+0x4C) = (1u << bitpos);
               *(volatile uint32_t *)(GPIO_BASE+0x54) = (1u << bitpos);
    
               *(volatile uint32_t *)(GPIO_BASE+0x5C) = (1u << bitpos);
    
               *(volatile uint32_t *)(GPIO_BASE+0x44 )= (1u << bitpos);
               *(volatile uint32_t *)(GPIO_BASE+0x38 )&= ~(1u << bitpos);
    
               *(volatile uint32_t *)(GPIO_BASE+0x08) = (1u << bank_id);
    
               *(volatile uint32_t *)(GPIO_BASE+0x4C) = (1u << bitpos);
               *(volatile uint32_t *)(GPIO_BASE+0x54) = (1u << bitpos);
               appLogPrintf("%s bank_id=%d \n",__func__,bank_id);
    
            }
            else if((bank_id == 4) || (bank_id == 5))
            {
               *(volatile uint32_t *)(GPIO_BASE+0x6C) = (1u << bitpos);//GPIO_CLR_DATA45 set low level
               *(volatile uint32_t *)(GPIO_BASE+0x60) &= ~(1u << bitpos);//GPIO_DIR45 set dir for output
    
               *(volatile uint32_t *)(GPIO_BASE+0x74) = (1u << bitpos);//GPIO_SET_RIS_TRIG45 Writing 1 enables rising edge detection for GPIO bank 2/3 bits
               *(volatile uint32_t *)(GPIO_BASE+0x78) = (1u << bitpos);//GPIO_CLR_RIS_TRIG45 Writing 1 clears rising edge detection for GPIO bank 2/3 bits
    
               *(volatile uint32_t *)(GPIO_BASE+0x84) = (1u << bitpos);//GPIO_INTSTAT45  Bank Interrupt Status Register
    
               *(volatile uint32_t *)(GPIO_BASE+0x6C )= (1u << bitpos);//repeat GPIO_CLR_DATA45
               *(volatile uint32_t *)(GPIO_BASE+0x60 )&= ~(1u << bitpos);//repeat GPIO_DIR45
    
               *(volatile uint32_t *)(GPIO_BASE+0x08) = (1u << bank_id);//GPIO_BINTEN Per bank interrupt enable
    
               *(volatile uint32_t *)(GPIO_BASE+0x74) = (1u << bitpos);//repeat GPIO_SET_RIS_TRIG45
               *(volatile uint32_t *)(GPIO_BASE+0x78) = (1u << bitpos);//repeat GPIO_CLR_RIS_TRIG45
               appLogPrintf("%s bank_id=%d \n",__func__,bank_id);
    
            }
           
    		else
    		{
    			appLogPrintf("%s bank_id=%d error \n",__func__,bank_id);
    			
    		}
           #endif
       }
    
    
    #endif
    }
    
    static void GpioIsr1(uintptr_t args)
    {
        appLogPrintf("%s \n",__func__);
    
    }
    
    
    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 ("App_setupGpioMuxIr Worked fine \n");
            }
            else
            {
                appLogPrintf("App_setupGpioMuxIr Failed status=%d \n",status);
            }
        }
    }
    
    
    
    void App_triggerGpio()
    {
    #ifdef GPIO_DEMO_DEFAULT
        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);
                //*(volatile uint32_t *)0x00600040 = (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);
                //*(volatile uint32_t *)0x00600044 = (1u << bitpos);
            }
        }
    
        iterCnt ++;
    
    #else
        #if 0
        static uint32_t iterCnt = 0;
         if (iterCnt % 2 == 0)
        {
             
    
        }
        else
        {
         
    
        }
    
        iterCnt ++;
        #else
        uint32_t    chIdx;
        uint32_t    gpio_id;
        uint32_t    bitpos;
        uint32_t   bank_id;
        static uint32_t iterCnt = 0;
    
        for (chIdx = 0; chIdx < APP_NUM_CH; chIdx ++)
        {
            gpio_id = GPIO_START + chIdx;
            bank_id = gpio_id / 16;
            bitpos = gpio_id % 32;
    		if((bank_id == 2) || (bank_id == 3))
            {
                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 *)(GPIO_BASE+0x40) = (1u << bitpos);//GPIO_SET_DATA23 Writing 1 sets the output drive state of GPIO bank 2/3 bits
                }
                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 *)(GPIO_BASE+0x44) = (1u << bitpos);//GPIO_CLR_DATA23 Writing 1 clears the output drive state of GPIO
                }
            }
            else if((bank_id == 4) || (bank_id == 5))
            {
                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 *)(GPIO_BASE+0x68) = (1u << bitpos);//GPIO_SET_DATA45 Writing 1 sets the output drive state of GPIO bank 4/5 bits
                }
                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 *)(GPIO_BASE+0x6c) = (1u << bitpos);//GPIO_CLR_DATA45 Writing 1 clears the output drive state of GPIO
                }
            }
    		
    		else
    		{
    			/*invalid bank*/
    		}
        }
    
        iterCnt ++;
    
    
        #endif
    #endif
    }
    
    static void App_print(const char *str)
    {
        appLogPrintf("%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)
    {
    #if 1
    
        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);
    #endif
    
        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);
        appLogWaitMsecs(100);
    
        App_GpioDmaTest();
    
        return 0;
    }

    If possible, could you help verify the code in PDK8.4?

  • ok, i see couple of issues in the application. Let me get it first working on EVM and i will share you changes. 

  • Hi,

    Have you tried the original example? It is working fine atleast on the EVM for the GPIO4_37. Here is the updated code which works on SDK8.6 release. I will check now GPIO4_90.

    /*
     *
     * 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     (200U)
    
    /** \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_inner(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,j,index1,index2,readback_index;
        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;
            }
    
            readback_index = 0;
            uint64_t *buf = (uint64_t *)appChObj->destBuf;
    
            for (i = 0u; i < APP_TIME_READ_CNT; i ++)
            {
                /* Now Trigger this GPIO */
                App_triggerGpio();
                appLogWaitMsecs(10);
            }
    
            SemaphoreP_pend(appChObj->transferDoneSem, SemaphoreP_WAIT_FOREVER);
    
            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*64, UDMA_CACHELINE_ALIGNMENT);
            appChObj->destBuf = appMemAlloc(APP_MEM_HEAP_DDR, APP_BUF_SIZE_ALIGN*128, 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)
    {
        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");
            }
        }
    
        return 0;
    }
    
    static int32_t App_pause(App_Obj *appObj)
    {
        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");
            }
        }
    
        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    = 0;
        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_inner(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_inner(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;
    }
    

    Regards,

    Brijesh

  • Hi,

    Even GPIO0(4)_90 is working fine. The issue was due to trigger on falling edge. It was wrong register, it was clearing trigger on rising edge. 

    *(volatile uint32_t *)(GPIO_BASE+0x74) = (1u << bitpos);//repeat GPIO_SET_RIS_TRIG45
    *(volatile uint32_t *)(GPIO_BASE+0x7c) = (1u << bitpos);//repeat GPIO_CLR_RIS_TRIG45

    Please find updated code. This is working on SDK8.6 release.

    /*
     *
     * 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     (200U)
    
    /** \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            (90)
    
    #define GTC_TIME_ADDR         (0xA90008u)
    
    #define GPIO_BASE             (0x00620000u)
    
    /* ========================================================================== */
    /*                         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_inner(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,j,index1,index2,readback_index;
        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;
            }
    
            readback_index = 0;
            uint64_t *buf = (uint64_t *)appChObj->destBuf;
    
            for (i = 0u; i < APP_TIME_READ_CNT; i ++)
            {
                /* Now Trigger this GPIO */
                App_triggerGpio();
                appLogWaitMsecs(10);
            }
    
            SemaphoreP_pend(appChObj->transferDoneSem, SemaphoreP_WAIT_FOREVER);
    
            retVal = Udma_ringDequeueRaw(Udma_chGetCqRingHandle(chHandle), &pDesc);
            if(UDMA_SOK != retVal)
            {
                printf ("Unable to Dequeue frm completion ring \n");
            }
    
            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*64, UDMA_CACHELINE_ALIGNMENT);
            appChObj->destBuf = appMemAlloc(APP_MEM_HEAP_DDR, APP_BUF_SIZE_ALIGN*128, 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)
    {
        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");
            }
        }
    
        return 0;
    }
    
    static int32_t App_pause(App_Obj *appObj)
    {
        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");
            }
        }
    
        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    = 0;
        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_inner(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_inner(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);
    
        /* Setup GPIO4_90 */
        *(volatile uint32_t *)0x0011C16C = 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;
    
            if (bank_id == 2 || bank_id == 3)
            {
                *(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);
            }
            else if (bank_id == 4 || bank_id == 5)
            {
                *(volatile uint32_t *)(GPIO_BASE+0x6C) = (1u << bitpos);//GPIO_CLR_DATA45 set low level
                *(volatile uint32_t *)(GPIO_BASE+0x60) &= ~(1u << bitpos);//GPIO_DIR45 set dir for output
    
                *(volatile uint32_t *)(GPIO_BASE+0x74) = (1u << bitpos);//GPIO_SET_RIS_TRIG45 Writing 1 enables rising edge detection for GPIO bank 2/3 bits
                *(volatile uint32_t *)(GPIO_BASE+0x78) = (1u << bitpos);//GPIO_CLR_RIS_TRIG45 Writing 1 clears rising edge detection for GPIO bank 2/3 bits
    
                *(volatile uint32_t *)(GPIO_BASE+0x84) = (1u << bitpos);//GPIO_INTSTAT45  Bank Interrupt Status Register
    
                *(volatile uint32_t *)(GPIO_BASE+0x6C )= (1u << bitpos);//repeat GPIO_CLR_DATA45
                *(volatile uint32_t *)(GPIO_BASE+0x60 )&= ~(1u << bitpos);//repeat GPIO_DIR45
    
                *(volatile uint32_t *)(GPIO_BASE+0x08) = (1u << bank_id);//GPIO_BINTEN Per bank interrupt enable
    
                *(volatile uint32_t *)(GPIO_BASE+0x74) = (1u << bitpos);//repeat GPIO_SET_RIS_TRIG45
                *(volatile uint32_t *)(GPIO_BASE+0x7c) = (1u << bitpos);//repeat GPIO_CLR_RIS_TRIG45
            }
        }
    }
    
    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, bank_id;
        static uint32_t iterCnt = 0;
    
        for (chIdx = 0; chIdx < APP_NUM_CH; chIdx ++)
        {
            gpio_id = GPIO_START + chIdx;
            bitpos = gpio_id % 32;
            bank_id = gpio_id / 16;
    
            if (iterCnt % 2 == 0)
            {
                if (bank_id == 2 || bank_id == 3)
                {
                    /* 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 if (bank_id == 4 || bank_id == 5)
                {
                    *(volatile uint32_t *)0x00620068 = (1u << bitpos);
                }
            }
            else
            {
                if (bank_id == 2 || bank_id == 3)
                {
                    /* 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);
                }
                else if (bank_id == 4 || bank_id == 5)
                {
                    *(volatile uint32_t *)0x0062006c = (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;
    }
    

    Regards,

    Brijesh

  • Hi,

    If I set APP_TIME_READ_CNT to 200, but App_ TriggerGpio() is only executed 10 times.

    Which function should I use to obtain the number of UDMA counts(10)? Or how can I obtain valid timestamp data?

    Thanks.

  • That's not possible. As per below loop, it should be executed for 200 times. Aren't you getting valid timestamp? i did not get on valid timestamp.. 

    for (i = 0u; i < APP_TIME_READ_CNT; i ++)
    {
    /* Now Trigger this GPIO */
    App_triggerGpio();
    appLogWaitMsecs(10);
    }

    Regards,

    Brijesh