Forum: Mikrocontroller und Digitale Elektronik STM32G0: UART DMA empfängt nach Sleep nicht mehr


von Mike (Gast)


Lesenswert?

Hallo zusammen!

Ich habe hier einen STM32G0 auf einer eigenen Platine.
Der MCU kommuniziert mit einem LTE Modem via AT Kommandos auf UART2.

Wenn ich den MCU in den Sleep schicke:
1
HAL_PWREx_EnableFlashPowerDown(PWR_FLASHPD_LPSLEEP);
2
HAL_SuspendTick();
3
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFE);

Wacht mir der MCU sofort wieder auf. Wenn ich vorher den UART noch 
de-Initialisiere mit:
1
HAL_UART_DeInit(&huart2);
funktioniert der Sleep-Mode wie gewünscht und ich wach sogar wieder auf. 
Leider funktioniert danach der UART nicht mehr. Ich habe verschiedene 
Methoden probiert, den UART wieder zu starten, aber anscheinend mache 
ich es immer falsch, egal welche der beiden UART Init Varianten ich 
verwende.
1
 
2
MX_DMA_Init();
3
MX_USART2_UART_Init();
4
HAL_UART_Init(&huart2);
5
HAL_UART_Receive_DMA(&huart2, &rxByte, 1);
Der UART RX Cplt Callback wird nach der Re-Init nicht mehr aufgerufen, 
wenn Daten ankommen. Habe ich mit dem Logic-Analyzer und einem 
getoggelten Pin auch "wasserdicht" geprüft. Es kommen nach dem Sleep 
auch wirklich Daten am RX Pin des STM32 an, also muss es am MCU liegen.

Hat jemand eine Idee? Woran könnte es noch liegen?

Danke!

von Harry L. (mysth)


Lesenswert?

Mike schrieb:
> HAL_UART_Receive_DMA(&huart2, &rxByte, 1);
                   ^^^

Glaub es, oder nicht!

UART mit DMA ist vollkommener Quatsch, wenn du mittels AT-Kommandos 
kommunizierst. (Und auch in 99,9999% aller anderen Fälle)

Ersetze DMA durch IT und die Welt ist in Ordnung.

von Mike (Gast)


Lesenswert?

Hi Harry,

wie meinst du das genau? Problem bei den AT Kommandos ist ja, dass ich 
die Länge der einzulesenden Strings nicht genau kenne, sondern Lesen 
muss, bis das Abschlusszeichen (\r\n) kommt.

Bisher erschien es mir als beste Möglichkeit, mit dem DMA immer ein 
zeichen zu lesen bis das Trennzeichen kommt und dabei in meinen Buffer 
zu schaufeln.
Implementation ungefähr wie 
hier:https://www.hwtronics.com/2020/05/03/stm32-hal-101-uart-receiving-arbitrary-string/

Hast du eine bessere Lösung?

Danke!

von A. B. (funky)


Lesenswert?

Ich denke er will sagen nimm IRQs für UART. 1 Byte per DMA empfangen 
dürfte jetzt nicht wirklich einen Geschwindigkeitsvorteil bringen. Beim 
senden sieht das evtl. anders aus und man könnte diskutieren.

von W.S. (Gast)


Lesenswert?

Mike schrieb:
> Hi Harry,
>
> wie meinst du das genau?

Das Verwenden von DMA für einen UART ist zum einen nicht nötig und führt 
zum anderen zu einer Menge von Zusatzproblemen. Und: ein DMA kann keine 
Probleme lösen, sondern lediglich Daten von A nach B schaufeln.

Ich habe hier schon viele Leute jammern sehen, die partout DMA für einen 
UART benutzen wollten. Immer nach dem Motto: "Aber DMA geht schneller!"

W.S.

von Mike (Gast)


Lesenswert?

Hi!

Ok, danke für den Input.

Ich verwende den DMA tatsächlich nicht wegen Geschwindigkeitsvorteil. 
Sondern weil es der einzige Weg war, mit dem ich bis zu einem 
definierten Trennzeichen Character einlesen konnte.

Habt ihr eine alternative, die immer Bereit ist, Zeichen einzulesen und 
mir nach jedem Zeichen einen Interrupt oder ähnlich triggert, damit ich 
die Zeichen entsprechend verarbeiten kann?

Danke!

von Harry L. (mysth)


Angehängte Dateien:

Lesenswert?

Mike schrieb:
> Habt ihr eine alternative, die immer Bereit ist, Zeichen einzulesen und
> mir nach jedem Zeichen einen Interrupt oder ähnlich triggert, damit ich
> die Zeichen entsprechend verarbeiten kann?

Bitte sehr!

von Mike (Gast)


Lesenswert?

Damit hab ich nicht gerechnet! Mega gut, danke dir!
Schaue ich an :-)

von W.S. (Gast)


Lesenswert?

Mike schrieb:
> Habt ihr eine alternative, die immer Bereit ist,...

Hier im Forum schon unzählige Male gepostet.
Hier mal ein mittlerweile so etwa 5 Jahre altes Beispiel, wie sowas für 
einen STM32F103C8T6 aussehen kann:
https://www.mikrocontroller.net/attachment/316790/STM32F103C8T6.ZIP

Das Prinzip:
1. es hat einen Lowlevel-Treiber, der sich um den UART kümmert, dabei in 
zwei Ringpuffern (einer für Sendedaten, der andere für empfangene Daten) 
die Zeichen zwischenspeichert und das eigentliche Senden und Empfangen 
organisiert.
2. es gibt ne Anfragefunktion, ob etwas empfangen worden ist. Dazu dann 
eine Lesefunktion, die das Zeichen liefert (aus dem Puffer im Treiber).
3. es gibt eine Funktion, die Zeichen zu einer Kommandozeile 
zusammenstellt.
4. es gibt ein Kommandoprogramm, das die Kommandozeile parst und 
Kommandos (nach Gusto der jeweiligen Anwendung) ausführt.

Nachtrag dazu: es gibt auch einen virtuellen COM Port per USB. Den kann 
man dann ganz genauso benutzen wie einen normalen COM Port bzw. UART. 
Das wird alles in verschiedenen Schichten der Firmware geregelt, so daß 
die einzelnen Ebenen sich nicht weiter um die Arbeit der anderen Ebenen 
kümmern  müssen. Deshalb sind einige Ebenen hardwareunabhängig, so daß 
es kein großes Problem ist, das Ganze oder Teile davon zu portieren.

Reicht das als Alternative für dich?

W.S.

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.