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

How would we know? You've given us no relevant information - not even what chip are you using.

UART overrun is an error indicated in UART status register, see RM, but that may be handled by Cube/HAL itself.

At the end of the day, it may be also your program which drops the characters.

Try increasing compiler optimization level.

JW

rwils.1
Associate III

Fair point Jan, I'm using the STM32L471RGT6 at 80MHz. The code is a simple IT based jump to the HAL routine to receive a character, increment a ring buffer, wait for 10 characters in the buffer ( at present) and then transmit the characters out of the serial line using HAL_UART_TX. The messages are incomlete with missing characters. As the code is not complex, and other people have claimed the HAL routines are bloated , I wondered if fundamentally, the HAL routines are just not capable of operating at this speed?

I'll try increasing the optimization level.

Thanks for replying BTW

gregstm
Senior III

A simple/efficient write to the GPIO BSRR register can set/reset an IO pin. That way you can do your own timing with an oscilloscope (I'm assuming your micro has that register, and also that you have access to an oscilloscope).

Also, I would just use UART status/data register reads in a hard loop (placing data into a simple buffer) to see if you receive the data ok, just to make sure that it is not a hardware issue causing the missing data. (Note: I've never used HAL, I just write to registers)

Thank you Greg, I have tried using register reads/writes but for some other reason, I can't get data from the RDR register, I must have the syntax of the following wrong -> Temp = READ_REG(UART4->RDR);

temp = UART4->TDR;

It's a structure in memory, the MCU can read it directly.

Keep the acquisition of the data separate from the processing. The interrupt should focus on collecting the data, if you stay in the interrupt/callback the MCU can't re-enter.

An 80 MHz MCU should be able to sink 115,200 baud data without loss.

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

Good time waste solver is place here some code

your code relevant lines ...

receive character by character is classic mistake = is imposible with bad implement not relevant to HAL or registers control.

rwils.1
Associate III
Function in main 
 
while(1) {
		if(character_available==1) 		//Character_available set to 1 by interrupt routine
		{
			character_available=0;
			UART4->TDR = Temp;   		// Load the Data and transmit 
			while (!(UART4->ISR & (1<<6)));  //Wait for transmission to end 
		}
 
Interrupt function
        while (!(UART4->ISR & (1<<5))); //Ensure that there is a character to be read
	Temp=UART4->RDR;				//Read the character and store in temp
	character_available=1;			//Informs main loop that a character is available

Thanks for the suggestion MM, here is the relevant code, as you can see , it's pretty straightforward, simply receive a character in the interrupt routine and transmit the character in the main routine. The problem with the code is that Temp never receives data from RDR.

If add Temp='A' then an A is transmitted when a character is received so I have reason to believe that the problem lies with line 13.

Your low level coding is under my low level knowl. You dont show where and how declare Temp.

Too isnt good practice place while in irq.