Der Raspberry Pi RP2040 ist eine MCU für etwa 1 Euro mit erstaunlichen Fähigkeiten. Einer seiner Ingenieure ist Luke Wren, der nicht nur am Raspberry Pi RP2040 gearbeitet hat, sondern auch gezeigt hat, dass der kleine RP2040 DVI-Ausgabe beherrscht, wie dies der Artikel „Videoausgabe mit Mikrocontrollern (2)" zeigt. Wenn er nicht gerade an geheimen Projekten für Raspberry Pi arbeitet, teilt er einige seiner Freizeitprojekte mit der Community auf Twitter (@wren6991) und den Code auf GitHub.

Mathias Claussen: Kannst du uns ein wenig über dich erzählen?

Luke Wren: Fangen wir mit der schwierigsten Frage an! Ich bin Ingenieur bei Raspberry Pi, und wenn ich das nicht tue, arbeite ich normalerweise an meinen Hobbyprojekten, spiele schlecht Gitarre, oder, seit kurzem, lerne ich Sprachen. Ich lebe in Cambridge, Großbritannien, nicht weil es eine besonders aufregende Stadt ist, sondern eher aus Trägheit nach dem Abschluss meines Studiums. Ich habe in Deutschland gelebt, als ich jünger war, aber mein Deutsch ist inzwischen ziemlich eingerostet, deshalb bin ich froh, dass wir das hier auf Englisch machen.

Mathias: Wie lange arbeitest du schon mit dem Raspberry Pi?

Luke: Ich bin im September 2018 als Mitarbeiter eingestiegen, habe aber vorher schon ein Praktikum bei Raspberry Pi gemacht.

Mathias: Was war deine Rolle bei der Entwicklung des RP2040?

Luke:
Ich habe an einem Teil des digitalen Designs gearbeitet — hauptsächlich PIO, DMA, XIP-Cache, Bus-Strukturen und PWM. Außerdem habe ich am Boot-ROM und am SDK gearbeitet, und natürlich musste ich auch bei der Dokumentation mit anpacken.

Mathias: Video von einer MCU/CPU zu bekommen ist etwas, was der Sinclair ZX81 konnte, aber DVI ist etwas Neues für eine MCU für einen Euro. Die VGA-Ausgabe wird von den meisten MCUs problemlos erledigt, aber was ist die Herausforderung bei DVI?

Luke: Es gibt zwei Dinge, die DVI-D schwieriger machen als VGA. Der erste ist die Serialisierung der Daten: Der minimale Pixeltakt für DVI-D beträgt 25 MHz, und der Bittakt ist zehnmal so hoch, so dass man mindestens drei differenzielle serielle Leitungen (rot/grün/blau) mit 250 Mbps ansteuern muss. Zweitens sendet DVI-D nicht einfach nur rohe Pixeldaten, sondern kodiert sie zunächst. Die Kodierung ist in der Hardware einfach, aber in der Software etwas fummelig. Vor allem, wenn die Software mit der Rohgeschwindigkeit der seriellen Ausgabe mithalten muss. Alles andere ist ähnlich. Es ist wirklich nur DPI durch eine schnellere Leitung. (Anmerkung der Redaktion: Display Pixel Interface (DPI) ist eine parallele RGB-Pixelschnittstelle - einschließlich eines Pixeltakts - zur Übertragung von Pixeldaten an ein Display). 

Mathias: Was war deine Motivation, DVI am RP2040 auszuprobieren?

Luke: Nachdem der Stress der Fertigstellung des Siliziumchips vorbei war, wollten einige von uns sehen, wie hoch wir die Systemtaktfrequenz treiben könnten. In der Praxis gibt es einen gewissen Spielraum gegenüber der Nennfrequenz von 133 MHz. Ich hatte im Rahmen meines RISCBoy project mit DVI-D auf einem FPGA gespielt, und als ich bemerkte, dass es eine Überschneidung zwischen den niedrigsten DVI-Bit-Taktfrequenzen und den höchsten Systemtaktfrequenzen auf dem RP2040 gab, ging ein Licht in meinem Kopf an. Die Motivation war: „Ich frage mich, ob das möglich ist.“

Mathias: Was war die größte Herausforderung, um einen DVI-Ausgang (Bild 1) auf dem RP2040 zu realisieren?

Luke: Die TMDS-Kodierung. Wenn man den Algorithmus in der DVI-Spezifikation befolgt, gibt es keine Chance, ihn auf zwei Cortex-M0+-Kernen, die mit der Bittaktfrequenz laufen, schnell genug zu bekommen. Aber es gibt einige Tricks und Abkürzungen, um es doch möglich zu machen, und dann etwas sorgfältig handgeschriebenen Code, um es brauchbar schnell zu machen. Der RP2040 hat zwar viel RAM, aber nicht genug, um die Pixel eines TMDS-kodierten Bildes zu speichern, so dass man während der Kodierung ein „Wettlauf gegen den Elektronenstrahl“ (Anmerkung: Im Original „Racing the Beam“ ist auch ein Videospiel) veranstalten muss.

Bild 1. Raspberry Pi Pico mit dem Pico-DVI-Sock (Quelle: Luke Wren).

Mathias: Du musstest den RP2040 leicht übertakten (von normalerweise 133 MHz auf 252 MHz). Gibt es einen kritischen Signalpfad im Chip für die DVI-Signale (man muss die I/O-Pins mit Geschwindigkeiten ansteuern, die auch schneller sind als die Standardgeschwindigkeit)?

Luke: Die erste Einschränkung, auf die man beim RP2040 stößt, ist, dass der Systemtakt 1:1 mit dem Bittakt übereinstimmen muss. Wenn man also versucht, zu Modi mit höherer Auflösung zu wechseln, stürzen die Prozessoren einfach ab. Der kritische Setup-Pfad für den Bereich des Systemtakts des RP2040 sind die Adressphasen-Signale des Prozessors zu den SRAMs. Davon abgesehen sind wir auch ziemlich nah an den Grenzen dessen, was man über diese gewöhnlichen 3V3-Pads treiben kann; wenn man sich das Augendiagramm (Bild 2) für 720p30 (372 Mbps) auf meinem GitHub ansieht. Es funktioniert, aber nur gerade so. Ich bezweifle, dass man 1080p30 ohne spezielle Hardware sehen würde.

Bild 2. Augendiagramm für RP2040-DVI bei 720p30 (Quelle: Luke Wren).

Mathias: Abgesehen von der Geschwindigkeitssteigerung, wie wichtig sind die PIOs und der Interpolator im RP2040, um DVI zum Laufen zu bringen?

Luke: Es ist eine feste Anforderung, drei serielle Datenbits plus ihre differenziellen Komplemente auf GPIOs mit mindestens 250 Mbps darstellen zu müssen. Um eine Konvertierung von Single-Ended zu Pseudo-Differential in der PIO durchzuführen, halbiert sich die DMA-Bandbreite, und die Aufteilung der TMDS-Verbindungen in drei FIFOs ist nützlich, wenn man die Kodierung in der Software durchführt, da man so seinen Code für die Kodierung der Rot/Grün/Blau-Komponenten spezialisieren kann. So etwas wie PIO ist entscheidend, wenn man keine dedizierte Hardware hat. Die Interpolatoren helfen, die nötige Leistung der Adressgenerierung für TMDS-Kodierung bereitzustellen, was sicherlich der Schlüssel zu einigen der Demos ist, die du gesehen hast, aber mein Trick mit der verdoppelten TMDS-Kodierung würde auch ohne die Interpolatoren auf einen einzelnen Cortex-M0+ Kern passen.

Mathias: Dein Pico DVI Sock für den RP2040 verwendet eine physische HDMI-Verbindung (Bild 3), die eindeutig als DVI-only gekennzeichnet ist, so dass wir keinen Audio erhalten. Ist das „nur“ ein Lizenzproblem mit dem HDMI-Konsortium?

Luke: Es gibt nichts, was einen daran hindert, HDMI-Dateninseln hinzuzufügen und eine Audioausgabe zu realisieren. Tatsächlich hat das schon jemand mit einem NES-Emulator-Port gemacht! Für die Audiosignale sind keine zusätzlichen physischen Verbindungen erforderlich, obwohl man streng genommen keine HDMI-Funktionen verwenden darf, bevor man den Display-Datenkanal abgefragt hat, der bei meiner Pico DVI Sock nicht angeschlossen ist. Die HDMI-Lizenzierung ist sicherlich ein kompliziertes Problem, das ich nicht angehen möchte. Deshalb habe ich das Repository auch nur „PicoDVI“ genannt, den Rest überlasse ich der Community.

Bild 3. Pico-DVI-Sock für den Raspberry Pi Pico (Quelle: Luke Wren).

Mathias: Wenn man den DVI-Ausgang verwendet, wie viele Ressourcen des RP2040 sind dann an diese Aufgabe gebunden? Bleibt da überhaupt noch Zeit, um anderen Code auf der MCU auszuführen?

Luke:
as kommt auf den Videomodus an. Bei der pixelverdoppelten RGB565-Ausgabe verbraucht man etwa 65 % der Kapazität eines Kerns für die TMDS-Kodierung und DMA-Interrupts, und der andere Kern steht dann vollständig für die Erzeugung des Videos und die Ausführung des Hauptprogramms zur Verfügung.

Anmerkung der Redaktion: Neben der reinen Videogenerierung wurden einige Anwendungen für den Pico DVI Sock hinzugefügt. Eine davon ist das Bewegen mehrerer Portraits von Eben Upton auf dem Bildschirm. Ein 640×480-Pixel-Bild, das als Vollbild mit 8-Bit-Auflösung gespeichert wird, würde etwa 308 KB RAM benötigen (mehr als der RP2040 hat), also beschränken wir es auf ein Maximum von 320×240 mit 16-Bit-Farbe (154 KB) im RAM. Die Demo (Bild 4) ist nicht so pixelig, so dass ein Software-Trick im Spiel zu sein scheint.

Bild 4. Hochauflösende Bilder mit einigen Tricks (Quelle: Luke Wren).

Mathias: Mit der Software zur Erzeugung eines DVI-Signals wird eine Bibliothek geliefert, die auch Sprites verarbeitet. Kannst du mehr darüber erzählen?

Luke: Klar! Wenn man eine solche Videoausgabe schreibt, ist das nächste Problem, auf das man stößt, dass man ein Video braucht, das man tatsächlich ausgeben kann. Die ARMv6-M-Sprite-Bibliothek ist etwas, das ich während der Arbeit an PicoDVI für genau diesen Zweck zusammengeschustert habe. Das entscheidende Merkmal dieser Bibliothek ist, dass sie keinen Frame-Buffer zum Rendern benötigt, sondern nur einen Scanline-Buffer. Das Rendering erfolgt direkt vor der TMDS-Kodierung. Das bedeutet, dass Videoauflösungen unterstützt werden können, die mit einem einfachen Frame-Buffer nicht in den Speicher passen würden, und dass der meiste Speicherplatz für die eigentlichen Grafikkomponenten frei bleibt. Es gibt einige recht schnelle Blit- und Fill-Routinen, einige Tiling-Routinen und einige affin transformierte Sprite-Routinen, mit denen man skalierte/gedrehte/geschnittene Sprites erstellen kann, genug für Spiele auf dem Niveau eines Game Boy Advance oder so. (Anmerkung der Redaktion: Ein Beispiel ist in Bild 5 zu sehen).

Bild 5. Sprite-Demo für den Raspberry Pi RP2040.

Mathias: Woher hattest du die Inspiration für die Bibliothek - und die Zeit, sie zu schreiben?

Luke: Ich habe einige Zeit an scanline-basierter Grafikhardware für RISCBoy gearbeitet, und da ich das in Hardware gemacht habe, war es ziemlich einfach, es in Software nachzubilden. Alles im PicoDVI-Repository habe ich in meiner Freizeit auf meinem Laptop gemacht, mit Ausnahme der Augendiagramme, für die ich ein Oszilloskop auf der Arbeit benutzt habe.

Mathias: Es gibt eine vom Videospiel Zelda inspirierte Sprite-Demo für das RP2040 (Bild 6). Kannst du uns etwas über die Idee dahinter erzählen? Bei einem NES oder SNES würde man spezielle Hardware verwenden, um solche Bilder zu komponieren, aber hier haben wir nur zwei CPUs, die die Pixel bewegen.

Luke:
Es ist eigentlich eine Portierung einer der RISCBoy-Demos. Wie du richtig sagst, gibt es eine Menge Overhead, wenn man das alles in Software macht, und der RISCBoy, der mit 36 MHz läuft, kann genauso viele Sprites auf den Bildschirm bringen wie der RP2040 mit 252 MHz.

Bild 6. Walker-Demo mit DVI-Ausgang.

Mathias: In den Dokumenten für die erwähnte Bibliothek gibt es die Idee eines Mario-Kart-Klons für den RP2040. War das nur eine Idee, oder hat man schon damit begonnen, daran zu basteln? Es wird auch erwähnt, dass der Interpolator dafür nützlich sein könnte.

Luke: An dieser Stelle muss ich gestehen, dass der ursprüngliche Grund für den Interpolator im Chip der Wunsch war, Textur- und Kachelmapping im Stil von Mode 7 der SNES zu erzeugen, obwohl wir zwischenzeitlich einige Zeit damit verbracht haben, ihn zu einem allgemein nützlichen und fähigen Stück Hardware zu machen. Wir haben nie einen echten MK-Klon gebaut, obwohl man im Internet viele Beispiele von Leuten sehen kann, die ähnliche Techniken verwenden. Wir hatten einen 3D-Würfel mit Textur-Mapping und Ebens Gesicht darauf, der auf einem FPGA lief.

Mathias: In der Dokumentation zu eurem Pico DVI Sock für den RP2040 Pico erwähnt ihr den Prototyp eines 48-MHz-FPGAs. Kannst du uns etwas über diesen Prototyp erzählen?

Luke: Wir hatten einen nachts laufenden Task, um ein FPGA-Image aus dem neuesten RP2040-Quellcode zu erstellen, damit wir es am nächsten Tag für die Softwareentwicklung verwenden konnten. Wir haben einfach ein handelsübliches Virtex-7-Entwicklungsboard verwendet, mit einer Tochterplatine für die Pegelwandlung der FPGA-IOs auf 3,3 V (Bild 7) und einer weiteren kleinen Platine, die einen QSPI-Flash in die SD-Fassung steckt, der mit der XIP-Schnittstelle des RP2040 verbunden ist. Der FPGA-Aufbau ist so ziemlich ein vollwertiger RP2040 — die Takt-/Reset-Schaltung ist vereinfacht, und der ADC wurde weggelassen, aber ansonsten ist alles vorhanden und korrekt. Das macht ihn zu einer idealen Plattform für die Softwareentwicklung, auch wenn die eigentliche Verifizierung des Chips mit konventionellen Simulationen und formaler Modellüberprüfung erfolgte.

Bild 7. Prototyp Raspberry Pi RP2040-FPGA (Quelle: Luke Wren).

Mathias: Neben dem DVI-Ausgang arbeitest du noch an einigen anderen Projekten. Eines davon ist die PicoStation 3D. Kannst du uns ein wenig darüber erzählen? Wenn du alle Teile beschaffen könntest, wäre es dann heute noch dasselbe Design?

Luke: Also, die PicoStation 3D (Bild 8) ist eine der vielen Hobby-Platinen, für die ich vor der Markteinführung des RP2040 noch Luft hatte. Es ist ein Board mit einem RP2040, einer iCE40UP5K-FPGA, microSD, Audioausgang, DVI-D-Ausgang über HDMI-Buchse und zwei SNES-Controller-Fassungen. Ich habe damals viel über 3D-Grafikhardware gelesen und wollte eine Plattform, um damit zu spielen, und zwar im Rahmen einer kleinen Spielkonsole. Es schmerzt mich, dass ich dieses Projekt so lange auf Eis legen musste, aber abgesehen von den Problemen mit den Bauteilen habe ich auch einfach zu viele andere Projekte am Laufen. Es ist alles Open-Source, also würde ich mich freuen, wenn jemand anderes die Idee aufgreift und sie weiterführt. Ich denke, die Wahl des FPGAs ist genau richtig - er ist klein und langsam genug, damit man für seine Demos hart arbeiten muss, gerade noch DVI-D-fähig, und er hat einen großzügigen Onboard-Speicher und eine Handvoll 16-Bit-DSP-Einheiten, so dass er eine brillante Plattform zum Spielen mit Spielzeug-Grafikhardware darstellt. Außerdem lässt er sich gut mit dem RP2040 kombinieren. Worüber ich gerne noch nachdenken würde, ist das IO. Wie wäre es zum Beispiel, wenn man den DVI-Anschluss zum Mikrocontroller und die SNES-Controller zum FPGA verlagern würde, und wie wäre es, wenn man die Audio-Schaltung noch ein bisschen besser gestalten würde, solche Dinge. Ich denke, der physikalische Formfaktor ist genau richtig, da er durch die beiden SNES-Controller-Anschlüsse definiert ist.

Bild 8. PicoStation3D-Prototyp (Quelle: Luke Wren).

Mathias: Neben den Raspberry-Pi-basierten Geräten hast du auch einen RISCBoy entwickelt, der von einem selbst entwickelten RISC-V-Kern und anderen Peripheriegeräten gesteuert wird, wie zum Beispiel einer Grafik-Engine (2D-Sprite-basiert?). Kannst du ein paar Worte zu dieser Entwicklung sagen?

Luke: Der RISCBoy ist mein etwas verspäteter Konkurrent des Game Boy Advance. Die vollwertige Hardware passt in einen iCE40 HX8K mit etwas externem parallelem SRAM (Bild 9). Irgendwann wird es eine physische Version geben, aber im Moment ist es immer noch ein HX8K-Entwicklungsboard mit etwas SRAM und Tasten und einem SPI-Display, das daran hängt (Bild 10). Ich habe mit der Arbeit daran ungefähr zu der Zeit begonnen, als ich die Universität verließ.

Bild 9. RISCBoy-Architektur (Quelle: Luke Wren).

Alles ist von Grund auf neu geschrieben. Das ist zwar keine gute Art des Entwickelns, aber eine großartige Art zu lernen, und es macht mehr Spaß, Fehler zu beheben, wenn es keinen einzigen Teil des Hardware/Software-Stacks gibt, dem man vertrauen kann. Es gibt einen 32-Bit-Prozessor (Hazard5), eine programmierbare 2D-Grafikhardware und die gesamte Infrastruktur, um alles miteinander zu verbinden. Die Grafikhardware erstellt die üblichen Sprites, Kacheln, affin-transformierte Sprites/Kacheln und so weiter, aber sie tut dies, indem sie vom Speicher aus Befehlslisten ausführt, die begrenzte Unterstützung für den Ablaufsteuerung und die Verzweigung zu Unterprogrammen bieten. Während jedes Bildes gibt der Prozessor die Befehlsliste für das nächste Bild aus. Es gibt zwei Scanline-Puffer in der Hardware, einen, in den gerendert wird, und einen, der zum Display gesendet wird, so dass die Kosten für Bandbreite, Latenz und Speicherplatzbedarf beim Rendern in einen Frame-Puffer vermieden werden. Im Moment ist das Projekt auf Eis gelegt, aber ich habe definitiv vor, es eines Tages zu beenden. 

Bild 10. RISCBoy-Prototyp (Quelle: Luke Wren).

(220575-02) Übersetzung: Rolf Gerstendorf
Anmerkung der Redaktion: Dies ist eine gekürzte Version eines Interviews mit Luke Wren. Lesen Sie das vollständige Interview in Elektor März & April 2023.