Forum: Mikrocontroller und Digitale Elektronik STM32 SPI2 mit DMA Problem (DMA TC-Flag kommt zu früh)


von domi_ (Gast)


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!

von (prx) A. K. (prx)


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.

von (prx) A. K. (prx)


Lesenswert?

Apropos: Welche Erfahrung hast du mit NSS gemacht?

von Martin T. (mthomas) (Moderator) Benutzerseite


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.

von Jean P. (fubu1000)


Lesenswert?

A. K. schrieb:
> Apropos: Welche Erfahrung hast du mit NSS gemacht?

Hi, AK
also bei mir habe ich schlechte Erfahrungen gemacht. Funzt nit so wie es 
soll. Auch nach zu lesen im STM Forum. Aber kann sein das neuere 
Revisions das gefixt haben.

Gruß

von domi_ (Gast)


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...

von Gee (Gast)


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.

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.