Forum: Mikrocontroller und Digitale Elektronik STM32 USART Verständnisproblem - Receive Timeout triggert ständig?


von Empfänger (Gast)


Lesenswert?

Hallo,

ich habe gerade einen kleinen Hänger beim Verständnis des "Receive 
Timeout" der STM32, z.B. STM32L073.

Wer die RTO-Funktion kennt: Frage im letzten Absatz.

Die USART (und auch der LPUART) können nach einer frei definierbaren 
Zeit (Anzahl von Bitlängen, USART_RTOR) einen "Receive Timeout" 
detektieren und diesen beispielsweise per Interrupt melden (einschalten 
mit RTOEN in USART_CR2 und Int freigeben mit RTOIE in USART_CR1). Im 
RT-Interrupt kann man dann z.B. den DMA ausschalten um den 
DMA-unterstützten Empfang einer unbekannten Anzahl von Zeichen dann zu 
beenden (dazu gibt es auch Beispiele im Netz).

Ich will den RTO benutzen um im "Transfer Complete" Interrupt des DMA 
Kanals zwei Ping-Pong Puffer für Nachrichten konstanter, mit bekannter 
Länge zu alternieren. Die Zeit zwischen zwei Übertragungen ist groß 
genug um den jeweils zuletzt genutzten Puffer zu verarbeiten. Sollte es 
aber doch mal zu einem Fehler kommen bzw. initial genau während einer 
Übertragung der Empfang starten empfange ich natürlich die korrekte 
Anzahl an Zeichen, jedoch "zusammengesetzt" aus eigentlich zwei Paketen, 
also nicht

12345    12345    12345    12345    12345

sondern

      34512    34512    34512    34512

Mit dem RTO könnte man nach dem Empfang von Byte 5 den Timeout 
detektieren, den DMA abbrechen, neu mit CNTDR laden und wieder starten.

Problem: Sobald ich die RTO-Funktion nutze scheint der DMA permanent 
deaktiviert zu werden. Natürlich setze ich im RTO-Interrupt das RTOF im 
USART_ISR zurück.

FRAGE: Wenn ich die Reference Manuals richtig verstehe, sollte die 
RTO-Funktion erst aktivieren können, dann beliebig lang warten können. 
Erst wenn ein Stop-Bit empfangen wurde zählt die RTO-Funktion los und 
meldet einen Timeout - wenn ich diesen Timeout quittiere sollte doch bis 
zum nächsten Stop-Bit Ruhe sein?

Danke!

von Empfänger (Gast)


Lesenswert?

Kurze Ergänzung:

USART_CR2
Bits 23:0 RTO[23:0]: Receiver timeout value
This bit-field gives the Receiver timeout value in terms of number of 
bit duration.
In standard mode, the RTOF flag is set if, after the last received 
character, no new start bit is detected for more than the RTO value.

-> klingt gut, also nur einmalige Detektion nach einem Stop-Bit

USART_CR3
Bit 23 RTOEN: Receiver timeout enable
This bit is set and cleared by software.
0: Receiver timeout feature disabled.
1: Receiver timeout feature enabled.
When this feature is enabled, the RTOF flag in the USART_ISR register is 
set if the RX line is idle (no reception) for the duration programmed in 
the RTOR (receiver timeout register).

-> klingt eher so als ob das Teil immer zählt ohne durch ein Stop-Bit 
ausgelöst zu werden?

Natürlich könnte ich noch das RXNE-Interrupt bemühen, um den Start einer 
Übertragung/eine laufende Übertragung zu erkennen und dann erst immer 
den RTO einschalten - das scheint mir aber umständlich.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Empfänger schrieb:
> When this feature is enabled, the RTOF flag in the USART_ISR register is
> set if the RX line is idle (no reception) for the duration programmed in
> the RTOR (receiver timeout register).
>
> -> klingt eher so als ob das Teil immer zählt ohne durch ein Stop-Bit
> ausgelöst zu werden?

 Ja.

Empfänger schrieb:
> Kanals zwei Ping-Pong Puffer für Nachrichten konstanter, mit bekannter
> Länge zu alternieren. Die Zeit zwischen zwei Übertragungen ist groß
> genug um den jeweils zuletzt genutzten Puffer zu verarbeiten. Sollte es

 Wenn du die Zeit zwischen zwei Übertragungen um 1/3 verkürzt (als Bsp.)
 in RTOR reinschreibst, erwischst du den Start der Nachricht (n), oder ?
 Das, was dann in aktuellem Puffer steht, ist die vorige Nachricht(n-1).

 Von da an kannst du die empfangenen Zeichen zählen, DMA auf Anzahl der
 zu empfangenen Zeichen einstellen oder weiter mit RTOR arbeiten.

: Bearbeitet durch User
von Empfänger (Gast)


Lesenswert?

Hallo Marc,

vielen Dank für Deine Antwort!

Ich versuche das dann noch mal spezifisch zu prüfen: Kein "Kabel", RTO 
einschalten -> müsste dann ja (leider) immer triggern.

Ich sehe dann zwei Möglichkeiten:

1. RTO immer an, RTOR wie du sagst relativ zum Inter-Frame-Space (IFS): 
IFS/2 < RTOR < IFS.
Für die Synchronisation beim Start/im Fehlerfall in Ordnung, allerdings 
auch mindestens immer mindestens ein unvermeidbares RTO-Interrupt pro 
IFS

2. RTO wird nur im zusätzlichen RXNE-Interrupt eingeschaltet und im 
TC-Interrupt des DMA (der evtl. vom RTO ausgelöst wurde) ausgeschaltet, 
RTOR dann ggfl. nur geringfügig größer als der Inter-Byte-Abstand 
während des Frames
Diese Version wäre insbesondere für unbekannte IFS bzw. auch den 
DMA-Empfang von Paketen unbekannter Länge sinnvoll, da der RTO zeitnah 
am Frame-Ende auslöst.

Bin enttäuscht, dass der RTO nicht erst durch ein Stop-Bit gestartet 
wird. Sehe so kaum einen Vorteil zur IDLE-Detektion!?

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Setze RTOEN mit dem Stop Interrupt und loesche es in der RTO Routine...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Empfänger schrieb:
> Für die Synchronisation beim Start/im Fehlerfall in Ordnung, allerdings
> auch mindestens immer mindestens ein unvermeidbares RTO-Interrupt pro
> IFS

 Ja, aber dadurch wird auch gleichzeitig ein EOF-Flag für zuletzt
 empfangene Nachricht gesetzt.
 Wenn Frames per DMA empfangen werden, brauchst du nach RTO-Interrupt
 nur die DMA-Adresse für Puffer zu wechseln und auf DMA-Int zu warten.
 Falls ein neues RTO-Int vor DMA-Int feuert, weisst du das etwas
 nicht in Ordnung war.
 DMA-Int sagt nämlich nichts darüber aus wieviel Zeit zwischen 2
 aufeinander folgenden Zeichen vergangen ist - und das war doch dein
 Problem, oder ?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.