Einige Fablabmitglieder haben vor einiger Zeit LED-Strips mit LPD8806 Controllern bestellt und Arietta G25 Boards damit alle in etwa die gleiche Hardware haben.

Übersicht

Die LPD8806-Controller werden über den SPI-Bus angesteuert und steuern dann die LEDs die an den jeweiligen Controller angeschlossen sind. Der SPI-Bus ist ein einfacher serieller Bus mit drei Leitungen MOSI (Master out Slave in), MISO (Master in Slave out) und SCLK (Clock-Signal). Im einfachsten Fall steuert der „Master“ (in unserem Fall der ARM-Prozessor auf dem Arietta-Board) die SCLK an und sendet über den MOSI Ausgang seine Daten an den „Slave“ (in unserem Fall der erste LPD8806-Chip). Da der LPD8806 nichts zurücksendet wird der MISO-Eingang nicht benutzt und da wir nur einen Slave haben brauchen wir uns auch nicht um die Chipselect Leitungen zu kümmern.

SPI an Arietta

Da auf den Arietta-Boards Linux läuft und dieses für uns schon fertige Treiber bereitstellt kann der SPI-Port wie ein normaler serieller Port benutzt werden.

Da es auf der Arietta kein BIOS oder ähnliches gibt, das Linux mitteilen könnte was für Hardware denn nun genutzt werden soll muss man dem Kernel erst mitteilen welche Ports denn nun wie genutzt werden sollen. Dies geschieht mit einem „Device Tree“ der auflistet welche Hardware verbaut ist (also z.b. wieviel RAM zur verfügung steht) und wie der Prozessor initialisiert werden soll (zb. ob überhaupt und wieviele SPI-Ports z.B.).

Um SPI zu aktivieren muss man folgenden Block in die acme-arietta.dts einfügen und diese dann zu einem dtb (Device Tree Blob) kompilieren:

spi1: spi@f0004000 {
  status = "okay";
  cs-gpios = <&pioA 8 0>;
  //only enable one device
  device@0 {
  compatible = "spidev";
  spi-max-frequency = <12000000>;     // 12 MHz is the maximum frequency for the LPD8806
  reg = <0>;
  };
};

Dieser Block aktiviert ein SPI-Device, das mit standardmäßig 12MHz läuft (kann über ioctls geändert werden und zumindest für kurze LED-Ketten funktionieren auch bis zu 20MHz) und einen Chipselect an Pin 25 hat. Der Chipselect-Pin wird nicht verwendet, da nur eine LED-Kette angeschlossen ist, aber er muss wohl definiert sein, wenn ich das richtig verstanden habe. Einen fertig gebaute dtb kann man sich auch einfach unter https://code.nerd2nerd.org/n2n/arietta/tree/master/boot/spi_256mb holen. Eine individueller dtb kann unter http://dts.acmesystems.it/arietta erstellt und auch heruntergeladen werden

Mit dieser dtb auf der Bootpartition sollte nun ein '/dev/spidev32766.0' auftauchen.

Verkablung

Die Verkablung ist recht einfach zu machen dabei ist aber sicherzustellen, dass Arietta-GND und LEDstreifen-GND verbunden sind da sich der SPI-Bus auf GND bezieht.

Achtung: Schwarz = +5V (bei unseren LED-Streifen)

Zum Betreiben der LEDs ist ein recht starkes Netzteil erforderlich, da die LEDs bis zu 10W/m verbrauchen können. Bei langen Ketten sollte die Spannung an mehreren Punkten eingespeist werden, z.B. nach jedem zweiten Streifen. Es ist auch möglich das Arietta-Board vom gleichen Netzteil zu betreiben.

SPI-Protokoll

Die beste Beschreibung des Protokolls die ich bisher gefunden habe ist diese: https://github.com/adafruit/LPD8806/blob/master/LPD8806.cpp

Um die LEDs anzusprechen sendet man einen Stream aus GRB(!)-codierten Farbwerten über den SPI-Bus, wobei ein Farbwert ein Byte mit gesetztem MSB ist, d.h. ein Farbwert kann 128 Werte annehmen. Ein LPD8806, der zwei RGB-LEDs anspricht, zeigt die beiden ersten GRB-Werte an, die er empfängt, und sendet alle nachfolgenden Bytes an den nächsten LPD8806 usw. Somit wird der erste GRB-Wert von der ersten LED der Kette angezeigt, deren LPD8806 am nächsten zum Arietta-Board ist. Die Anzeige eines Farbwertes erfolgt sobald das nächste Byte empfangen worden ist. Um ein neues Paket beginnen zu können muss ein Null-Byte an die LPD8806 gesendet werden. Allerdings wird ein Null-Byte nach 32 LEDs nicht mehr weitergereicht, weshalb für die nächsten 32 LEDs ein zusätzliches Null-Byte gesendet werden muss usw. Deshalb lässt sich die Kette schnell und korrekt ansteuern, indem zur Initialisierung der LED-Kette eine entsprechende Anzahl an Null-Bytes gesendet wird. Anschließend werden direkt nach jedem gesendeten Paket aus Farbwerten wieder die Null-Bytes übertragen.

Es lässt sich einfach testen, ob die LED-Streifen vom Arietta-Board ansprechbar sind, da der SPI-Treiber ein Device bereitstellt:

cat /dev/urandom  | tr -dC '\d0-\d255' > /dev/spidev32766.0

Nun kann man mit fopen die Device-Datei öffnen und mit fwrite schreiben, da der Chipselect-Pin sowieso nicht verwendet wird.

Hier gibt es eine in C geschriebene Bibiliothek: https://code.nerd2nerd.org/n2n/lpd8806-ledstrip/tree/master

todo:libraries usw…