Page 1 of 2

UART line idle handling.

Posted: Fri Jul 08, 2016 1:57 pm
by barthess
Hi Giovanni.
In our current project for STM32F767 we need to receive
a lot of data from 4 UARTs on baudrate about 460800 without
hardware flow control. So DMA is our best friend. We need
timeouts to avoid wait until last message's byte arrives in next
filled DMA buffer. First I have tried to handle timeouts restarting
UART receiving from virtual timer but have lots of garbaged
messages (not sure why, probably because of starting receive
in the middle of byte). Later I decided to catch synchronization
on line idle interrupt after the last message byte. That method
works perfect.

My proposition:
1) Add idle callback in driver config
2) Add ISR handler for it (needs minimal modification of serve_usart_irq fucntion).

Looks like this suitable for all STM32, not sure about other MCUs.

Re: UART line idle handling.

Posted: Fri Jul 08, 2016 5:52 pm
by Giovanni
Hi,

Did you uartStop() from a VT callback? that should result in a violation from the state checker.

Note that the UART driver never stops receiving, it calls a function if a byte arrives while a receive operation is on started.

Question, how you detect the start of a packet? this is relevant for synchronization.

Idle detection is not a common feature but it could be added in the STM32-specific part without problems.

Giovanni

Re: UART line idle handling.

Posted: Fri Jul 08, 2016 10:17 pm
by barthess
Giovanni wrote:Did you uartStop() from a VT callback? that should result in a violation from the state checker.

I use I-class functions + lock/unlock there.

Giovanni wrote:Note that the UART driver never stops receiving

I know that. And I still do not know what exactly going wrong. I will try to debug it using oscilloscope on Monday.

Giovanni wrote:Question, how you detect the start of a packet? this is relevant for synchronization.

Start of packet detects during iteration over already received bytes. It is more important to detect end of packet. Imagine you need to collect NMEA single sentence from GNSS receiver sent every second. You have set 64 bytes DMA buffer and call uartStartReveive. But sentence may be from 10 to 80 character length. Data must be parsed when whole sentence arrived, not when DMA buffer filled with 64 bytes. Otherwise you see additional unpredictable delay. So silence detector is best when no hardware handshake available.

Re: UART line idle handling.

Posted: Fri Jul 08, 2016 11:39 pm
by Giovanni
Question, instead of detection of idle, wouldn't be sufficient to use a timeout? a timeout would imply an idle.

Giovanni

Re: UART line idle handling.

Posted: Sat Jul 09, 2016 10:48 pm
by skute
ST also has an app note for using a timer capture/compare to implement DMA timeout: http://www.st.com/content/st_com/en/pro ... 2027.html#

This would require board changes however.

Re: UART line idle handling.

Posted: Sun Jul 10, 2016 9:45 pm
by barthess
Giovanni wrote:Question, instead of detection of idle, wouldn't be sufficient to use a timeout? a timeout would imply an idle.

Do you mean USART_RTOR register? I would prefer idle interrupt because it can be detected by any UART in any STM32 in opposite to USART_RTOR. If you mean software timeouts based on virtual timers than I can not say any meaningful without deeper investigation of broken data problem using oscilloscope.

skute wrote:ST also has an app note for using a timer capture/compare to implement DMA timeout

I know that appnote. Hardwiring uart rx with timer input looks much more ugly than idle frame detection.

Re: UART line idle handling.

Posted: Tue Jul 19, 2016 11:44 am
by barthess
Hi people.

Finally I have a time to test timeout/idle feature in hardware. Both works as expected.
Data corruption reason was not in UART driver nor in virtual timers but in my
code of double buffer.

Some conclusions.
Out custom GNSS receiver produces too much IDLE frames (with exactly 10-bit len) in random
places. So I decided to use hardware timeout feature. It works as expected too. Now interrupt
comes after the whole message receiving. Any way, IDLE detection with later uartStartReceiveI()
works excellent and may be recommended as timeout for "poor people MCUs".

Now questions @Giovanni:
1) API. It is just timeout callback and timeout value in driver config for a moment. CR1 and CR2
flags must be manually set by user in driver config. It looks convenient for me. Is it worth
to add code for CR flags under the hood of driver or leave it to user responsibility?
2) Timeout ability detects using writing and reading back content of RTOR register.
RM0410 wrote:This register is reserved and forced by hardware to “0x00000000” when the Receiver
timeout feature is not supported.

Necessity of adding timeout ability flag in registry files for every MCU and every UART scares me.
3) Feature currently tested only for USARTv2. Pure IDLE variant may be easily added to USARTv1
but I do not know when I will have time to test it.

Re: UART line idle handling.

Posted: Tue Jul 19, 2016 12:08 pm
by Giovanni
I think it should be a configuration, not part of API, the callback would be in the STM32-specific part of the driver structure.

Giovanni

Re: UART line idle handling.

Posted: Tue Jul 19, 2016 7:57 pm
by barthess
I have commited changes in trunk. Any notes and feedback are welcome.

Re: UART line idle handling.

Posted: Wed Jul 20, 2016 10:24 am
by Giovanni
hi,

I see two problems:

1) What if the user does not want timeout handling? which is the default behavior.
2) There is no handling for the synchronous API, the callback could be NULL.

Giovanni