Forum: Mikrocontroller und Digitale Elektronik STM32H523 SPI-DMA-Problem


von Rangi J. (rangi)


Lesenswert?

Hallo Forum,
ich habe ein Problem mit meinem aktuellen Projekt. Ein Sensor ist per 
SPI an meinen STM32H523 angeschlossen. Zyklisch werden Daten eingelesen. 
Dazu verwende ich die DMA mit einer linked List (CubeIDE 1.18.1, 
HAL_SPI_TransmitReceive_DMA(..)). Ein Timer arbeitet als Watchdog, falls 
mal keine neuen Daten ankommen. Das ganze funktioniert prima bis auf 
eine Stelle, an der die Kommunikation durch 'was auch immer' gestört 
wird (Mein Test: kann der Sensor bei einem Fehler neu initialisiert 
werden). Dann schlägt der Watchdog zu und ich versuche ein reinit der 
SPI-DMA mit HAL_SPI_Abort(...).
Aber genau hier kommt es zum Problem, indem die HAL-Schicht hier klemmt:
1
HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi)
2
{
3
...
4
    /* Request a Suspend transfer */
5
    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSUSP);
6
    do
7
    {
8
      count--;
9
      if (count == 0UL)
10
      {
11
        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
12
        break;
13
      }
14
    } while (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART));
15
...
16
}
Das CSTART-Flag wird nicht gelöscht und die while-Schleife wird erst bei 
count == 0 abgebrochen. Das Datenblatt sagt dazu:
"A transfer can be suspended at any time by setting the CSUSP bit of the 
SPI_CR1 register, which clears the CSTART bit. This software suspension 
control ensures the completion of any ongoing data frame."
Lt. meinem Oszi ist aber in dem Moment kein Frame unterwegs, die SPI 
clockt nicht und tut auch sonst nichts.
Ich vermute es liegt an der DMA. Und tatsächlich wird die DMA auch 
weiter unten in der HAL_SPI_Abort() abgeschaltet. Aber eben erst danach.
Kann mir hier jemand weiterhelfen?
Danke

von Johnny B. (johnnyb)


Lesenswert?

Rangi J. schrieb:
> Ich vermute es liegt an der DMA

Mit den DMA Controllern der STM32 bin ich auch oft am kämpfen; es gibt 
aufgrund der Komplexität der grösseren STM32 sehr viele Hürden.

Diese Punkte fallen mir gerade ein und würde ich mal genau anschauen:

- Wird für den Buffer ein Bereich im RAM verwendet, welcher sowohl vom 
verwendeten DMA-Controller wie auch der verwendeten Peripherie 
zugreifbar ist?

- Liegt der Buffer 32-Bit aligned im RAM?

- Ist sichergestellt, dass richtig mit den Cashes umgegangen wird, also 
entweder manuell mit SCB_InvalidateDCache_by_Addr / 
SCB_CleanDCache_by_Addr oder dass das cashing für die angelegten Buffer 
mit der MPU deaktiviert wird.

- Passt es mit den Prioritäten der Interrupts (HAL tick, DMA, FreeRTOS 
tick)

Wenn alles richtig ist, dann funktionieren bei mir die DMAs sehr 
zuverlässig und stabil.

: Bearbeitet durch User
von Wastl (hartundweichware)


Lesenswert?

Johnny B. schrieb:
> Ist sichergestellt, dass richtig mit den Cashes umgegangen wird

Johnny B. schrieb:
> oder dass das cashing für die angelegten Buffer
> mit der MPU deaktiviert wird.

Ich denke mit Bargeld bzw. Kassen hat das ganze Thema nichts zu tun.

: Bearbeitet durch User
von Johnny B. (johnnyb)


Lesenswert?

Wastl schrieb:
> Ich denke mit Bargeld bzw. Kassen hat das ganze Thema nichts zu tun.

Da hast Du recht, hätte Caching heissen sollen. Aber die Wichtigkeit von 
Bargeld ist dennoch nicht zu unterschätzen.

von Rangi J. (rangi)


Lesenswert?

Johnny B. schrieb:
> - Wird für den Buffer ein Bereich im RAM verwendet, welcher sowohl vom
> verwendeten DMA-Controller wie auch der verwendeten Peripherie
> zugreifbar ist?
Ja, 0x0800000 - 0x0800FFFF

Johnny B. schrieb:
> - Liegt der Buffer 32-Bit aligned im RAM?
ich bin mir nicht sicher, aber:
1. es funktioniert im normalfall
2. es wird immer nur der selbe ram verwendet, nie ein anderer

Johnny B. schrieb:
> das cashing für die angelegten Buffer
> mit der MPU deaktiviert wird.
Ich habe beides getestet ohne Effekt

Johnny B. schrieb:
> Passt es mit den Prioritäten der Interrupts (HAL tick, DMA, FreeRTOS
> tick)
- kein OS verhanden
- in dem Moment, in dem die SPI klemmt, ist der Code nicht im 
Interruptkontext. Das ist ein guter Hinweis, ich werde mal eine Critical 
Section drum herum bauen.

von Rangi J. (rangi)


Lesenswert?

Rangi J. schrieb:
> ich werde mal eine Critical Section drum herum bauen.

Nope, kein Erfolg

von Johnny B. (johnnyb)


Lesenswert?

Rangi J. schrieb:
> Rangi J. schrieb:
>> ich werde mal eine Critical Section drum herum bauen.
>
> Nope, kein Erfolg

Dann habe ich gerade auch keine Idee mehr.
Bei mir war letztes mal das Problem, dass der DMA Interrupt eine höhere 
Priorität hatte als der HAL-Tick interrupt. Das führe dann sporadisch zu 
einem HardFault.

von Hans-Georg L. (h-g-l)


Lesenswert?

Beim H7 kann die DMA Übertragung von SPI oder DMA gesteuert werden. 
Jetzt frag mich nicht wie man das genau feststellt ;-) Es gibt nur eine 
Tabelle im RM das es die Modi gibt und was in dem jeweiligen Modus 
möglich ist. Das Problem liegt darin das die Events zusätzlich einen 
internen Handshake haben wo der Empfänger das Signal nach Bearbeitung 
quittieren muss. Am besten du schaust in den Register von SPI, DMAMUX 
und DMA welche Flags gesetzt sind nachdem dein Timeout zugeschlagen hat. 
Vielleicht musst du die DMA auch neu starten / anhalten oder 
irgendwelche Flags in den Registern löschen. Eine andere Möglichkeit 
könnte noch eine Timeout Schleife in der HAL sein wo er hängen bleibt.
Viel Spaß bei der Suche ;-)

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.