Hallo Zusammen
Ich verzweifel hier gleich ...
Also ich will einen Mp3 Player bauen, wie leicht zu erkennen ist an der
Überschrift.
Ich hab mir so gut wie alle Quelltexte durchgelesen, die hier überall
veröffentlicht sind. Aber er will nicht!
Zum Stand: Der Mega32 läuft, die SD Karte wird ausgelesen und auch eine
MP3 Datei kann ich öffnen und über UART die einzelnen Bytes ausgeben.
Aber der VS1011b will einfach nicht.
Der VS hat 12,288MHz Clock, Schaltung hab ich diese
(Beitrag "Wecker mit MP3 (vs1011) und SD-Card") aus dem Threat genommen.
Überall stand, ich muss erstmal Register schreiben und lesen, aber auch
das will nicht.
Dieser Quelltext funktioniert zumindest von Init und vom Reset:
1
voidvs1001_init_io(void)
2
{
3
unsignedchardummy;
4
5
// setup BSYNC
6
sbi(DDRA,BSYNC_PIN);// pin is output for BSYNC
7
cbi(BSYNC_PORT,BSYNC_PIN);// output low
8
9
// set the MP3/ChipSelect pin hi
10
sbi(DDRA,MP3_PIN);// pin output for xCS
11
sbi(MP3_PORT,MP3_PIN);// output hi (select MP3)
12
13
14
// set the /Reset pin hi
15
sbi(DDRA,RESET_PIN);// pin output
16
cbi(RESET_PORT,RESET_PIN);// output hi
17
18
cbi(DDRC,DREQ_PIN);//DREQ->INPUT
19
// setup serial data interface :
20
// clock = f/4
21
// select clock phase positive going in middle of data
22
// master mode
23
// enable SPI
24
25
// setup serial data I/O pins
26
27
sbi(DDRB,PB5);// set MOSI a output
28
29
// PB4 also used as SCK for SPI data
30
sbi(DDRB,PB4);// SS must be output for Master mode to work
31
32
33
sbi(DDRB,PB7);// set SCK as output
34
cbi(PORTB,PB7);// set SCK lo
35
36
outp((1<<MSTR)|(1<<SPE),SPCR);// enable SPI interface already done in the mmc routine!!!
Also diese Texte scheinen zu funktionieren, also der VS kommt aus dem
DREQ zurück. Beim Senden und Empfangen der Registereinträge will er
nicht, ich weiß aber auch nicht so richtig, wie ich es anstellen soll.
delay(5);//wait 5 microseconds after sending data to control port
19
}
Ich hab jetzt in der main einfach erst "write" aufrufen und dann bei
"read" die gleiche Adresse wieder auslesen. Aber er gibt immer wie den
Anfangswert aus aber keinen Ausgelesenen.
Auch einen Sinustest hab ich schon versucht zu senden, alles mit
fertigen Codes, angepasst auf meine Pins natürlich, aber will einfach
nicht klappen.
Hat jemand Tips, woran es liegen kann, worauf man bei dem guten Stück
besonders achten muss.
Ich bedanke mich schonmal vielmals!
Viele Grüße
André
Kennst du diese Appnote schon?
http://www.vlsi.fi/uploads/media/vs10XXan.pdf
Wenn du die Anleitung dadrin wirklich Schritt für Schritt von Oben
durcharbeitest sollte es eigentlich funktionieren. Oder zumindest hilft
es den Fehler einzugrenzen.
Gruß, Sebastian
Also Fehler ist erstmal eingegrenzt, der Chip antwortet nichtmal auf
Punkt 4.3 (Firmware WakeUp)
Ich hab dazu folgenden einfachen Code verwendet:
1
#include"uart.h"
2
#include<util/delay.h>
3
4
#define VS_PORT PORTA
5
#define VS_DDR DDRA
6
7
#define DREQ_PORT PORTC
8
#define DREQ_DDR DDRC
9
#define DREQ_PIN PINC
10
11
#define VS_DREQ PC0
12
#define VS_RESET PA0
13
#define VS_BSYNC PA1
14
#define VS_CS PA2
15
16
voidmain()
17
{
18
uart_init();
19
intcount=4096;
20
21
VS_DDR|=1<<VS_RESET|1<<VS_BSYNC|1<<VS_CS;//PORTS sind Ausgänge
22
VS_PORT|=1<<VS_BSYNC|1<<VS_CS;//BSYNC und CS sind HIGH
23
24
DREQ_DDR=0x00;//DREQ ist Eingang
25
DREQ_PORT|=1<<VS_DREQ;//Pullupwiderstand - Braucht man den hier???
26
27
28
VS_PORT&=~(1<<VS_RESET);//RESET geht auf LOW
29
_delay_us(3000);//Kurze Verschnaufpause
30
VS_PORT|=1<<VS_RESET;//RESET geht auf HIGH
31
32
while(count--)//Um zu sehen, ob DREQ erst LOW dann HIGH wird
33
{
34
if(DREQ_PIN&(1<<VS_DREQ))
35
{
36
uart_putc('~');
37
}
38
else
39
{
40
uart_putc('_');
41
}
42
}
43
}
Aber der DREQ bleibt auf LOW :( Es kam zwar schon zweimal ein HIGH am
Ende, aber beim nächsten Controller-Reset ging es wieder nicht mehr.
Sieht jemand einen Fehler? Hab ich was falsch verstanden? Was heißt das
Ergebnis jetzt? Ist der Chip kaputt?
Die Spannung an RCAP stimmt aber, wenigstens etwas ;)
Ohne deinen Code angeschaut zu haben (ich vertrau da mal auf deine
Programmierkünste).
Wahrscheinlich läuft der Quarz vom VS nicht. Hatte wie viele andere Auch
genau dieses Problem. Ich hab's dann quasi mit dem Holzhammer gelöst und
einen Quarzoszillator rangehängt. Wenn du beim einfachen Quarz bleiben
willst:
Hast du den 1M-Widerstand zwischen IN und OUT?
Die Leitungen vom VS zum Quarz sollten so kurz wie möglich sein. Wenn
der VS auf einer Adapterplatine sitzt sollte der Quarz auf jeden Fall
mit da drauf. Die Kondensatoren auch (Die sollte man natürlich auch
nicht vergessen haben).
Manchmal hilft es, wenn man den Finger auf das Quarz oder die
Quarzleitungen hält. Wenn es dann halbwegs läuft kannst du zumindest
ziemlich sicher sein, dass es der Quarz ist.
Achso: Mess mal mit dem Multimeter DREQ. Wenn ich mich recht erinner
wird der auch nicht mehr low wenn der Kontroller keine Daten sendet.
Dann kannst du auch einen Softwarefehler ausschließen.
Gruß, Sebastian
Hallo,
ich bin auch dabei fast den gleichen Mp3 Player zu bauen wie du, nur mit
dem VS1001.
Also was mir einmal ein ähnliches Problem verschafft hat war, dass ich
wie du auch mit den PORT Registern gearbeitet habe. Setzt du hier die
entsprechenden Bits wird das nicht direkt am Ausgang/Eingang übernommen.
Versuch mal alle Zustandsänderungen an den PINS mit den PICx Registern
zu realisieren. Dann ist erstmal sichergestellt, dass da nichts schief
geht. Und dann auf jeden Fall am DREQ mit Multimeter/Oszi Messen. Auf
die uart-Ausgabe kannst du später vertrauen.
Hier mein Vorschlag:
1
#include"uart.h"
2
#include<util/delay.h>
3
4
#define VS_PORT PORTA
5
#define VS_DDR DDRA
6
#define VS_PIN PINA
7
8
#define DREQ_PORT PORTC
9
#define DREQ_DDR DDRC
10
#define DREQ_PIN PINC
11
12
#define VS_DREQ PC0
13
#define VS_RESET PA0
14
#define VS_BSYNC PA1
15
#define VS_CS PA2
16
17
voidmain()
18
{
19
uart_init();
20
intcount=4096;
21
22
VS_DDR|=1<<VS_RESET|1<<VS_BSYNC|1<<VS_CS;//PORTS sind Ausgänge
23
VS_PIN|=1<<VS_BSYNC|1<<VS_CS;//BSYNC und CS sind HIGH
24
25
DREQ_DDR=0x00;//DREQ ist Eingang
26
//DREQ_PORT |= 1 << VS_DREQ; //Pullupwiderstand - Braucht man den hier??? Glaube ich weniger.
27
28
29
VS_PIN&=~(1<<VS_RESET);//RESET geht auf LOW
30
_delay_us(3000);//Kurze Verschnaufpause
31
VS_PIN|=1<<VS_RESET;//RESET geht auf HIGH
32
33
while(count--)//Um zu sehen, ob DREQ erst LOW dann HIGH wird
Da bin ich wieder ;)
1. Vielen Dank für den Tip mit dem Clock, daran lag es, das gar nichts
passiert ist.
-> Hab den Quarz, sowie R und C direkt an den Baustein gelötet.
2. Vielen Dank für die Appnotes. Bin diese jetzt durchgegangen, hat
alles mehr oder weniger schnell geklappt.
Jetzt bin ich bis zum Sinus-Test gekommen, der kommt laut und deutlich
draußen an.
Nun also Mp3 Daten:
Ich habe von Roland Riegel die SD Bibliothek genommen, die läuft auch,
liest die Karte, gibt mir Infos.
Man kann damit auch eine Datei öffnen und sich diese Byte für Byte
ausgeben lassen. Also immer 32 Byte genommen und an den VS geschickt.
Aber er will keinen Ton drauß machen :(
- BSYNC ist auf Low beim Senden
- nach 32 Byte wird DREQ abgefragt
- Volume ist hoch
Frage: Muss ich dem VS noch sagen, dass jetzt MP3-Daten kommen
(VS_STREAM?)
Braucht er nach dem Senden eine gewisse Wartezeit? Darf ich ihm die
ganze MP3-Datei schicken, am Anfang stehen ja die ID3-Tags (die zeigt
UART auch richtig an)?
Vielen Dank
André
Schaut doch schonmal gut aus.
Das Volume-Register brauchst du erstmal garnicht anfassen. Das ist
standartmäßig voll aufgedreht.
Dein VS läuft ja auf 12,xxx MHz. Dann musst du den Clock doubler im
Clock frequency-Register aktivieren.
Nachdem du das register geschrieben hast muss man das Audata-Register
beschreiben, damit der doubler aktiv wird. Inhalt ist so weit ich weiß
egal, da dieses Register eigentlich nur zum Lesen von Songdaten ist.
Sonst muss man nichts machen. Bei meiner Init wird auch nur Mode-,
Frequency- und Audataregister beschrieben. Der Controller erkennt den
mp3-Header und weiß damit was zu tun ist. ID3-Tag kann auch dabei
bleiben
Nimm zum Testen erstmal eine mp3 mit geringer Bitrate (z.B. 32kbit/s).
Wenn du Timingprobleme hast (zu langsamer SPI, Quarz falsch eingestellt,
zu große Latenzzeit auf DREQ,...) funktioniert es am ehesten noch so.
Und meld dich wieder wie's läuft.
Gruß, Sebastian
Du musst als erstes das Mode-Register beschreiben. Und VOR jedem Befehl
musst du mit DREQ prüfen, ob der VS wieder bereit ist.
Das gleiche gilt vor jedem 32-Byte-Block an Daten.
Wenn garnichts gehen will kannst du mal versuchen ein kurzes mp3 (2-5
sekunden) mit niedriger Bitrate (8-32 kbit/s) direkt mit in den Flash zu
schreiben und von da aus auszulesen. Für diesen test wird dann nichts
anderes mehr mitbedient, insbesondere die SD-Karte nicht. Also einfach
stur aus dem Flash ins SPI. Wenn das mit DREQ nicht hilft könnte es
nämlich gut sein, dass du Timingprobleme hast.
Grüße, Sebastian
Achso ok, da versteh ich aber was nicht:
Hat das komplette Mode-Register 16Bit? Wenn ich also beispielsweise
folgendes sende:
SPI_MasterTransmit(0x02); //für write
SPI_MasterTransmit(0x00); //für Mode-Register
SPI_MasterTransmit(0x01); <- Nur SM_DACT ist auf 1 gesetzt, 9:13 ist 0
SPI_MasterTransmit(0x01); <- Nur SM_DIFF ist auf 1 gesetzt, 1:7 ist 0
Hab ich das richtig verstanden?
Oder ist die Zahl im Datenblatt einfach als Dezimale Zahl zu sehen und
muss dort ins Register geschrieben werden?
Und was muss ich da genau reinschreiben für die ganzen Werte? Einige
sind ja logisch, den SM_SHARE muss ich ja auf 0 setzen ...
Mode hat 16 bit, es werden aber nur 14 genutzt. Die anderen muss man auf
null setzen.
Ich hab im Mode-Register nur SM SDINEW gesetzt, der rest ist alles null.
Wenn du zwei CS-Leitungen (XCS und XDCS) hast muss SM_SDISHARE null
sein, sonst eins. Wenn du nicht die "stadart-SPI-konfig" verwenden
willst musst du da auch noch was einstellen (So wie ich das sehe musst
du das aber nullsetzen).
Sebastian
Gut, also auch mit Mode-Register mag er mich nicht.
Die SD-Karte wird richtig gelesen, auch Dateien richtig geöffnet und
richtige Daten angezeigt (würd ich am ID3-Tag jedenfalls vermuten). Auch
der Sinustest wird eingebettet in die SD-Routinen richtig abgespielt.
Zum Ablauf:
- Öffnen der Datei auf der SD-Karte (ist es möglich)
- Hard-Reset (Reset-Pin auf 0 - dann wieder 1 - DREQ abfragen)
- Soft-Reset (CS-Pin auf 0, SPI senden 0x02 - 0x00 - 0x00 - 0x04 -> DREQ
)
- Mode-Reg (CS-Pin auf 0, SPI senden 0x02 - 0x00 - 0x00 - 0x00 -> DREQ)
- ClockF-Reg (CS-Pin auf 0, SPI senden 0x02 - 0x03 - 0x98 - 0x00 ->
DREQ)
- AuData-Reg (CS-Pin auf 0, SPI senden 0x02 - 0x05 - 0xAC - 0x45 ->
DREQ)
- Immer 32 Byte von der Datei lesen, Bsync-Pin auf 0, SPI senden, Bsync
auf 1, DREQ abfragen, neue Daten lesen ...
Hab ich da irgendwo was falsch verstanden? Es kommt nämlich gar nichts,
kein Knacken, nichts.
Dann hab ich heute mal die FuseBits nochmal ausgelesen. Dachte
eigentlich, die wären richtig gesetzt, jetzt stand aber Interner Clock
mit 8 MHz da. Wollte ich auf Extern Crystal High ändern, jetzt ging der
Chip nicht mehr. Also neuer Chip, die Fusebits sind: LOW: 0xE3 ; HIGH:
0x99 ; LOCK 0xFF
Irgendwie raff ich das noch nicht, will aber auch nicht wieder was
kaputt machen. Was wäre denn Richtig für Externen Quarz mit 4MHz bzw
auch 8MHz (wenn das besser wäre für die Übertragung)
VIELEN DANK!!!
Nimm einfach den internen Oszillator. Der SD-karte gibts du ja so weit
ich weiß den Takt vor, beim VS bist du sowieso der Boss. Macht also
nichts, wenn der Oszillator nicht sooo exakt schwingt. Und 8 MHz reichen
dicke.
Durchsuch mal bei vlsi.fi die Appnotes. Irgendwo hatte ich dort noch
gefunden, dass man beim Einschalten RESET und DCS low halten soll. Dann
erst Reset auf high, mindestens 10ms warten und dann DCS auf high.
Die Registerwerte sollten soweit erstmal passen.
Passen polarität und Flanke beim SPI von VS und AVR überein?
Und versuch es wirklich mal ne mp3 in Flash zu schreiben und von dort
aus abzuspielen.
Hab bei mir sehr viel Ram angeschlossen und für den ersten Versuch
einfach ein paar Sekunden mp3 erst in den RAM geladen und von dort
gespielt. Der erste Versuch von Festplatte zu streamen ist total daneben
gelaufen.
Sebastian
Kleine Ergänzung:
Eben war ein Ton zu hören, aber stockend, viel zu langsam bei einer
32kbit/s Datei. Nach etwas basteln kommt jetzt aber nichts mehr :S
Was für eine SPI-Geschwindigkeit ist denn gut? Ich habe grad SPR0, SPR1
und SPI2X auf 0, also Clock/4 -> Clock ist auf Intern 8MHz
Was mir aufgefallen ist: Der Sinustest ist ruckelfrei bei 1MHz und 4MHz,
aber 8MHz stockt er unregelmäßig.
Welche Geschwindigkeit hat denn der VS - ist mit 0x9800 im
ClockF-Register das richtig mit Clockdoubler bei 12,288MHz Quarz dran?
Sind 32Byte als Buffer ok oder lieber mehr/weniger?
Soweit weg vom Ziel kann ich doch fast gar nicht mehr sein oder? ;)
Klingt genau nach dem was ich schon länger befürchte: Du bist nicht
schnell genug. 32 Byte ist schon sehr knapp als Puffer, mach den mal
größer. Deine SD-Karte wird ja auch eine gewisse Zugriffszeit haben.
Ob der Wert im ClockF-Register genau passt weiß ich jetzt nicht. Der
Clock-doubler sollte aber aktiv sein. Könnte nur noch sein, dass die mp3
zu schnell/langsam gepielt wird. Aber bei einer 32kbit mp3 muss
eigentlich immer was rauskommen.
1 oder 2 MHz als SPI sollten gehen. Mehr macht beim initialisieren des
VS probleme.