Forum: Mikrocontroller und Digitale Elektronik AVR VS1011 MP3-Daten richtig senden


von DinoKrokodil (Gast)


Lesenswert?

Guten Tag,

auch ich will mich einmal hier zu Wort melden.

Ich versuche seit Tagen korrekte MP3-Dateien an einen VS1011 im NewMode 
zu senden.

Ich kann Register auslesen, den Sinus Test durchführen und vernehme ein 
Knacken, Rauschen und abgehackten Lärm in den Lautsprechern, wenn ich 
die Audio-Daten sende.

Ich denke das Problem liegt also eindeutig in dem Code, den ich zum 
Senden der Dateien verwende.
Ich habe bisher drei SD/MMC Libraries ausprobiert, sie alle 
funktionieren wirklich wunderbar, nur leider nicht für meine Zwecke.

Ich initialisierie folgendermaßen:
HardReset->Softreset->SetzeModus(SDINEW)->Setze ClockDoubler->Schreibe 
ins AUDATA register

Wie gesagt, der Sinus Test funktioniert, der Quarz schwingt also?

Erster Versuch (Library von Daniel R. siehe: 
http://www.mikrocontroller.net/articles/AVR_FAT32:
1
void Play()
2
{
3
unsigned char file_name[20]="test    mp3";
4
 if(MMC_FILE_EXISTS == ffopen(file_name))
5
 {
6
 //geht super
7
 uputs((unsigned char*)"Datei exisitert!\n");
8
        // setzen einer Variable und dann runterzählen geht am schnellsten !
9
        unsigned long int seek=file.length;
10
     //runterspulen
11
        while ( seek > 0)
12
      {
13
      //buffer voll
14
          WaitforDREQ();
15
        SelectSDI();
16
        //32 Byte Blöcke senden
17
        for (long i = seek; i > (seek-32); i--)
18
        {
19
        WriteByteSPI(ffread());
20
        }
21
        DeSelectSDI();
22
23
        seek = seek - 32;
24
    }
25
     
26
      uputs((unsigned char*)"Dateiende!\n");
27
        ffclose();
28
     }
29
    
30
}

Ich höre nichts.

Zweiter Versuch (Library von Ulrich Radig):
1
Clustervar = 0;
2
if (fat_search_file((unsigned char *)"test.mp3",&Clustervar,&Size,&Dir_Attrib,Buffer) == 1)
3
{
4
uputs("\nDatei gefunden!!\r\n");
5
  
6
7
    for (int b = 0;b<52;b++)
8
      {
9
      fat_read_file (Clustervar,Buffer,b);
10
      
11
       uint8_t k = 0;    
12
       WaitforDREQ();
13
       SelectSDI();
14
      while(k < 512)
15
      {
16
17
               WriteByteSPI(Buffer[k]);
18
         k++;
19
      }
20
      DeSelectSDI();
21
      
22
23
  }
24
    
25
    }
26
    return;

Hier vernehme ich abgehackten Lärm aus den Kopfhörern, der jedoch 
schnell wieder vorbei ist. Ich nehme an es handelt sich dabei um einen 
Dekodierungsversuch =).

Ich entschuldige mich schon jetzt für meine miserablen Programmierkünste 
und wünsche euch allen einen schönen Tag!

von DinoKrokodil (Gast)


Lesenswert?

Ich weiß mit an Sicherheit grenzender Wahrscheinlichkeit, dass es hier 
Leute gibt, die das Wissen. Deswegen starte ich mal einen 
Wiederbelebungsversuch.

Viele Grüße.

von holger (Gast)


Lesenswert?

>       uint8_t k = 0;
>      while(k < 512)

k ist immer kleiner als 512 weil es nie größer als 255 wird.

>        SelectSDI();
>        //32 Byte Blöcke senden
>        for (long i = seek; i > (seek-32); i--)
>        {
>        WriteByteSPI(ffread());
>        }
>        DeSelectSDI();

Hast du zwei getrennte SPI?

von DinoKrokodil (Gast)


Lesenswert?

Ersteinmal vielen Dank, dass hier jemand antwortet :).

Ich verwende ein Hardware SPI. An diesem Hängen die SD-Karte und der 
VS1011 (und der ISP, aber den ziehe ich raus).

Viele Grüße.

von holger (Gast)


Lesenswert?

>Ich verwende ein Hardware SPI. An diesem Hängen die SD-Karte und der
>VS1011 (und der ISP, aber den ziehe ich raus).

Dann versuchs mal so:

       //32 Byte Blöcke senden
       for (long i = seek; i > (seek-32); i--)
       {
        unsigned char by;
        by = ffread();
        SelectSDI();
        WriteByteSPI(by);
        DeSelectSDI();
       }

von DinoKrokodil (Gast)


Lesenswert?

Daraus wurde leider auch nichts, es scheint mir fast so, als wäre seek 
immer 0 und er würde die Schleife überspringen. Schreibe ich direkt in 
den Schleifeninhalt eine kurze Rückmeldung per UART, kommt diese nicht 
an.

Ich erhalte nur "Datei gefunden!" und "Dateiende!".

Das sind aber auch einfach sehr viele Fehlerquellen....

Viele Grüße und ganz herzlichen Dank für ihre Bemühungen.

von DinoKrokodil (Gast)


Lesenswert?

Ich habe es jetzt nochmal anders Versucht:

1
      uint8_t buffer[32];
2
      uint8_t i = 0;
3
        do{
4
           buffer[i] = ffread();
5
       i++;
6
       if (i > 31)
7
       {
8
         uputs((unsigned char*)"Sende Datenblock!\n");
9
         WaitforDREQ();
10
        SelectSDI();
11
        for (uint8_t k = 0; k < 32; k++)
12
        {
13
          WriteByteSPI(buffer[k]);
14
        } 
15
        DeSelectSDI();
16
        i = 0;
17
18
       }
19
        }while(--seek);

Jetzt habe ich zumindestens die Ausgabe "Sende Datenblock!" sehr häufig, 
er scheint also die Datei zu lesen. Ich höre ein pulsierendes leises 
Piepsen. (erinnert mich an einen alten CD-Player, wenn man CDs gespult 
hat).

von holger (Gast)


Lesenswert?

>Jetzt habe ich zumindestens die Ausgabe "Sende Datenblock!" sehr häufig,

Dann nimm die Ausgabe mal raus. Was glaubst du wie lange die dauert?
Möglicherweise ist der Puffer dann schon abgespielt.

von DinoKrokodil (Gast)


Lesenswert?

Das hat leider den gleichen Effekt. Kann es sein, dass die Datei einfach 
viel zu schnell übertragen wird?

von holger (Gast)


Lesenswert?

>Das hat leider den gleichen Effekt. Kann es sein, dass die Datei einfach
>viel zu schnell übertragen wird?

Wenn du auf DREQ wartest nicht.

Das hier passt auch noch nicht:

        }while(--seek);


Besser:

 if(seek > 32) seek -= 32;
 else seek = 0;
 }while(seek);


Wie sehen eigentlich

        WaitforDREQ();
        SelectSDI();
        WriteByteSPI(buffer[k]);

aus?

von DinoKrokodil (Gast)


Lesenswert?

Hier die 3 Funktionen:
1
void WaitforDREQ()
2
{
3
loop_until_bit_is_set(PINA, DREQ);
4
5
}
1
uint8_t
2
WriteByteSPI (uint8_t data)
3
{
4
5
    SPDR = data;    
6
7
    while (!(SPSR & _BV (SPIF)));  
8
9
    return SPDR;
10
}
1
void SelectSDI()
2
{
3
  PORTA &= ~_BV(xDCS);
4
}

Hier noch die SPI Schnittstelle an sich:
1
void InitSPI(void)
2
{
3
4
    DDRB |= _BV (MOSI) | _BV (SCK);  
5
    PORTB |= _BV (MOSI) | _BV (SCK);
6
7
    DDRB |= _BV (SS);
8
    PORTB |= _BV (SS);  
9
10
  SPCR = _BV (MSTR) | _BV (SPE); 
11
  SPCR |= _BV (SPR0);
12
}

von DinoKrokodil (Gast)


Lesenswert?

Was noch zu sagen wäre ist, dass ich zuerst eigentlich die SD/MMC 
library von Roland Riegel nehmen wollte, weil ich für diese ein Beispiel 
zum korrekten Senden der Daten habe.
Die Library erkennt aber nach erfolgreicher initialisierung der 
Speicherkarte leider die Datei "test.mp3" nicht.

Verwendetder Code:
1
  struct fat16_file_struct* fd = open_file_in_dir(fs, dd, "test.mp3");
2
   uint8_t buffer[32];
3
  if(!fd)
4
    {
5
//hier landet er immer, fs und dd wurden korrekt zugewiesen
6
  uputs("Datei nicht gefunden!");
7
  return;
8
  }

von Dinokrokodil (Gast)


Lesenswert?

Ich habe mir jetzt das DREQ Signal nochmal genau angesehen, ist es 
normal das es immer zwischen 0 und 1 schwankt, also das es nie eine Zeit 
lang auf eins bleibt, sondern mit relativ schneller Geschwindigkeit 
zwischen beiden Zuständen hin und her pendelt (auch nach dem 
Hard/Softreset), dabei aber keinem bestimmten Muster folgt?

Viele Grüße.

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.