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.

TDA4VEN-Q1: udma Udma_ringQueueRaw function error

Part Number: TDA4VEN-Q1

Tool/software:

Hi team,

When I use UDMA 4 channels to transport 1M data, I occasionally have the problem of submitting a TRPD request to the queue. After too many failures, this part of the code will not run, and the problem only in high temperature operation, and very difficult to reproduce, what causes the problem and how to avoid the problem? Here's how I did it:

int8_t bsp_udma_multi_ch_copy_data_func(uint8_t *destBuf, uint8_t *srcBuf, uint32_t width, uint32_t height)
{
    int8_t   l_int8_ret = 0;
    int32_t  l_int32_status = 0, l_int32_i = 0;
    uint32_t l_u32_length = UDMA_TEST_NUM_BYTES, l_u32_addr_offset = UDMA_CHANNEL_ADDR_OFFSET;
    udma_config_info_type *l_udma_multi_ch_config_info = NULL;

    uint8_t *l_pu8_dst_buf = (uint8_t *)destBuf;
    uint8_t *l_pu8_src_buf = (uint8_t *)srcBuf;

    /* check size */
    l_u32_length = width * height;
    if (l_u32_length <= UDMA_TEST_NUM_BYTES)
    {
        l_u32_length = UDMA_TEST_NUM_BYTES;
        l_u32_addr_offset = 0x2000;      // 32K四等分
    }

    /* init */
    g_udma_channel_complete_cnt = 0;
   
    for (l_int32_i = 0; l_int32_i < UDMA_CHANNEL_NUM; l_int32_i++)
    {
        l_udma_multi_ch_config_info = &g_udma_multi_ch_config_info[l_int32_i];

        /* set address */
        l_pu8_dst_buf = (uint8_t *)(destBuf + l_u32_addr_offset * l_int32_i);
        l_pu8_src_buf = (uint8_t *)(srcBuf  + l_u32_addr_offset * l_int32_i);

        /* Init buffers and TR packet descriptor */
        bsp_udma_trpd_init(l_udma_multi_ch_config_info->chHandle, l_udma_multi_ch_config_info->trpdMem, l_pu8_dst_buf, l_pu8_src_buf, l_u32_length);

        /* Submit TRPD to channel */
        l_int32_status = Udma_ringQueueRaw(Udma_chGetFqRingHandle(l_udma_multi_ch_config_info->chHandle), l_udma_multi_ch_config_info->trpdMemPhy);
        if (l_int32_status != UDMA_SOK)
        {
            l_int8_ret = 1;
        }
    }
   
    l_udma_multi_ch_config_info = &g_udma_multi_ch_config_info[0];
    /* Wait for return descriptor in completion ring - this marks transfer completion */
    SemaphoreP_pend(&l_udma_multi_ch_config_info->udma_done_sem, 10);   // SystemP_WAIT_FOREVER

    for (l_int32_i = 0; l_int32_i < UDMA_CHANNEL_NUM; l_int32_i++)
    {
        l_udma_multi_ch_config_info = &g_udma_multi_ch_config_info[l_int32_i];

        l_int32_status = Udma_ringDequeueRaw(Udma_chGetCqRingHandle(l_udma_multi_ch_config_info->chHandle), &l_udma_multi_ch_config_info->pDesc);
        if (l_int32_status != UDMA_SOK)
        {
            l_int8_ret = 2;
        }

        // /* Check TR response status */
        // CacheP_inv(l_udma_multi_ch_config_info->trpdMem, UDMA_TEST_TRPD_SIZE, CacheP_TYPE_ALLD);
        // l_int32_status = UdmaUtils_getTrpdTr15Response(l_udma_multi_ch_config_info->trpdMem, 1U, 0U);
        // if (l_int32_status != CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE)
        // {
        //     LOG_PRINT("[warn]l_int32_status:%d\r\n", l_int32_status);
        // }
    }

    return l_int8_ret;
}

What measures should I take to ensure that UDMA works properly? Thanks.

Best Regards