Forum: Mikrocontroller und Digitale Elektronik STM32 SPI mit 2 DMA Streams - geht das?


von 6a66 (Gast)


Lesenswert?

Hallo!

Etwas für die STPM32 HAL DMA und SPI Profis.

Wir möchten an einem STM32F4xx an EINER SPI (SPI1) zwei externe 
Bausteine (Display und FLASH) verwenden die wir BEIDE mit DMA ansteuern 
möchten.
Wir verwenden die HAL in aktueller Version.
Dazu benötigten wir zwei verschiedene DMA Streams an einer SPI.
Die Hardware des STM32 macht das mit (DMA2 Stream1 und Stream3).

Die Kommunikation mit EINEM externen Bauteil (Display) über SPI1 und 
DMA2 funktioniert tadellos.

Aber uns ist nicht klar:

a) In der HAL SPI-Handle gibt es nur einen DMA-Connector (hspi1.hdmatx). 
Wenn wir mit zwei verschiedenen DMA-Streams arbeiten wollten müssten wir 
an diesem Konnektor dynamisch arbitrieren - Einmal den DMA2-Stream1 und 
dann den DMA2-Stream3. Wir sehen das als sehr aufwendig und 
fehleranfällig an (neben dem Management der ChipSelect Signale).

b) Alternativ: Können wir mit zwei verschiedenen SPI-Handles (hspi1 und 
hspi2) auf EINER SPI arbeiten in denen wir die beiden Connectoren 
hspi1.hdmatx und hspi2.hdmatx unterschiedlichen DMA-Streams belegen?

rgds

von Walter T. (nicolas)


Lesenswert?

6a66 schrieb:
> Dazu benötigten wir zwei verschiedene DMA Streams an einer SPI.

Warum? Es kann doch eh nur ein Baustein gleichzeitig angesteuert werden. 
Es sei denn, man taktet direkt den SPI vom einen in den anderen. Aber 
selbst dann braucht man nur einen (zum mitlesen).

: Bearbeitet durch User
von STK500-Besitzer (Gast)


Lesenswert?

6a66 schrieb:
> Wir sehen das als sehr aufwendig und
> fehleranfällig an (neben dem Management der ChipSelect Signale).

Das ist dann wohl Eure Herausforderung.
Peripherie-DMA-Streams sind immer an die Schnittstelle gebunden.

Um Probleme zwischen zwei Bausteinen an einer Schnittstelle zu 
vermeiden, verwendet man bei RTOSen einen MUTEX oder Semaphoren zur 
Zugriffssteuerung.

von 6a66 (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> Um Probleme zwischen zwei Bausteinen an einer Schnittstelle zu
> vermeiden, verwendet man bei RTOSen einen MUTEX oder Semaphoren zur
> Zugriffssteuerung.

Wir haben kein RTOS :( und werden auch keines einsetzen.
Das hilft uns da erst mal nicht weiter.

rgds

von STK500-Besitzer (Gast)


Lesenswert?

6a66 schrieb:
> Wir haben kein RTOS :( und werden auch keines einsetzen.
> Das hilft uns da erst mal nicht weiter.

Wie wollt Ihr denn auf die Schnittstelle zugreifen?
Irgendwie müsst Ihr ja erkennen, dass Euer DMA-Stream fertig übertragen 
wurde.

Es darf also maximal wechselweise einer der Bausteine beschrieben 
werden.
Wie wollt Ihr das bewerkstelligen?

von 6a66 (Gast)


Lesenswert?

Walter T. schrieb:
> Warum? Es kann doch eh nur ein Baustein gleichzeitig angesteuert werden.
> Es sei denn, man taktet direkt den SPI vom einen in den anderen. Aber
> selbst dann braucht man nur einen (zum mitlesen).

Das ist richtig. Wie müssen dann aber zwischen dem Display und dem FLASH 
Multiplexen. Mit dem Multiplexen muss dann auch der DFMA-Stream 
umgeschaltet werden. Das Display wird etwa 80x pro Sekunde (8 DMAs alle 
100ms) mit dem DMA angesteuert. Wenn dann von oben auch noch das FatFS 
auf das FLASH dazwischen scheiben oder lesen will wird das eine 
verflixte Arbitrierung der beiden DMAs.

Geht das geschickter?

rgds

von 6a66 (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> Irgendwie müsst Ihr ja erkennen, dass Euer DMA-Stream fertig übertragen
> wurde.

Klar. Das erkennen wir im Falle des Displays ganz gut. Der Framebuffer 
wird in 8 Einzelteilen per DMA übertragen. So und jetzt kommt das FatFS 
dazwischen und sagt: Ich will FLASH Lesen. Gut, das stellen wir dann mal 
hinten an bis das Display fertig ist. Dann müssen wir
- Den Chipselect fürs Display abschalten
- den CS fürs FLASH einschalten
- in der SPI-Handle den DMA-Connector umbiegen
- und dann auf das FLASH zugreifen.
Wenn fertig dann wieder auf Display umschalten.

Alternative war eben: zweiten Handle für die gleiche SPI verwenden - 
geht das?

rgds

von STK500-Besitzer (Gast)


Lesenswert?

6a66 schrieb:
> Alternative war eben: zweiten Handle für die gleiche SPI verwenden -
> geht das?

Warum sollte es?
Ihr braucht eine Warteschlange oder sowas.
Greift das FatFS  von sich aus auf die Schnittstelle zu, oder habt Ihr 
da Steuermöglichkeiten?

Ich programmiere STM32 mit einem RTOS - das vereinfacht die Sache 
ungemein.

So müsst Ihr das, was ein RTOS als Threadkommunikation mitliefert, 
manuell basteln.

von 6a66 (Gast)


Lesenswert?

Zur Klarstellung:

Die Lösung
- SPI1 mit Handle initialisieren
- DMA2 Stream3 mit Handle inititalisieren
- Beide Handles miteinader verbinden
- CS ansteuern
- Loop
- 1/8 Frame übertagen per DMA
- Interrupt bekommen da DMA fertig
- Display Kommando auf nächste Teilpage setzen
- Nächsten Teilframe per DMA absetzen
- solange bis fertig
- LoopEnd
- CS disable

GEHT, funktioniert sauber und stabil. SPI1 und DMA2 arbeiten 
hervorragend zusammen.

ABER:
Jetzt kommt noch von oben das FatFS und will über die gleiche SPI über 
einen anderen DMA Stream das FLASH extern lesen.

a) Geht das - sprich hat das schon jemand mal gemacht - an der 
SPI-Handle den DMA-Connector auszutauschen (Prefer NACH der 
Display-Schleife) und dann per DMA auf einen anderen Baustein 
zuzugreifen?

b)Alternativ eine mit einer zweiten SPI-Handle zu arbeiten?

rgds

von 6a66 (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> So müsst Ihr das, was ein RTOS als Threadkommunikation mitliefert,
> manuell basteln.

Die Threads auseinander zu halten ist nicht das Problem - das bekommen 
wir hin.
Das Problem ist die SPI. Die müsste ja mit zwei verschiedenen Handles 
arbeiten können: Kann die STM32-HAL das ???

rgds

von Walter T. (nicolas)


Lesenswert?

6a66 schrieb:
> a) Geht das - sprich hat das schon jemand mal gemacht - an der
> SPI-Handle den DMA-Connector auszutauschen (Prefer NACH der
> Display-Schleife) und dann per DMA auf einen anderen Baustein
> zuzugreifen?

Ich habe es noch nie mit HAL gemacht. Ohne HAL ist es einfach Teil der 
Chip-Select-Routine
 - CS aus
 - disable DMA
 - ändere Speicheradresse und -Länge (schalte also auf eine anderen 
Puffer um)
 - enable DMA
 - neuer DMA

Das geht blitzschnell.

: Bearbeitet durch User
von STK500-Besitzer (Gast)


Lesenswert?

6a66 schrieb:
> Kann die STM32-HAL das ???

NEIN,  geht nicht.
Warum sollte sie das auch?
Wie schon geschrieben: DMA-Kanäle gehören zur Hardware.
Wenn da mehr als ein Baustein dran hängt, müsst Ihr euch darum kümmern, 
dass es keine Kollision gibt.

Ihr müsst doch sowieso dem FatFs-DMA einen Speicher fürs Lesen und einen 
fürs Schreiben "verlinken".
Das muss sich halt abwechseln. Oder jedem seine eigene Schnittstelle 
spendieren.

von Walter T. (nicolas)


Lesenswert?

Walter T. schrieb:
>  - CS aus
>  - disable DMA
>  - ändere Speicheradresse und -Länge (schalte also auf eine anderen
> Puffer um)
>  - enable DMA
>  - neuer CS

(konnte nicht mehr korrigieren)

von Johnny B. (johnnyb)


Lesenswert?

6a66 schrieb:
> Das Problem ist die SPI. Die müsste ja mit zwei verschiedenen Handles
> arbeiten können: Kann die STM32-HAL das

Selbstverständlich; das Handle muss ja bei allen HAL-Funktionen immer 
mitgegeben werden. Siehe entsprechende Header-Dateien (SPI, DMA, etc.).

von 6a66 (Gast)


Lesenswert?

Johnny B. schrieb:
> Selbstverständlich; das Handle muss ja bei allen HAL-Funktionen immer
> mitgegeben werden. Siehe entsprechende Header-Dateien (SPI, DMA, etc.).

Auch auf EINER SPI?
Das wäre dann die Lösung des Problems.

rgds

von 6a66 (Gast)


Lesenswert?

6a66 schrieb:
> Auch auf EINER SPI?
> Das wäre dann die Lösung des Problems.

Muss da kein DEInit und Init dazwischen?

rgds

von J. S. (jojos)


Lesenswert?

wenn beide Streams initialisert sind müsste ein Umschalten mit 
__HAL_LINKDMA() gehen, Versuch macht kluch. Synchron im DMA Complete des 
Displays, das kommt ja vermutlich zyklisch.
__HAL_LINKDMA setzt nur die Verzeigerung in den Handles.

von STK500-Besitzer (Gast)


Lesenswert?

Johnny B. schrieb:
> Selbstverständlich; das Handle muss ja bei allen HAL-Funktionen immer
> mitgegeben werden. Siehe entsprechende Header-Dateien (SPI, DMA, etc.).

ZWEI DMA-Streams auf eine Schnittstelle?
Dass man DMA-Streams mit unterschiedlichen RAM-Speicheradressen 
"verlinken" kann, sollte klar sein, aber für eine Schnittstelle zwei 
unabhängige DMA-Streams verwenden?

von Simon D. (jamen)


Lesenswert?

6a66 schrieb:

> Dazu benötigten wir zwei verschiedene DMA Streams an einer SPI.
> Die Hardware des STM32 macht das mit (DMA2 Stream1 und Stream3).
>
> Die Kommunikation mit EINEM externen Bauteil (Display) über SPI1 und
> DMA2 funktioniert tadellos.

Hallo 6a66,

mir ist noch nicht klar warum ihr zwei verschiedene DMA-Kanäle 
verwendet. Mit zwei CS muss die Arbitrierung ja sowieso in der Software 
erfolgen, solange man sich keine ausgefuchste Verkettung von DMA-Kanälen 
hat einfallen lassen.

Was hält euch davon ab denselben DMA-Kanal für beide Devices am SPI zu 
verwenden und diesen je nach Device mit dem richtigen Speicherbereich zu 
starten?

LG Simon

von Harry L. (mysth)


Lesenswert?

6a66 schrieb:
> b) Alternativ: Können wir mit zwei verschiedenen SPI-Handles (hspi1 und
> hspi2) auf EINER SPI arbeiten in denen wir die beiden Connectoren
> hspi1.hdmatx und hspi2.hdmatx unterschiedlichen DMA-Streams belegen?

Nein!
Wäre auch unsinnig...

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.