cancel
Showing results for 
Search instead for 
Did you mean: 

Using HAL UART, I can't receive a ~20 byte string at 115k, the string is variable length so I have to read character by character but the routine misses characters. Am I correct to think that the HAL routine is too slow to handle this?

rwils.1
Associate III
 
19 REPLIES 19

Cube/HAL may be bloated, but I somehow refuse to believe that it can't cope with 115200 in an 80MHz mcu. IMO that might've been some improper usage.

> Too isnt good practice place while in irq.

+1, while has nothing to do in ISR, so

> while (!(UART4->ISR & (1<<5))); //Ensure that there is a character to be read

No. You want only

if (UART4->ISR & USART_ISR_RXNE) {  
  Temp = UART4->RDR;
  character_available = 1;
}

Check also the overrun flag and clear it.

JW

Of course, the character_available and Temp variables need to be defined as volatile.

And lines 4 and 6 have race condition - it the interrupt happens in between those lines, a byte is lost.

vd
Associate III

Like I said in one of the previous, get rid of the crappy cubemx HAL for UART and write one your own. You can disable generating IRQ handler for it in the cubemx. I also found a few stupid things done there, making it impossible for me to change the baudrate during run time.

S.Ma
Principal

Monitor the overflow flag and make a nop to breakpoint as it happen in debug mode.

Interrupt should never wait, the duration of the interrupt should be as fixed as possible. Check on WCET. Are there any other interrupt disabled long code strip in the sw? Are you managing tx within rx interrupt? Does the used uart have hw fifos?

He is writing his own code!

> get rid of the crappy cubemx HAL for...

...everything

rwils.1
Associate III

My own code now works. I wrote a tight circular buffer in the interrupt and used the code that I previously posted. I can read and write at 115k without losing bytes. what was not clear to me was that in Cube MX I foolishly enabled Jtag TMS as an i/o pin ( wrong bank) and so what was happening was that following programming, the program disabled the JTAG and so the breakpoints and the values in the registers were messed up 9 ways since Sunday. After correcting this I can now see that the code works as it should. Thank you all for your advice. now on to FATFS - which really doesn't work!

Piranha
Chief II

By the way, for the absolute best and simplest circular buffer implementations, read these:

https://ferrous-systems.com/blog/lock-free-ring-buffer/

https://www.snellman.net/blog/archive/2016-12-13-ring-buffers/

vd
Associate III

Or you could use this ring buffer, super easy to use and does the job!

https://github.com/AndersKaloer/Ring-Buffer

Thank you Piranha , I'll take a look

STM32L471RGT6 at 80MHz should be more than capable of transmitting 20 byte at 115k speed

>>"wait for 10 characters"

that sounds like an ugly active wait loop...... manage your reception buffer outside the interruption or use DMA (<- DMA is nice and fast)

we dont need to firmware by ourselves, lets talk