cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F04xx USART Idle line detection

Tom Eaton
Associate II
Posted on March 09, 2018 at 13:19

I have been trying to use the USART idle line detection flag to  detect when an incoming transmission stream has ended. 

if

((USART1

->

ISR

&

USART_ISR_RXNE)

!=

RESET) {  

if

((

1+

RX_BUFFER_POS)

<

RX_BUFFER_SIZE) {         RX_Buffer[

1

+

RX_BUFFER_POS

++

]

=

USART1

->

RDR;   } }    

if

(__HAL_UART_GET_FLAG(

&

huart1,UART_FLAG_IDLE)) {     can_read

=

1

;     __HAL_UART_CLEAR_FLAG(

&

huart1, UART_FLAG_IDLE); }

I used this code to set a flag, can_read which is checked in the main loop. If the flag is true, then I parse the data.

The problem is that the IDLE flag is being set after each character received, not after the end of the string.

Please can I have some clarification on when the IDLE interrupt is triggered.

Many thanks.

#hal-usart #usart-idle #usart-pins
3 REPLIES 3
Tilen MAJERLE
ST Employee
Posted on March 09, 2018 at 13:45

Hello

tomeaton17

‌,

You if statement checks only if there is byte ready to read.

IDLE line event is triggered if UART RX line is inactive for one frame. The frame time depends on your baudrate. Higher baudrate, lower frame.

You should not use IDLE line to detect end of string. You should use IDLE line to detect IDLE line only and then check if you have entire string already received. To detect end of string, you should (in most cases) wait for line feed(LF) character or carriage return (CR).

Please check

http://www.st.com/content/ccc/resource/technical/document/reference_manual/c2/f8/8a/f2/18/e6/43/96/DM000319pdf/files/DM000319pdf/jcr:content/translations/en.DM000319pdf

for more information.

Best regards,

Tilen

Posted on March 09, 2018 at 13:54

when the IDLE interrupt is triggered

RM0090 says:

An Idle character is interpreted as an entire frame of “1�s

followed by the start bit of the

next frame

which contains data (The number of “1� ‘s will include the number of stop bits).

(my emphasis)

T J
Lead
Posted on March 09, 2018 at 16:02

I use a circular DMA buffer;

    if (HAL_UART_Receive_DMA(&huart4, (uint8_t *)Usart3RxDMABuffer, U3RxBufSize) != HAL_OK)

    _Error_Handler(__FILE__, __LINE__);

char readableU3(void) {

    U3RxBufferPtrIN =  U3RxBufSize - huart4.hdmarx->Instance->CNDTR;

    return U3RxBufferPtrIN - U3RxBufferPtrOUT;

}

char getc3(void) {

    char Rxbyte = Usart3RxDMABuffer[U3RxBufferPtrOUT++];

    if (U3RxBufferPtrOUT >= U3RxBufSize) U3RxBufferPtrOUT = 0;

    return Rxbyte;

}

usage:

(every mS)

{

       if (readableU3() >= LoRaPacketLength)   // have packet end   <-  polling of buffer size, waiting for packet length

            {                

                haveLoraMessageinRxTable = true; // flag foreground to process LoRa Rx Frame

                for (int i = 0; i < LoRaPacketLength; i++)   // copy away frame contents for later processing

                    LoRaRxFrames[LoRaRxFrameIn][i] = getc3();          

.            }              

.

.}