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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-07-24 7:06 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-07-24 7:12 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-07-24 7:19 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-07-24 7:19 AM
Thanks for replying BTW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-07-24 7:40 AM
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)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-07-24 7:54 AM
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);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-07-24 8:17 AM
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.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-07-24 8:53 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-07-24 9:33 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-07-24 10:27 AM
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.
