Skip to main content
aa bb
Associate
November 19, 2017
Question

UART TX DMA issues

  • November 19, 2017
  • 2 replies
  • 2463 views
Posted on November 19, 2017 at 18:16

Hi,

I am trying to set up a uart TX using DMA to send data (mostly strings).

I am using FREERTOS. The semaphore is taken when I want to send the data and released when the UART_EndTransmit_IT() function is called.

The issue is that I have to add delay between data sent (~10ms).otherwise the strings sent are not complete. 

I don't understand why this is necessary..

I ma using: HAL_UART_Transmit_DMA() to send data.

Anyone witht the same problem?

Cheers,

A

    This topic has been closed for replies.

    2 replies

    S.Ma
    Principal
    November 19, 2017
    Posted on November 19, 2017 at 20:47

    Do you wait for the DMA transfer completion before the next string is pushed in?

    A FIFO behaviour is what seems best for UART Tx, or a DMA block FIFO...

    aa bb
    aa bbAuthor
    Associate
    November 19, 2017
    Posted on November 19, 2017 at 22:18

    Yes, I release the semaphore when this function is called: 

    UART_EndTransmit_IT()

    S.Ma
    Principal
    November 20, 2017
    Posted on November 20, 2017 at 08:13

    Try to activate the DMA only when the UART TX is ready to proceed (status register of UART) as extra security.

    aa bb
    aa bbAuthor
    Associate
    November 23, 2017
    Posted on November 23, 2017 at 19:02

    Hi, 

    Still not working, I can't figure out what's wrong. That must be a very stupid thing..

    waclawek.jan
    Super User
    November 23, 2017
    Posted on November 23, 2017 at 19:23

    Crystal ball hazy here.

    The semaphore is taken when I want to send the data and released when the UART_EndTransmit_IT() function is called.

    What semaphore? Is it some code of yours inserted into Cube sources, into UART_EndTransmi_IT() function? If not, what do you exactly mean by it? What exactly is the consequence of 'semaphore taken' and 'released'?

    The issue is that I have to add delay between data sent (~10ms).otherwise the strings sent are not complete. 

    Where did you add the delay exactly? How exactly are the strings not complete?

    JW

    aa bb
    aa bbAuthor
    Associate
    November 23, 2017
    Posted on November 23, 2017 at 19:30

    Okay, here it is my sending function:

    void Console_PrintFmt(const char *fmt, ...)

    {

        if (fmt == NULL)

        return;

    if (xSemaphoreTake(consolePrint_mutex, osWaitForever) == pdTRUE)

    {

        int n;

        int size = CONSOLE__MAX_BUFFER_LENGTH - 1;

        char pBuffer[size+1];

        va_list va;

        TimerMsType timeNow = TimerMs_GetTimeMs();

        memset(pBuffer, 0, size+1);

        n = snprintf(pBuffer, size, '[%d.%03d]:', (int)timeNow / 1000, (int)timeNow % 1000);

        va_start(va,fmt);

        n += vsnprintf(pBuffer + n, size - n, fmt, va);

        va_end(va);

        if ((0 < n) && (n < size))

       {

            HAL_UART_Transmit_DMA(&huart1, (uint8_t* )pBuffer, n);

           osDelay(20);

        }

        else

        {

             xSemaphoreGive(consolePrint_mutex);

        }

      }

    }

    Mu mutex is released when HAL_UART_TxCpltCallback() is called. 

    void HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)

    {

        portBASE_TYPE higherPriorityWoken = pdFALSE;

        xSemaphoreGiveFromISR(consolePrint_mutex, NULL);

        if (higherPriorityWoken)

        {

             portYIELD_FROM_ISR(higherPriorityWoken);

         }

    }

    I have do add the delay just after calling 

    HAL_UART_Transmit_DMA()...

    Sorry but the <p> code </p> doesn't work...