Skip to main content
David Pekin
Senior
August 21, 2019
Question

Serial UART design for various size transfers

  • August 21, 2019
  • 3 replies
  • 3278 views

Hello,

I'm writing an application on the STM32F303 Nucleo board that uses the serial UART to receive commands and send responses. I believe example code from the standard peripherals library shows either single byte transfers or fixed size buffer transfers. That is, the UART receive interrupt is fired only after N bytes are received. But N is fixed... This doesn't work for the case where you may be receiving a variable number of characters in your input stream to make up a command.

I've got a system limping along asking for and receiving a single character interrupt at a time but this is less than a reasonable solution and it fails randomly with a HAL_UART_ErrorCallback as other things are going on in the Nucleo code. The error occurs much more frequently when I am simultaneously reading/writing the I2C bus.

Is there a way to peek into the RX UART handle and see how many characters are in the RX buffer and grab them? Polling the number of characters received at the top of the main loop and pulling them into my own circular buffer would probably work more reliably than single character interrupts.

Any thoughts on the best solution?

Thanks,

Dave

This topic has been closed for replies.

3 replies

Tesla DeLorean
Guru
August 21, 2019

The UART on the F3 fire the interrupt for every byte, there is no FIFO, HAL might call the callback at a decimated rates, but is super inflexible.

You could peer inside the HAL structures at the interrupt, I just chose to s**tcan the HAL code for this, and use proper ring buffers like I do everywhere else.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
David Pekin
Senior
August 22, 2019

Thanks Clive. I would like to use a simple ring buffer and get rid of HAL (at least for rx). Are you aware of any public or sample code that demonstrates how to do this?

Thanks again.

Dave

Trevor Jones
Senior
August 22, 2019

using the DMA buffer hardware;

I use this to "Peek" into the buffer: where U1RxBufferPtrOUT points to the last byte read.

char readableU1(void) {

   U1RxBufferPtrIN = U1RxBufSize - huart1.hdmarx->Instance->CNDTR;

   return U1RxBufferPtrIN - U1RxBufferPtrOUT;

}

David Pekin
Senior
August 22, 2019

Thanks Trevor. I'm trying not to rewrite the whole serial UART HAL implementation. I'm currently using the interrupt driven HAL UART dode which is giving me the problem. The DMA implementation has the same drawback where you need to know the number of bytes you're going to be receiving.

I wonder if I could tell the system that the incoming serial read is a large N bytes. Where N is larger than the biggest packet I'm expecting. In the main loop I could monitor how many bytes the incoming DMA buffer has and when I'm not receiving any more data, set the DMA requested size to what I've already received, thereby causing a DMA RX interrupt to get the data. I know this is a lot of hand waving and I'm not sure if the DMA controller would allow that sort of peeking and poking while it's running. Or maybe this same type of kluge using the interrupt based code. What do you think?

I'm somewhat loath to open Pandora's box and start rewriting the HAL UART code from scratch. That's not really in the project timeline....

Dave

Trevor Jones
Senior
August 23, 2019

its super simple...

you dont need to rewrite HAL, just use it...