cancel
Showing results for 
Search instead for 
Did you mean: 

high baud rates dropping carachters

bakhti
Associate II

hi i'm using the stm32h750 and in it using the baud rate of 500000 well i want ot go higher but everytime i increase the baud rate there is some charachters dropped or missing in the final received message i tried DMA its worst not filling the buffer

my question is this i'm using HAL can i have high baud rates and use DMA circular to read from the UART

16 REPLIES 16
What is your stm32h750 communicating with?

orange pi i'm using it as a Serial 2 ethernet bypass i cant use the ethernet on my h750 all the pins are used

How are they connected?

simple wires "jumpers"

Have you used an oscilloscope to verify that the signals are well-formed, at the correct baud rate, etc?

i really don't know how to do that like i said earlier i'm fairly new to this

Is your code checking for receiver errors - overruns, framing, etc?

i dont think so no all i have checked and think its a problem is the 16bytes oversampling

static void MX_NVIC_Init(void)
{
  /* USART1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* DMA1_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
  /* DMA1_Stream2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
  /* ADC_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(ADC_IRQn);
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}

DMA 1 Stream 2 and 3 are for UART

I can add that I'm running UART at 921600 bps on F7 with interrupts (no DMA) and software FIFO. Data processing is done in FreeRTOS thread. Works like a charm! The trick - proper IRQ priorities and code.

It's not 16-byte oversampling, it is sampling the bit. It relates to the granularity where by it can center/synchronize to the middle of the bit signal.

Now as the baud rate goes up the integer divider becomes more of an issue in hitting preferred baud rates. 500Kb should divide into MHz quite well, and if you're running at an 8 MHz multiple the bit timing should be pretty solid. The ST design is a bit simplistic, smarter people use adders, not counters.

The UART can report framing, noise and overrun errors. If you're getting data loss, look at those. You need to make a determination if the problem is with the fire hose, or your ability to drink from it, otherwise you're going to be looking in the wrong place to resolve it.

The callbacks are done under interrupt, anticipate that you need to do anything you need to quickly, and within a byte-time. Any use of HAL_Delay(), or other 1ms excursion to other things, is going to break it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

" i'm really new to Stm32 and c programming in general"

Perhaps it would be better to spend some time laying good foundations with some basic projects before leaping into something like this?

" i'm doing it per-character in the receive interrupt because (sic) the RxCpltCallback doesnt fire until pre defined numer of bytes are received"

No that doesn't follow.

All you need to do at the time the character is received is to ensure that you have saved it, and get ready for the next.

You can do the scanning for EOL and parsing messages at your leisure.

The usual approach is to collect characters in a Ring Buffer (aka "Circular Buffer", or FIFO).

My guess is that since you use HAL_UART_Receive_IT, without RX FIFO enabled, loss of bytes at high speed is expected.

Because, HAL_UART_Receive_IT enables the interrupt on entry and disables after completion. In the middle, there are periods of RX interrupt disabled.

The proper solution is to roll your own UART RX code - which the OP cannot do yet.

So, just use the simplest HAL_UART_Receive, one byte in a loop, without interrupts and callbacks.

And enable the FIFO. And by all means TL; DR disable detection of overrun.

If bytes still are lost, consider what Clive @Community member​ wrote - mismatch of baudrate, etc.

-- pa