Hallo zusammen! Ich betreibe einen STM32 mit 72Mhz. Dieser hat unter anderem die Aufgabe eine ADS1178 (16-Bit ADC) über SPI auszulesen. Dieser IC hat ein "Data Ready" Pin Ausgang, der eine fallende Flanke bei einen neuen Messwert ausgibt. In dem uC wird daraufhin ein Interrupt ausgelöst, der eine Rouitine ausführt, in der Berechnungen mit den Werten durchgeführt wird. Außerdem gibt es noch einen Interrupt für den DMA, wo das SPI-Signal (ADC-Werte) in eine Struktur eingelesen werden. Der Bus wird mit 9Mhz betrieben und der ADC hat eine Abtastrate von ca 35KSPS. Nun kommt es leider vor, dass scheinbar "zufällig" Werte verloren gehen oder "falsch" ausgelesen werden. Das ganze System läuft zudem unter FreeRTOS, welches "nebenbei" noch andere Routinen ausführt, die aber geblockt werden, wenn dieser Interrupt für einen neuen Messwert ausgelöst wird. Ich könnte auch denn Source mal reinstellen, um mehr Klarheit zu verschaffen :-) Deswegen mein Anliegen an euch, hat jemand von Euch Erfahrung im Auslesen des SPI Buses mittels DMA. Viele Grüße Stephan
In der FW-Lib von STM (V3.2.0) gibt es ein Demo wie man SPI in das RAM bekommt mit dem DMA. Siehe hier STM32.
Hallo Markus, ich habe das "DMA1 Channel2 transfer complete flag" mit eingebaut und es ist scheinbar Besserung in Sicht! Am Montag werde ich es nochmal genauer unter die Lupe nehmen ;-)
Wenn man mit SPI per DMA arbeitet, dann muss man darauf achten, dass der Transfer erst beendet ist, wenn das letzte Byte/Wort davon empfangen wurde. Wenn man CS deaktiviert sobald Tx-DMA durch ist, dann hat man verloren, weil noch Daten im SPI Puffer sein können. NB: Das bedeutet, dass man auch dann, wenn nur Daten gesendet werden, mit Rx-DMA arbeiten sollte, weil man nur so einen sinnvollen Abschluss-Interrupt bekommt, um CS abzuschalten. Notfalls mit einem Dummy-Puffer ohne Adressinkrement. PS: Deine Problembeschreibung suggeriert, dass du erst mit den ADC-Werten rechnest und sie danach einliest. Merkwürdige Reihenfolge ;-). Eine etwas systematischere Beschreibung könnte helfen.
Noch was zu DMA allgemein: Wenn man DMA bzw. DMA-Steuerung und Zugriff auf das davon verwendete RAM sehr zeitnah oder gar gleichzeitig verwendet, dann sollte man sich vorsichtshalber mal die memory barrier Befehle ansehen.
Hallo A.K., danke erstmal für deine Kommentare! Es gibt 2 Interrupt-Routinen, die eine liest mittels DMA den SPI Buffer aus, in dem auch die ADC Werte eingelesen werden und die andere wird von einem externen Signal ausgelöst, wo die Werte in einen Ringpuffer geschrieben, aufsummiert und ausgewertet werden. Ich denke die Reinfolge ist in Ordnung. Alles weitere kann ich nur am Montag wieder testen.
Ohne Code oder präzise Schilderung bleibt mir das immer noch weitgehend unverständlich, denn die 99%, die in deinem Kopf aber nicht im Posting stehen, kennst nur du. Insofern können meine Kommentare nur allgemeines Gewäscht sein, nicht direkt auf das Problem bezogen.
Ich habe den Code nicht zur Hand, da ich im Studienpraxissemester bin und das Teil einer Aufgabe in meinen Betrieb ist. Schau doch bitte nochmal Montag ins Forum, dann poste ich den Code mal...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.