cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L476rg UART RX missing data. Continue receiving data until "OK" or "ERROR" encountered.

devtty
Associate III

I am trying to receive some uart input from data that is an unknown size. I should end on \r\n or on an OK or ERROR received. The issue I am having with interrupts(HAL_Receive_IT()) is obviously losing too much data. I have also tried to implement this with DMA and a buffer but could not get it working. I have looked at some of the other solutions posted as well (one by user Tesla Delorean in 2018 on streaming uart data from a different module) and another from an ST employee here: https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx/blob/master/projects/usart_rx_idle_line_irq_L4/Src/main.c

I do not want to use any RTOS though. Is there some really simple example of just getting the uart data and outputting it to console on another uart? Or can someone guide me on how to do this/ tell me the best/better way ? Just reading 1 byte and interrupting each time is too slow and missing too much data.

Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions
Pavel A.
Evangelist III

These examples have very high reputation. Keep studying them.

Below is a really simple code to read from one UART and write to another. It was tested on H7 (I don't have L4) but it could work for you.

int peek_char(UART_HandleTypeDef *h)
{
    USART_TypeDef *U = h.Instance;
    uint32_t uartsts = U->ISR;
    if (!(uartsts & UART_FLAG_RXNE)) {
        return 0;
    }
    uint32_t ch = U->RDR;
    return (uint8_t)ch;
}
 
 
void two_uarts_loop(UART_HandleTypeDef *h1, UART_HandleTypeDef *h2)
{
    while (1) {
        int ch = peek_char(h1);
        if (ch) {
            if (ch == '\e' || ch == 0x03) {
                break;
            }
            HAL_UART_Transmit(h2, (void*)&ch, 1, 10);
        }
 
       HAL_StatusTypeDef st;
       st = HAL_UART_Receive(h2, (void*)&ch, 1, 2);
       if (st == 0) {
           HAL_UART_Transmit(h1, (uint8_t *)&ch, 1, 0xFFFF);
       }
    }
}

View solution in original post

1 REPLY 1
Pavel A.
Evangelist III

These examples have very high reputation. Keep studying them.

Below is a really simple code to read from one UART and write to another. It was tested on H7 (I don't have L4) but it could work for you.

int peek_char(UART_HandleTypeDef *h)
{
    USART_TypeDef *U = h.Instance;
    uint32_t uartsts = U->ISR;
    if (!(uartsts & UART_FLAG_RXNE)) {
        return 0;
    }
    uint32_t ch = U->RDR;
    return (uint8_t)ch;
}
 
 
void two_uarts_loop(UART_HandleTypeDef *h1, UART_HandleTypeDef *h2)
{
    while (1) {
        int ch = peek_char(h1);
        if (ch) {
            if (ch == '\e' || ch == 0x03) {
                break;
            }
            HAL_UART_Transmit(h2, (void*)&ch, 1, 10);
        }
 
       HAL_StatusTypeDef st;
       st = HAL_UART_Receive(h2, (void*)&ch, 1, 2);
       if (st == 0) {
           HAL_UART_Transmit(h1, (uint8_t *)&ch, 1, 0xFFFF);
       }
    }
}