Optimierte SPI-Treiber für die MCU

Höherer Durchsatz für High-Speed-ADCs

16. Oktober 2023, 8:10 Uhr | Von Denny Wang und Sally Tseng
Diesen Artikel anhören

Fortsetzung des Artikels von Teil 1

DMA-Transaktionen im Basic-Modus

Beispielcode für DMA-Transaktionen im Basic-Modus
Bild 6. Beispielcode für DMA-Transaktionen im Basic-Modus.
© Analog Devices

Vor jeder DMA-Transaktion sind bestimmte SPI- und DMA-Einstellungen erforderlich (siehe Code-Beispiel in Bild 6). Bei »SPI_CTL« handelt es sich um die SPI-Konfiguration. »SPI_ CTL=0x280f« wird von dem für den ADI-SPI-Treiber eingestellten Wert abgeleitet. SPI_CNT ist die Anzahl der übertragenen Bytes. Da jede DMA-Transaktion nur die fest vorgegebene Zahl von 16 bits übertragen kann, muss SPI_CNT stets ein Vielfaches von 2 sein. Im vorliegenden Fall wird SPI_CNT=4 gewählt, um die Ausgangsdatenbreite von 24 bit des ADC abzudecken. Das SPI_DMA-Register ist die SPI-DMA-Freigabe. »SPI_DMA=0x5« gibt die DMA-Empfangsanforderung frei. »pADI_DMA0->EN_SET=(1<<5)« aktiviert die DMA-Funktionalität des fünften DMA-Kanals (SPI0 RX).

DMA-Strukturregister
Tabelle 3. DMA-Strukturregister
© Analog Devices

Jeder DMA-Kanal besitzt ein DMA-Strukturregister (Tabelle 3). Zu beachten ist, dass das Ende der Quelladresse (SPI0 Rx) in diesem Fall während der gesamten Operation nicht inkrementiert werden muss, da das Rx-FIFO die Daten automatisch aus dem Register herausschiebt. Das Ende der Zieladresse hingegen wird gemäß dem SPI-Treiber von ADI berechnet (Funktion: Ziel- adresse + SPI_CNT - 2).

Bei der aktuellen Adresse handelt es sich in unserem Fall um die Adresse eines internen Array-Puffers. Die DMA-Kontrolldatenkonfiguration umfasst das Einstellen der Quelldatengröße, die Inkrementierung der Quelladresse und der Zieladresse, die Zahl der verbleibenden Transfers und den DMA-Kontrollmodus. Der Wert »0x4D000011« stellt die Konfiguration ein, wie in Tabelle 4 beschrieben.

 DMA-Konfiguration für die Kontrolldaten-Konfiguration 0x4D00011
Tabelle 4. DMA-Konfiguration für die Kontrolldaten-Konfiguration 0x4D00011.
© Analog Devices

Mit dem Dummy-Lesebefehl »SPI_SPI0 -> RX« wird das Takten von SCLK gestartet, und die Ausgangsdaten werden über die MISO-Leitung vom ADC zur MCU übertragen. Hinzu kommen einige hier nicht weiter relevante Datentransfers auf der MOSI-Leitung. Sobald der Rx-FIFO gefüllt ist, wird der DMA-Request generiert, wodurch der DMA-Controller angewiesen wird, die Daten von der DMA-Quelle (d. h. vom Rx-FIFO des DMA-Kanals SPI0) an das DMA-Ziel (also den internen Array-Puffer) zu übertragen. Es wird darauf hingewiesen, dass der TX-Request bei SPI_DMA=0x3 erzeugt wird. Abschließend erhält man die Zieladresse für die nächste 4-Byte-Übertragung, indem der Wert 4 zur aktuellen Zieladresse addiert wird.

Wichtig ist ebenfalls, dass sowohl »pADI_DMA0->DSTADDR_CLR« als auch »pADI_DMA0->RMSK_CLR« für den DMA-Kanal »SPI0« in der Hauptfunktion gesetzt werden müssen, bevor der erste Interrupt erfolgt. Das vorherige Register ist »DMA Channel Destination Address Decrement Enable Clear«, das die Verschiebung der Zieladresse nach jedem DMA-Transfer im Inkrement-Modus vorgibt (die Funktion zum Berechnen der Zieladresse ist nur im Inkrement-Modus wirksam). Das letzte Register, »DMA Channel Request Mask Clear«, löscht den DMA-Request-Status für den Kanal.

Zeitdiagramm für den DMA-Betrieb im Basic-Modus (a) und im Pingpong-Modus (b)
Bild 7. Zeitdiagramm für den DMA-Betrieb im Basic-Modus (a) und im Pingpong-Modus (b).
© Analog Devices

In Bild 7a ist ein Zeitdiagramm für die DMA-Transaktion im Basic-Modus zu sehen. Die Zeitschlitze geben das DRDY-Signal bzw. die SPI/DMA-Einstellungen und die DMA-Datentransaktion wieder. Um die Leerlaufzeiten der CPU besser zu nutzen, werden ihr Aufgaben zugewiesen, während der Datentransfer selbst vom DMA-Controller abgewickelt wird.

DMA-Transaktionen im Pingpong-Modus

Im Anschluss an die Implementierung des Dummy-Lesebefehls startet der DMA-Controller die Datentransaktion, sodass die CPU des Mikrocontrollers keine Aufgaben durchführen muss. Wenn es gelingt, die CPU und den DMA-Controller gleichzeitig arbeiten zu lassen, erfolgt das Task-Handling nicht mehr seriell, sondern parallel. Damit können die DMA-Konfiguration (seitens der CPU) und die eigentliche DMA-Datentransaktion (seitens des DMA-Controllers) zur gleichen Zeit erfolgen. Um dieses Konzept zu realisieren, muss der DMA-Controller im sogenannten Pingpong-Modus arbeiten. In dieser Betriebsart kommen zwei DMA-Strukturen, nämlich die primäre und die alternative Struktur, zum Tragen, und der DMA-Controller wechselt bei jeder DMA-Anforderung automatisch zwischen diesen beiden Strukturen hin und her. Die anfangs auf 0 gesetzte Variable p gibt an, ob die primäre (p = 0) oder die alternative DMA-Struktur (p = 1) aktiv ist. Bei p = 0 beginnt die primäre DMA-Datentransaktion mit dem Dummy-Lesebefehl.

Gleichzeitig werden Werte für die alternative DMA-Struktur zugewiesen, die im nächsten Interrupt-Zyklus aktiv ist. Bei p = 1 wechseln die primäre und die alternative Struktur ihre Rollen. Die Modifikation der DMA-Struktur kann während einer DMA-Transaktion nur dann fehlschlagen, wenn sich die primäre Struktur im Basic-Modus befindet. Der Pingpong-Modus ermöglicht es der CPU, auf die alternative DMA-Struktur zuzugreifen und zu schreiben, während die primäre Struktur vom DMA-Controller gelesen wird, und umgekehrt. Wie aus Bild 7b hervorgeht, kann die DMA-Datentransaktion ausgeführt werden, sobald der ADC das DRDY-Signal an die MCU gesendet hat, denn das Konfigurieren der DMA-Struktur ist bereits im vorausgegangenen Zyklus erfolgt. CPU und DMA-Controller arbeiten jetzt gleichzeitig, ohne aufeinander warten zu müssen. Da sich die gesamte Verarbeitungszeit hierdurch entscheidend verkürzt, dürfte sich die Ausgangsdatenrate des ADC steigern lassen.

Optimierung des Interrupt-Handlers

Das Zeitintervall zwischen den Data-Ready-Signalen enthält nicht nur die Verarbeitungszeit der Befehle in der Callback-Funktion, sondern auch der Anweisungen im GPIO-Interrupt-Handler von ADI.

Bei Aktivierung des Mikrocontrollers arbeitet die CPU die Start-up-Datei (startup.s) ab, in der sämtliche Event-Handler, also auch der GPIO-Interrupt-Handler, definiert sind. Sobald der GPIO-Interrupt getriggert wird, wird die Interrupt-Handler-Funktion (also GPIO_A_INT_HANDLER und GPIO_B_INT_HANDLER im GPIO-Treiber von ADI) ausgeführt. In generischen Interrupt-Handler-Funktionen sucht die CPU sämtliche GPIO-Pins nach demjenigen ab, der getriggert wurde, löscht dessen Interrupt-Status und führt die hinterlegte Callback-Funktion aus. In der hier vorliegenden ADC-MCU-Anwendung ist DRDY aber das einzige Interrupt-Signal, sodass es sich anbietet, die Funktion insgesamt zu straffen und dadurch schneller zu machen. Hierzu kann entweder das Sprungziel in der Start-up-Datei verändert oder der ursprüngliche Interrupt-Handler modifiziert werden. In der Start-up-Datei könnte also ein Verweis auf einen selbst geschriebenen Interrupt-Handler hinterlegt werden.

 Ein Nested Vectored Interrupt Controller (NVIC)
Bild 8. Ein Nested Vectored Interrupt Controller (NVIC)
© Analog Devices

Eine Modifikation erfordert allerdings einen selbst definierten GPIO-Treiber, weshalb eine Veränderung vorgenommen wird, wie sie in Bild 8 gezeigt ist. Es wird also nur der Interrupt-Status des mit DRDY verbundenen Pins gelöscht, um daraufhin direkt die Callback-Funktion aufzurufen. Zusätzlich muss unbedingt der ursprüngliche GPIO-Treiber gesperrt werden, indem das entsprechende Häkchen in »include in build target« entfernt wird

Ergebnisse im Vergleich

∆t-Werte im Basic-Modus (a), im Pingpong-Modus (b) und im Pingpong-Modus mit optimiertem Interrupt-Handler (c)
Bild 9. ∆t-Werte im Basic-Modus (a), im Pingpong-Modus (b) und im Pingpong-Modus mit optimiertem Interrupt-Handler (c).
© Analog Devices

Es sei angenommen, dass der Anwender gerade die 200 24-bit-Ausgangsdaten des ADCs ausliest. Dabei soll die SPI-Bitrate auf 13 MHz eingestellt sein. Nun wird der Pin, an dem das DRDY-Signal anliegt, und SCLK mit einem Oszilloskop verbunden. Durch Beobachten des Zeitintervalls zwischen dem DRDY-Signal und dem Beginn der SPI-Datentransaktion (bzw. der DMA-Transaktion) lassen sich die Geschwindigkeits-steigerungen ablesen, die mit den zuvor beschriebenen Methoden erzielt werden können. Aus Gründen der Einfachheit wird das Intervall zwischen dem DRDY-Signal und dem Beginn des SCLK-Signals als ∆t bezeichnet.

Bei einer SPI-Bitrate von 13 MHz werden folgende ∆t-Werte gemessen (Bild 9):
Basic-Modus – a): Δt = 3,754 μs
Pingpong-Modus – b): Δt = 2,8433 μs
Pingpong-Modus mit optimiertem Interrupt-Handler – c): Δt = 1,694 μs

Die Methoden a) und b) eignen sich für Ausgangsdatenraten (ODR) von 64 kHz, während Methode c) ein ODR von bis zu 128 kHz unterstützt. Der ∆t-Wert von Methode c) ist am kürzesten, sodass SCLK früher enden kann. Wenn das SCLK-Signal (d. h. die Datentransaktion) zurückgenommen wird, bevor die Hälfte der ADC-Ausgangsdatenperiode verstrichen ist, kann die ODR vervielfacht werden. Verglichen mit der ODR-Geschwindigkeit von 8 kHz beim ADI-SPI-Treiber stellt dies eine enorme Verbesserung dar.

MAX32660 und AD7768-1

 ODR-Resultat mit dem MAX32660 ohne DMA
Bild 10. ODR-Resultat mit dem MAX32660 ohne DMA.
© Analog Devices

Welches Ergebnis erhält man mit dem MAX32660, einem Mikrocontroller mit einer Haupttaktfrequenz von 96 MHz? Um diese Frage zu klären, wurde eine Interrupt-Datentransaktion mit optimiertem Interrupt-Handler durchgeführt. Bei dieser Interrupt-Konfiguration lässt sich ohne DMA-Funktion eine Ausgangsdatenrate von 256 kHz erreichen (Bild 10).

Zusammenfassung

Schnelle SPI-Übertragung mit ADuCM405 und MAX32660
Tabelle. Schnelle SPI-Übertragung mit ADuCM405 und MAX32660.
© Analog Devices

Mit dem gewählten ADC (AD7768-1) und den MCUs ADuCM4050 oder MAX32660 lassen sich schnelle Datentransaktionen per SPI realisieren (Tabelle 5). Um die angestrebte Geschwindigkeitsoptimierung zu erreichen, werden die Datentransaktionen wie im ADI-SPI-Treiber vorgenommen, allerdings ohne redundante Befehle. Zusätzlich entlastet das Aktivieren des DMA-Treibers den Prozessorkern und beschleunigt die kontinuierliche Datenübertragung. Mit DMA-Transaktionen im Pingpong-Modus wird Zeit für die DMA-Konfiguration gespart. Zusätzlich zu der per DMA erzielten Beschleunigung kann auch der Interrupt-Handler optimiert werden, indem der Interrupt-auslösende Pin direkt angegeben wird. Die beste Lösung kommt bei einer SPI-Bitrate von 13 MHz auf eine ADC-Ausgangsdatenrate von 128 kS/s.

 

Die Autoren

 

Denny Wang von Analog-Devices
Denny Wang von Analog-Devices.
© Analog Devices

Denny Wang

arbeitet als Applications Engineer und war eineinhalb Jahre im Rahmen des NCG-Programms bei Analog Devices Taiwan tätig. An der Universität Peking erwarb er einen Master-Abschluss im Fach Integrated Circuit Engineering. Während seines Studiums befasste er sich mit der Halbleiterverarbeitung, der Ansteuerung von BLDC- und PMSM-Motoren und der analogen Schaltplanmigration. Er kam 2021 zu ADI und ist derzeit im Bereich der Systemlösungen, der Datensicherheit und der Authenticator-Technik sowie der drahtlosen MQTT-Übertragung tätig.

Sally Tseng von Analog-Devices
Sally Tseng von Analog-Devices.
© Analog Devices

Sally Tseng

kam als Applikationsingenieur-Praktikantin zu ADI Taiwan. Sie studiert an der National Taiwan University (NTU) mit dem Schwerpunkt Elektrotechnik. Ihre Projekte an der NTU haben vorranging mit der Forschung an analogen Schaltungen zu tun. Während ihrer Zeit als Praktikantin bei ADI befasst sie sich außerdem mit Embedded-Systemen.


  1. Höherer Durchsatz für High-Speed-ADCs
  2. DMA-Transaktionen im Basic-Modus

Lesen Sie mehr zum Thema


Das könnte Sie auch interessieren

Jetzt kostenfreie Newsletter bestellen!

Weitere Artikel zu Analog Devices GmbH

Weitere Artikel zu Datenwandler (A/D, D/A)

Weitere Artikel zu Mikrocontroller