Lin reception doesn't work in higher baudrate

I am using freertos for ARM CM4, for s32k142 microcontroller, and i have an application which runs lin driver (lpuart), it have send and receive functions, which were working fine with the baudrate 9600, but once i used the baudrate 19200 the receive function doesn’t work anymore, this is the main code i have for reception:


    while ((n != 0) && (loop != 0))
    {
        loop--;
        if ((ctx->base->STAT & LPUART_STAT_RDRF_MASK) == 0)
        {
            *buf++ = (uint8_t)ctx->base->DATA;
            break;
        }
        else
        {
            continue;
            vTaskDelay(1);
        }
   }

    if (loop == 0)
    {
        return TIMEOUT;
    }

so from what i understand, because i have this delay “vTaskDelay(1)” inside the waiting for reception flag to be set, when i have 9600 the data comes slow so when i go to execute another task i will still have the data when i am back (after 1ms) but when i use 19200 it like the data is received faster so when i comeback i will find it gone already.

Any one has any idea how to fix this
Thank you

for one, your delay is never executed as it is located right behind the continue?

Do not “poll” on a flag like that. You should do the reception in an ISR. The issue is that if you actually try to use the ability of FreeRTOs to be running multiple tasks, this loop might not get run for a period of time, and all the data lost.

Sorry that was my bad it’s the delay first then the continue, i just mistaken while simplifying the function

So you mean i should add an interrupt so whenever i receive any data i should go to the interrupt stay there until get everything then go back to the latest task ?

No, as each character arrives, the ISR should take the data from the serial port and put it somewhere. It can then notify what ever task needs the data. I often will have the ISR put the data into a queue, so tasks can take the data off the queue. (That’s what the demos do). This is a bit inefficient for real high baud rates, but 19200 isn’t that high.

better post your real code here. Yours does not make sense left or right. For example, what is n and under what conditions may it terminate the loop? How do you expect us to help you if you only post random code fragments?

okey i understand.
but, if this solution doesn’t work for higher baudrates, then what is usually the best way to do like these kind of things

i just wanted to make it simple for you guys but yeah sure i put the reception part of my code.
But the idea is the same so when i am waiting for the reception flag to be set, i will go execute other task, that way when i come back i will find the data already gone

lin_lpuart.c (4.3 KB)

Interrupt.

When in an RTOS, then answer should almost NEVER be “poll for a signal”, but instead “wait for an interupt” (and let the ISR to the time critical part, and then wake the task that is waiting).

Note, many vendor supplied libraries don’t work that way, as they are based on “bare-metal” single tasking programs where polling works, and is simpler. To use an ISR this way, they would need to be either aware of the particular RTOS being used, or use some form of generic ISR callbacks.

Hello, i just have one question, can i use dma on LIN driver, will it fix this problem ?

Generally 19200 baud should be easily doable without DMA provided the driver is reasonably well written. Note that DMA on the receive side of serial transmission makes sense only with protocols where the number of bytes to follow is known so you can start a reception for a deterministic sized chunk.