Hallo,
ich habe ein kleines bis mittelgroßes Problem, bei der Lösung könnt Ihr
mir sicherlich helfen. Ich nehme alle Hinweise gerne an! Vielen Dank für
eure Zeit und Mühe!
Ich probiere gerade ein Waveplayer zu schreiben für den
STM32F407(benutze das Discoveryboard) mit der Entwicklungsumgebung SiSy
in UML.
Das Problem beschreibt sich wie folgt, ich schicke Daten an den SPI3
bzw.
I2S. Erst nach einer längeren Zeit (~1-2 Minuten) kann ich mit meinen,
an den Klinkestecker angeschlossenen Kopfhörer einen Ton hören.
Meine Quellen sind:
http://www.mind-dump.net/configuring-the-stm32f4-discovery-for-audio,
das Manual des CS43L22 und das Reference Manual. Ich habe mir bereits
das Beispiel von ST angeschaut und kann leider daraus keine sinnvollen
Informationen für mich akquirieren.
Ich weiß auch nicht, ob ich einen Fehler bei der Initialisierung des
Audiodacs oder des I2S gemacht habe. Jetzt zum Quellcode ( im Anhang
findet sich ein SiSy-Archiv).
onStart
1
audiodac.init();
2
led2.on();
3
i2s.init();
4
led3.on();
5
waitMs(1000);
6
7
led3.on();
8
9
I2S_Cmd(SPI3, ENABLE);
10
11
while(1)
12
{
13
if ((SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE)))
Bei deinem Problem kann ich dir leider nicht helfen,
aber ich habe mich bei meinem Board ebenfalls an die Anleitung von
"mind-dump" gehalten bzw. den Code von dieser Seite verwendet.
Bei mir läuft der CS43L22 sofort los.
was ich komisch finde:
du sendest zusätzlich zu den 16-bit Daten, nochmal kurz darauf andere
Daten.
Du solltest pro "Flag"-Anzeige nur ein Datenpaket senden.
mach lieber sowas wie:
if(zähler==0)
daten1 senden
zähler=1
if(zähler==1)
daten2 senden
zähler=0
Ich sende wesentlich langsamer Daten, als in deiner Variante.
Mittlerweile habe ich das Problem gelöst, ich habe vergessen vor dem
Initialisieren des DAC's seinen Reset auf Low zu ziehen.
Zwischenzeitlich hatte ich das Problem, dass es immer wieder Aussetzer
beim senden von Daten gab. Kurioserweise geschieht das ohne die
LED-Klasse nicht mehr!
Jetzt werde ich probieren eine Wavedatei abzuspielen.
Ich bräuchte nochmal ein wenig Hilfe! Ich habe das Filesystem(FatFs)
angebunden und das Abspielen, der Sawwave klappt auch problemlos. Nun
stellt sich mir die Frage: Wie soll ich die Wavedatei auslesen? Bringt
das Filesystem eine Funktion mit, mit welcher ich die Datei Stück für
Stück auslesen und abspielen kann?
Vielen Dank und Freundliche Grüße!
@ Cel (Gast)
>stellt sich mir die Frage: Wie soll ich die Wavedatei auslesen?
Stückwese und über einen Software-FIFO.
>Bringt>das Filesystem eine Funktion mit, mit welcher ich die Datei Stück für>Stück auslesen
Ja. das normale fread() oder wie auch immer sie heißt.
>und abspielen kann?
Da muss man selber einiges tun.
Okay, Danke für die Hilfe, ich habe bisher folgendes:
1
File fa;
2
3
if(fa.open("/test.wav", true, false))
4
{
5
size = fa.getSize();
6
7
do{
8
fa.read((uint8_t*)&sample, 2);
9
i++;
10
}while(i < 22);
11
12
// Header überspringen
13
14
i=0;
15
16
do{
17
fa.read(((uint8_t*)&sample),2);
18
i2s.Datasend(sample);
19
i++;
20
}while(i <= size);
21
22
fa.close();
23
}
Leider funktioniert das bisher noch nicht! Der Grund dafür ist mir nicht
ganz klar.
Habe ich einen Denkfehler? Ich überspringe die ersten 44 Bytes des
Headers, folgend lese ich theoretisch die Daten der Wavedatei und gebe
sie über den I2S aus, leider ist nichts auf dem Kopfhörer zu hören.
2 Möglichkeiten;
-- Lesen geht nicht richtig
-- I2S Senden geht nicht richtig.
Lass einfach mal das Lesen weg und sende eine synthetischen Ton.
z.B. einen Sinus, den du dir vorher in eine kleine Tabelle schreibst.
Dann kann du hören, ob zumindest das geht. Und dann etnsprechend weiter
nach dem Fehler suchen.
Bei einen Read können immer Wartezeiten auftreten, falls wirklich mal
ein neuer Block vom Device geholt werden muss.
Deshalb buffert man im Normalfall mehr, und hat 2 Threads: einen zum
Lesen, einen zum Abspielen.
Danke PittyJ!
Wie schon oben geschrieben, lässt sich ein 'synthetischer Ton' ausgeben.
Auch das Lesen und schreiben funktioniert auf die SD - Karte.
Du hattest aber Recht mit den Wartezeiten, ich habe bei meinen Routinen
jetzt alle 'Debug' - Ausgaben u.ä. raus geworfen. Jetzt höre ich
zumindest wieder etwas( Rauschen und Knacken) und die Dauer stimmt über
den Daumen gepeilt, auch mit der Dauer der Audiodatei überein.
Du hattest also auch damit Recht, dass ich zwei Routinen brauch. Eine
zum lesen und in einen Buffer schreiben - die Zweite für das Lesen aus
dem Buffer und den I2S senden.
Ich habe die Routinen jetzt geschrieben. Über die Effizienz und
Schönheit lässt sich sicher streiten.
Aber, ich muss diese ja Quasi'-parallel' ab arbeiten? Hat dazu jemand
eine schöne Idee?
1
// Routine um zu schauen ob Ende der Datei erreicht ist
2
a=10000;
3
i=0;
4
5
if(size > (sizeof(buffer1))) // sizeofbuffer= 10.000, Buffer mit 10.000 Werten befüllen, wenn mehr als 10.000 Werte da sind