www.mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP BF533 Eval mit AD1836, I²S, Sampling Frame bearbeiten


Autor: Christoph G. (huecksy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo an alle,
ich bin neu hier und hoffe Ihr könnt mir zu mehr Verständnis verhelfen. 
Ich hab folgendes Problem. Ich bin gerade dabei ein ADSP-BF533 EZ-KIT 
Lite Board in Betrieb zu nehmen. Analog hat einige Beispiel Programme 
mitgeliefert und ich habe die I²S Software aufgespielt (C). Soweit 
funktioniert das auch, jedoch möchte ich nun das Signal verstärken und 
verstehe nicht in welchem Format die Audioframes vom Codec kommen.
Laut der I²S-specifications müsste das Signal in "two’s complement with 
the MSB first" übertragen werden.
Nun passieren zwei Dinge, die ich nicht verstehe:
1. Wenn ich mir beim Debugging ein Audioframe anzeigen lasse, ist der 
Wert immer positiv und hat einen Wert zwischen 30000 und 60000
2. Wenn ich den Wert eines Audioframes zur Verstärkung mit Ganzzahligen 
Werten multipliziere ist das Ergebnis ok (wird verstärkt und lauter) 
wenn ich mit einem gebrochenen Wert multipliziere hört sich das Ergebnis 
verzerrt oder übersteuert an.
Als Konsequenz muss ich sagen, das ich nicht verstehe in welchem Format 
das Signal vorliegt.
Ich habe einen Sinus programmiert und an das Codec (AD1836) geschickt 
und das wird scheinbar richtig ausgegeben (1kHz hörbar) . Hier noch der 
Quellcode, mit der das Codec Initialisiert wird.
//--------------------------------------------------------------------------//
// Function: Init1836() //
// //
// Description: This function sets up the SPI port to configure the AD1836. //
// The content of the array sCodec1836TxRegs is sent to the //
// codec. //
//--------------------------------------------------------------------------//
void Init1836(void)
{
int i;
int j;
static unsigned char ucActive_LED = 0x01;
// write to Port A to reset AD1836
*pFlashA_PortA_Data = 0x00;
// write to Port A to enable AD1836
*pFlashA_PortA_Data = ucActive_LED;
// wait to recover from reset
for (i=0; i<0xf0000; i++) asm("nop;");
// Enable PF4
*pSPI_FLG = FLS4;
// Set baud rate SCK = HCLK/(2*SPIBAUD) SCK = 2MHz
*pSPI_BAUD = 16;
// configure spi port
// SPI DMA write, 16-bit data, MSB first, SPI Master
*pSPI_CTL = TIMOD_DMA_TX | SIZE | MSTR;
// Set up DMA5 to transmit
// Map DMA5 to SPI
*pDMA5_PERIPHERAL_MAP = 0x5000;
// Configure DMA5
// 16-bit transfers
*pDMA5_CONFIG = WDSIZE_16;
// Start address of data buffer
*pDMA5_START_ADDR = (void *)sCodec1836TxRegs;
// DMA inner loop count
*pDMA5_X_COUNT = CODEC_1836_REGS_LENGTH;
// Inner loop address increment
*pDMA5_X_MODIFY = 2;
// enable DMAs
*pDMA5_CONFIG = (*pDMA5_CONFIG | DMAEN);
// enable spi
*pSPI_CTL = (*pSPI_CTL | SPE);
// wait until dma transfers for spi are finished
for (j=0; j<0xaff0; j++) asm("nop;");
// disable spi
*pSPI_CTL = 0x0000;
}
Hier noch ein paar weitere Daten:
- Datenübertragung mittels I²S
- Abtastrate 48kHz mit 16 Bit Auflösung

Vielleicht kann mir ja jemand auf die Sprünge helfen. Ich möchte später 
noch weiteren Code einfügen in dem dann einige Filter laufen sollen. 
Dazu muss ich aber erstmal verstehen wie die Daten vorliegen die ich 
dann bearbeiten möchte.
Vielen Dank schon mal fürs lesen und erst recht für jeden Hilfeversuch!

Autor: Christoph G. (huecksy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm, so richtig komme ich allein nicht weiter.

Das AD1836 legt mir das Audioframe mit 16 oder 24 Bit (je nach 
Einstellung) in den Speicher des DSP. Ich vermute das hier das MSB 
"verloren geht" bzw nicht mehr erkannt wird.
Das ist die einzige Erklärung, weshalb mir immer nur positive Zahlen 
während des Debuggings angezeigt werden.
Ist bei jemandem schon mal etwas ähnliches aufgetreten oder ist mein 
Ansatz falsch?

Ich programmiere das erste mal embedded und hab noch keine Erfahrung in 
dem Bereich.

Autor: Christoph G. (huecksy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, ich habs gelöst, glaub ich :)
Beim Auslesen des vom Codec ankommenden Audioframes geht das Vorzeichen 
unter. Das liegt daran, dass das Codec AD1836 mit 24 Bit codiert, ich 
das Frame aber in eine 32 Bit Int Variable schreibe.
Die Lösung die ich jetzt nutze ist, die Daten um 8 Bit nach links zu 
shiften und ich dann eine Multiplikation zur Verstärkung oder eine 
Division zur Dämpfung rechnen kann. Anschließend shifte ich zurück und 
lass an das Codec zurück übergeben.
Ich glaube zumindest das es daran liegt?!?

Autor: Strubi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Christoph,

klingt schluessig, also so, als ob du auf dem richtigen Weg waerst.
Arbeite zwar nur mit den GNU-Tools, aber soweit ich mich erinnere, gab 
es bei VDSP diverse Moeglichkeiten, Memory-Inhalte zu plotten.
Im Endeffekt reduzieren sich deine Probleme in diesem Fall wohl auf die 
Datenformate (Konfiguration, unsigned/signed, usw.). Fuer die 
Audio-Verarbeitung empfiehlt sich ev. fuer spaetere Optimierung, die 
Assembler-Instructionen genau zu studieren, manche davon normieren, 
runden, und begrenzen die Rechenergebnisse im gleichen Zyklus.

Viel Erfolg!

- Strubi

Autor: Christoph G. (huecksy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Strubi,

ich denke das es der Vorzeichenverlust Aufgrund des nicht erkannten MSB 
gewesen ist. Ich bin aufgrund dieses Forenbeitrags darauf gekommen.
http://ez.analog.com/thread/1229?tstart=0
In jedem Fall werden mir jetzt beim Debugging auch negative Zahlerwerte 
angezeigt.

> Fuer die
> Audio-Verarbeitung empfiehlt sich ev. fuer spaetere Optimierung, die
> Assembler-Instructionen genau zu studieren, manche davon normieren,
> runden, und begrenzen die Rechenergebnisse im gleichen Zyklus.

vielen Dank für den Hinweis. Momentan bin ich erstmal froh das es jetzt 
überhaupt läuft. Aber ich werde später bestimmt noch einiges Optimieren.

> bei VDSP diverse Moeglichkeiten, Memory-Inhalte zu plotten.

Das habe ich auch gelesen, bin mit dem Plotting-tool nicht so richtig 
warm geworden. Es gibt x verschiedene Einstellmöglichkeiten, aber 
irgendwie sah die resultierende Kurve immer murks aus.

Das Beispiel Programm von Analog "Audio Codec Talkthrough - I2S (C)" 
sieht vor das sämtliche Algorithmen innerhalb eines Interrupts 
abgearbeitet werden. Ist das üblich? Wenn ich einen sehr 
rechenintensiven Filter dort laufen lasse, kann es doch passieren das 
mein Zeitfenster bis zum nächsten Interrupt nicht ausreicht um den 
Interrupt "ordentlich" zu beenden, oder?

Grüße, Christoph

Autor: Strubi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Christoph,

Die Daten wuerde ich auch nicht im Interrupt bearbeiten. Leider sind die 
Examples aus dem VDK etwas 'sparsam'. Die typische Vorgehensweise ist 
die:

1. Stichwort Ping-Pong-Buffer: zwei verkettete DMA-Buffer, die per DMA 
laufend vom SPORT gefuellt wuerden.
2. Wenn ein Buffer voll ist, wird ein Interrupt ausgeloest, in der 
IRQ-Routine fuehrst du die Zeiger nach
3. Im 'user space' holst Du die Daten aus dem vollen Buffer und 
verarbeitest sie moeglichst in Echtzeit (was beim Blackfin kein Problem 
sein sollte).

Bei der Soundverarbeitung willst Du ja moeglichst geringe Latenzen, 
deswegen kurze Buffer queues. Wenn allerdings andere Sachen das System 
ausbremsen, musst du aus dem Ping-Pong-Buffer eine laengere 
Ring-Buffer-Queue machen - damit reisst Dir der Datenstrom nicht ab, 
aber du hast halt groessere 'latencies'.

Fuer ein Effekt-Geraet, das gleichzeitig I/O macht, hat man dann 
normalerweise zwei Queues, und laesst einfach den DMA immer weiter 
laufen.
Der Gag am Blackfin ist die echt starke DMA-Engine - die Verarbeitung 
also nur mit einem Mindestbedarf an Interrupts zu loesen, spart Dir 
massiv Rechenzeit.

Gruss,

- Strubi

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.