Forum: Mikrocontroller und Digitale Elektronik Datenfluss -> SD -> ATMega128 -> VS1001k


von Niko (Gast)


Lesenswert?

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:
1
uint8_t Qte=32;
2
3
  if (fat_search_file("musik.mp3",&Clustervar,&Size,&Dir_Attrib,Buffer) == 1)
4
    {
5
    printf("\nFile Found!!\n\n");
6
    //Lese File und gibt es auf der seriellen Schnittstelle aus
7
    for (uint32_t b = 0;b<Size;b++)
8
      {
9
      fat_read_file (Clustervar,Buffer,b);
10
      for (uint8_t a = 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

von Carsten P. (papa_of_t)


Lesenswert?

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!

von Niko (Gast)


Lesenswert?

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.

von Carsten P. (papa_of_t)


Lesenswert?

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.

von Carsten P. (papa_of_t)


Lesenswert?

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..

von Cute Knut (Gast)


Lesenswert?

> 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?

von Niko (Gast)


Lesenswert?

@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:

von Knut (Gast)


Lesenswert?

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.

von Falk (Gast)


Lesenswert?

@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

von Knut (Gast)


Lesenswert?

Reg dich ab Falk, hab mein Fehler gemerkt.

von Falk (Gast)


Lesenswert?

@Knut

>Reg dich ab Falk, hab mein Fehler gemerkt.

Ich bin entspannt, keine Bange. ;-)

MFG
Falk

von Knut (Gast)


Lesenswert?

> http://www.geocities.com/jacquesmartini/mptritium/mp3.htm

Ist der Schaltplan von dir gezeichnet?

von Falk (Gast)


Lesenswert?

@Autor: Knut

>> http://www.geocities.com/jacquesmartini/mptritium/mp3.htm

>Ist der Schaltplan von dir gezeichnet?

Ja, alles selfmade. Wenngleich schon etwas angestaubt.

MFG
Falk

von Knut (Gast)


Lesenswert?

> 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.

von Falk (Gast)


Lesenswert?

@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

von holger (Gast)


Lesenswert?

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]);
        }
      }
    }

von holger (Gast)


Lesenswert?

Nachtrag: Und warum Qte als Index für Buffer[] nicht
geeignet ist verrate ich dir nächsten Monat.

Gruss
 Holger

von Knut (Gast)


Lesenswert?

Warum nicht?

von holger (Gast)


Lesenswert?

@ 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 ?

von Knut (Gast)


Lesenswert?

So wie ich das verstanden habe, ist "Qte" der Zähler für die 32 Byte, 
die im Buffer des VS Platz finden. Allerdings fällt mir da gerade 
folgendes auf:
1
for (uint8_t a = 0;a<512;a++)

Das ist glaube ich nicht so gut, oder?

von Niko (Gast)


Lesenswert?

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.

von Mario (Gast)


Lesenswert?

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


von holger (Gast)


Lesenswert?

@ 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.

von holger (Gast)


Lesenswert?

@ Knut

      for (uint8_t a = 0; a<512; a+=32)
        {
        //Warten auf DREQ
        while(!(PORT_MP3_IN & (1<<DREQ))){;}

        //Statt Ausgabe auf die Schnittstelle erfolgt die Ausgabe auf
        //den VS1001K
        Qte=32;
        while(Qte)
          {
           PORT_MP3_OUT |= (1<<BSYNC);         // BSYNC High
           SPDR = Buffer[a + 32 - Qte];
           PORT_MP3_OUT &= ~(1<<BSYNC);         // BSYNC Low
           Qte--;
           while(! ( SPSR & (1<<SPIF) ) );
          }
        }

Sieht doch schon besser aus, oder ?

Gruss
 Holger

von Niko (Gast)


Lesenswert?

@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.

;-)

von Knut (Gast)


Lesenswert?

> 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?

von Niko (Gast)


Lesenswert?

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.

von holger (Gast)


Lesenswert?

@ 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 !



von Malzbier (Gast)


Lesenswert?

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.


von holger (Gast)


Lesenswert?

@ 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

von Niko (Gast)


Lesenswert?

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 holger (Gast)


Lesenswert?

>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 ?

von Niko (Gast)


Lesenswert?

Ok. Aber nur, weil du es bist.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.