Hallo,
auch wenn es einigen schon aus den Ohren rauskommt, aber ich muss doch
eine MP3-Player-Frage
stellen.
Doch zunächst etwas Grundinformation.
Die Hardware:
- Atmega128 @ 16Mhz
- FTDI USB <-> RS232
- VS1001k @ 24.576MHz (als Quarz, ohne Taktverdopplung)
- SD-Karte 256MB mit der Hardwareansteuerung nach Ulrich Radig
(Widerstandsspannungsteiler)
Die SD-Karte liegt nicht am SPI sondern liefert die Daten an einen
freien Pin.
Zur Software:
Ich habe quasi einzelne Test gestartet, um zu schauen ob denn meine
Hardware überhaupt funktioniert.
- Zur Ansteuerung der SD-Karte habe ich auf den Code von Ulrich
zurückgegriffen, um zu sehen ob das
überhaupt funktioniert.
Fazit: Die Karte läuft wird jedesmal erkannt und die MP3 Datei wird
auch sauber an das Terminal-
programm übertragen
- Den VS1001k habe ich gemäß des Datenblattes bzw. der Application Notes
getestet.
Fazit: Ich kann Register lesen und schreiben und auch der Sinustest
läuft einwandfrei.
Nun habe ich mir nochmal den Code von Ulrich geschnappt und an folgender
stelle geändert (Ist nur ein Ausschnitt:
//Lese File und gibt es auf der seriellen Schnittstelle aus
7
for(uint32_tb=0;b<Size;b++)
8
{
9
fat_read_file(Clustervar,Buffer,b);
10
for(uint8_ta=0;a<512;a++)
11
{
12
//Warten auf DREQ
13
while(!(PORT_MP3_IN&(1<<DREQ))){;}
14
15
//Statt Ausgabe auf die Schnittstelle erfolgt die Ausgabe auf
16
//den VS1001K
17
while(Qte--)
18
{
19
PORT_MP3_OUT|=(1<<BSYNC);// BSYNC High
20
SPDR=Buffer[Qte];
21
PORT_MP3_OUT&=~(1<<BSYNC);// BSYNC Low
22
}
23
//printf ("%c",Buffer[a]);
24
}
25
}
26
}
27
28
printf("FERTIG!!\n");
So. Und nun zu meinen Fragen.
Warum klingt die Ausgabe so abgehakt?
Ist die Übertragung der Daten von der Karte zum Decoder zu langsam?
Und wenn ja, wie könnte ich sie beschleunigen?
Ich bedanke mich schon jetzt für eure Antworten. Und um eines vorweg zu
nehmen:
Ja, ich habe die Forumsuche in Anspruch genommen. Und ja, ich habe
gegoogelt. ;-)
Gruß
Niko
Warum das so ist, mußt Du selbst herausfinden, aber einige
"Denkanstöße":
1) Versuche es zuerst mit einer MP3-Datei mit niedriger Übertragungsrate
2) wenn DREQ signalisiert, daß Daten gesendet werden können, sende 16
Werte auf einmal (das spart Rechenzeit und ist zumindest bei VS1002
aufwärts erlaubt nach Datenblatt).
3) Die SD-Karte liefert die Daten evtl. nicht kontinuierlich - nach 512
Byte macht sie wahrscheinlich eine mini-Pause. Du mußt also dafür
sorgen, daß zu diesem Zeitpunkt der Puffer im VS10XX voll genug ist.
Viel Erfolg!
Genau diese Art von Antworten wollte ich haben. Sprich Denkanstöße :-)
Zu 1.)
Das habe ich schon probiert, macht aber keinen Unterschied. Meine
Testdatei hat 128kbits/s. Klingt aber genau wie eine 32kbits/s Datei die
ich zuvor getestet hatte.
Zu 2.)
Der VS1001k bekommt von mir sogar 32 Werte (in meine Codeausschnitt ist
das die Variable 'Qte').
Zu 3.)
Genau das scheint mein Problem zu sein. Aber wenn ich sehe wie andere
das machen die zusätzlich noch eine Anzeige und Bedienung dran haben,
dann kommen mir ein paar Zweifel auf ob ich das auch mal aufs End
bekomme.
Danke auf jeden Fall erstmal für deinen Input.
Bei 32kb/s sollte der VS10XX schon ins "Gähnen" kommen. Fat_Read_File
dauert dann wahrscheinlich zu lange. Schau mal, ob die Routine evtl. (in
Deinem Fall sinnlos) wartet, bis die Karte nach Sektor-Lesen "fertig"
meldet. Ansonsten kannst Du mal versuchen, direkt Sektoren zu lesen:
Nimm eine MP3-Datei (kopiert auf eine leere SD-Karte), such Dir den
Anfang mit einem Hex-Editor und lies dann Sektoren - da spartst Du den
Zeitaufwand für die Interpretation der FAT.
Und: Probier doch mal die SD-Karte an den Hardware-SPI anzuschließen und
den VS10XX anderswo - so haben es fast alle hier gemacht, glaube ich -
von und zur SD-Karte müssen mehr Daten übertragen werden also zum VS10XX
(Sektornummern, ProtokollBytes, ...)
Schließlich kannst Du noch probieren, wie lange es dauert, die Datei zu
lesen, ohne auf DREQ zu achten - wenn es fast so lange wie die Spielzeit
oder sogar länger also die Spielzeit der Datei dauert, dann hast Du
ohnehin ein Zeitproblem, ganz unabhängig vom VS10XX..
> Der VS1001k bekommt von mir sogar 32 Werte (in meine Codeausschnitt ist> das die Variable 'Qte').
Und woher weist du, das im Buffer des VS Platz für 32 Werte ist?
@Carsten
Das werde ich wohl mal ausprobieren. Ich werde mich heute abend dazu
wohl nochmal äußern. Dann habe ich wieder Zeit zum Probieren.
@Knut
Da ich nich weiss was du meinst beantworte ich mal beide Möglichkeiten
auf deine Frage.
a)
Ich frage den Pin "DREQ" ab. Findet dort ein Pegelwechsel statt, dann
braucht der vs1001k Nachschub.
b)
Ich zitiere aus den Application Notes:
7.3.4 Sending SDI/MP3 Data (01) //01 steht für den vs1001k
The following algorithm may be used to send a 32-byte or smaller MP3
data chunk to VS1001k:
Oh, du hast recht, ich war etwas irritiert. Ich dachte, der VS kann bei
DREQ max. 16 Byte aufnehmen, daher meine Frage. Aber so wie du es
gemacht hast, ist es natürlich richtig.
Mach das auf jeden Fall mal, was Carsten vorgeschlagen hat.
@Cute Knut
>> Der VS1001k bekommt von mir sogar 32 Werte (in meine Codeausschnitt ist>> das die Variable 'Qte').>Und woher weist du, das im Buffer des VS Platz für 32 Werte ist?
RTFM.
"The DREQ signal of the data interface is used in slave mode to signal
if VS1001k’s FIFO is capable of
receiving more input data. If DREQ is high, VS1001k can take at least 32
bytes of data. When there is
less than 32 bytes of free space, DREQ is turned low, and the sender
should stop transferring new data.
Because of the 32-byte safety area, the sender may send upto 32 bytes of
data at a time without checking
the status of DREQ, making controlling VS1001k easier for low-speed
microcontrollers."
@Niko
>Ich frage den Pin "DREQ" ab. Findet dort ein Pegelwechsel statt, dann>braucht der vs1001k Nachschub.
VORSICHT! Wenn DREQ HIGH ist, dann braucht der VS1001 neue Daten! Wenn
du einen Pin-Change Interrupt verwendest dann schiebst du möglicherweise
auch Daten rein wenn DREQ einen 1-0 Flanke macht. Das ist falsch, die
Daten landen im Nirvana.
Du darfst also nur auf DREQ=HIGH oder meinetwegen die steigende Flanke
0-1 reagieren.
MfG
Falk
P.S. To whom it may concern. Mein Mp3 Player, wenn auch nicht wirklich
neu und ohne schicke SD-Karte.
http://www.geocities.com/jacquesmartini/mptritium/mp3.htm
> Wenngleich schon etwas angestaubt.
Ok, dann sei es dir verziehen. Ansonsten hätte ich dir nämlich
erhebliche Defizite im zeichnen von Schaltplänen bescheinigen müssen.
@Knut
>> Wenngleich schon etwas angestaubt.>Ok, dann sei es dir verziehen. Ansonsten hätte ich dir nämlich>erhebliche Defizite im zeichnen von Schaltplänen bescheinigen müssen.
Ich war jung und naiv. ;-)
MFG
Falk
Für mich sieht der ganze Programmteil völlig vermurkst aus ;)
Ich hab mal ein paar Kommentare drangehängt.
uint8_t Qte=32;
if (fat_search_file("musik.mp3",&Clustervar,&Size,&Dir_Attrib,Buffer)
== 1)
{
printf("\nFile Found!!\n\n");
//Lese File und gibt es auf der seriellen Schnittstelle aus
for (uint32_t b = 0;b<Size;b++) // von 0 bis Dateigröße in 512 Byte
steps, b+=512 ?
{
fat_read_file (Clustervar,Buffer,b); // lies einen Sektor ? oder
nur ein Byte
for (uint8_t a = 0;a<512;a++) // spiele 512 Byte Sektordaten, a 32
Bytes pro Ausgabe, a+=32 ?
{
//Warten auf DREQ
while(!(PORT_MP3_IN & (1<<DREQ))){;}
//Statt Ausgabe auf die Schnittstelle erfolgt die Ausgabe auf
//den VS1001K
while(Qte--) // Buffer von hinten nach vorne auslesen, wie
ungewöhnlich
{
PORT_MP3_OUT |= (1<<BSYNC); // BSYNC High
SPDR = Buffer[Qte];
PORT_MP3_OUT &= ~(1<<BSYNC); // BSYNC Low
}
// Wo wird Qte wieder auf 32 gesetzt ?
//printf ("%c",Buffer[a]);
}
}
}
@ Knut
Na gut für dich mach ich eine Ausnahme ;)
Qte zählt von 32 auf Null.
Ein Sektor ist aber 512 Bytes groß.
Welche Variable wäre also besser geeignet ?
So. Nu gehts.
Ja. Der Code hatte noch ein paar Macken. Aber jetzt läuft er.
Schuld daran (sofern man überhaupt von Schuld sprechen kann) hat die
Funktion
fat_read_file(). Diese musste ein bischen angepasst werden, damit nicht
permanemt die FAT eingelesen wurde.
Ich komme wohl nicht drum rum mir die FAT16, oder besser gleich die
FAT32 nochmal genau anzusehen.
@Holger
Ja. Ok. Der Code ist nicht so sauber wie er sein sollte, aber das war
nur ein Flickwerk um meine Neugierde zu besiegen, ob ich mit meinem
Aufbau wirklich Musik hören kann. Ich gelobe hiermit Besserung und werde
den Quelltext nochmal so überarbeiten wie es sich gehört. :-)
Ich bedanke mich auf jeden Fall erstmal für euer Wissen, dass ich
anzapfen durfte.
File-zugriff kannst Du so machen:
http://sourceforge.net/projects/efsl/
In der Config stellst Du die Größe des Buffers ein um die FAT
zwischenzuspeichern.
Viel Spass damit
Mario
@ Niko
>So. Nu gehts.
Glaub ich nicht. Du prügelst Daten in SPDR ohne SPIF
abzufragen. Da hast du aber einen Compiler der unglaublich
schlechten Code erzeugt.
@Holger
Doch. Es geht. Mein oben beschriebener Codeausschnitt hat sich geändert.
Ausserdem:
>Der Code ist nicht so sauber wie er sein sollte, aber das war>nur ein Flickwerk um meine Neugierde zu besiegen, ob ich mit meinem>Aufbau wirklich Musik hören kann.
Mit der Betonung auf Flickwerk.
;-)
> for (uint8_t a = 0; a<512; a+=32)> Sieht doch schon besser aus, oder ?
Ich stehe wohl gerade auf dem Schlauch und bitte um Aufklärung :)
uint8_t ist ein unsigned char, d. h. 0..255
Der Verleich "a<512" bringt doch dann nichts, oder?
Vergesst den Quellcode er ist schlicht und ergreifend falsch.
Ich habe ihn während meiner Frühstückspause aus dem Kopf aufgeschrieben.
Er sollte eigentlich nur dazu dienen das Prinzip zu verdeutlichen wie
ich vorgegangen bin und woran es liegen könnte, dass die Musik Aussetzer
hatte.
Und wie bereits beschrieben:
>Schuld daran (sofern man überhaupt von Schuld sprechen kann) hat die Funktion>fat_read_file(). Diese musste ein bischen angepasst werden, damit nicht>permanemt die FAT eingelesen wurde.
Ich konnte ja nicht ahnen, dass es zu so einer Entrüstung über die paar
Zeilen Code kommen würde. :-)
Ich verspreche hiermit .
"Ich tue das nie nie wieder, dass ich Quellcode veröffentlichen werde,
der nur aus dem Gedächtnis entstanden ist und nicht vorher geprüft
wurde."
;-)
btw:
@Knut
Ja. Du hast recht es geht so nicht. Grund: Siehe Anfang dieser Antwort
:-)
Wenn aber Interesse besteht, dann werde ich den Codeausschnitt mal
einstellen, mit dem es nun läuft.
@ Niko
Wer sollte Interesse an Codes von so einem SCHLECHTEN
Programmierer haben ? Einem Programmierer der ABSICHTLICH
falschen und UNGEPRÜFTEN Code postet ! Was ist das für eine Art ?
Ich verstehe so etwas einfach nicht. Was läuft bei dir falsch ?
Alle folgenden Niko's die hier Fragen stellen, werden jetzt
möglicherweise keine Antworten mehr bekommen. Dafür bist
DU verantwortlich.
Deine Codeschnipsel kannst du dir an die Pinwand heften !
Entspann dich. Es liegt nicht bei dir zu entscheiden, ob Interesse an
dem Code besteht. Wenn er dich nicht interessiert, dann ist das in
Ordnung, aber halt dann bitte auch deinen Mund.
Abgesehen davon hat Niko niemals behauptet, er sei ein guter
Programmierer. Der einzige, der hier fehlende Kompetenz bewiesen hat,
warst du*. mit der Aussage
*)
> Nachtrag: Und warum Qte als Index für Buffer[] nicht> geeignet ist verrate ich dir nächsten Monat.
@ Malzbier
Ich bin total entspannt ;)
> Nachtrag: Und warum Qte als Index für Buffer[] nicht> geeignet ist verrate ich dir nächsten Monat.
Zum Thema Kompetenz lies doch mal ein Post weiter oben ?
Gruss
Holger
Och. Ich dachte eigentlich schon von mir, dass ich ein guter
Programmierer bin.
Eigentlich war ich geradezu überzeut davon. Aber Gott sei Dank hat
Holger mich wieder auf den Pfad der Tugend zurückgebracht.
An dieser Stelle also meinen Dank an Holger.
Von meiner Seite hat sich die Frage geklärt (und zwar schon nach dem
dritten Post) und nun werde ich weiter falschen, schlechten und
ungeprüften Code schreiben.
Anscheinend besitze nur ich allein diese Fähigkeit und das will ich der
Welt nicht vorenthalten.
;-) Gut´s Nächtle
>Von meiner Seite hat sich die Frage geklärt (und zwar schon nach dem>dritten Post) und nun werde ich weiter falschen, schlechten und>ungeprüften Code schreiben.>Anscheinend besitze nur ich allein diese Fähigkeit und das will ich der>Welt nicht vorenthalten.
Aber bitte nicht hier posten ! Versprochen ?