Hardware-Encoder für NeoPixel (WS2812)/Hardware: Unterschied zwischen den Versionen
Fki (Diskussion | Beiträge) (Den Weg der Daten eingefügt.) |
KKeine Bearbeitungszusammenfassung |
||
(3 dazwischenliegende Versionen von einem anderen Benutzer werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
[[ | [[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]] | ||
Unser Grobkonzept steht, jetzt geht es in die Details. Dazu machen wir uns zuerst Gedanken darüber, wie unser Encoder-System grundsätzlich arbeiten soll. Daraus ergeben sich erste Funktionsblöcke, die zur Gesamtschaltung verbunden werden. Bei Bedarf werden diese Blöcke noch weiter unterteilt, bis wir auf einem Level angekommen sind, daß wir gut beschreiben und '''testen''' können. | Unser Grobkonzept steht, jetzt geht es in die Details. Dazu machen wir uns zuerst Gedanken darüber, wie unser Encoder-System grundsätzlich arbeiten soll. Daraus ergeben sich erste Funktionsblöcke, die zur Gesamtschaltung verbunden werden. Bei Bedarf werden diese Blöcke noch weiter unterteilt, bis wir auf einem Level angekommen sind, daß wir gut beschreiben und '''testen''' können. | ||
== Der Weg der Daten == | == Der Weg der Daten == | ||
[[Datei:WS_Encoder_grob.png|right|thumb]] | |||
Beginnen wir bei den Eingabedaten und verfolgen ihre Verarbeitung. Im einfachsten Fall werden wir ein RGB-Farbtripel an den Encoder schicken, daß in das WS-Protokoll überführt und ausgegeben wird. Egal, welche unserer seriellen Schnittstellen wir benutzen, das übertragene Datum steht nach dem erfolgreichen Empfang in einem Register und kann parallel weiter verarbeitet werden. Unsere ersten Funktionsblöcke werden also einmal ein '''UART-Modul''' und ein '''SPI-Modul'''. | Beginnen wir bei den Eingabedaten und verfolgen ihre Verarbeitung. Im einfachsten Fall werden wir ein RGB-Farbtripel an den Encoder schicken, daß in das WS-Protokoll überführt und ausgegeben wird. Egal, welche unserer seriellen Schnittstellen wir benutzen, das übertragene Datum steht nach dem erfolgreichen Empfang in einem Register und kann parallel weiter verarbeitet werden. Unsere ersten Funktionsblöcke werden also einmal ein '''UART-Modul''' und ein '''SPI-Modul'''. | ||
Zeile 9: | Zeile 10: | ||
Aus diesem Video-RAM holt sich der eigentliche '''WS2812-Encoder''' die Daten, wandelt sie und gibt sie aus. | Aus diesem Video-RAM holt sich der eigentliche '''WS2812-Encoder''' die Daten, wandelt sie und gibt sie aus. | ||
== Das Konfigurations-Interface == | |||
Dinge ändern sich. Zum Beispiel die Timings von einer Version des WS2812 zur anderen. Oder dein FPGA-Board wird mit einem anderen Takt betrieben als meins. Lange Rede, kurzer Sinn: Wir wollen bestimmte Parameter einstellen können. Und dazu brauchen wir neben der reinen Datenverarbeitung ein Konfigurationsinterface. | |||
Das Konfigurationsinterface besteht aus Registern, der Hardware-Entsprechung zu Variablen in der Programmierung. Hier können wir Parameter hinterlegen, die die Datenverarbeitung steuern, z.B. die Anzahl der LEDs auf einem angeschlossenen Streifen oder die Dauer des Reset-Signals. In meinem aktuellen Entwurf habe ich 12 solcher Register vorgesehen. Es lohnt sich also, darüber nachzudenken, wie man den Zugriff auf diese Register regeln kann, ohne daß die Modulschnittstelle überfrachtet wird. | |||
Ein weiteres Thema ist Wiederverwendbarkeit. Dir passen die seriellen Schnittstellen nicht, du willst lieber ein paralleles Interface? Je nachdem, wie die Schnittstelle des Encoder-Moduls aussieht kann das simpel sein oder zu einem Schreikrampf führen. Ziel ist also eine möglichst einheitliche, übersichtliche Modulschnittstelle. Das führt uns zu Bussen. | |||
== Wir nehmen den Bus == | |||
Ein Bus besteht aus Daten-, Adress-, und Steuerleitungen. Die Adresse legt fest, auf welches Register wir zugreifen wollen, die Daten sind die Daten, die wir schreiben oder lesen wollen und die Steuerleitungen sind dafür da, die Abläufe zu koordinieren. | |||
Es gibt eine ganze Menge verschiedenster Busse, parallele, serielle, schnelle für kurze Distanzen, langsamere für groß, whatever. Für uns interessant sind vor allem Busse, die sich dazu eignen, Systeme aus Modulen auf einem FPGA zusammenzuschalten. Da gibt es selbstverständlich auch mehrere, AXI oder AMBA zum Beispiel. Ich favorisiere in diesem Zusammenhang den [http://opencores.org/opencores,wishbone "Wishbone-Bus"], eine offene Busspezifikation, frei verwendbar und sehr leistungsfähig und flexibel. | |||
== Infrastrukturmaßnahmen == | |||
[[Datei:WS_Encoder_WB.png|right|thumb]] | |||
Strukturieren wir das Projekt also nach unseren neuesten Erkenntnissen um: | |||
* Das WS2812-Encodermodul bekommt ein Wishbone-Slave-Interface. | |||
* Das Modul umfaßt die Buslogik, den VRAM und den eigentlichen Encoder | |||
Um die Daten von den seriellen Schnittstellen in den Encoder zu bekommen, müssen diese über ein Wishbone-Master-Interface verfügen. Hier könnten wir jetzt jeder Schnittstelle ein solches Interface verpassen oder ein kleines Hilfsmodul bauen, daß Daten von den Schnittstellen abholt und über den Wishbone-Bus an das WS2812-Modul überträgt. Diese Lösung hat darüber hinaus den Vorteil, daß es nur einen Master gibt. Gäbe es mehrere, müssten diese untereinander aushandeln, wer gerade übertragen darf. Diese zusätzliche Komplexität würde ich mir gerne schenken. | |||
Das Abholen der Daten von den externen Schnittstellen kann natürlich auch wieder per Wishbone erfolgen. Ein weiterer Vorteil dabei ist, daß man einfach Schnittstellen austauschen oder hinzufügen kann, in dem man sie an den Bus koppelt. | |||
Erweitern wir unsere Liste von oben also noch ein wenig: | |||
* Wir bauen einen kleinen Steuercontroller, der das Wishbone-Master-Interface steuert | |||
* Die seriellen Schnittstellen erhalten, wie das WS-Modul, ein Wishbone-Slave-Interface. | |||
== Die Komponenten im Detail == | |||
Da die Besprechung der einzelnen Blöcke umfangreich wird, habe ich entsprechende Unterseiten eingerichtet: | |||
* Zum [[/Wishbone|Wishbone-Bus ->]] | |||
* Zum [[/SPI|SPI-Modul ->]] | |||
* Zum [[/UART|UART-Modul ->]] | |||
* Zum [[/WS_Encoder|WS2812-Encoder ->]] | |||
[[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]] | |||
[[Kategorie:Projekt]] |
Aktuelle Version vom 22. April 2023, 13:31 Uhr
Unser Grobkonzept steht, jetzt geht es in die Details. Dazu machen wir uns zuerst Gedanken darüber, wie unser Encoder-System grundsätzlich arbeiten soll. Daraus ergeben sich erste Funktionsblöcke, die zur Gesamtschaltung verbunden werden. Bei Bedarf werden diese Blöcke noch weiter unterteilt, bis wir auf einem Level angekommen sind, daß wir gut beschreiben und testen können.
Der Weg der Daten
Beginnen wir bei den Eingabedaten und verfolgen ihre Verarbeitung. Im einfachsten Fall werden wir ein RGB-Farbtripel an den Encoder schicken, daß in das WS-Protokoll überführt und ausgegeben wird. Egal, welche unserer seriellen Schnittstellen wir benutzen, das übertragene Datum steht nach dem erfolgreichen Empfang in einem Register und kann parallel weiter verarbeitet werden. Unsere ersten Funktionsblöcke werden also einmal ein UART-Modul und ein SPI-Modul.
Damit die Datenübertragung zum Encoder die Ausgabe an die LEDs nicht beeinflusst, brauchen wir einen Pufferspeicher zur Entkopplung, in den die empfangenen Daten geschrieben werden. Wir benötigen also ein Modul, daß RAM implementiert und ansteuert, also einen VRAM-Controller.
Aus diesem Video-RAM holt sich der eigentliche WS2812-Encoder die Daten, wandelt sie und gibt sie aus.
Das Konfigurations-Interface
Dinge ändern sich. Zum Beispiel die Timings von einer Version des WS2812 zur anderen. Oder dein FPGA-Board wird mit einem anderen Takt betrieben als meins. Lange Rede, kurzer Sinn: Wir wollen bestimmte Parameter einstellen können. Und dazu brauchen wir neben der reinen Datenverarbeitung ein Konfigurationsinterface.
Das Konfigurationsinterface besteht aus Registern, der Hardware-Entsprechung zu Variablen in der Programmierung. Hier können wir Parameter hinterlegen, die die Datenverarbeitung steuern, z.B. die Anzahl der LEDs auf einem angeschlossenen Streifen oder die Dauer des Reset-Signals. In meinem aktuellen Entwurf habe ich 12 solcher Register vorgesehen. Es lohnt sich also, darüber nachzudenken, wie man den Zugriff auf diese Register regeln kann, ohne daß die Modulschnittstelle überfrachtet wird.
Ein weiteres Thema ist Wiederverwendbarkeit. Dir passen die seriellen Schnittstellen nicht, du willst lieber ein paralleles Interface? Je nachdem, wie die Schnittstelle des Encoder-Moduls aussieht kann das simpel sein oder zu einem Schreikrampf führen. Ziel ist also eine möglichst einheitliche, übersichtliche Modulschnittstelle. Das führt uns zu Bussen.
Wir nehmen den Bus
Ein Bus besteht aus Daten-, Adress-, und Steuerleitungen. Die Adresse legt fest, auf welches Register wir zugreifen wollen, die Daten sind die Daten, die wir schreiben oder lesen wollen und die Steuerleitungen sind dafür da, die Abläufe zu koordinieren.
Es gibt eine ganze Menge verschiedenster Busse, parallele, serielle, schnelle für kurze Distanzen, langsamere für groß, whatever. Für uns interessant sind vor allem Busse, die sich dazu eignen, Systeme aus Modulen auf einem FPGA zusammenzuschalten. Da gibt es selbstverständlich auch mehrere, AXI oder AMBA zum Beispiel. Ich favorisiere in diesem Zusammenhang den "Wishbone-Bus", eine offene Busspezifikation, frei verwendbar und sehr leistungsfähig und flexibel.
Infrastrukturmaßnahmen
Strukturieren wir das Projekt also nach unseren neuesten Erkenntnissen um:
- Das WS2812-Encodermodul bekommt ein Wishbone-Slave-Interface.
- Das Modul umfaßt die Buslogik, den VRAM und den eigentlichen Encoder
Um die Daten von den seriellen Schnittstellen in den Encoder zu bekommen, müssen diese über ein Wishbone-Master-Interface verfügen. Hier könnten wir jetzt jeder Schnittstelle ein solches Interface verpassen oder ein kleines Hilfsmodul bauen, daß Daten von den Schnittstellen abholt und über den Wishbone-Bus an das WS2812-Modul überträgt. Diese Lösung hat darüber hinaus den Vorteil, daß es nur einen Master gibt. Gäbe es mehrere, müssten diese untereinander aushandeln, wer gerade übertragen darf. Diese zusätzliche Komplexität würde ich mir gerne schenken.
Das Abholen der Daten von den externen Schnittstellen kann natürlich auch wieder per Wishbone erfolgen. Ein weiterer Vorteil dabei ist, daß man einfach Schnittstellen austauschen oder hinzufügen kann, in dem man sie an den Bus koppelt.
Erweitern wir unsere Liste von oben also noch ein wenig:
- Wir bauen einen kleinen Steuercontroller, der das Wishbone-Master-Interface steuert
- Die seriellen Schnittstellen erhalten, wie das WS-Modul, ein Wishbone-Slave-Interface.
Die Komponenten im Detail
Da die Besprechung der einzelnen Blöcke umfangreich wird, habe ich entsprechende Unterseiten eingerichtet:
- Zum Wishbone-Bus ->
- Zum SPI-Modul ->
- Zum UART-Modul ->
- Zum WS2812-Encoder ->