STM32 SPI2 mit DMA Problem (DMA TC-Flag kommt zu früh)

Gast #1361927
Lesenswert?

Hi,

ich bin gerade dabei eine der SPI-Schnittstellen an meinem Cortex-M3 
(STM32F103RBT6) in Betrieb zu nehmen. Zur Übertragung nutze ich den 
DMA-Controller und frage nachdem ich die Daten übertragen habe ob das 
DMA1_FLAG_TC gesetzt ist. Nun habe ich Probleme meinen angeschlossenen 
SPI-Slave zu erreichen bzw. zu initalisieren, dabei ist mir aufgefallen, 
dass meine CS-Leitung viel zu früh wieder hochghet (SPI-Clock noch aktiv 
und ein letztes Datenbyte fehlt noch). Diese CS-Leitung wird manuel 
durch Setzen/Rücksetzen des entsprechenden Pins betrieben, da die 
NSS-Funktionalität des stm32 nicht richtig bzw. nach meinem Verständins 
funktioniert. Durch weiteres Debuggen ist mir aufgefallen, dass das 
DMA1_FLAG_TC zu früh gesetzt wird (dadurch dann auch der CS-Pin), das 
letzte Byte wird gerade übertragen bzw. steht kurz vor der Übertragung.

Ist euch ähnliches passiert beim STM32 mit SPI und DMA? Gibts dafür eine 
Erklärung bzw. ist das ein bekannter Bug? Gibt es ähnliche Probleme auch 
beim Empfangen von Daten über SPI?

Gruß und danke!
#1362154
Lesenswert?

Das TC Flag signalisiert nur, dass der DMA Controller das letzte Byte 
beim SPI-Puffer abgeliefert hat. Das SPI braucht dann natürlich noch ein 
bischen Zeit bis der Kram rausgeschoben ist. Kein Bug, sondern 
missverstandene Arbeitsweise von DMA.

Wenn du SPI ohne DMA machst, kassierst du CS ja auch nicht gleich wieder 
ein nachdem du das letzte Byte ins Register verfrachtet hast, sondern 
wartest bis Puffer und Shifter leer sind.
Moderator Persönliche Seite #1362283
Lesenswert?

Erklärung ja bereits von A.K. gegeben, daher nur als Ergänzung: Habe das 
bei SD-Karte am STM32-SPI damit "gelöst" indem auf RX-complete gewartet 
wird, bevor Chip-Select manuell über gewöhnliche GPIO wieder auf high 
gesetzt wird. Falls man eigentlich nichts empfangen will, kann man das 
Inkrement ausschalten (DMA_MemoryInc_Disable) und muss nur ein paar Byte 
für einen "Dummy-RX-Buffer" bereitstellen. Falls man nicht einfach in 
einer Schleife auf das RX-complete warten will, kann man auch einen 
Interrupt dafür scharfstellen und dann in der ISR /CS deselektieren. 
Funktioniert soweit zuverlässig, wir aber sicher auch bessere Lösungen 
geben.
Gast #1363432
Lesenswert?

Danke für die Antworten! Da habe das das DMA-Flag falsch interpretiert. 
Ein einfügen von while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 
RESET) brachte nichts, da meine NSS-Pin wieder zu früh gesetzt wird, 
werde daher wohl auf die Lösung von Martin zurückgreifen und den empfang 
von Dummybytes abfragen. Auch wenn mir das nicht sooo sehr gefällt, aber 
was solls...
Gast #1428247
Lesenswert?

Auf das TXE flag zu warten funktioniert nicht weil das ja nur bedeutet 
das neue daten in den Buffer geschrieben werden können, nicht das die 
Daten aus dem Shift Register schon gesendet wurden. Willst du abfragen 
ob alle Daten gesendet, muß das BUSY Flag abgefragt werden. Dieses Flag 
ist so lange gesetzt wie Daten im TX Buffer und im Shift Register 
vorhanden sind.

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