2048 Pixel RGB-LED-Matrix: TIVA uDMA

Durch intensiven Einsatz des DMAs, sind die Wiederholraten erst möglich geworden.

Da sich jeder DMA von µC zu µC erheblich unterscheiden kann, möchte ich den vom Tiva hier etwas näher erläutern.

Einer der Vorteile des uDMAs sind die verschiedenen Modis die möglich sind. Darunter der Ping-Pong Modus, dabei werden zwei DMA Kanäle (Primärer und Alternativer) so verschalten, dass diese sich abwechseln. Dadurch gibt es keine Verzögerung, wenn ein Kanel fertig ist und ein Interrupt ausgelöst wurde. Der andere Kanal führt die Aufgabe weiter und der Interrupt kann in Ruhe den gerade fertig gewordenen Kanal reinitialisieren.

Der Scatter-Gather Modus ist Interessant, wenn Daten von verschiedenen Quellen zusammengeführt werden soll. Dazu wird vorher eine bis zu 256 große Aufgabenliste definiert. Die einzelnen Aufgaben werden vom Primär-Kanal abgearbeitet, ist ein Auftrag fertig, lädt der Alternative-DMA-Kanal die neue Aufgabenliste und startet damit erneut den Primären-Kanal. So entsteht zwar eine kurze Verzögerung zwischen den Aufgabenwechseln, aber es wird Prozessorzeit gespart, da weniger Interrupts ausgelöst werden.

Was für die Ausgabe der Matrix-Daten interessant ist, ist der Ping-Pong Mode. Um das Bild einmal komplett auf eine oder zwei Panels anzuzeigen, müssen bis zu 65536 Elemente (1 Byte oder 2 Byte) verschoben werden. Da sich der DMA jedoch den Buszugriff mit der CPU teilen muss oder natürlich anderen DMA Transaktionen, ist nicht immer Zeit um den Buffer für die Bildausgabe zu füllen.

Für die Parallelschnittstelle die zum Ausgeben der Bilddaten verwendet wird, gibt es einen Warteschlange (FIFO) von 4 Plätzen. Beim initialisieren wird angegeben, ab welchem Füllstand ein neuer DMA-Transfer getriggert wird, um die frei gewordenen Plätze wieder zu füllen. Es zeigte sich, dass es besonders effektiv ist, wenn ab halbem FIFO-Füllstand eine Transaktion des DMAs angefordert wird. Der DMA transferiert mit einem Rutsch direkt zwei neue Daten für den FIFO, ohne das die CPU dazwischen den Bus arbitrieren darf (Burst-Transfer). Außerdem erhält das Paar EPI-DMA-Kanäle Vorrang, vor dem SPI-DMA.  (EPI = Parallel-Interface)

Bei einer Clockrate von ca. 17 MHz ergeben sich, bei der parallelen Datenausgabe, keine Lücken mehr. So kann die recht große Refreshrate von 270 Hz erreicht werden. Die einzige Lücken die entsteht, ist zwischen den DMA-Kanalwechsel beim Ping-Pong Modus. Aber halt, hatte ich nicht oben erzählt, dass dieser Wechsel ohne Verzögerung passiert?

Kommen wir nun zu den Schwachstellen des Tiva DMAs. Ein DMA-Auftrag kann leider nur 1024 Transfers verarbeiten und muss dann neugestartet werden. Da das ganze Bild direkt linear im Speicher liegt, wäre es kein Problem das komplette Bild mit einem Auftrag auszugeben. Leider gibt es, wie schon erwähnt, auch noch Hürden für den Ping-Pong-Modus im EPI-Betrieb. Unüblicherweise gibt es einen weiteren Zähler, der die DMA Transaktionen mitzählt. Dieser muss in jedem EPI-DMA-Interrupt resetet werden, bevor zwischen „Ping und Pong“ gewechselt wird. Wird der Interrupt ausgelöst vergehen mindestens 12 CPU-Cycles anschließend ist der zusätzliche Zähler nicht in jedem Fall bereit und so muss mit einem Workaround gekämpft werden, um die Lücke zwischen den DMA-Aufträgen möglichst klein zu halten.

Die Bildausgabe auf der Matrix ist nur DMA und Interrupt gesteuert. Einmal gestartet läuft das System völlig autark. Einzig der Zeiger auf das aktuelle Bild, wird an anderer Stelle getauscht (Double-Buffering).

Zur Veranschaulichung, ein Ablaufdiagramm des EPI-DMA-Interrupts im Ping-Pong-Modus:

EPI-DMA-Interrupt

Advertisements
Dieser Beitrag wurde unter Allgemein, LED-Matritzen abgelegt und mit , , , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

4 Antworten zu 2048 Pixel RGB-LED-Matrix: TIVA uDMA

  1. Jens Kerrinnes schreibt:

    Hi,
    ich kämpfe mich durch deinen Quellcode und versuche das auf die 32×32 Pixel Displays anzupassen. Die Displays arbeiten mit 1/16 Scan und haben eine Adressleitung mehr. Ich verstehe nur nicht wirklich warum das Display erst ab Bit 2 an den Adressleitungen hängt und wieso die Adresse so berechnet wird.
    Vielleicht kannst du ja ein paar Tips geben wie man den Code ändern müsste.

    Jens

    • Hallo Jens,

      bei mir ist das Projekt schon ein wenig her.
      Soweit mir in Erinnerung, ist das mit der Adressleitung nur „historisch gewachsen“. Also könnte man es auch anders Verbinden + Adresszähler anpassen.
      Für den 16-fach Scan musst du dir den Unterschieden zu meinem Quellcode bewusst werden:
      – eine Adressleitung mehr
      – zwei mal R-G-B Leitungen weniger
      – die Daten müssen beim Eintreffen schon anders in den Buffer angeordnet werden!
      – die Refreshrate wird um die Hälfte reduziert, weil weniger Daten parallel in die Anzeige geschoben werden können (wird sich von allein einstellen)
      – die Schleife zum Einspielen der EPI-Daten muss angepasst werden

      Ich denke mit einem Zettel und nem Stift kommst du erst mal weiter als mit dem Quellcode.
      Wichtig zu wissen ist, dass immer erst eine komplette Zeile (komplette Helligkeit) geschrieben wird. Bevor die nächste gesetzt wird (bei mir 8, bei dir 16)

      Viel Erfolg noch,

      der Basti

      • Jens Kerrinnes schreibt:

        Wollte nur mal eine Rückmeldung geben, hab es zum laufen bekommen. Die Änderungen sind im wesentlichen die Vergrößerung des ausgabe Arrays von 256 auf 512 Elemente, Anpassung von make_pwm von 8 auf 16 Doppel-Zeilen, adressvariable um 1 Bit nach rechts geschoben und ändern des dma_counters von 16 auf 32 bit mit rücksetzen bei 128k-Elementen. Rausgefallen ist der zweite Ausgabepuffer, weil der RAM sonst voll ist.
        Neu hinzugekommen ist bisher schon mal eine Setpixel-Funktion, die nur die Elemente neu beschreibt die auch nötig sind und ein clearscreen. Unterm Strich bin ich dabei die Borgware 2D von das-labor.org zu portieren, so dass das Panel autark Animationen anzeigt und man diverse Spiele spielen kann (Tetris/Snake/Spaceinvaders/Breakout).

        Jens

      • Hallo Jens,

        Jetzt fällt es mir auch wieder ein, warum ich das 16er Scan nicht umgesetzt habe. Das double-buffering fällt da leider weg, da der SRAM nicht ausreichend ist.
        Ich hoffe du bekommst noch ein sauberes Bild, wenn alle deine Zeichenroutinen auf dem aktuell gelesenen Bild angewendet werden. Kannst ja deine Erfahrungen später noch mal posten.

        Aber es klingt richtig gut, was du da vor hast! Vielleicht könntest du den Quellcode in Ursprungsform irgendwie Anbieten?! Hast du evtl. einen Link zu einem Blog von dir? Falls jemand noch das Gleiche vor hat…

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s