cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 UART/USART RX message terminator detection with LIN Mode

mauro2399
Associate II
Posted on September 01, 2015 at 09:32

Hi everybody,

I am using several flavours of STM32: STM32F407, STM32F030, STM32F071, STM32F303 (soon).

Concerning UART, I want to set up a protocol using variable-length messages.

In order to minimize the CPU overhead, I want to use the TX with DMA and interrupt at the end of the transmitted message, and RX with DMA and interrupt at the end of the received message.

  • On the TX side I can fire an IRQ with TXE or TC status bits, that's fine.
  • On the RX side I want to fire an IRQ at the end of the received message. Since the protocol uses variable-length messages, how can the RX tell the received message has ended?
At first I thought I might exploit a scheme for few-char idle line detection:

  • RTOF (RX timeout)
  • CMF (Character match)
  • I don't like using IDLE because it would fire and IRQ as soon as the TX leaves the line idle for just 1 char, no mercy for the TX being a little busy sometimes...
But I discovered that the USART of the STM32F407, which is the richest MCU of the ones I am using, doesn't implement RTOF and CMF. Sounds strange...

Anyway, I thought I could use the Break character as a message terminator.

According to the Reference manuals, on the RX side the Break character is treated as a Framing error. Uhm... I don't like using this as a message terminator, as there's no way to distinguish it from a real error.

But the LIN mode seems to handle it slightly different, requiring *all* received bits as 0 (mark). The Break character used in LIN Mode sounds like a viable message terminator, although STM32F030 doesn't implement the LIN Mode.

I have no experience with

LIN mode

, can you give me some advice?

Q1: On the TX side, is there any difference with UART mode @ 8-bit data length?

Q2: On the RX side, apart from the Break character handling, is there any difference with UART mode @ 8-bit data length?

Q3: Any other caveats or constraints with LIN mode?

Best regards,

Mauro

#stm32-uart-lin-break

Note: this post was migrated and contained many threaded conversations, some content may be missing.
11 REPLIES 11
Posted on May 23, 2017 at 16:51

I should also mention I'm trying to use this also. will report back here if I get this working

/* enable RX NOT EMPTY inturrupt on uart */

__HAL_UART_ENABLE_IT(&UartHandle,USART_CR1_RXNEIE);
Posted on May 25, 2017 at 14:35

Ben,

you must enable RX NOT EMPTY inturrupt on uart, as you suggested:

__HAL_UART_ENABLE_IT(&UartHandle,USART_CR1_RXNEIE);

Hence,

USARTx_IRQHandler()

will be called upon *each* byte reception on the UART.

I suggested you can add your own code in source file stm32f7xx_it.c, inside USARTx_IRQHandler(), between

USER CODE BEGIN USART2_IRQn 1 and

USER CODE END USART2_IRQn 1.

Since USARTx_IRQHandler() will be called upon *each* byte reception on the UART, you know where is the last character received!

The HAL functions know where is the next free array position, since they must store the next received character.

If you read stm32f7xx_hal_usart.c, inside USART_Receive_IT() you can see that the handle husart contains such pointer.

The *last* received character has been stored at (husart->pRxBuffPtr -1).

If your UART handle is named UartHandle, then the last received character is

*(UartHandle->pRxBuffPtr -1)

.

So, you can write something like:

if (*(UartHandle->pRxBuffPtr -1) == '\n')

end_of_line_reached = TRUE;

else

end_of_line_reached = FALSE;

You can learn a lot by reading inside the HAL sources.

Finally, your function USARTx_IRQHandler() seems way too long for an IRQ handler, which is usually executed at a priority level and therefore delays other lower priority IRQ handlers until it is finished.

Good real time coding requires to do as

little as you can inside the IRQ handler, and perform all longer actions which can be delayed (like calling

BSP_LCD_ClearStringLine()

and

BSP_LCD_DisplayStringAtLine()

)outside the IRQ handler, e.g. in the background scheduler.

Cheers,

Mauro