STM32 SPI DMA-Timings zwischen Datenrahmen und mehreren DMA-Profilen

Ich versuche, die STM32L432-MCU für die SPI-Kommunikation (24 MHz, 16-Bit-Datengröße, nur Master-Übertragung) mithilfe von DMA einzurichten.

Das Slave-Gerät ist ein 32-Kanal-Verstärkerchip. Ich muss eine bestimmte Bitfolge nur einmal zu Beginn senden, um die Register auf dem Slave-Gerät einzurichten, und dann kontinuierlich eine weitere Bitfolge senden, um den Slave wissen zu lassen, dass er weiter abtasten und seine 32 Kanäle durchlaufen soll, bis er empfängt ein Stoppbefehl oder Abschalten.

Ich habe mit CubeMx einen Code mit den entsprechenden Parametereinstellungen generiert. Ich habe den Befehl HAL_SPI_Transmit_DMA verwendet, um die Daten zu senden. Ich erhalte die korrekten SCLK- und MOSI-Signale, erhalte jedoch nicht die korrekten Timings zwischen aufeinanderfolgenden SCLK-Bursts. Meine zwei Fragen lauten:

  1. Das Timing zwischen den aufeinanderfolgenden SCLK-Bursts ist zu kurz, wenn die Circular DMA-Übertragung aktiviert ist (siehe Screenshot). Kanal 3 Pink SCLK, Kanal 4 Grün CSIch müsste es ungefähr doppelt so groß sein (ca. 200 ns). Wo kann ich das Timing steuern? Wenn ich Normal DMA aktiviere und den HAL_SPI_Transmit_DMA-Befehl in eine While-Schleife setze, bekomme ich das gegenteilige Problem, die Lücke zwischen den aufeinanderfolgenden SCLK-Bursts wird zu groß, etwa 5 us. Ich habe auch versucht, die Software-NSS-Pin-Steuerung mit Writepin zu verwenden, habe jedoch das gleiche Problem wie bei der Verwendung der While-Schleife, zu große Lücken zwischen den Datenframes.

  2. Wie könnte ich zwei verschiedene DMA-Profile für den Betrieb mit einem Skript einrichten und bei Bedarf aufrufen? Ich würde dies benötigen, da der Bitstrom dataTx2 nur einmal gesendet werden muss, sodass DMA auf normal eingestellt werden müsste, während dataTx kontinuierlich mit zirkulärem DMA gesendet werden müsste.

Den Code finden Sie hier: https://github.com/varkong/SPI-DMA-Ver-C/tree/master/Src

Vielen Dank im Voraus,

Varkong

Sie sollten jederzeit die entsprechenden HAL-Funktionen aufrufen können, um den DMA neu zu konfigurieren, nur der Cube wird nicht zwei Konfigurationen gleichzeitig für Sie generieren.
Übrigens, wenn der Slave so zeitempfindlich ist, dann ist es kein echtes SPI, das Sie dort haben. Haben Sie darüber nachgedacht, die erforderliche Wellenform auf andere Weise zu erzeugen (PWM, Bit-Banging, ...)?

Antworten (1)

Das Problem ist, dass das von ST bereitgestellte Standard-SPI-DMA-Zeug hier nicht wirklich zu Ihrem Anwendungsfall passt. Wenn Sie ihren SPI-Treiber verwenden, wird davon ausgegangen, dass Sie die Daten so schnell senden möchten, wie es der Bus unterstützt. Dies bedeutet Back-to-Back-Transfers, was Sie sehen.

Sehen Sie nach, ob Sie das Referenzhandbuch durchsehen können, finden Sie heraus, wie das SPI-Tx-Signal den DMA auslöst, und prüfen Sie, ob dieser Trigger auf einen Timer-Zähler verschoben werden kann. Dies ist normalerweise auf voll ausgestatteten Mikrocontrollern möglich. Richten Sie dann einen Timer-Zähler ein, der in dem Zeitraum ausgelöst wird, an dem Sie interessiert sind.

Wenn Sie den ST HAL-Treiber überhaupt verwenden können, muss er umgeschrieben werden, um das zu tun, was Sie wollen.