Posts mit dem Label DE0-Nano werden angezeigt. Alle Posts anzeigen
Posts mit dem Label DE0-Nano werden angezeigt. Alle Posts anzeigen

Freitag, 4. April 2014

Autonomous Light Controller - Hardware Synthese


Und dann war da noch die Sache mit dem FPGA. Bevor ich mit diesem Projekt angefangen habe wusste ich nichts darüber, außer das die Dinger schnell sein müssen. Schneller als ein CPLD zumindest, damit hatte ich schon einmal Kontakt als es darum ging Linux mittels einem PassMe auf einem Nintendo DS booten zu können. Das gute beim ersten Kontakt mit dieser Art Baustein war, dass man es mit JTAG ansprechen konnte. Und wenn man in ein Entwicklungs-Board wie das DE0-Nano investiert sogar komfortabel per USB damit arbeiten kann. Allerdings ist so ein FPGA (wiedererwarten) alles andere als ein besserer Mikrocontroller- so meine erste Annahme. Ein FPGA ist für mein Empfinden mittlerweile eine Spielwiese der nur die eigene Rechenkapazität im Gehirn eine Grenze setzt (ja ich weiß sehr hochgestochen).
Die erste Sache die man sich als Software-Entwickler aus dem Kopf schlagen muss, wenn man mit einem FPGA arbeiten möchte, ist das man da ein Programm für schreibt das darauf läuft. Zumindest wenn man VHDL (Very High Speed Integrated Circuit Hardware Description Language) sieht das dann sogar noch wie ein Programm aus. Es verhält sich aber in sehr vielen Punkten einfach so wie man es erwartet. Das fängt an bei parallelen Prozessen, dass Variablen einen bösen Beigeschmack haben können und endet bei der Synchronisierung von Signalen in verschiedenen Clock-Domains. Beißt man sich jedoch durch das Thema durch hat man jedoch ein wirklich sehr komfortables und mächtiges Werkzeug in der Hand um verschiedenste Probleme lösen zu können.
Wie ich bereits in einem früheren Post geschrieben habe, verwende ich für den analogen Teil einen DSP, der in der Lage ist analoge Videosignale in ITU-R BT.656 kodierte Daten zu transformieren. Diese Daten werden in meinem Fall mit 27MHz bitparallel aus dem DSP mit einer Farbtiefe von 10Bit heraus getaktet.
Für den von mir verwendeten XMega deutlich zu schnell wenn man bedenkt das dieser mit 32MHz läuft und ca. 1-2 Takte benötigt um einen einzelnen Pin auszulesen.

Mit der richtigen Hardware-Synthese im richtigen FPGA sind diese Laufzeiten jedoch kein Problem. Was also muss die Hardware-Synthese tun damit das Ergebnis für Ausgabe auf LED-Streifen als Hintergrundbeleuchtung für einen Bildschirm verwendet werden kann. Es ist recht simpel. Der FPGA muss die Pixeldaten taktgesteuert annehmen, puffern, herunter skalieren (von beispielsweise einer PAL-Auflösung) auf eine vom XMega verarbeitbare Pixel-Größe, und ausgeben des Ergebnisses an den XMega. Und all das so, dass mindestens 25 Bilder pro Sekunde verarbeitet werden können um unschönes Geflacker zu vermeiden.

Meine Logik auf dem FPGA realisiert genau das. Zur Laufzeit werden alle Pixeldaten (eines Halbbildes) eingelesen und in einen kleinen OnChip-RAM gepuffert. Gleichzeitig wird über einen Hardware-Algorithmus die Auflösung des Eingangs-Bildes auf 20x20 Pixel skaliert. Warum nur ein Halbbild verwendet wird liegt daran, dass es unnötig ist die volle Auflösung beim Eingangs-Bild zu verwenden wenn man es Bild danach auf ein gerade noch verwendbares Minimum zu skalieren.

Die Übertragung zum Mikrocontroller erfolgt darauf hin direkt aus dem OnChip-RAM heraus. Der Mikrocontroller lädt die Pixel einzeln und komponentenweise, mittels einer Taktleitung und bitparallel über einen 12Bit-Bus aus dem FPGA. Wurden alle Daten übertragen beginnt dieser damit aus den Pixeldaten die Farben für die LEDs heraus zu rechnen. Parallel dazu verarbeitet der FPGA das nächste Halbbild. Der beschriebene Ablauf verarbeitet damit alle 25 empfangenen Halbbilder des Eingangssignals. Die Ausgabe der LED-Farben erfolgt ebenfalls mit 25 "Bildern" pro Sekunde.

Aufgrund der Performance des Gesamtsystems war es sogar notwendig einen Puffer in die Software einzufügen, damit die ausgegebenen Farben mit dem angezeigten Bild synchronisiert werden kann. Der AmbiController ist deutlich schneller in der Bildverarbeitung als mein TV-Gerät.

Freitag, 26. Juli 2013

Autonomous Light Controller - The FPGA Ambilight clone?

Wie angekündigt möchte ich hier nach und nach mehr Details über mein Projekt verraten. Dem aufmerksamen Leser ist sicher bereits schon aufgefallen, dass die Verlinkungen (Tags) zu den Posts in Kategorien fallen, in denen sich bereits kleine andere Projekte befinden.
Beispielsweise verwende ich als Mikrocontroller-Basis mein XMega-Evaluation-Board.
Genauer gesagt wurde dieses genau für diesen Zweck erstellt...

Letztendlich handelt es sich um eine Grundschaltung für den XMega und diversen Schnittstellen um das Board mit der anderen Peripherie anzubinden. Der Schaltplan ist im Bild rechts zu sehen. Ein Layout gibt es hierfür nicht, da das ganze auf Lochraster aufgebaut ist (Bilder unten).

Den Schaltplan (Eagle) zu dem Board ist auf GitHub Verfügbar...

Die Aufgaben dieses Boards sind die folgenden:

  1. Steuerung aller weiteren Komponenten wie dem FPGA-Board und dem Signalprozessor.
  2. Kommunikation und Steuerung der Beleuchtungsanlage (Fnordlichter oder LED-Stripes).
  3. Kommunikation per USB/Bluetooth mit externen Komponenten oder dem Anwender (TTY)
  4. Power- und Videosignal-Management.
  5. Empfang und Aufbereitung der bereits durch den FPGA vorbereiteten Bilddaten.
  6. Übertragung der vom FPGA empfangenen Bilddaten per USB oder Bluetooth.
Die Software auf dem Chip besteht aus einer in C geschriebenen Firmware welche alle Aufgaben aus der Liste oben. Der größte Teil der Implementierung entspricht einer TTY-Emulation für die Interaktion mit dem System.
Per TTY können verschiedene Konfigurationseinstellungen vorgenommen und Systemtests durchgeführt werden.

Das folgende Video zeigt den Zugriff auf das System bzw. auf verschiedene Register des Signalprozessors per I²C. Das Terminal enthält eine ausführliche Online-Hilfe und erlaubt, neben dem vollem Systemzugriff, zudem die Steuerung der Beleuchtung. Der Controller kann damit auch anderweitig verwendet werden.
Eine wesentlich maschinenlesbare Variante der Kommunikation ist in Arbeit.
Das Video soll schlicht demonstrieren, dass so eine Schnittstelle existiert und verwendet werden kann. Als einfacher Anwender kommt man damit nicht in Berührung. Damit wäre die Usability sonst komplett unmöglich...


Wie in der Auflistung oben bereits erwähnt (Punkt 6) ist das System zudem in der Lage die Bild-Rohdaten, welche vom FPGA erzeugt werden, per USB oder Bluetooth auszugeben. Hierzu ist das Tool "FrameView" entstanden. FrameView verwendet unter anderem SDL, ist plattformunabhängig und als Linux-Binary gerade mal 14kb groß.
Das folgende Video zeigt die Applikation in Aktion. Das Bild des Desktops wird dabei per VGA->CVBS-Adapter in den AmbiController geleitet, automatisch ausgewertet, und das Ergebnis per USB an die FrameView-Anwendung weitergeleitet, welche das aktuell ermittelte Bild in dem kleinen Fenster links darfstellt. Das Größere Fenster ist Video mit einem ein einfachen Farbtest. Das Ganze stammt aus den Anfängen der Entwicklung. Daher ist das Ergebnis noch sehr sehr pixelig.
Das Protokoll an dieser Stelle ist recht proprietär und nur zu Debug-Zwecken gedacht, da diese Ausgabe zudem die Framerate drückt. Um Bandbreite bei der Datenübertragung zu sparen werden hier immer nur Änderungen übertragen. 


Damit erstmal genug für heute und viel Spaß beim Video schauen...

Mittwoch, 12. Oktober 2011

Altera Quartus 11.0 Tools, Ubuntu 11.4, USB-Blaster

Wer mit Ubuntu 11.4 (x86) und der Software Quartus II Version 11.0 Build 157 04/27/2011 SJ Web Edition von Altera arbeitet, um z.B. sein DE0-Nano Board mit "Leben" zu befüllen wird schnell feststellen, dass diese Kombination leider ohne manuellen Eingriff, direkt nach der Installation der Altera Software, nicht funktioniert. Quartus II stürzt direkt nach dem Start mit einem Segfault (zumindest bei mir) ab. Und weder mit dem grafischen Programmer noch mit den Tools auf der Kommandozeile kann auf das DE0-Nano, welches sich am System als USB-Blaster ausgibt, zugegriffen werden. Da ich persönlich lieber auf der Konsole und mit Quartus II (aus vielerlei gründen) nur ungern arbeite, gehe ich hier nur auf die Konfiguration der Kommandozeilen Tools ein, um diese zur korrekten Arbeit zu bringen. Meine Altera Software habe ich mittels dem Altera-Installer unter ~/bin/altera/11.0 installiert.

1. Die ~/.bashrc anpassen

Als erstes muss selbstverständlich der Pfad zu den Binaries der PATH-Variable hinzugefügt werden. Weiterhin benötigen diverse Quartus Tools die Umgebungsvariable QUARTUS_ROOTDIR um korrekt arbeiten zu können, daher habe ich auch diese in meine .bashrc eingefügt.

export PATH=$PATH":~/bin/altera/11.0/quartus/bin:~/bin/altera/11.0/nios2eds/bin:~/bin/altera/11.0/quartus/sopc_builder/bin"

export QUARTUS_ROOTDIR="~/bin/altera/11.0/quartus ~/bin/altera/11.0/nios2eds/sdk_shell"

2. UDEV Zugriffsrecht auf den USB-Blaster einrichten

Ich habe die Datei "/etc/udev/rules.d/40-altera-usbblaster.rules" mit dem folgenden Inhalt angelegt:

BUS=="usb", SYSFS{idVendor}=="09fb", SYSFS{idProduct}=="6001", MODE="0666", SYMLINK+="usbblaster", GROUP="plugdev"

Startet man danach das System neu oder führt einen Reload von UDEV durch, kann auf den USB-Blaster zugegriffen werden. Die Voraussetzung dafür ist natürlich, dass dieser in der Liste der USB-Geräte auch angezeigt wird.

user@host:~$ lsusb -d 09fb:6001
Bus 002 Device 013: ID 09fb:6001 Altera

UDEV kann mit den entsprechenden Rechten mittels service udev reload dazu angewiesen werden die Konfiguration neu zu laden.

3. JTAG Daemon


Dieser Daemon muss laufen, um korrekt auf die JTAG-Chain per USB-Blaster zugreifen zu können. Gestartet wird dieser mit jtagd. Natürlich kann man diesen Daemon auch permanent laufen lassen.

4. Testen der JTAG-Verbindung

Beim Aufruf von jtagconfig wird als Standard die Option --enum ausgeführt. Es werden alle diejenigen Devices angezeigt, die an der JTAG-Chain hinter dem USB-Blaster hängen.

user@host:~$ jtagconfig
1) USB-Blaster [2-1.2.2]
  020F30DD

5. Quartus Programmer testen

Der Quartus Programmer muss selbstverständlich auch auf den USB-Blaster zugreifen können. Das kann mit dem folgenden Aufruf getestet werden.

user@host:~$ quartus_pgm --list

Info: *******************************************************************
Info: Running Quartus II Programmer
    Info: Version 11.0 Build 157 04/27/2011 SJ Web Edition
    Info: Copyright (C) 1991-2011 Altera Corporation. All rights reserved.
    Info: Your use of Altera Corporation's design tools, logic functions
    Info: and other software and tools, and its AMPP partner logic
    Info: functions, and any output files from any of the foregoing
    Info: (including device programming or simulation files), and any
    Info: associated documentation or information are expressly subject
    Info: to the terms and conditions of the Altera Program License
    Info: Subscription Agreement, Altera MegaCore Function License
    Info: Agreement, or other applicable license agreement, including,
    Info: without limitation, that your use is for the sole purpose of
    Info: programming logic devices manufactured by Altera and sold by
    Info: Altera or its authorized distributors.  Please refer to the
    Info: applicable agreement for further details.
    Info: Processing started: Sat Oct  8 18:10:02 2011
Info: Command: quartus_pgm --list
1) USB-Blaster [2-1.2.2]
Info: Quartus II Programmer was successful. 0 errors, 0 warnings
    Info: Peak virtual memory: 82 megabytes
    Info: Processing ended: Sat Oct  8 18:10:02 2011
    Info: Elapsed time: 00:00:00
    Info: Total CPU time (on all processors): 00:00:00

Die Tools quartus_pgm und quartus_pgmw (die grafische Version) sollten nun den USB-Blaster korrekt erkennen und ansteuern können.

Da aber nun das übertragen der synthetisierten Logik nicht genug ist und ich den Build-Vorgang mit einem kurzen Makefile automatisiert habe, möchte ich dass natürlich nicht vorenthalten. Voraussetzung für den korrekten Betrieb sind die oben genannten Einstellungen, dass man sich beim Start im Verzeichnis des Quartus-Projektes befindet und das die Haupt-Datei des Projektes identisch mit dem Projektnamen ist (alles natürlich Case-Sensitive).

#
# Makefile to build FPGA/CPLD synthesis with altera tools.
#
# Licensed under GPL v3.0 (15.10.2011)
# by Kai Lauterbach (klaute at gmail dot com)
#

TARGET=test

MAPPER=quartus_map
MAP_OPTIONS=--read_settings_files=on --write_settings_files=off $(TARGET) -c $(TARGET)

FITTER=quartus_fit
FIT_OPTIONS=--read_settings_files=off --write_settings_files=off $(TARGET) -c $(TARGET)

ASSEMBLER=quartus_asm
ASM_OPTIONS=--read_settings_files=off --write_settings_files=off $(TARGET) -c $(TARGET)

STA=quartus_sta
STA_OPTIONS=$(TARGET) -c $(TARGET)

PROGRAMMER=quartus_pgm
PGM_OPTIONS=-m jtag -c USB-Blaster -o "p;$(TARGET).sof"

compile: clean map fit asm sta

map:
    $(MAPPER) $(MAP_OPTIONS)

fit:
    $(FITTER) $(FIT_OPTIONS)

asm:
    $(ASSEMBLER) $(ASM_OPTIONS)

sta:
    $(STA) $(STA_OPTIONS)

program:
    $(PROGRAMMER) $(PGM_OPTIONS)

clean:
    rm -rf db/ dse/ incremental_db/ sim.do $(TARGET)ig.archive.rpt $(TARGET).asm.rpt $(TARGET).bsf $(TARGET).cdf $(TARGET).done $(TARGET).dse.rpt $(TARGET).fit.rpt $(TARGET).fit.summary $(TARGET).flow.rpt $(TARGET).inc $(TARGET).map.rpt $(TARGET).map.smsg $(TARGET).map.summary $(TARGET).mif_update.rpt $(TARGET).pin $(TARGET).sof $(TARGET).sta.rpt $(TARGET).sta.summary $(TARGET).tis_db_list.ddb $(TARGET)_assignment_defaults.qdf wave.do $(TARGET).archive.rpt



PowerMgr in der Praxis: PV, Batterie, Kühlung und Hauszustand steuern

PowerMgr in der Praxis: PV, Batterie, Kühlung und Hauszustand steuern PowerMgr geht über eine Sammlung von Gerätetreibern hinaus. Der inte...