Zum Hauptinhalt Zur Navigation Zur Suche

Reverse Engineering: Signale auslesen an bunten Pins

Die Übersicht über 256 Pins zu behalten, ist schwer. Deswegen greifen wir zum Malstift. Zur Belohnung zeigt uns Linux schließlich hübsche Sinuskurven.
/ Christer Weinigel
16 Kommentare Auf Google folgen (öffnet im neuen Fenster)
Schaltbild des Panels (Bild: Christer Weinigel)
Schaltbild des Panels Bild: Christer Weinigel

Eine Vielzahl von GPIO-Pins des FPGA eines Oszilloskops kenne ich seit dem vierten Teil der Artikelserie, doch es ist nicht einfach, die Übersicht zu behalten und mir zu merken, welcher Pin wofür zuständig ist. Deshalb werde ich mir im letzten Teil der Artikelserie einen Überblick aufmalen. Mit diesem Wissen kann ich schließlich ein Signal an einer Oszilloskop-Sonde auswerten und unter Linux auf dem Oszilloskop darstellen.

Malen nach Zahlen

Ein FPGA hat jede Menge Pins mit unterschiedlichen Funktionen. Die Pins sind auf verschiedene I/O-Bänke aufgeteilt und können mit verschiedenen Spannungen und Standards arbeiten. Um den Überblick nicht zu verlieren, habe ich die Infos zu den Pins aus der zugehörigen Dokumentation(öffnet im neuen Fenster) herauskopiert und mit einem kleinen Python-Programm ein PNG erzeugt, das die Pins und ihre Nutzung anzeigt.

Die Form der Symbole zeigt die Funktion eines Pins. Ein Kreis steht für einen normalen GPIO-Pin. Pins mit einem Hexagon können entweder als GPIO-Pin oder als Takteingabe fungieren. Ein Karo steht für einen normalen GPIO-Pin oder dient als Referenzspannung (VREF), wie sie bei einigen Schnittstellenstandards erforderlich ist. Die übrigen Symbole stehen für Pins mit festgelegten Funktionen und können nicht für GPIO-Aufgaben konfiguriert werden.

Die Farbe des Symbols zeigt dessen Bank an. Die Pins für die Stromversorgung der internen Logik des FPGA und die Masse-Pins gehören keiner Bank an, sie sind grau markiert. Die farbigen Vierecke um einige Pins zeigen an, welche Funktion sie meiner Meinung nach haben. Zum Beispiel dienen die Pins mit den gelben Vierecken zur Konfiguration des FPGA. Die Farbe der Symbole für diese Pins ist Blau, daher benutzen sie die Spannungswerte von Bank 2.

Die Pins P10, R3 und T11 können nach der Konfiguration als GPIO-Pins benutzt werden. Im Gegensatz dazu kann die Konfiguration der Pins L13 und T2 nicht geändert werden. L11 und N14 werden nicht zur Konfiguration eingesetzt und sind deshalb grau. A15, C12, C14 und E14 sind JTAG-Pins, allerdings sind diese Pins anscheinend nirgendwo angebunden.

Wo der SoC-Bus anliegt

Im vorherigen Artikel habe ich eine ganze Reihe von Pins gefunden, die ständig geschaltet werden. Sie sind wohl mit dem DDR-Speicherbus des SoC verbunden. Darüber kommuniziert der SoC hauptsächlich mit dem FPGA. Dazu simuliert der FPGA einen DDR-Speicher, den der SoC ausliest oder beschreibt. Ich habe die Pins entsprechend als "SoC bus" markiert und meine Grafik neu erzeugt.

Die meisten dieser Pins befinden sich in Bank 2, aber einige auch in Bank 3. Bank 2 befindet sich auch physisch am nächsten am SoC, weshalb ihre Nutzung auch vom Platinenlayout her sinnvoll ist.

Der DDR2-Speicher benutzt den SSTL-Standard(öffnet im neuen Fenster) zur elektrischen Datenübertragung. Die Spannung beträgt dabei 1,8 Volt, weshalb eine externe Referenzspannung von 0,9 Volt über einen VREF-Pin benötigt wird. Ich habe einen Spannungsteiler auf der Platine gefunden, der diese Spannung bereitstellt.

An den Pins P7 und M7 liegt ein symmetrisches 133-MHz-Taktsignal vom SoC an. Noch ist mir nicht die komplette Pin-Belegung des SoC-Busses klar. Aber ich habe einige Ideen, wie ich sie herausfinden kann.

Den echten DDR-Bus identifizieren

Am FPGA ist ein echter DDR-Speicherbaustein angeschlossen. Ich hoffe, dass die Hardware-Ingenieure dafür die gleiche Pin-Belegung verwendet haben, wie sie Xilinx im MIG(öffnet im neuen Fenster) (Memory-Interface-Generator) vorgeschlagen wird. Ich habe meine Zeichnung entsprechend ergänzt.

Der Speicherbaustein sitzt über dem FPGA auf der Platine, so dass die Pin-Belegung auch hier sinnvoll ist. SSTL kommt erneut als Verbindungsstandard zum Einsatz, der VREF-Pin wird also auch hier mit 0,9 Volt Spannung versorgt.

So weit, so gut, allerdings gibt es hier auch ein Problem.

Wie zu sehen ist, habe ich neun Pins der Bank 3 als unbenutzt markiert. Diese wurden bei meinem Test ständig beschaltet und sind wahrscheinlich Teil des SoC-Busses. Das sollte üblicherweise kein Problem bereiten. Zum Beispiel fungiert der Pin B1 als M3BA2, er dient damit zur Adressierung des Speicherbausteins durch den FPGA-Speichercontroller. Da DDR2-Speicher nur aus zwei Bänken besteht, sind lediglich M3BA0- und M3BA1-Pins erforderlich und M3BA2 verbleibt ungenutzt – die Namen der Pins entstammen der Xilinx-Dokumentation. Beim Pin F4 sollte es sich um den Pin M3CKE (Clock Enable) handeln, der zum entsprechenden Pin des DDR2-Speicherbausteins führt. Es ist aber auch möglich, dass dieser Pin beim Speicherbaustein fest verdrahtet wurde und das Signal nicht durch den FPGA geschaltet wird.

Das große Problem an dieser Stelle ist die Aussage der Xilinix-Dokumentation, dass einer der Pins M4, M5, N4 oder B3 für die RZQ-Kalibrierung benutzt und nicht beschaltet werden sollte. So können Umwelteinflüsse auf die Datenleitungen erkannt und ausgefiltert werden. Das entsprechende Zitat aus der Dokumentation: "The RZQ pin is required and cannot be removed from the design". Aber alle Pins sind mit dem SoC-Bus verbunden. Ich habe nicht genug Erfahrung mit dem MIG-Werkzeug, um eine solche Verschaltung zum Laufen zu bekommen und dabei die Empfehlung von Xilinix zu ignorieren.

Ansonsten sollte es recht einfach sein, mit Hilfe von MIG den Speichercontroller auf dem FPGA zu konfigurieren.

Es fehlt nur noch der ADC-Bus

Es bleibt nun noch ein großer Bus übrig: Er verbindet den FPGA mit dem Analog-Digital-Konverter (ADC). Wenn ich das Oszilloskop normal starte, dann per OpenOCD den SoC neu starte und Linux boote, läuft der ADC normal weiter und dessen Pins liefern weiterhin Signale. Das ist praktisch zur Analyse.

Die ADC-Signale sind symmetrische (differenziale) Signale, und als ich die Frequenzen der Signale an den Pins analysiere, wird deutlich, dass die Frequenzen stets paarweise auftreten und es insgesamt 32 Stück davon gibt. Das entspricht genau meinen Erwartungen. Denn der ADC lieferte 32 symmetrische Signale (zwei Kanäle mit je 2 x 8 Bits).

Der ADC befindet sich auf der Platine unterhalb des FPGA, das Layout ergibt auch hier Sinn.

Diesmal ist alles recht einfach.

Die Signalwechsel des symmetrischen Signals an den Pins E7 und E8 liegt selbst dann an, wenn der ADC ausgeschaltet war. Wahrscheinlich handelt es sich um den Takt, mit dem der ADC über die Pins DCLK+/DCLK- betrieben wurde. Ich starte das Oszilloskop erneut, ändere die horizontale Auflösung der Signaldarstellung und starte erneut Linux. Darüber spiele ich wieder mein FPGA-Image ein und die Frequenz (Häufigkeit) der Signalwechsel an den Pins hat sich geändert. Ich bin mir sicher, es handelt sich um den Sampling-Takt, mit dem der ADC die gemessenen Signale an den angeschlossenen Tastköpfen erfasst.

Als ich später an einigen Pins des ADC herumstochere, führt das ebenfalls zu Schaltvorgängen an den Pins F13 und F14. Ich bin mir nicht sicher, was sie tun. Es könnte sich um die Pins des ADC handeln, die einen Überlauf und einen Kalibrierungsvorgang signalisieren.

Ich weiß nicht direkt, welche symmetrischen Signale am FPGA zu den Datenausgabe-Pins am ADC passen, aber das sollte nicht zu schwer herauszufinden sein. Wenn es mir gelingt, das Analog-Frontend zum Laufen zu bringen und eine Signalquelle anzuschließen, könnte ich den Gain-Wert (Verstärkung) so weit verändern, dass nur das niederwertigste Bit in der Datenausgabe auf dem zugehörigen FPGA-Pin auftaucht. Erhöhe ich dann den Gain-Wert, sollten schrittweise auch die höherwertigen Bits in der Datenausgabe auftauchen. So kann ich herausfinden, welches Pin-Paar welchem Bit entspricht, statt per Brute-Force alles durchzuprobieren. Doch das ist am Ende gar nicht notwendig, wie sich zeigen wird.

Die restlichen FPGA-Pins

Jetzt, wo ich die großen Verbindungen und ihre Pins zugeordnet habe, kann ich mit den übrigen beginnen. Ich benutze hierzu die gleiche Methode wie auf dem SoC. Ich habe einen FPGA-Pin als Eingabe definiert, mit einem Pull-up- oder Pull-down-Widerstand konfiguriert. Danach verbinde ich interessante Kontakte auf der Platine über einen 330-Ohm-Widerstand mit der Masse oder einer Stromquelle und verfolge, ob ein Schaltvorgang auf dem FPGA registriert wird.

Zuerst probiere ich die beiden Kontakte des I2C-Busses am AT88SC-Kryptospeicher. Es stellt sich heraus: Pin C4 am FPGA entspricht dem SCL-Pin und B6 dem SDA-Pin. Wenn ich darüber nachdenke, ist das sinnvoll. Wenn die Seriennummer und der Lizenzschlüssel für die Firmware im FPGA stecken, dann könnte sich dort auch der Lizenzcheck befinden und ist damit schwerer zu umgehen. Clever!

In meinem Blog(öffnet im neuen Fenster) habe ich noch eine ganze Reihe weitere gefundener Pins aufgelistet, hier beschränke ich mich auf eine Auswahl.

Ich bemerke außerdem, dass am Pin A4 ein Signal mit der Frequenz von 50 MHz anliegt, wenn ich es über den regulären Stromanschluss betreibe statt über die Batterie. Ich schaue in der Dokumentation nach: Das Oszilloskop kann tatsächlich über den Stromanschluss getriggert werden.

Der Pin D5 schaltet mit einer Frequenz von 1 KHz, wenn ich einen Oszilloskop-Tastkopf an Kanal 1 mit einem 1-KHz-Testsignal verbinde. Ich vermute, das ist die Ausgabe des Trigger-Schaltkreises von Kanal 1 des Oszilloskops. Nicht gefunden habe ich bislang den Trigger für Kanal 2 oder den externen Trigger. Das sollte aber leichter sein, wenn ich weiß, wie ich das Analog-Frontend konfigurieren kann.

Zwei weitere Pins scheinen mit dem Video-Trigger-IC verbunden zu sein. Ich weiß gar nicht, wie ich eine Quelle für ein Composite-Video-Signal auftreiben soll, das ist so 20.-Jahrhundert-mäßig. Vielleicht muss ich meinen alten Amiga 1000 aus dem Keller holen und hoffen, dass er noch funktioniert.

Die finale Karte

Jetzt können wir die Karte weiter vervollständigen.

Immer noch sind gut ein Dutzend IO-Pins des FPGA übrig, die ich nicht zuordnen kann. Bei einigen handelt es sich wohl um Trigger, einige könnten ADC-Signale sein, und manche sind sicherlich unbenutzt.

Abgesehen davon habe ich wohl tatsächlich alle Verbindungen innerhalb des Oszilloskops aufdecken können. Ich weiß, wie der SoC mit seiner Peripherie und einigen Komponenten im Analog-Frontend verbunden ist. Ich weiß, wie der FPGA mit dem SoC verbunden ist, dem DDR-Speicher, dem ADC und anderen Komponenten wie dem Taktgenerator, dem DAC und den übrigen Komponenten im Analog-Frontend.

Die FPGA-SoC-Bus-Verbindung wird schwer auszunutzen sein. Die Verbindung arbeitet sehr schnell, und jeder Fehler in der Signalverarbeitung des FPGA korrumpiert den Speicher im SoC und führt zum Absturz des Oszilloskops. Das wird sehr schwer zu testen und zu debuggen. Der DDR-Speichercontroller im FPGA entspricht nicht den Empfehlungen von Xilinx und ich weiß noch nicht, wie ich damit umgehe.

Es sollte nicht zu aufwendig sein, ein FPGA-Image zu erzeugen, das den Taktgenerator und das Analog-Frontend startet. Dann kann ich die Daten vom ADC im internen RAM des FPGA speichern und über die drei IO-Pins übertragen, die ich auch bisher benutze, auch wenn die Datenrate dabei deutlich unter 10 MBit pro Sekunde liegen wird. Dabei gibt es wahrscheinlich noch viele Kleinigkeiten zu beachten, um alle Komponenten zu initialisieren. Das ist zwar nicht hart, aber sehr zeitaufwendig, auch weil ich gerade mal ein HDL-Einsteiger bin.

Die Tasten am Gerät auswerten

Schauen wir uns stattdessen das Frontpanel näher an, das über den Steckverbinder mit der Hauptplatine verbunden ist. Der Forenteilnehmer "lemon" im EEVBlog-Forum(öffnet im neuen Fenster) hat bereits einige gute Bilder der Leiterplatten des Frontpanels gemacht. Im dortigen Bild sind die Schaltkreise gut zu sehen.

Bei U31 handelt es sich um einen 74HC393-Dual 4-Bit-Binary-Ripple-Counter(öffnet im neuen Fenster). U7 und U26 sind 74HC4051-8-Channel-Analog-Multipler-Demultiplexer (PDF)(öffnet im neuen Fenster). Die Leiterbahnen sind im Bild deutlich sichtbar und selbst ohne Blick auf die Rückseite der Platine ist die Funktionsweise erkennbar. Hier das Schaltbild:

Die Tasten sind im Schaltplan in einer Matrix angeordnet, auf der realen Platine wird das nicht sofort deutlich, einige Tasten sind sogar auf anderen Platinen. Jede Taste besteht aus einem Schalter, der eine Spalte mit einer Zeile über eine Diode verbindet. Einige Tasten sind eigentlich Drehgeber, aber hier reicht es, sie als einfache Tasten zu betrachten.

Der U31-Counter hat zwei Zählwerke. Das erste Zählwerk steuert über diesen drei niederwertige Bits U7 und wählt darüber die abzufragende Spalte aus, die dann mit einem FPGA-Pin verbunden wird. Das zweite Zählwerk steuert gleichfalls über die drei niederwertigsten Bits U26 und verbindet jeweils die abzufragende Zeile mit der Masse.

Normalerweise liegt an allen Spalten über die Widerstände R1-R8 ein High-Signal an. Wenn eine Taste gedrückt wird, und die zugehörige Spalte wie auch die Zeile sind gerade ausgewählt, dann verursacht die Taste einen Kurzschluss mit der Masse. Dadurch liegt am Z-Pin von U7 ein Low-Signal an, das von einem FPGA-Pin ausgewertet wird.

Die Prüfung des Status der Tasten erfolgt über den FPGA. Zuerst führt er einen Zähler-Reset über den FPGA-Pin A5 durch. Beide Zähler stehen auf 0, über U7 und U26 sind die erste Spalte und erste Zeile der Tastenmatrix ausgewählt. Am FPGA-Pin B5 liegt nun das Signal der ersten Taste an. Zur Prüfung der nächsten Taste liefert der FPGA am Pin C6 ein Taktsignal, das den ersten Zähler um eins erhöht. Damit wird der Taster in der zweiten Spalte der ersten Reihe ausgewertet.

Erreicht der erste Zähler einen bestimmten Wert, wird der zweite Zähler um eins erhöht und damit zur nächsten Zeile weitergeschaltet. Wurden so alle 64 Tasten geprüft, wird ein erneuter Reset durchgeführt und das Spiel geht von neuem los. Da die Schaltfrequenz des Pin C6 mit 312,5 KHz recht hoch ist, wirkt es für den Nutzer, als ob alle Tasten gleichzeitig geprüft werden.

Ein Bauteil fehlt

Die übrigen Pins des Steckverbinders vom Frontpanel kontrollieren die Beleuchtung der Tasten. Ich habe keine Ahnung, warum ein SoC-Pin für die grüne LED benutzt wird, die anderen beiden hingegen vom FPGA kontrolliert werden.

Ein Pin bleibt noch übrig: Der SoC-Pin GPH3 liegt ebenfalls am Steckverbinder an. Aber ich konnte keinen zugehörigen Kontakt am Panel finden.

Allerdings gibt es an der Front etwas, das wie ein kleines Fenster für einen Infrarotempfänger aussieht. Und auf der Leiterplatte befinden sich unbenutzte Kontakte für zusätzliche Bauelemente direkt hinter diesem Fenster.

Der SoC-Pin GPH3 ist der Empfänger-Pin für einen seriellen Anschluss, und die zugehörigen UARTs unterstützen die Auswertung von Infrarotsignalen!

Ich habe bislang noch nicht überprüft, ob GPH3 tatsächlich mit den unbenutzten Kontakten verwendet wird, da ich dafür das Frontpanel aufschrauben müsste. Aber ich halte es für sehr wahrscheinlich. Vermutlich sollte ursprünglich ein Infrarotempfänger verbaut werden, doch dann wurde davon abgesehen.

Oszilloskop-Daten auslesen

Zurück zur eigentlichen Oszilloskop-Funktion. Welche Datenpins des ADC sind mit den Pins des FPGA verbunden?

Ich habe mich mittlerweile einige Wochen mit MyHDL beschäftigt und dabei einige FPGA-Module gebaut, die über einen Wishbone-Bus(öffnet im neuen Fenster) miteinander kommunizieren.

Als Erstes entstand ein SPI-Slave(öffnet im neuen Fenster), der die drei Leitungen für die FPGA-Konfiguration benutzt. Normalerweise benötigt eine SPI-Schnittstelle vier Leitungen. Deshalb kombinierte ich die Leitungen für Serial Data Out (SDO) und Serial Data In (SDI) in einer bidirektionalen SDIO-Leitung. Ich versuchte, den Linux-Treiber spi-gpio zu modifizieren, damit er mit dieser einzelnen Leitung funktioniert, allerdings stellte sich das als zu schwierig heraus. So bastelte ich mir einen einfachen Treiber selbst zusammen.

Dieses SPI-Slave-Modul fungiert als Master des Wishbone-Busses und kann einen angeschlossenen Wishbone-Slave steuern. Ich funktionierte meinen MyHDL-Code zum Auswerten von Pin-Flanken um, so dass er als Wishbone-Slave fungierte. Das war relativ einfach. Schwieriger war es, einen Bus-Multiplexer zu schreiben, mit dem ich mehrere Wishbones-Slaves mit einem Wishbone-Master verbinden konnte. MyHDL funktionierte nicht immer so, wie ich es erwartet hatte und hatte verschiedene Einschränkungen, deshalb brauchte ich einige Wochen, bis es funktionierte.

Nachdem ich das alles zusammenhabe, erzeuge ich einen RAM-Baustein mit zwei Verbindungen im FPGA. Eine Verbindung besteht mit einem Wishbone-Slave, so dass der RAM-Inhalt vom SoC ausgelesen werden kann. Die zweite Verbindung besteht mit dem ADC des Oszilloskops. Im Takt des ADC werden die 32 symmetrischen Signale vom ADC im RAM gespeichert, bis er voll ist. Ein weiterer Wishbone-Slave mit einem einzelnen Bit-Register dient zum Starten und Stoppen des Speichervorgangs (Capturing).

Das erste Capturing

Mit dem Kommandozeilenprogramm sox(öffnet im neuen Fenster) auf einem Linux-PC spiele ich eine 3-KHz-Sinuskurve ab, die ich mit einem Tastkopf an Kanal 1 des Oszilloskops auswerte.

Ich boote wieder das Oszilloskop mit der Owon-Firmware und warte, bis ich eine Sinuskurve auf dem Bildschirm sehe. Dann führe ich wieder ein Soft-Reset durch und lade Linux. Dabei läuft der ADC weiter, so entdeckte ich damals die Pins, mit denen der ADC mit dem FPGA verbunden ist. Ich sehe außerdem, dass der ADC mit 100 MHz getaktet wurde. Deshalb modifiziere ich den FPGA-Code zum Speichern der Daten, es wird jetzt nur noch jede hundertste Abtastung im RAM gespeichert. Meine Abtastrate beträgt also 1 Msamples pro Sekunde.

Welche Pins bekommen welches Signal?

Der ADC liefert 32 symmetrische Signale an die FPGA-Pins. Die 32 Signale sind aufgeteilt in vier Gruppen mit je acht Pins, jeder Pin entspricht einem Bit. Tastet der ADC nur einen Kanal ab, werden dafür alle vier Gruppen genutzt und miteinander verzahnt übermittelt. Werden zwei Kanäle abgetastet, werden pro Kanal je zwei Gruppen verwendet. Verzahnt bedeutet, dass jeweils mehrere, zeitlich hintereinanderliegende Messwerte gleichzeitig übermittelt werden.

Es gilt nun herauszufinden, welche FPGA-Pins zu welcher Gruppe gehören und welcher Pin innerhalb einer Gruppe welcher Bitposition entspricht.

Als Ausgangspunkt für die Analyse der Pin-Gruppen-Zugehörigkeit nutze ich die Angaben zur Anordnung der Pins, wie sie im FPGA-Datenblatt angegeben werden. Ich übertrage die Daten in eine Grafik. Es ergab sich folgendes Bild. Die Rohdaten sind hier verfügbar(öffnet im neuen Fenster).

Die roten, grünen, blauen und magentafarbenen Punkte entsprechen den jeweiligen Pin-Gruppen. Das sieht nicht direkt nach einer Sinuskurve aus, aber es wäre reiner Zufall gewesen, wenn ich die korrekte Zuweisung der Pins zu den Gruppen bereits beim ersten Versuch gefunden hätte.

Allerdings ist ein Muster erkennbar: eine 3-KHz-Sinuskurve, die mit 1 Msample pro Sekunde abgetastet wird, und bei 1.000 dargestellten Stichproben sollte sich das Signal dreimal im abgebildeten Graphen wiederholen, und das tut es.

Die Daten sehen auf den ersten Blick wie reines Rauschen aus, aber an drei Stellen haben wir eine klare Linie. Es gibt einige Punkte im Rauschen, die entfernt wie eine Sinuskurve aussehen, wenn ich ein wenig die Augen zudrücke.

Positiv oder negativ?

Nach etwas Nachdenken komme ich darauf, dass beim Start von Linux einige GPIO-Pins geschaltet werden, die den Schaltbereich der Dämpfungsrelais im Analog-Frontend verändern. Deshalb erhöht sich die Amplitude der Kurve, das Signal übersteigt die Erfassungsfähigkeit des ADC und wird abgeschnitten. Dann wird mir klar, dass es für die Analyse ganz praktisch ist, dass das Signal abgeschnitten wird, da sich die zugehörigen Pins einfacher verfolgen lassen.

Jedes symmetrische Signal wird über zwei Leitungen mit entgegengesetzter Polarität übertragen. Wenn die Leiterbahnen auf der Leiterplatine geplant werden, ist es manchmal einfacher, das positive Signal vom Sender mit dem Pin desjenigen Empfängers zu verbinden, der das negative Signal erwartet, und umgedreht. Damit wird das Layout der Leiterplatine einfacher, aber dann muss das Signal beim Empfänger invertiert werden. Da das Signal abgeschnitten wird und es zwangsläufig längere Abschnitte mit Einsen in den Bitdaten geben sollte, müssen alle Nullen in diesen Abschnitten invertiert werden. Also invertieren wir die entsprechenden Bits und zeichnen die Messpunkte erneut.

Jetzt sind die flachen Abschnitte komplett auf null gesetzt, die Abschnitte dazwischen erinnern deutlicher an eine Sinuskurve.

Die Macht der Statistik

Wie geht es weiter? Die Signale der niederwertigsten Bits in jeder Pin-Gruppe sollten sich öfter ändern als die höherwertigen. Warum also nicht eine kleine Statistik aufmachen? Ich sortiere die Signale an den Pins nach der Häufigkeit der Änderungen und ordne sie in Vierergruppen an.

Bei einer Sinuskurve, die sich dreimal wiederholt, wird sich das höchstwertige Bit zweimal pro Wiederholung ändern, damit gilt 2 * 3 = 6 Änderungen, das entspricht dem ersten Eintrag. Die anderen Einträge sind Vielfache von 3. Erst ab 173 wird das Schema durchbrochen, das liegt um eins unter 58 * 3 = 174. Wahrscheinlich ist das Signal nicht ganz mittig über den gesamten Bereich. Die Anzahl der Änderungen für die niederwertigsten drei Bits variiert deutlich, eventuell sind sie durcheinander und einige Signaländerungen sind wahrscheinlich einfach Rauschen.

Ordnen wir die Pins entsprechend der obigen Tabelle und schauen erneut darauf:

Das sieht jetzt definitiv wie eine abgeschnittene Sinuskurve aus. Es gibt immer noch viel Rauschen, aber langsam wird es.

Weiter geht es. Da alle Pin-Gruppen ähnliche Daten zeigen, muss der ADC mit allen vier Gruppen Daten von Kanal 1 liefern. Also starte ich das Oszilloskop neu und schalte beide Kanäle an, beide werden mit der gleichen Signalquelle gespeist. Jetzt sollten je zwei Gruppen die Daten für Kanal 1 und Kanal 2 enthalten. Ich schalte auf Linux um und führe eine neue Erfassung durch.

Die Pins für beide Kanäle wirken teilweise vermischt, also probiere ich wieder den Trick mit dem abgeschnittenen Signal und vertausche die Pins so lange, bis die ersten beiden Gruppen die Daten von Kanal 1 enthalten.

Das sieht wieder besser aus. Die rote und die grüne Gruppe enthalten die Daten von Kanal 1, die blaue und magentafarbene Gruppe die von Kanal 2. Offensichtlich sind die grüne und blaue Gruppe immer noch vermischt. Zwischen der 80. und der 230. Stichprobe ist der Wert der blauen Stichproben um 128 zu hoch und der der grünen 128 zu niedrig. Ich tausche die Pins, die den Wert 128 repräsentierten, zwischen den Gruppen aus.

Langsam sieht es gut aus. Es gibt noch einige Artefakte bei den drei niederwertigsten Bits, aber das ist nicht so schlimm. Ich spiele einfach ein wenig weiter herum, bis der Graph gut aussieht. Schließlich ergibt sich der finale Graph:

Wenn ich die Dämpfung erhöhe, verändert sich der Graph entsprechend.

Ich habe es geschafft. Es kann sein, dass die Ordnung der Gruppen noch nicht ganz korrekt ist. Die 1. Gruppe von Kanal 1 könnte tatsächlich auch die 2. Gruppe von Kanal 1 sein. Ich müsste mit höheren Signalfrequenzen experimentieren, um herauszufinden, ob die Abfolge stimmt oder nicht.

Aber mein Ziel habe ich erreicht. Ich kann das Oszilloskop mit meiner eigenen Software nutzen, um Signale zu analysieren.

Weiterlesen lohnt

Wir haben eine Vielzahl von Werkzeugen, Methoden und teils unorthodoxen Ideen kennengelernt, um die Hard- und Software eines Gerätes zu verstehen. Die Analyse von Christer Weinigel(öffnet im neuen Fenster) ist allerdings noch längst nicht vorbei. In weiteren Blogbeiträgen widmet er sich unter anderem dem genaueren Verständnis des Analog-Frontends und seiner Ansteuerung, greift erneut die DDR-RAM-Implementierung im FPGA auf – diesmal mit Erfolg. Mit der Kenntnis der gesamten Artikelserie sollte es auch für Einsteiger möglich sein, den umfangreichen Ausführungen zu folgen.

Diese Artikelserie erschien zuerst im Blog von Christer Weinigel. Mit seiner Erlaubnis hat Golem.de seine Artikel ins Deutsche übersetzt und dabei einige Kürzungen und Ergänzungen vorgenommen, damit der Inhalt auch Einsteigern verständlich ist.


Relevante Themen