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: TDA4VM: How to receive variable length of uart's data in dma mode?

Part Number: TDA4VM

Hi, we currently developing uart driver for tda4 mcu's,we want to use dma to transmit and receive variable length of data, like other mcu we developed

we ask a related question about this, and we don't know what is the mean of Jian reply. In conclusion:

1.How can we get current dma received bytes counter so that we can implement software dma fifo.

2.is there circular mode for pdma? so we don't need to restart dma again.

The stm32 demo code is below, and we want tda4 driver has the similar implement

/**
 * @description: Initialize uart dma
 * @param {UartDev_t} *uartDev
 * @return 0 on OK,others on error.
 */
static int8_t BSP_UartDmaInit(UartDev_t *uartDev)
{
    DMA_HandleTypeDef *hdmaTx = &uartDev->dmaTx.hdma;
    DMA_HandleTypeDef *hdmaRx = &uartDev->dmaRx.hdma;

    if ((uint32_t)hdmaTx->Instance > (uint32_t)DMA2)
    {
        __HAL_RCC_DMA2_CLK_ENABLE();
    }
    else
    {
        __HAL_RCC_DMA1_CLK_ENABLE();
    }

    /* enable clk */
    if ((uint32_t)hdmaRx->Instance > (uint32_t)DMA2)
    {
        __HAL_RCC_DMA2_CLK_ENABLE();
    }
    else
    {
        __HAL_RCC_DMA1_CLK_ENABLE();
    }

    /* set uart tx dma param */
    hdmaTx->Instance = uartDev->dmaTx.dmaStream;
    BSP_UartGetDmaTxRequest(uartDev->huart.Instance, &hdmaTx->Init.Request);
    hdmaTx->Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdmaTx->Init.PeriphInc = DMA_PINC_DISABLE;
    hdmaTx->Init.MemInc = DMA_MINC_ENABLE;
    hdmaTx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdmaTx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdmaTx->Init.Mode = DMA_NORMAL;
    hdmaTx->Init.Priority = uartDev->dmaTx.dmaPriority;
    hdmaTx->Init.FIFOMode = DMA_FIFOMODE_DISABLE;

    if (HAL_DMA_Init(hdmaTx) != HAL_OK)
    {
        return 1;
    }

    __HAL_LINKDMA(&uartDev->huart, hdmatx, uartDev->dmaTx.hdma);

    /* set uart rx dma param */
    hdmaRx->Instance = uartDev->dmaRx.dmaStream;
    BSP_UartGetDmaRxRequest(uartDev->huart.Instance, &hdmaRx->Init.Request);
    hdmaRx->Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdmaRx->Init.PeriphInc = DMA_PINC_DISABLE;
    hdmaRx->Init.MemInc = DMA_MINC_ENABLE;
    hdmaRx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdmaRx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdmaRx->Init.Mode = DMA_CIRCULAR;
    hdmaRx->Init.Priority = uartDev->dmaRx.dmaPriority;
    hdmaRx->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(hdmaRx) != HAL_OK)
    {
        return 1;
    }

    __HAL_LINKDMA(&uartDev->huart, hdmarx, uartDev->dmaRx.hdma);
    HAL_UART_Receive_DMA(&uartDev->huart, (uint8_t *)uartDev->rxBuffer, uartDev->rxBufferSize);
    return 0;
}

/**
 * @description: get available data in dma rx buffer
 * @param {UartDev_t} *uartDev
 * @return {uint32_t } available data length
 */
static uint32_t BSP_UartReadAvailable(UartDev_t *uartDev)
{
    return uartDev->rxBufferSize - __HAL_DMA_GET_COUNTER(&uartDev->dmaRx.hdma);
}

/**
 * @description: read uart data from dma buffer
 * @param {UartDev_t} *uartDev
 * @return {*}
 */
static void BSP_UartRead(UartDev_t *uartDev)
{
    uint32_t length;
    uint32_t timeout = 0;
    length = BSP_UartReadAvailable(uartDev);
    if (length == 0 || length == uartDev->rxReadPtr)
    {
        return;
    }
    if (SCB->CCR & SCB_CCR_DC_Msk)
    { /*INVALID Cache before DMA -> CPU*/
        SCB_InvalidateDCache_by_Addr((uint32_t *)(uartDev->rxBuffer), uartDev->rxBufferSize);
    }
    if (uartDev->rxReadPtr < length)
    {
        /*user callback*/
        uartDev->uartReceive((uint8_t *)(uartDev->rxBuffer + uartDev->rxReadPtr),
                             length - uartDev->rxReadPtr);
    }
    else if (uartDev->rxReadPtr > length)
    {
        /*user callback*/
        uartDev->uartReceive((uint8_t *)(uartDev->rxBuffer + uartDev->rxReadPtr),
                             uartDev->rxBufferSize - uartDev->rxReadPtr);
        while (__HAL_DMA_GET_COUNTER(&uartDev->dmaTx.hdma) != 0 && timeout++ < 0xFFFF)
        {
        }
        uartDev->uartReceive((uint8_t *)(uartDev->rxBuffer), length);
    }
    uartDev->rxReadPtr = length;
}