An meinem STM32F417IG Mikrocontroller habe ich einen externen 16bit-DAC
(TI DAC81404) angeschlossen, der mit einer Rate von 32kHz ein Signal
generieren soll. Die Kommunikation soll über SPI und unabhängig von der
CPU erfolgen. Daher möchte ich DMA verwenden, welches über einen Timer
getriggert werden soll und die Daten mit der Rate von 32kHz ins SPI Data
Register schreibt, sodass die Daten zum DAC gesendet werden.
Infos zum DAC
Der DAC aktualisiert seine Ausgangsspannung immer wenn ein neuer Wert
über SPI empfangen wurde. Das wird erreicht, indem:
1. der CS/NSS/SYNC – Pin auf low gezogen wird
2. eine 24bit/3 byte große Nachricht gesendet wird und
3. CS anschließend wieder auf high gezogen wird.
In den ersten 8bit (von 24bit) befindet sich u.a. die Information an
welchem Channel die Ausgangsspannung anliegen soll. Die restlichen 16bit
enthalten den digitalen Wert der Ausgangsspannung.
Infos zum STM32
Leider haben die Mikrocontroller von ST ein Hardwareproblem mit dem NSS.
Der Pin wird richtigerweise zu Beginn einer SPI-Kommunikation auf low
gezogen. Anschließend bleibt er jedoch low bis SPI letztendlich komplett
deaktiviert wird. (Reference Manual Seite 877). Das ist aber nicht Sinn
der Sache. Der Pin soll nach jeder Nachricht wieder auf high gezogen
werden. Eine „Lösung“ wäre die Verwendung eines GPIOs als Output für den
NSS, der manuell geschaltet wird.
Das steht auch genauso im Datenblatt:
When a master is communicating with SPI slaves which need to be
de-selected between transmissions, the NSS pin must be configured as
GPIO or another GPIO must be used and toggled by software.
Problem
Das hat zur Folge, dass ich den Prozess nicht einfach zu Beginn starten
kann und anschließend keine CPU-Ressourcen mehr benötigt werden.
Stattdessen muss ich eine Lösung finden, DMA über einen Timer getriggert
zu nutzen und zwischendurch Interrupts zu verwenden, um den NSS zu
schalten.
Meine Frage ist nun, ob ich eine Möglichkeit übersehen habe, um doch
irgendwie mit DMA ohne zyklischen Aufruf einer CPU-lastigen Funktion
auszukommen oder ob es eine andere Methode gibt, den NSS-Pin
ressourcenarm zu steuern. Bei letzterem habe ich auch Schwierigkeiten
bei der Umsetzung, da die BUSY Flag natürlich erst am Ende der
SPI-Übertragung, also am Ende des ganzen Datenblock auf low gesetzt wird
und nicht nach jeder 24bit Nachricht.