cancel
Showing results for 
Search instead for 
Did you mean: 

Using LPUART to transmit byte wise: Space between Bytes

HRaup.1
Associate II

0693W00000NqLf1QAF.pngHello,

I have a STM32 L081KZT and want to use the LPUART to send an Array of bytes, byte wise. For that, I use HAL_UART_Transmit_IT to send the first Byte of the Array and HAL_UART_TxCpltCallback to recursively write the rest of the Array with HAL_UART_Transmit_IT byte by byte. When I look at the Transmission with my Oscilloscope I see the above image. There are spaces between the bytes, which make my Transmission much longer than needed. When I send the same Array with HAL_UART_Transmit, I have no spaces in between the bytes and the Transmission is much shorter.

I am doing this for current consumption optimization and I have to do it byte by byte, because I must be able to send a special Byte in between a transmission.

Is there a way to cut these spaces? Or is there a better approach to this?

Thanks in advance

6 REPLIES 6
JPeac.1
Senior

From your description it appears you are seeing gaps due to interrupt latency, the time it takes to respond to the TX interrupt request. If a higher priority interrupt routine is in progress the LPART interrupt will be deferred until pending interrupts reach the LPUART level. If you have multiple interrupts at the same priority level you may also see delays while the requests are processed in round-robin order.

The easiest way to get around this is to use a DMA channel for LPUART TX. The only latency is bus contention to access the TX data, which should be well below the gaps you see now. DMA is ideal what you describe since you know the length of data to be sent in advance.

Jack Peacock

Your presentation of the trace/gaps isn't compelling. Zoom down showing a few bytes with framing and inter-symbol gap shown/measured.

May be the interrupt service here is slow/sloppy, the TXE should fire at least 8-9 bit times before the data needs to be replenished.You should review your method/algorithm, and if the HAL / callback methodology adds too much additional drag.

You should be able to service a UART IRQ such that the data is continuous, with little to no inter-symbol gaps, except those defined by the stop/start bits.

DMA is also an option, but not sure that's the issue here.

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

Why are you telling the HAL functions to only send 1 byte at a time??? Why not make a single call to HAL_UART_Transmit_IT() to send the entire array? That should get rid of SOME of the code running on each interrupt.

And even IF there are gaps between the bytes, are those gaps significant? Are you sending so much data that you cannot tolerate any gaps between bytes?

HRaup.1
Associate II

@Bob S​ As I mentioned before, I need to be able to send a single byte during the Transmission of data. When an Interrupt occures, I have to send this byte, even if Im transmitting data. So, when I get this Interrupt during transmission, I can set the current member of the output array to the byte I want to send and do output index--

HRaup.1
Associate II

@Community member​  Thanks for your answer I tried using DMA, but I have the same problem with the regular transmit. When I send the all Bytes at once, I am unable to send a Byte during transmission. When I send it byte by byte, I have gaps. After reviewing the sending process, I noticed, that the gaps are produced by the IRQ Handler. At the end of the function: void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) is this:

  /* UART in mode Transmitter (transmission end) -----------------------------*/
  if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
  {
    UART_EndTransmit_IT(huart);
    return;
  }

This is where the wating/gaps occures.

I wouldn't use TC, that fires after the LAST bit has crossed the wire. The TXE asserts immediately after the holding register (Transmit Data Register) is moved to the active shift register, around the time the FIRST bit departs, and in that case you've got 8-9 bit times to play with to fill the holding register.

On most STM32 platforms there is No FIFO, and the HAL interrupt method occurs for every byte, and once the count of bytes complete, then the call-back is performed.

Some systems can have issues with synchronization and resync, with tightly packed data streams.

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