Audio-DSP mit Spartan 3-FPGA: Unterschied zwischen den Versionen

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche
Zeile 390: Zeile 390:


[[Bild:DAP mit Touch-Display.jpg|thumb|600px|left|DAP-Board mit Touch-Display]]
[[Bild:DAP mit Touch-Display.jpg|thumb|600px|left|DAP-Board mit Touch-Display]]
<br clear="all" />
[[Bild:DAP Synthesizer Ansicht 1.jpg|thumb|600px|left|DAP-Board plus UI-Board mit Potis, Schaltern, LED's im Synthesizer-Stil]]


<br clear="all" />
<br clear="all" />

Version vom 14. Dezember 2009, 18:39 Uhr

von Benutzer:TheMason

Ziel

Ziel dieses Projekts ist es, eine FPGA-basierte Plattform aufzubauen mit der es möglich ist Synthesizer, Effektgeräte, Mischpulte oder gar ein Harddiskrecording-System zu realisieren.

Feature-Liste

Features des Audio-Prozessors:

  • Oszillatoren
  • Biquads (Filter)
  • Addierer, Schalter, Verstärker (Multiplizierer)
  • Delays
  • Steuerung des Audio-Prozessors via SPI oder RS232
  • 4 Mono Ein- und Ausgänge
  • GPO (General Purpose Outputs) zur Konfiguration der Codecs

Übersicht

Overview wo uc.jpg

Basis des Audio-Systems ist das Xilinx Spartan 3-Development Board. An diesem Board werden 2 Audio-Codecs angschlossen von denen einer als Master und der andere als Slave agiert. Optional kann noch ein Mikrocontroller angeschlossen werden welcher den FPGA per SPI steuert. Da dieses Projekt mittlerweile recht umfangreich geworden ist, kann ich hier nur einen kurzen Umriss des Systems geben. Dabei beschränke ich mich auf die grobe Funktionsweise des Audio-Prozessors, erläutere das Interface (welches ich als Basis für weitere Projekte bereits nutze) und gebe einen kleinen Überblick über die Hardware.

Das System kann (sofern man 2 Audio-Codecs, von denen einer als Master, der andere als Slave arbeitet, angeschlossen und konfiguriert hat) direkt genutzt werden, da der DAP per RS232 gesteuert werden kann. Der Audio-Prozessor startet mit einem Stereo-Tiefpass-Filter der sich auf den ersten Codec bezieht, sodass man ein erstes Demo hat (selbst wenn es etwas unspektakulär ist)


Nachbau

Derjenige der sich dieses System nachbauen möchte benötigt erstmal ein FPGA-Board. Mit dem Spartan 3 Board von Digilent gestaltet sich der Nachbau dadurch einfach, als das die Programmier-Dateien für den FPGA direkt für dieses Board verwendet werden können. Nutzer anderer Boards (Xilinx) müssten zuerst die UCF-Datei für die Pins ihres jeweiligen Boards anpassen, und dieses Projekt neu synthetisieren (compilieren). Nutzer von Altera-Boards hingegen müssen die BlockRAM Instanzen auf die Altera-Architektur anpassen (den Inhalt der RAMs dabei nicht vergessen :-). Vielleicht findet sich ja der eine oder andere der den VHDL Code für Altera-FPGAs portiert. Der eigentliche wichtige Teil eines Nachbaus ist der Codec-Teil. Dieses System verwendet zwar zwei Codecs, aber es kann auch mit einem gearbeitet werden. Als Codec kommt der TLV320AIC23B von Texas Instruments zum einsatz. Diesen kann man als kostenloses Sample bei TI direkt bekommen. Des weiteren benötigt man noch eine handvoll Bauteile wie Kondensatoren, Widerstände und einen Quarz. (Ein Codec MUß als Master laufen, sonst hat das System keine Audio-Clocks, da diese nicht vom FPGA generiert werden) Die Initialisierung des Codecs wird vom PC aus gemacht. Dazu dienen die 4 GPO Leitungen auf dem B1- Connector. Da der Codec nur "halbes" SPI unterstüzt (man kann nur schreiben, nicht lesen) gestaltet sich die Initialisierung recht einfach. Die 4 GPO-Leitungen teilen sich folgendermaßen auf :

  • Chip-Select Codec 2
  • Chip-Select Codec 1
  • SPI Data Out
  • SPI Clock

Audio-Prozessor (DAP)

Overview dap core.JPG

Der FPGA beinhaltet in dem gesamten System einen Quasi-DSP. Quasi-DSP deshalb, da die Struktur im Gegensatz zu einem DSP bzw. Mikrocontroller keine Verzweigungen, Interrupts oder ähnliches zulässt. Der Audio-Prozessor besteht im wesentlichen aus 3 Teilen : Einem Rahmen, einem SDSP (Small DSP)-Kern sowie einem Utility-Kern. Beide Kerne können theoretisch parallel arbeiten, da jeder Kern eine eigene Statemachine und einen eigenen Mikro-Code Speicher besitzen. Dieses Feature ist allerdings noch nicht implementiert.

Der SDSP-Kern besteht im wesentlichen aus einer MAC-Einheit, einem Speicher für Audio-Daten, einem Koeffizienten-Speicher, einem Adress-Generator und mehreren Muxern, sowie der schon angesprochenen Statemachine und dem Microcode. Weiterhin ist ein Hidden-Write- (bzw. Shadow Register) Mechanismus integriert, welcher ein "knackser-freies" Updaten von Koeffizienten ermöglicht. Alle diese Komponenten werden vom MicroCode aus gesteuert (genau wie bei einem Mikrocontroller). Mit diesem Kern ist es möglich, Audio-Signale zu bearbeiten. Zu Den Bearbeitungsmöglichkeiten zählen in erster Linie das Verändern der Lautstärke, Mischen, Filtern (Biquad) sowie Laden und Speichern von Audio-Werten.

Der Utility Kern besteht aus einem Akkumulator (für DDS), einem Shaper, einem Adress-Generator, einem Wavetable-Speicher, einem Random-Number Generator, einigen Muxern, (einem Adress-Generator für SRAM, einem SRAM-Controller; diese sind allerdings nur nutzbar wenn man das ganze mit dem ISE 6.2 synthetisiert) und der schon angesprochenen Statemachine und dem MicroCode. Der MicroCode steuert (genau wie beim SDSP-Kern) dabei die einzelnen Komponenten des Utility Kerns. Dieser kern ist für das Erzeugen von Audio-Signalen zuständig, und erlaubt ein Audio-Signal zu verzögern, sofern man die ISE-Version 6.2 Verwendet (später dazu mehr). Als Wellenformen stehen Sägezahn, Rechteck (mit veränderbarem Puls/Pausen-Verhältnis), Rauschen sowie benutzderdefinierbare Wellenformen (Wavetable) zur verfügung.

Der Rahmen besteht aus einer Statemachine, einem Programm-Speicher, einigen Muxern, sowie einem doppelten I2S Sender-Empfänger (für 2 Stereo Ein- und Ausgänge). In dem Rahmen werden die beiden Kerne "eingehängt". Die Kerne werden vom Programmspeicher aus mit Daten versorgt, und von der Statemachine angetriggert. Der Programmspeicher (PMEM) ist als 512x32 Bit organisiert. Das heißt das ein Befehl im Programmspeicher 32 Bit Informationen enthält und der Audio-Prozessor max. 512 Befehle umfassen kann.

SDSP-Core

Struktur des SDSP-Kerns

Der eigentliche Kern des DAPs ist die MAC-Einheit. Mit ihr werden die grundlegenden Operationen Multiplikation und Addition durchgeführt. Es ist eine 32x32 Bit Einheit. Die Funktionsweise des Kerns ist eigentlich recht einfach. Die MAC-Einheit hat 2 Eingänge. Einer dieser Eingänge kann ein Audio-Signal, ein Wert aus dem Audio-Speicher (AMEM-BlockRAM) oder ein zuvor berechnetes Ergebnis sein. Der andere Eingang kann ein Koeffizient aus dem CMEM-BlockRAM oder eine Konstante (1.000, 0.000 oder -1.000) sein. Der Ausgang (32-Bit, hardgeclippt) geht auf das AMEM-BlockRAM und zum Ausgangs-Clipping. Das Ausgangsclipping schneidet das Audio-Signal auf 24-Bit zurecht. Die Adressen für die Speicher (AMEM und CMEM) werden im Address-Generator erzeugt. Dieser wird von außen mit einer 8-bit Basis-Adresse gespeist und erzeugt einen Offset zu den Eingangs Adressen. Er besitzt 2 setzbare Zähler und einige Multiplexer. Alle Steuerignale der Komponenten von einem weiteren aus BlockRAM (MMEM) versorgt. Weiterhin wird von außen eine Start-Adresse vorgegeben. Dadurch lassen sich quasi Opcodes mit von außen vorgegeben Parametern (Adressen) aufrufen. Das MMEM-BlockRAM wird nun einfach nur linear ausgelesen bis ein Stop-Bit gesetzt ist.



Util-Core

Struktur des Utility-Kerns

Beschreibung folgt


Opcodes des DAP

Diese 32 Bit eines Befehls teilen sich folgendermaßen auf :

  • 4 Bit = Opcode (für SDSP und Utility Kern gleich)
  • 2 Bit = noch leer
  • 1 Bit = Core Select (SDSP oder Utility)
  • 1 Bit = Ende des Programms
  • 4 Bit = Eingangs-Routing (Kanal 1 - 4, Ergebnis SDSP Core, Ergebnis Utility Core)
  • 4 Bit = Ausgangs-Routing (SDSP-Ausgang auf Kanal 1-4, Utility Ausgang auf Kanal 1-4)
  • 8 Bit = Adresse 1 (bei SDSP für Audio-Memory, bei Utility Kern für Data Memory)
  • 8 Bit = Adresse 2 (bei SDSP für Koeffizienten-Memory, bei Utility Kern unbenutzt)

Das Eingangsrouting bestimmt mit welchem Signal der gewählte Kern arbeiten soll. Dies können die Eingänge 1-4 sein, aber auch ein vorher berechnetes Ergebnis des SDSP- bzw. Utility-Kerns sein. Das Ausgangsrouting bestimmt von welchem Kern das Signal auf welchen Ausgang geroutet wird.

Die Opcodes des DAPs sind:

SDSP-Kern:

  • Biquad rechnen
  • Audio Wert speichern
  • Audio Wert laden
  • Move eines Wertes im Audio-Speicher
  • Summe resetten
  • Eingang zu Summe addieren
  • Wert aus dem Audio-Speicher zu Summe addieren
  • Eingang zu summe mischen (mit Lautstärke Koeffizient)
  • wert aus dem Audio-Speicher zu Summe mischen (mit Lautstärke Koeffizient)
  • Lautstärke

Utility-Kern:

  • Oszillator (DDS-Teil)
  • Waveshaper
  • Delay

Der Ablauf eines Audio-Programms ist folgender:

Sobald ein neues Sample anliegt, wird die Abarbeitung des Programms von Adresse 0x0000 an im PMEM angestossen. Es wird dabei jeweils ein Befehl geladen und Daten wie Opcode und Adressen liegen dabei an beide Kernen gleichermaßen an. Ist das Programm-Ende Bit nicht gesetzt so wird der jeweilige Kern (mit dem im Opcode angegeben Routing) angetriggert. Legt der betreffende Kern sein Ready Signal auf 1, so wird der nächste Befehl abgearbeitet. Dieses Verhalten (Laden und Verteilen von Opcode-Daten, sowie die Ablaufsteuerung; also das Antriggern des Programms, Antriggern der einzelnen Kerne, warten auf dessen Abarbeitung und das Programm-Ende) wird vom Rahmen übernommen.

Speicherorganisation

Alle Speicher die vom DAP angesprochen werden haben eine Wort-Breite von 32 Bit, der Zugriff erfolgt aber ausschließlich über 8 Bit Breite (Interface).

DAP

  • Programmspeicher (PMEM) 0x0000 - 0x07ff

SDSP

  • Audio-Speicher (AMEM) von außen nicht zugänglich
  • Koeffizienten-Speicher (CMEM) 0x2000 - 0x2023 (man "sieht" nur den Hidden Write -> später mehr dazu)
  • Microcode-Speicher (MMEM) 0x4000 - 0x47ff

Utility-Core

  • Daten-Speicher (DMEM) 0x6000 - 0x67ff
  • Wavetable Speicher (WMEM) 0x8000 - 0x87ff
  • MicroCode-Speicher (UMEM) 0xa000 - 0xa7ff

Hidden-Write

Um bei Änderung der Koeffizienten "Knackser" zu vermeiden (die dadurch entstehen das der Koeffizient nur teilweise [durch 8 Bit Zugriffe] geändert wird, währenddessen aber Audio trotzdem noch "weiterläuft", und mit "falschen" Zwischenwerte gerechnet wird) ist ein Mechanismus implementiert der die zu ändernden Koeffizienten im Hintergund in den Speicher schreibt. Um diesen Mechanismus zu nutzen müssen zuerst die Koeffizienten in interne Register geschrieben werden. Die Register (es sind 8 32 Bit Register) liegen im Speicherbereich 0x2000 bis 0x201f. Die Speicherstelle 0x2020 gibt die Start-Adresse innerhalb des Koeffizienten Speichers an. Diese Adresse ist nur 8 Bit breit. Die Speicherstelle 0x2021 gibt an wieviele der 8 Register übertragen werden sollen. Die Speicherstelle 0x2022 triggert den Kopier-Vorgang an. Hier reicht es ein Dummy byte zu schreiben. Um den Kopiervorgang zu beenden (MUß GEMACHT WERDEN!!, sonst können keine weiteren Koeffizienten Updates gemacht werden) schreibt man an Speicherstelle 0x2023 ebenfalls ein Dummy Byte.

I/O Register

Es gibt noch einen 8-Bit breiten Adress-Bereich innerhalb des DAPs mit dem der I2S-Teil gemutet werden kann. Weiterhin hat man die Möglichkeit die Anzahl der System-Takte pro Sample und die Anzahl der aktiven System-Takte (also die Zeit die der Audio-Prozessor beschäftigt ist) zu ermitteln. Dadurch lässt sich eine Auslastungsanzeige des DAPs realisieren.


Interface

Um von außen nun ein Programm (bzw. Koeffizienten und Daten) zu laden ist ein Interface implementiert, welches einfach zu handhaben ist und einfach erweitert werden kann. Das Interface kann per RS232 (fest eingestellt auf 115,2kBaud) oder per SPI (wird Hardware-Mässig eingestellt) angesteuert werden. Das Interface in seiner Gesamtheit ist schichtweise aufgebaut und beginnt mit einem Data-Dispatcher. Dieser Data-Dispatcher entscheidet (nach dem dieser selektiert wurde) mit dem ersten Byte, an welches angeschlossene Gerät der weitere Datenstrom geleitet wird.

Als angeschlossene Geräte sind im aktuellen Design ein Gerät namens "StdIO" und der Audio-Prozessor angeschlossen.

Das "StdIO" Gerät steuert die 7Segment-Anzeige (16-Bit Hexadezimal Anzeige oder 32-Bit Einzelsegment Anzeige), die 8 Leuchtdioden, und erlaubt es die 3 Drucktaster sowie die 8 Schiebeschalter auszulesen.

Der Audio-Prozessor besteht (Interface-seitig gesehen) nur aus einem Speicher-Zugriffs-Interface. Dieses Speicher-Interface entscheidet mit dem ersten Byte (sobald es selektiert wurde) ob in den Speicher geschrieben, von diesem gelesen, ein I/O Schreib oder Lese Zugriff erfolgen soll. Die Folgenden 2 Bytes (im Falle eines I/O Zugriffs nur 1 Byte) bestimmen die Adresse und damit den Speicher-Bereich des Audio-Prozessors auf den Zugegriffen werden soll. Das Speicherinterface besitzt einen Autoincrement, mit dem fortalufende Bytes einfach hintereinander weggeschrieben werden können, ohne das jedesmal wieder der FPGA, das Gerät und die neue Adresse neu geschrieben werden müssen, was den Zugriff erheblich beschleunigt.


Ursprünglich basierte das System auf einem SPI-Interface. Dabei wurde die Chip-Select Leitung als "globaler" Interface Reset betrachtet, d.h. war die Leitung auf High, war der FPGA Deselektiert und und alle Interface-Statemachines wurden im Reset gehalten. Erst mit dem Setzen dieser Leitung wurde der FPGA angesprochen. (erstes Byte -> Daten-Dispatcher, folgende Bytes gehen an das Gerät, wenn eines ausgewählt wurde). Weiterhin hat SPI die Eigenschaft das mit jedem gesendeten Byte auch eines Emfpangen wurde. Der Umstand das RS232 weder eine Chip-Select Leitung benötigt, noch eine synchrone Übertragung erzwingt führt zu dem Umstand das man bei Nutzung von RS232 einige Befehle zusätzlich benötigt. Diese Befehle werden durch das Zeichen 0x1b (ESC) eingeleitet. Soll statt der "Spezial-Funktion" das Byte 0x1b übertragen werden, so wird dieses einfach erneut gesendet. Soll die Chip-Select leitung gesetzt bzw. gelöscht werden so wird die Sequenz 0x1b 0x00 (Selektieren) bzw. 0x1b 0x01 (Deselektieren) gesendet. Soll ein zuvor im Ausgangsregister gesetztes Byte gesendet werden so muß die Sequenz 0x1b 0x02 gesendet werden.

Beispiele:

0x121b auf dem 7 Segment Display per RS232 Anzeigen:

  • - ESC 0x00 (FPGA Selektieren)
  • - 0xf0 (StdIO Selektieren)
  • - 0x00 (Hi Byte der 7 Segment Hex Anzeige wählen)
  • - 0x12 (Wert 12)
  • - ESC 0x01 (FPGA Deselektieren)
  • - ESC 0x00 (FPGA Selektieren)
  • - 0xf0 (StdIO Selektieren)
  • - 0x01 (Lo Byte der 7 Segment Hex Anzeige wählen)
  • - 0x1b 0x1b (Wert 1b -> zu beachten: wenn der Wert 0x1b übertragen werden muß, muß dieser doppelt gesendet werden !!)
  • - ESC 0x01 (FPGA Deselektieren)

Beispiel um in den Programmspeicher des Audio-Prozessors an Adresse 0x0010 das Langwort 0x12233445 zu schreiben:

  • - ESC 0x00 (FPGA Selektieren)
  • - 0xf1 (DAP Selektieren)
  • - 0x00 (Speicher Schreiben)
  • - 0x00
  • - 0x10 (Adresse 0x0010 -> PMEM Adresse 0x010)
  • - 0x12 (Adresse 0x0010 -> 0x12)
  • - 0x23 (Adresse 0x0011 -> 0x23, autoincrement)
  • - 0x34 (Adresse 0x0012 -> 0x34, autoincrement)
  • - 0x45 (Adresse 0x0013 -> 0x45, autoincrement)
  • - ESC 0x01 (FPGA Deselektieren)

Auslesen der 8 Schalter:

  • - ESC 0x00 (FPGA Selektieren)
  • - 0xf0 (StdIO Selektieren)
  • - 0x04 (Schalter auslesen)
  • - 0x00 (dummy byte -> überträgt Schalter-Stellung in Ausgabe-Register)
  • - ESC 0x02 (Ausgabe Register übertragen, danach empfängt man die 8 Schalterstellungen binär-codiert)
  • - ESC 0x01 (FPGA Deselektieren)

Der Datendispatcher (welcher mit dem ersten Byte nach dem Selektieren des FPGAs [0x1b 0x00] angesprochen wird) hat weiterhin einige nützliche Funktionen die in Ihrer Gesamtheit allerdings noch nicht ausführlich getestet wurden. Darunter sind Funktionen mit denen Inrformationen über die an den Ports des Daten-Dispatchers angeschlossenen Geräte zu ermitteln. Dieses Feature kann dazu genutuzt werden um zu ermitten welche Geräte im FPGA implementiert sind und an welchen Ports welche Geräte angeschlossen sind.

Anzahl der Ports des Daten Dispatchers liefern:

  • - ESC 0x00 (FPGA Selektieren)
  • - 0xed (Anzahl Ports lesen)
  • - 0x00 (dummy byte -> überträgt Inhalt des Ausgabe-Registers)
  • - ESC 0x02 (Ausgabe Register übertragen, danach empfängt man 0x22)
  • - ESC 0x01 (FPGA Deselektieren)

DAP-Modul-Schnipsel

Um mal "eben" mit dem DAP zu spielen, ein paar Schnipsel die sich recht leicht zu kompletten Funktionsblöcken zusammenschließen lassen. Es werden hier nur die RS232 Sequenzen mit einer kurzen Erklärung aufgelistet.

  • Dual Mono Biquad
  • ESC 0x00 - FPGA Selektieren
  • 0xF1 - DAP Auswählen
  • 0x00 0x00 0x00 - Memory Write (Adresse 0x0000 -> Program Memory)
  • 0x10 0x00 0x00 0x08 - Biquad mit Kanal 1 (0) rechnen (AMEM = 0x00;CMEM = 0x08) und auf Kanal 1 (0) ausgeben
  • 0x10 0xf0 0x08 0x10 - Biquad mit vorherigem Ergebnis (0xf) rechnen (AMEM = 0x08; CMEM = 0x10) und auf Kanal 1 (0) ausgeben
  • 0x01 0x00 0x00 0x00 - Audio Programm Ende (wichtig !!!)
  • ESC 0x01 - DAP & FPGA deselektieren

Erklärung :

Der Aufbau des Opcodes 0x100008 deutet an, das ein Biquad durchgerechnet werden soll. Das Eingangsregister 0 bedeutet das Kanal 1 des 1. Codecs verwendet wird. Das Ausgangsregister welches nach Fertigstellung des Ergebnisses benutzt werden ist 0 (-> Kanal 1 des 1. Codecs). Der Teil 0x00 0x08 bedeutet hierbei, das die Biquad-Koeffizienten im CMEM ab Adresse 0x08 stehen. Die Audio-Zwischenwerte werden im Audio-Speicher AMEM ab Adresse 0x00 gelegt. Der zweite Opcode (0x10f00810) rechnet ebenfalls ein Biquad durch. Nur das hier statt Kanal 1 des Codecs das voher vom SDSP berechnete Ergebnis verwendet werden soll (Kanal 0xf, wenn man so will). Ausgangsregister ist auch hier wieder Kanal 1. Da dieser Biquad unabhängig vom ersten (d.h. mit anderen Parametern) gerechnet werden soll, sind hier logischerweise auch andere Adressen für AMEM (0x08) und CMEM (0x10) angegeben. Die CMEM-Adresse ist dabei etwas unkritischer, da es ja durchaus sein kann das ein Audio-Signal zweimal mit den selben Biquad-Werten gerechnet werden soll, bzw. unterschiedliche Kanäle mit den selben Biquad-Werten, z.b. bei einem Stereo-Equalizer. Kritischer ist allerdings die Verwendung der AMEM-Adresse. Diese sollte für jede Operation (sofern AMEM denn verwendet wird) unterschiedlich sein, vor allem bei der Berechnung von Biquads. Dies hat den Grund das bei Operationen, die dieselben AMEM Adressen haben die vorher berechneten Werte überschrieben werden. Dies ist bei Biquads gaanz böse (kann u.u. SEHR laut werden), und vom Ergebnis her nicht vorhersagbar.

Hardware

Fpga ext board schematic no uc.JPG

Wie Eingangs erwähnt benötigt das System eine (bzw. zwei) Audio-Codecs. Im aktuellen Schaltplan wird auf einen Mikroprozessor verzichtet. Dieser diente im System erstmal nur zu Initialisierung der Codecs. Dieser Vorgang kann nun vom PC aus gesteuert werden, da in der neuen ISE 6.2 Version 4 Leitungen herausgeführt wurden, welche per RS232 gesetzt und gelöscht werden. Wer das System nachbauen möchte kann entweder die TLV320AIC23B Codecs, aber auch beliebige andere Codecs verwenden, solange einer als Master und der andere als Slave arbeitet und beide auf den I2S Modus mit 64FS und 20 Bit Wortlänge eingestellt sind. Die Initialisierung dieser Codecs muß dann aber separat vorgenommen werden (wobei man dann wahrscheinlich nicht um einen uC drum herum kommt). Um das System zu Testen (Programme und Koeffizienten in den DAP einzuspielen) wird lediglich eine serielle Schnittstelle verwendet. Wer will kann aber genausogut den SPI-Modus verwenden und den DAP direkt von einem Mikrocontroller aus steuern. Zur Auswahl der verwendeten Schnittstelle (RS232 oder SPI) wird Pin 13 des B1-Connectors benutzt. Liegt dieser Pin auf GND so wird der FPGA per RS232 gesteuert. Liegt dieser Pin auf 3.3V so wird der FPGA per SPI gesteuert.

Hier der Schaltplan meines verwendeten Audio-Boards.

Hier noch die Pin-Belegung des B1-Expansion Connectors:

  • 01 GND
  • 02 VCC 5V
  • 03 VCC 3.3V
  • 04 N.C.
  • 05 SPI_CS - Chip Select (von uC nach FPGA)
  • 06 N.C.
  • 07 SPI_DI - SPI Data In (von uC nach FPGA)
  • 08 BCLK - Bit Clock (von Master Codec)
  • 09 SPI_CLK - SPI Clock (von uC nach FPGA)
  • 10 LRCLK - LR-Clock (von Master Codec)
  • 11 SPI_DO - SPI Data Out (von FPGA nach uC)
  • 12 SDOUT1 - zum D/A Wandler (Codec) 1
  • 13 IF_SEL - Interface Select (GND = RS232; VCC3.3 = SPI)
  • 14 SDIN1 - vom A/D Wandler (Codec) 1
  • 15 RXD_OUT - RS232 Signal vom MAX232 zum uC
  • 16 SDIN2 - vom A/D Wandler (Codec) 2
  • 17 TXD_IN - RS232 Signal vom uC zum MAX232
  • 18 SDOUT2 - zum D/A Wandler (Codec) 2
  • 19 GPO 3 - Chip-Select Codec 2
  • 20 N.C.
  • 19 GPO 2 - Chip-Select Codec 1
  • 20 N.C.
  • 19 GPO 1 - SPI-Data out
  • 20 N.C.
  • 19 GPO 0 - SPI-Clock Out
  • 20 N.C.

Nexys Board

Im SVN Repository (s.u.) gibt es eine Version des DAPs für das Nexys Board. Diese ist voll SW-Kompatibel zum alten Spartan 3 Board (allerdings z.Z. nur über RS232 steuerbar). Neu bei der Version ist das das Speicherinterface generisch ausgelegt wurde und ein einfacher SRAM-Controller für das Nexys Board PSDRAM geschrieben wurde. Durch das generische Interface ist es möglich andere Speicherarten anzubinden. Der verwendete Codec ist wie schon im bisherigen Projekt der TLV320AIC23B. Dieser wird via RS232 (6-pin Port A des Nexys Boards) über die GPO Leitungen (6-pin Port D des Nexys Boards) initialisiert. Die eigentlichen Datenleitungen des Codecs liegen an Port B (BCLK, LRCLK, DIN, DOUT).


Diese Version ist voll lauffähig (wurde mit den Demos getestet). Die Pin Belegung für die RS232 und den Audio-Codec ist wie folgt :

Header A : RS232 Schnittstelle

Pin 1 : RxD von MAX232
Pin 2 : TxD von MAX232
Pin 3 : -
Pin 4 : -
Pin 5 : GND
Pin 6 : VCC (3.3V/5V für MAX232/MAX3232)


Header B : I2S Schnittstelle für 1 Codec

Pin 1 : BitClk
Pin 2 : L/R Clk
Pin 3 : SDIN
Pin 4 : SDOUT
Pin 5 : GND
Pin 6 : VCC (3.3V für den Codec)


Header D : Codec-Konfiguration via SPI

Pin 1 : Codec 2 CS
Pin 2 : Codec 1 CS
Pin 3 : Codec SPI Data
Pin 4 : Codec SPI Clk
Pin 5 : GND
Pin 6 : VCC

DAP mit selbstgelötetem FPGA-Board

Auf einen Beitrag von Thomas Pototschnig hin bin ich auf sein selbstentworfenes Spartan-3-FPGA-Board (Grafikkarte) aufmerksam geworden. Thomas hat mir die Erlaubnis gegeben dieses Board für den DAP verwenden zu können und die Schaltpläne hier zu veröffentlichen. Nachdem ich von ihm noch einige Vorversionen (nur die Platinen) ergattern konnte und diese erfolgreich aufgebaut (mit Spartan 3-200 und -400) habe bin ich von diesem Board echt begeistert. Danke nochmals.

FPGA-Board.jpg

Hier der Schaltplan und Layout.

Media:miniFPGA-Board.zip

Das Board ist 2-seitig und die "schlimmsten" zu lötenden Bauteile sind lediglich der FPGA (QFP-144) und die beiden RAMs (SOJ36, ekelig). Der Rest ist recht einfach. Auch die Inbetriebnahme des Boards gestaltete sich recht einfach.

Den Quellcode für den DAP mußte ich etwas ändern und abspecken. Durch den ineffizienten VHDL-Code der MAC-Einheit gestaltete es sich schwierig das Design synthetisierbar zu machen. Das Synthetisieren auf einem FT256 gestaltete sich einfacher. Hier ist noch Handlungsbedarf in der Form das die MAC-Einheit überarbeitet werden muß. Das abgespeckte Design läuft auf dem FPGA-Board mit einem Spartan 3-400 sowie auf einem Spartan 3-200. Den Audio-Codec, das FPGA Board, einen AVR und noch etwas IO-Kram habe ich auf eine Lochraster aufgebaut. Was noch fehlt ist ein MIDI und ein SD/MMC-Karten Interface. Dann hat man eine schöne Plattform für Synthesizer und Effektgerät.



Anmerkung

Da wie schon gesagt das Projekt komplett auf meinem "Mist" gewachsen ist wird es wohl noch eine Weile dauern bis alles was den DAP betrifft hier in diesem Artikel (und auch in einem Dokumentations-PDF) eingearbeitet ist. Ich werde (sofern ich Zeit dazu habe) noch ein Delphi Programm mit Source-Code einstellen, welche den DAP richtig nutzbar macht und man dann direkt damit "spielen" kann. Eine umfangreiche und vollständige Dokumentation würde momentan einfach zu viel Zeit in Anspruch nehmen und ich möchte langsam das Projekt Vorstellen um Anregung, Kritik und Verbesserungsvorschläge ernten zu können. Ich hoffe noch Leute zu finden um diesem Projekt noch mehr Leben und Möglichkeiten einhauchen zu können.

Fotos

Hier mal in paar Fotos (Gemacht mit meiner unscharfen Handy-Kamera :-x) der Hardware.

Ursprüngliche Version:

Spartan3 Board und Expansion Board
Expansion Board


Nexys-Board:

Nexys Board mit 1 Audio-Codec
Nexys Board mit Lochraster-Board und 2 Audio-Codec-Boards (siehe Artikel Audio Codec Board)
2 Audio-Codec-Boards (siehe Artikel Audio Codec Board)


Aufbau von Benutzer:Andreas:

Nexys + Breadboard + 1 Audio Codec Board


Aufbau des DAPs mit FPGA-Board (entworfen von Thomas Pototschnig) auf Lochraster an AVR, Codec und weiterer IO


Synth Board. DAP mit AVR,Codec, MIDI Interface, RS232 (schaltbar) und LCD


Synth Board. Komplettansicht



Synth Board. Synth-Board




Selbstgeroutetes DAP-Board


Selbstgeroutetes DAP-Board



Selbstgeroutetes DAP-Board auf Trägerplatine


DAP-Board mit Touch-Display Seitenansicht


DAP-Board mit Touch-Display



DAP-Board plus UI-Board mit Potis, Schaltern, LED's im Synthesizer-Stil



Youtube Videos

DAP-Effekt-Demo des DAP-Boards mit Touch-Display:

{{#ev:youtube|LUvqG7hGzsg}}


DAP-Synthesizer-Demo des DAP-Boards mit Touch-Display:

{{#ev:youtube|lSO267qKo14}}

Audio Demos

Ein EQ-Demo mit Rosa Rauschen. Klingt wie eine Meeresbrandung.

Media:eq_demo1.zip

Der DAP als Synth. Der DAP wird komplett vom PC aus gesteuert (Hüllkurve, Sequencer und Filterberechnung werden im PC gemacht).

Media:synthdemo1.wav.zip


MC505 Demos

Die folgenden Demos stammen von meiner Roland-MC505 Groovebox. Es wird einfach nur ein Werkspreset abgespielt und durch den DAP gejagt.


Synth Board Audio Demos

Die folgenden Demos stammen vom DAP in Verbindung mit einem AVR der die Filterkoeffizientenberechnung sowie eine komplette Synthesizer-Steuerung beinhaltet, also qausi einen Synthesizer aus dem DAP macht (inkl. MIDI-Steuerung).

MIDI-Sequenz und Tiefpass-Filter (Filter und Modulation über MIDI gesteuert) :

Media:Dap-syn-demo-01.mp3

Diesselbe MIDI-Sequenz mit Hochpass-Filter (Filter und Modulation ebenfalls über MIDI gesteuert) :

Media:Dap-syn-demo-02.mp3

Ein eher Techno-ähnliches Demo, welches die Auflösung des Systems (DAP+AVR+MIDI) ein wenig zeigt.

Media:Dap_syn_demo_03.mp3

Delphi Tools

Um den DAP nutzbar zu machen benötigt man entweder ein uC Programm oder ein PC Programm. Da das verwenden von PC-Programmen einfacher fürs Spielen und Experimentieren ist, werde ich hier im Laufe der Zeit kleine Demo-Programme aber auch komplette Front-Ends für den DAP reinstellen. Die Delphi-Programme sind allesamt in Turbo-Delphi geschrieben und die dazugehörigen Quellcodes werden ebenfalls im Laufe der Zeit geuploaded. Ich werde allerdings zuerst noch das Feature des Konfigurierens der Codecs vom PC aus einbauen. Nachtrag zum Konfigurieren des Codecs : Prinzipiell funktioniert es, allerdings ist das mit häßlichen Nebengeräuschen verbunden, da ich bei jeder Änderung der Lautstärke im Codec, diesen auch Resetten muß, da sonst immer beide Codecs beschrieben werden, was unschön ist. Warum dies so ist kann ich leider nicht sagen, da ich keine Möglichkeit habe die SPI-Leitungen mitzusniffen (bräuchte dafür einen kleinen LA, den ich nicht habe).


Es folgen noch der Quellcode für den Mischer (hab ich gerade nicht zur Hand) und weitere Demos (ein Synthesizer und eine 4x4 Patchbay mit EQ und was mir sonst noch einfällt. Dann natürlich mit Source-Codes). Anhand dieser Beispiele wird auch eine grobe Doku erstellt.

SVN-Repository

svn co svn://mikrocontroller.net/audiodsp

Ein automatisch aktualisiertes Paket mit den Daten aus dem Repository gibt es unter http://www.mikrocontroller.net/download/audiodsp-snapshot.tar.gz.


Änderungen

  • 12.07.2007: Es wurde ein generisches Speicherinterfaces welches Wartezyklen im DAP erlaubt implementiert. Dadurch kann man auf die jeweilgen Speicher des Boards eingehen. Z.Z. ist nur ein einfaches Speicherinterface für den asynchronen Betrieb des PSDRAM des Nexys Boards implementiert. Das Interface ermögicht es einen RAM Controller anzuschließen welcher z.B. ein quasi-Multiport RAM darstellt. Getestet wurde der Stand mit dem Nexys-1000 Board.

To do

--nähere Zukunft--

  • Einen Konfigurationsdialog in die Demo-Programme einarbeiten mit denen man mit den Codecs etwas spielen kann (Line-In Level, Mikrofon-Level, Bypass, Head-Phone Volume) tlw. erledigt. Funktioniert aber nicht richtig, und daher noch nicht eingebaut. Quellcodes dazu sind vorhanden.
  • Doku anhand der Demo-Programme erstellen
  • C-Code schnipsel erstellen

--fernere Zukunft--

  • Front-End des DAPs machen, mit dem sich DAP-Programme erstellen lassen, der Koeffizienten-, Daten- und Wellenform-Speicher beschrieben und gelesen werden kann, der Mikro-Code editierbar gemacht wird und noch ein paar Sachen mehr machbar sind
  • weitere Module für den Rahmen (HDD-Core, weitere Routing-Möglichkeiten innerhalb der bisherigen Cores SDSP und Util)

Diskussion