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: DmaUtilsAutoInc3d_deinit() fails with "[Error] DRU ch teardown timed out!!!"

Part Number: TDA4VM

Hi, 

I'm currently experimenting using DmaUtilsAutoInc3d API on the C7X. Basing myself on dmautils_autoincrement_example.c, I did a unit test where I only init and deinit. I get the following errors printed through the driver print callbacks:

  • UDMA: [Error] DRU ch teardown timed out!!!
  • AutoInc: DmaUtilsAutoInc3d_deconfigure : Failed : Udma_chDisable

Here's the test

bool TestInitDeinit()
{
    bool success = true;
    
    UdmaDriver driver;      // C++ wrapper 
    REQUIRE(driver.Init()); // Calls UdmaInitPrms_init, Udma_init

    // Setup DmaUtilsAutoInc3d_InitParam
    //==================================
    constexpr int N_CHANNELS = 1;
    int32_t ctxSize = DmaUtilsAutoInc3d_getContextSize(N_CHANNELS);
    REQUIRE(ctxSize > 0);

    // Using unique_ptr so that it gets deallocated even on failure
    auto dmaCtx = std::make_unique<DmaAutoIncTests::HeapMem>((size_t) ctxSize); // calls tivxMemAlloc(TEST_DMAUTILS_ALIGN_CEIL(size, 128), TIVX_MEM_EXTERNAL);

    DmaUtilsAutoInc3d_InitParam initParams;
    initParams.numChannels = N_CHANNELS;
    initParams.contextSize = ctxSize;
    initParams.traceLogLevel = 1;
    initParams.udmaDrvHandle = driver.Handle();
    initParams.DmaUtilsVprintf = &DmaAutoIncTests::DmaUtilsVprintf;
    //==================================

    // Setup DmaUtilsAutoInc3d_ChannelInitParam
    //==================================
    DmaUtilsAutoInc3d_ChannelInitParam chPrm;
    chPrm.dmaQueNo = 0;
    chPrm.druOwner = DMAUTILSAUTOINC3D_DRUOWNER_DIRECT_TR;
    //==================================

    // Init API
    //==================================
    REQUIRE(UDMA_SOK == DmaUtilsAutoInc3d_init(dmaCtx->ptr, &initParams, &chPrm));
    //==================================
    
    // Deinit API
    //==================================
    REQUIRE(UDMA_SOK == DmaUtilsAutoInc3d_deinit(dmaCtx->ptr));
    //==================================

    REQUIRE(driver.Deinit());

    RETURN_STATUS(success);
}

What am I missing? 

Thanks, 

Fred

  • Apparently, the solution was to use tivxPlatformGetDmaObj().

    I'm not sure what I was doing wrong:

    class UdmaDriver
    {
    public:
        UdmaDriver()
        {
            m_drvHandle = &m_udmaDrvObj;
        }
        bool Init()
        {
            Udma_InitPrms udmaPrm;
            UdmaInitPrms_init(UDMA_INST_ID_MAIN_0, &udmaPrm);
            udmaPrm.printFxn = &UdmaDriver::Printf;
            udmaPrm.virtToPhyFxn = &UdmaDriver::VirtToPhyFxn;
            udmaPrm.skipGlobalEventReg = 1;
            return UDMA_SOK == Udma_init(m_drvHandle, &udmaPrm));
        }
        bool Deinit()
        {
            return UDMA_SOK == Udma_deinit(m_drvHandle);
        }
        Udma_DrvHandle Handle()
        {
            return m_drvHandle;
        }
    
    private:
        struct Udma_DrvObj m_udmaDrvObj;
        Udma_DrvHandle m_drvHandle;
    
        static void Printf(const char *str)
        {
            std::cout << str << std::endl;
        }
    
        static uint64_t VirtToPhyFxn(const void *virtAddr, uint32_t chNum, void *appData)
        {
            uint64_t phys = appMemGetVirt2PhyBufPtr((uint64_t) virtAddr, 0);
            return phys;
        }
    };

  • Hi ,

    Yes, you require reference to global UDMA handle. In OpenVX, UDMA driver is opened once per core and we can get this handle using tivxPlatformGetDmaObj API. This is how it is used for the other modules in the system, where UDMA is used. 

    Regards,

    Brijesh