Forum: Mikrocontroller und Digitale Elektronik VS1053 SPI- und CLKI Frequenz


von Max (Gast)


Lesenswert?

Hallo,

ich habe derzeit Probleme mein VS1053 Board von Sparkfun.com zum Laufen 
zu bekommen.

Ich sende meine MP3 in 2048Byte Blöcken an meinen XMega128A1 per USB und 
dieser leitet sie weiter.

Mit 64kb/s mp3s funktioniert es wunderbar.
Mit 128kb/s mp3s stockt es.
mit 320kb/s mp3s funktioniert es nicht.

Nun weiß ich nicht, wo der Fehler stecken kann.

1. Möglichkeit: SPI Frequenz zu gering
der VS1053 kann SPI mit 4Mhz. Allerdings kann ich den xMega nur auf 2Mhz 
konfigurieren. Die nächste Stufe wäre schon 8Mhz:
(SPIx.CTLR->SPR0/1 = 2Bit für 128/64/16/4) als SPI_PRESCALER_DIV

2. Möglichkeit: SCI_CLOCKF zu gering
der VS1053 ist mit einem 12.288Mhz Quarz ausgestattet. Nun steht im 
Datenblatt das beim Abspielen von WMA oder AAC der Clock multiplier 
verwendet werden muss um die Frequenz zu erhöhen. Maximal sind 66Mhz 
möglich.

3. Möglichkeit: SPI driver von Atmel nicht performant.
Für die SPI-Kommunikation habe ich die treiber exampels verwendet und 
betreibe den SPI im Polled-Modus im gegensatz zum USART(921600er Baud im 
höchsten Interrupt-Level)



Hat da jemand einen Lösungsansatz?

Gruß Max

von holger (Gast)


Lesenswert?

>mit 320kb/s mp3s funktioniert es nicht.

320kb/s ist schon heftig. Oder sind es 320kbit/s?

Das schaff ich mit einem Atmega32 und VS1001 bei 8MHz Clock;)

von Max (Gast)


Lesenswert?

Sry, sind selbstverständlich alles Bits bei den MP3s :)

von Max (Gast)


Lesenswert?

holger schrieb:
>>mit 320kb/s mp3s funktioniert es nicht.
>
> 320kb/s ist schon heftig. Oder sind es 320kbit/s?
>
> Das schaff ich mit einem Atmega32 und VS1001 bei 8MHz Clock;)

Kannst du mir wohl fix in Worten erklären wie du die Weiterleitung 
gemacht hast?

Ich vermute zwar nicht dass es daran liegt aber vielleicht habe ich 
meinen Buffer auch falsch umgesetzt.
Ist ein 4096Byte Fifo.
In der ISR wird das Byte lediglich reingeschoben.
in der "Main" werden sie weitergeschickt und sobald 2048Byte frei sind 
wird ein 0xFF zum PC geschickt als Auslösen für das Senden weiterer 
2048Bytes.
Ich habe schon Testweise versucht das Senden von 2048Byte über SPI und 
das Empfangen von 2048 Bytes voneinander zu trennen um das Senden nicht 
von der ISR ständig unterbrechen zu lassen. Es macht aber garkeinen 
Unterschied.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Was sagt denn der DREQ vom VS?
Will er neue Daten, weil der Puffer leer ist und es knackt dann?
Woher hasten das mit der maximalen SPI Freq vom VS?
Ich besafte den mit 6MHz SPI Takt unds funzt, denn der maximale SPI Takt 
ist der Systemtakt/7 ((12,288MHz*3,5)/7 = 6,1MHz).
Kannst natürlich den Systemtakt noch höher drehen (55MHz).
>Recommended SC MULT=3.5×, SC ADD=1.0× (SCI CLOCKF=0x8800).

Das Problem wird aber eher die Datenanfrage sein.
Dein AVR fragt per USB die Daten an.
Bevor das Flag vom USB Host abgefragt wird vergeht Zeit, dann beim 
Multitasking OS und dann noch das senden.
Baus also lieber aufn Puffer um, dass wenn er nurnoch zu 50% gefüllt ist 
neue Daten ansausen.
Wenn der DREQ Daten will, kannste auch gleich 32byte auf einmal 
reinstopfen!
Ist er imemrnoch aktiv, gibste ihm nochmal 32byte.
Hier was zur SPI Performance:
http://www.matuschek.net/atmega-spi/

Betreibe nen VS1053 an nem M644, der liest MP3 vonner SD Karte mit FAT32 
und schubst das aufn VS ohne Probs.
M644 = 12MHz
SPI = 6MHz

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Nochmal ins DB gesehen:
SPI schreiben: CLKI/4
SPI lesen: CLKI/7

Also hoch den CLKI_MUL auf 3,5 und den SPI auf 8MHz nach dem 
Konfigurieren.

von holger (Gast)


Lesenswert?

>Betreibe nen VS1053 an nem M644, der liest MP3 vonner SD Karte mit FAT32
>und schubst das aufn VS ohne Probs.
>M644 = 12MHz
>SPI = 6MHz

Bei mir ATmega32 mit 16MHz Takt.
Holt die Daten auch von SD und zeigt noch 2x Temperatur von zwei DS1821
und Uhrzeit und Datum vom DCF77 Empfänger auf einem DOGM128 an.
VS1001, DOGM und SD Karte hängen alle am selben SPI.

von Max (Gast)


Lesenswert?

Martin Wende schrieb:
> Baus also lieber aufn Puffer um, dass wenn er nurnoch zu 50% gefüllt ist
>
> neue Daten ansausen.

Vorab vielen Dank für die Hilfe. Im Nachhinein weiß ich leider nicht wo 
ich die fehlerhafte
Der Artikel von Matuschek ist sehr lehrreich. Ich werde als erstes die 
SPI-driver von Atmel rauswerfen und die Sendesequenz nach seinem Schema 
umbauen.

Allerdings ist mir noch das Thema SPI-Takt und Bufferung unklar.

Ein SPI-Takt von 8Mhz dürfte den VS1053 sehr ins schwitzen bringen in 
Fällen bei denen SCI-Register gelesen werden.
Der höchste CLKI Takt des VS liegt bei 55,3Mhz und wird durch das setzen 
des SC_MULT auf 4,5 erreicht (bei 12.288Mhz Quarz). Maximale Frequenz 
für das Lesen ist dann
(XTALI * SC_MULT) / 7
12.288Mhz * 4,5 / 7 = 7,899 Mhz :(

Was ich auch noch nicht ganz verstehe ist das behandeln des Buffers auf 
dem xMega.

Da die USART baud erheblich höher(1M) ist als die zu haltende 
SPI-Sendegeschwindigkeit muss der xMega doch Rückmeldung über den 
Füllstand seiner Buffer liefern und somit Daten "holen" oder verstehe 
ich das falsch?

In meiner derzeitigen Implementierung wird die Rückmeldung bei 50% 
Bufferfüllstand gesendet was das nachfüllen auf 100% am Stück auslöst.
Um zeit bei der Überwachung des Füllstandes zu sparen habe ich einen 
festen Zeitinterval realisiert.
Zu beginn werden 2048Bytes empfangen (50%). Anschließend werden weitere 
2048Bytes angefordert(Füllung auf 100%) und während diese empfangen 
werden werden die ersten 2048Bytes verschickt. Sind die ersten 
verschickt werden wieder 2048 angefordert und die 2. 2048Bytes werden 
verschickt.
Durch die Wahl einer Datenpaket-Größe von 2048Byte möchte ich die Anzahl 
an Rückmeldungen und somit Verzögerungen auf der Windows-Machine 
möglichst klein halten.
Gibt es da eine optimalere lösung?

Gruß Max

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Angehängte Dateien:

Lesenswert?

Ausm VS liest man ja auch kaum was aus.
Nur beim Lautstärke ändern den vorherigen Wert oder das Endfillbyte.
Da dann einfach den SPI Takt kurz verringern und dann wieder zum MP3 
rüberschubsen auf 8MHz anziehen.

Leg dir mal nen Puffer voll/leer/50% Signal an Pins von dem AVR und häng 
nen Oszi ran um zu gucken ob der Puffer leerläuft oder wirklich nur der 
SPI zu lahm ist.
Der UART mag zwar 1mbaud haben, aber USB ist Host basierend, also dein 
Flag liegt ersmal ne Weile im USB-UART IC rum.
Wenn du dann auchnoch byteweise auf den virtuellen comport schreibst 
macht er um jedes byte nen USB Packet -> arschlahm.
Daher die 2048byte am Stück aufn VCP geben.

von Max (Gast)


Lesenswert?

Ich betreibe die USB-Verbindung über einen CP2102 im USBXpress 
Modus(kein COM-Port) unter Verwendung der SiLabs Treiber.

Eine ungenaue Zeitnessung auf Hostseite(C#->Stopwatch) ergab eine 
Übertragungszeit von 22ns für 2048 Bytes was auf ca. 93kByte/s schließen 
lässt.

Aber das USB-Host-Argument leuchtet ein.


Das auslegen des Füllstands auf einen Pin macht keinen Sinn da bei einer 
Puffergröße von 4096Bytes und einer Paketgröße von 2048Bytes der Puffer 
immer befüllt bleibt
Beispiel:
Füllstand 50%:
xMega fordert 2048Bytes vom PC
xMega sendet vorhandene 2048Bytes "zeitgleich" während angeforderten 
Bytes eintreffen.
xMega wartet auf Abschluss der USB-Übertragung (Wäre interessant zu 
wissen ob es überhaupt dazu kommt)
Füllstand wieder 50%:

Das wiederholt sich für die Länge der MP3.

von Max (Gast)


Lesenswert?

Max schrieb:
> von 22ns für 2048 Bytes

*ms

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.