STM32H523 SPI-DMA-Problem

OP #7926518
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

#7926534
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
OP #7926596
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.
#7926725
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 ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren