Hi,
ich habe beim Stöbern im STM32G0xx Refmanual den DMAMUX gefunden.
Kann mir jmd. in verständlichen Worten erklären, was man damit genau
machen kann?
Ich habe mir die englischsprachige Präsentation und die AN5224
angesehen, aber so ganz verstehe ich es noch nicht.
Gut, man kann über externe Eingänge wie z.B. EXTI0 oder auch über einen
Timer dann DMA-Transfers triggern.
Aber was noch? Speziell das "Multiplexing" erschließt sich mir noch
nicht.
Gruß
Markus
Ohne nachgelesen zu haben meine ich das es darum geht jeden DMA Kanal
für jede Peripherie nutzen zu können, wenn ich mich richtig erinnere.
Das geht bei den älteren STM32 nicht, da konnten für SPI z.B. nur
gewisse DMA Kanäle genutzt werden.
Beim neuen STM32WB55 nutze ich diesen. Damit kann ich quasi auf einen
DMA Kanal eine beliebige Peripherie mappen.
Antwort ohne Gewehr (peng). Aber eine Begrenzung ist mir spontan nicht
bekannt.
Also es ist offenbar tatsächlich das (freie) Mapping zwischen der
Peripherie und einem DMA-Kanal, zusätzlich die anderen Zusatzfunktionen
wie triggern durch externes Event etc.
So wie ich es sehe bzw. ausprobiert habe, MUSS man den sogar benutzen,
sonst kommt der DMA-Request von der Peripherie garnicht beim DMA-Kanal
an.
Hi
Ich versuche aktuell meinen SPI Treiber DMA-gesteuert mit meinem
STM32G031 zum Laufen zu bringen. Aktuell tut sich da leider noch gar
nichts und ich habe den Verdacht, dass die Peripheral Request nicht
wirklich beim DMA Controller ankommt und die einzige Geschichte, die ich
noch nicht so wirklich verstanden habe ist diejenige des DMAMUX.
Kurz zum Verständnis, wenn ich für SPI1_Rx den Channel 3 vom DMA und für
SPI1_Tx den Channel 4 vom DMA verwenden will, muss ich dann im DMAMUX
request line multiplexer channel x configuration register (DMAMUX_CxCR)
ebenfalls die Channels 3 und 4 nutzen oder fungieren die unabhängig
voneinander?
SPI1_Rx und SPI1_Tx haben gemäss Reference Manual den DMA request MUX
input 16 bzw 17. Folglich müsste meiner Meinung nach eine
Initialisierung des Registers so aussehen:
Zumindest habe ich aus dem Reference Manual verstanden, dass das so
genügen dürfte, weiss allerdings auch nicht, ob der Wurm wirklich hier
begraben ist, ich nehme an es gibt keine Möglichkeit zu überprüfen, ob
vom SPI eine Request am DMA ankommt
Die Zeile verstehe ich nicht ganz, warum "+1", ich nahm an im CPAR
Register soll die Adresse des Datenregisters des entsprechenden
Peripherals (In unserem Fall ja das SPI Datenregister) gespeichert
werden?
Ich habe es mir vorerst noch erspart, irgendwelche RXNE/TXE oder BSY
Bits abzufragen, denn noch findet ohnehin keine Kommunikation statt, die
Bits sind also so oder so nicht gesetzt. Ich vermute nach wie vor, das
beim DMA Controller gar keine Request ankommt, da das TXE bit gesetzt
bleibt, der Buffer also stets empty ist und offenbar keine Daten ins SPI
Datenregister geschrieben werden.
>> Die Zeile verstehe ich nicht ganz, warum "+1", ich nahm an im CPAR> Register soll die Adresse des Datenregisters des entsprechenden> Peripherals (In unserem Fall ja das SPI Datenregister) gespeichert> werden?
Stimmt. Eigentlich ist es tatsächlich falsch bzw. funktioniert wohl
trotzdem aufgrund der Gutmütigkeit der HW in meinem Projekt (ich benutze
diesen Code seit vielen Stunden in einem Deko-Projekt mit WS2812-LEDs
ohne jeglichen Fehler).
Ich glaube mein Gedanke war, dass ich ja nur 8-Bit übertrage, das
Register aber 16-Bit groß ist. Mir war allerdings entgangen, dass der
Speicher als little endian organisiert ist, also die Bits 0-7 des
Registers tatsächlich im ersten Byte liegen.
Muss ich bei Gelegenheit mal testen ob es ohne das "+1" bei mir auch
noch funktioniert.
Also ich habe das "+1" tatsächlich aus meinem Code entfernen können und
er funktioniert nach wie vor problemlos.
Da scheint die Hardware intelligent genug zu sein, je nachdem ob man in
das High-oder Low-Byte schreibt wird das dann entsprechend in den TX
FiFo übernommen.
Warum löscht Du denn eigentlich die Enable-Bits gleich wieder nachdem Du
sie gesetzt hast? Da kann es doch eigentlich garnicht funktionieren.
Du müsstest schon warten bis der DMA-Transfer fertig ist.
Meinen Dank in die Runde, diese Antworten Code-Schnipsel haben auch mir
geholfen. Da ich ein leicht anderes Problem hatte (und Google mich
hierher geführt hat), möchte ich dieses explizit betonen:
Bekannt ist, dass je ein Dmamux-Kanal hart verdrahtet ist mit je einem
Dma-Kanal. Bei älteren Stm32Fxxx gibt es salopp gesagt einen Dma-Kanal,
der nur Spi kann, und einen weiteren für Uart. Die G-Familie hat einen
Dmamux, wo jeder Dma-Kanal die zugehörige Peripherie einstellbar hat,
mittels DMAMUX > CxCR > DMAREQ_ID.
Woran ist es bei mir gescheitert? Hier ein Auszug aus der stm32g031xx.h:
DMA1_Channel1 ist hart verdrahtet mit DMAMUX1_Channel0, DMA1_Channel5
ist hart verdrahtet mit DMAMUX1_Channel4, allgemein: DMA1_Channel[x+1]
ist hart verdrahtet mit DMAMUX1_Channel[x]. Umgekehrt: Ich habe
DMA1_Channel1 und DMAMUX1_Channel1 (sowie jew. 4) konfiguriert, der
Compiler kann den Fehler nicht sehen und meine Events laufen ins Leere.
In meiner spi.h ist das wie folgt gelöst:
1
#define DMA_Channel_BP_Rx DMA1_Channel1
2
#define DMA_Channel_BP_Tx DMA1_Channel4
3
#define DMA_Channel_BP_Rx_IRQn DMA1_Channel1_IRQn
4
// Note, that stm32g031xx.h enumerates DMA1_Channel1..5 and DMAMUX1_Channel0..4 so DMAMUX1_Channel(x) applies to DMA1_Channel(x+1)
5
#define DMAMUX_Channel_BP_Rx DMAMUX1_Channel0
6
#define DMAMUX_Channel_BP_Tx DMAMUX1_Channel3
7
8
#define BP_Rx_IRQHandler DMA1_Channel1_IRQHandler
9
#define DMA_ISR_BP_Rx DMA_ISR_TCIF1
10
#define DMA_IFCR_BP_Rx DMA_IFCR_CTCIF1
Notiz am Rande: Die Low-Level-Funktionen von CubeMx haben ja durchaus
ihre Berechtigung. Geschickt ist, dass die LL_DMA_SetPeriphRequest() auf
den Dmamux zielt, aber als Parameter den Dma-Kanal nutzt. Damit steht in
der spi.c steht immer der gleiche Kanal, also niemals ein "+1". Das
funktioniert, weil die Werte der defines alle beim Offset 0 starten.
Interessant, dass ich auch einen Fehler mit diesem "+1" hatte.
Nochmals Danke in die Runde! Ich hoffe, dass meine Antwort hier
niemandem hilft und euch mein Ärger erspart blieb.