Home › Forums › Sparkfun MP3 Shield Library Support Forum › SFEMP3Shield works with Arduino Due
Tagged: Due
- This topic has 24 replies, 4 voices, and was last updated 11 years, 3 months ago by Anonymous.
-
AuthorPosts
-
August 8, 2013 at 9:57 am #2824AnonymousInactive
gallegojm, I’m having problems getting things to work properly. Have I forgotten some configuration setting?
I’m using the Sparkfun MP3 shield with the Due only, no Ethernet shield. I have modified SFEMP3ShieldConfig.h to set MP3_XCS to 10 under #ifdef __arm__
I have bent pin 6 of the Sparkfun card and used a jumper lead to connect pin 6 of the Sparkfun card to pin 10 of the Sparkfun (i.e. pin 10 of the Due).
The problem is that pin 10 never seems to go low. It is always high.
As a result, SFEMP3Shield::vs_init() fails and returns 4. This is because Mp3ReadRegister(SCI_MODE) returns 0xFFFF.
In SFEMP3Shield::Mp3ReadRegister() I paused the program just after the line spiTransfer(0x03). Using my voltmeter I can see that the MP3_XCS pin (i.e. pin 10 in my case) is 3.3V, i.e. high. It ought to be low. The same thing happens if I set MP3_XCS to 4 in the config file. Pin 4 always stays high.
However, if I set MP3_XCS to another pin such as 50, then that pin goes low.
Any ideas?
August 8, 2013 at 10:29 am #2825AnonymousInactiveI am trying to remember all errors I made before putting it to work…
1- did you bent pins 10, 11, 12 of the Sparkfun shield and redirect them to SPI connector of Due ?
2- did you test the SD card alone, running the sketch SdInfo (example of SdFat library) after modifying it with your new CS=10 ?
3- did you use SFEMP3Shieldlibrary fork for Due of Bill or mine ?About your test of CS high or low with voltmeter:
SPI library set the CS low, make the transfer, and then set it back to high automatically. (That is precisely one of the advantage of the “extended” library). So if you want to read that voltage, you have to halt the program inside the SPI library, not after calling spiTransfer(0x03)( unless you use SPI_CONTINUE parameter, but not shure)
Hope this would help. keep me informed.August 8, 2013 at 11:32 am #2826AnonymousInactiveThanks for your reply.
1- No, not pins 10 to 12, but pins 11 to 13 of the Sparkfun shield are bent and connected to the Due’s SPI. (Trick question, eh? 😉 )
2- Yes, SD card works fine.
3- I originally tried Bill’s branch and after some time realised that it is only partially complete. I have been trying yours lately and the current problems are when using yours.
Yes, I understand the low to high bit about SPI transfer. I pause the program straight after the call spiTransfer(0x03). You edited spiTransfer() so that it calls SPI.transfer( MP3_XCS, value, SPI_CONTINUE ). This means that CS should be low after the transfer. It should only go high after the line, spiLastTransfer(0xFF).
The only obvious difference between my and your setups is that you cut a track on the Sparkfun shield for pin 4 which is normally connected to GPIO1. I’m not using pin 4 so I can’t see that being an issue.
August 8, 2013 at 2:43 pm #2827AnonymousInactiveOops, of course you are right about pins 11 to 13.
I do not think GPIO1 can be an issue.Its occurs to me others basic questions:
1- did you copy to the SD card root the patches files? SFEMP3Shield need at least file patches.053 to initialize.
2- what version of SdFat library did you use? There is one included in SFEMP3Shield repository on GitHub but I use the last (?) version updated for Due. That is sdfatlib20130629.zip . Would be fine we both use the same
3- in SdFatConfig.h near line 50, be sure to have #define USE_ARDUINO_SPI_LIBRARY 1 (instead of 0)After that what you can do is uncomment lines 230 to 241 from SFEMP3Shield.ccp so that you would get more debugging info when vs_init () is called by begin(). And run sketch MP3Shield_Library_Demo.ino
Keep me informed.August 9, 2013 at 5:57 pm #2830AnonymousInactiveThank you for continuing to help me. I couldn’t do this without you.
Yes, the patch files have been copied. Yes, I am using sdfatlib20130629.
1- Okay, changing USE_ARDUINO_SPI_LIBRARY 1 fixes the problem and MP3_XCS drops to 0V
But why does changing USE_ARDUINO_SPI_LIBRARY affect this? That macro is in the SDFat stuff. The problem I was getting occurred early in SFEMP3Shield::vs_init() before the patch files are loaded and AFAIK, no SD card access is taking place (except for the initialisation of the SD card before the MP3 chip initialisation). I was not getting any problems when simply accessing a file on the SD card when USE_ARDUINO_SPI_LIBRARY was 0. So why should a setting in SDFat affect the initialisation of the MP3 chip?
2- I changed SFEMP3Shield::spiTransfer() from
return SPI.transfer( MP3_XCS, value, SPI_CONTINUE );to
return SPI.transfer( MP3_XCS, value, SPI_LAST );
and I get problems again. Any idea why that should be? I was hoping to make a version that could use pins other than 4 and 10. I thought that the only extended API stuff was just using SPI_CONTINUE and that the default SPI calls used SPI_LAST anyway.
3- I now have a new problem. This seems the same as I used to have when trying Bill’s version of the software.
I have #define USE_MP3_REFILL_MEANS USE_MP3_Polled. When I call MP3player.begin() the following happens.
In MP3player.begin() there are the lines:
playing_state = playback;
Mp3WriteRegister(SCI_DECODE_TIME, 0);In SFEMP3Shield::Mp3WriteRegister() it has:
if(playing_state == playback)
refill()SFEMP3Shield::refill() then keeps on pulling data from the SD card
After about 54 seconds, there is no more data to read from the file on the SD card and track.close() is called. I hear no sound during this time.
The MP3 file is 8,908,772 bytes which, according to the file properties in Windows, should play for 5 minutes and 19 seconds. So it would seem that digitalRead(MP3_DREQ) is always returning TRUE. So either no data is getting to the MP3 chip or MP3_DREQ is not going low.
In case it means something, uncommenting lines 230 to 241 in SFEMP3Shield.ccp means I get the following diagnostic data:
SCI_Mode (0x4800) = 0x4800
SCI_Status (0x48) = 0x48
SCI_ClockF = 0x0
MP3Clock = 6000I see that in SFEMP3Shield::refill() you have:
for(uint8_t y = 0 ; y < sizeof(mp3DataBuffer) ; y++) {
//while(!digitalRead(MP3_DREQ)); // wait until DREQ is or goes high // turns out it is not needed.
spiLastTransfer(mp3DataBuffer[y]); // Send SPI byte
}Why call spiLastTransfer() for every write instead of spiTransfer() for all but the last one?
I just tried replacing the above with this:
uint8_t y;
for(y = 0 ; y < (sizeof(mp3DataBuffer) – 1) ; y++) {
//while(!digitalRead(MP3_DREQ)); // wait until DREQ is or goes high // turns out it is not needed.
spiTransfer( mp3DataBuffer[y] ); // Send SPI byte
}
spiLastTransfer( mp3DataBuffer[y] ); // Send SPI byteThings now appear to work properly.
Why didn’t you have the same problem and why should it matter if spiLastTransfer() is called for every write?
August 10, 2013 at 10:24 am #2831AnonymousInactiveHappy it is working (better…)
“1- Okay, changing USE_ARDUINO_SPI_LIBRARY 1 fixes the problem…”
Sorry I do not think before to tell you about value of USE_ARDUINO_SPI_LIBRARY.
You right, SD card works with a value of zero. But our problem is precisely to put to work TOGETHER several devices using the same SPI interface. SD card, MP3 shield and IR receiver in your case, SD card, MP3 shield and Ethernet in mine.
Setting USE_ARDUINO_SPI_LIBRARY to 1 insure SdFat library use the same SPI library (see #include <SPI.h> at line 27 of Sd2Card.ccp) as SFEMP3Shield library ans Ethernet library. I do not know how you would drive your IR receiver.“2- I changed SFEMP3Shield::spiTransfer() from …”
See http://http://arduino.cc/en/Reference/DueExtendedSPI : “The parameter SPI_CONTINUE ensures that chip selection is keep active between transfers”
Extended SPI make easier to programmer to manage multiple device, storing parameters as clockDevider, dataMode, bitOrder for each device.
But I did not say you can’t make a version of SFEMP3Shield library without extended SPI capacities! I guess it is possible.
I take that way because Ethernet library for Due use those capacities and I think it is somehow faster.“3- I now have a new problem…”
I assume you want to say SFEMP3Shield::playMP3() instead of SFEMP3Shield::begin().
Effectively, SFEMP3Shield::Mp3WriteRegister() include a call to refill(), in case it is called during reproduction of music.
But the most important is that you MUST include in the loop() function of your sketch a call to refill(), more precisely a call to SFEMP3Shield::available(). See lines 122 to 127 of example MP#Shield_Library_Demo.ino
Actually, I think you have this line because without it mp3 chip would not last more than 1 second playing!
Did you have this line in your sketch? Are you sure there is not an other process that occupy too much time?
Did your file play entirely with MP#Shield_Library_Demo.ino ?
Did you try with an other file?“I see that in SFEMP3Shield::refill() you have:…”
Oops! That is right. And in contradiction with what I say at beginning of that: I remember having tried such code, but don’t remember why I let this version.
Let me time to verify.“Things now appear to work properly”
That means your file plays entirely with that modification?I am not an expert, I make mistakes, but I am confident that by sharing our knowledge we all progress
August 10, 2013 at 3:22 pm #2832AnonymousInactiveI think that there is a misunderstanding. I am not using an IR receiver. I only have the Due and the Sparkfun MP3 shield.
1- I saw the use of USE_ARDUINO_SPI_LIBRARY in Sd2Card.cpp but since we use a different chip select pin for the SD card and for the MP3 chip I couldn’t see why there should be a conflict.
Any way, evidently there is a conflict so either I change SFEMP3Shield.cpp to use the native DMA capability of the Due or I set USE_ARDUINO_SPI_LIBRARY to 1. I’ll keep life simple and stick to setting USE_ARDUINO_SPI_LIBRARY to 1.
2- I understand the extended SPI functionality and the use of SPI_CONTINUE and SPI_LAST. I was just surprised that only using SPI_LAST should cause problems. I suppose it’s because there needs to be some kind of delay between each write if SPI_LAST is used.
More importantly, I was surprised that the source code that I downloaded from you used SPI_LAST for every write which doesn’t work for me. Either the source code on GitHub is not the same version as you’re using or I have a hardware issue.
I suppose that it’s possible that yours worked purely by luck and that the clock frequencies of my system are very slightly different – just enough to cause problems.
3- “I assume you want to say SFEMP3Shield::playMP3() instead of SFEMP3Shield::begin()”
Yes. Apologies, my mistake.
Yes, I do call SFEMP3Shield::available() in my loop() function.
I have tried MP3Shield_Library_Demo.ino and I have the same problems – whether I have #define USE_MP3_REFILL_MEANS USE_MP3_Polled or #define USE_MP3_REFILL_MEANS USE_MP3_INTx.
I have tried two different MP3 files: one I created myself and one I downloaded from Amazon. The Amazon properties are:
sample rate of 44.1kHz, 16 bit, 250kbps, contains album art and ID Tags ID3v2.3 and v1.1
My file is:
sample rate of 44.1kHz, 16 bit, 223kbps, contains ID Tags ID3v2.3 and v1.1
“That means your file plays entirely with that modification?”
No. Unfortunately neither of the two MP3 files I have tried work.
What I see is that SFEMP3Shield::refill() gets called several times but the total number of bytes written to the MP3 chip is less than 2kB. The exact amount varies each time I reset the chip but is never more than 2048 bytes.
Since there is a variation, it feels to me like there is some kind of clocking problem. Maybe something is too fast or there needs to be a pause between a read or write maybe.
4- I have tried changing setup() so as to no longer try and play an MP3 file but instead run the memory test, SFEMP3Shield::memoryTest(). I get a result of 0. The correct answer should be 0x83ff (see p67 of the data sheet http://www.vlsi.fi/fileadmin/datasheets/vlsi/vs1053.pdf).
BTW, the definition of SFEMP3Shield::memoryTest() is wrong. It is defined as returning an unsigned value. This should be changed to signed since the function can return -1. Same for SFEMP3Shield::disableTestSineWave() and SFEMP3Shield::enableTestSineWave().
I wonder if I have a hardware problem. However:
– I can read the contents of a text file on my SD card with no problems;
– the diagnostic print outs from SFEMP3Shield::vs_init() , SCI_Mode and SCI_Status are correct.5- The diagnostic print out for SCI_ClockF in SFEMP3Shield::vs_init() I get is 0. Is that the correct value?
August 11, 2013 at 2:13 pm #2833AnonymousInactiveThis morning I double check the code I use and what is on GitHub and there is no difference.
In refill(), I try to replace the first (sizeof(mp3DataBuffer) – 1) transfers with spiTransfer( mp3DataBuffer[y] ); and that does not work. Making memory, I remember I had tried it before, because this is the logicall way, and it has failed. In that moment I don’t look farther.
The diagnostic print out for SCI_ClockF is 0. Correct.
Memory test: You are right about the mistake in definition of function memoryTest()
I run it one more time this morning, using MP3Shield_Library_Demo example. And it give the correct 0x83ff.How long are your connections between Due’ SPI connector and MP3 shield pins? This can be critical at high speed and would explain initialization seems to work but things fails once the speed of SPI bus increase
May be an idea would be to increase value of spiRate at line 252 of SFEMP3Shield.cppHere is a short code than I get on Sparkfun site, if I remember well.
It only use SPI library. It does not use SD card, the mp3 data is in an array. I just modify it to run on Due. It must play with no modification on your board.
As there is no calls to external functions (except SPI), I think it is more easy to debug. Hope you would hear it says hello!/* 3-16-2011 Spark Fun Electronics 2011 Nathan Seidle This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). This code works with the MP3 Shield based on the VS1053 IC. I wrote it to work only with VS1053. Attach the shield, attach head phones, load code, and you should hear 'Hello' four times. Debugging is done at 115200bps. This code is heavily based on Rui's example code. Nice work Rui! You got me up and running. I just made some low level improvements. http://macauadventure.com/robotics/arduino/hello_world_2.pde Rui has embedded an MP3 file within the Arduino code so no external SD card is necessary. There is a lot of comments here because these are all the gotchas I found using the VS1053. The flow of data is controlled by two pins: xDCS: Pull low to send data xCS: Pull low to send control commands From now on, xCS (aka *CS) will be called CS. The x just means it's active low which will be taken care of in firmware. We can also remove the need for DCS by setting SM_SDISHARE = 1. DCS signal is internally generated by inverting CS input. However, if we want to hook up an external SD card, this is a bad idea. The reason is that if we combine the two pins (CS and DCS) then we always have to be in one of the modes (either data or control). This is bad since we need to get the VS1053 off the SPI bus so we can go grab data bytes from the SD card. Four pins are needed to control the VS1503: DREQ CS DCS Reset (optional but good to have access to) Plus the SPI bus Please make not of what version of the MP3 shield you have: 1) Shield with VS1033 may not work with this code 2) Shield with VS1053 works with this code but requires the TX and RX traces to be cut in order to boot load an Arduino 3) This code works best with the newest MP3 shield with VS1053 and SD combination SCI: Pull XCS low to send a command to the VS1053. When a new SCI operation is sent the VS1053 pulls DREQ low. We then have to wait for VS1053 to let DREQ go high again. SCI consists of instruction byte, address byte, and 16-bit data word. XCS should be low for the full duration of operation. Size of audio FIFO is 2048 stereo (2x16 bit) samples. If DREQ is high, VS1053B can take, at a minimum, 32 bytes of SDI data. DREQ is low when stream buffer is full. The max SPI frequency of the VS1053 upon start up is 1.75MHz. From the datasheet: "Max SDI clock freq = CLKI/7 and CLKI = 12.288", hence the max clock = 1.75MHz. Page 10, input clock is 12.288MHz. Internal clock multiplier is 1x after power up. Therefore, max SPI speed is 1.75MHz. We will use 1MHz to be safe. Once we are up and running, we increase the clock multiplier to 3x and increase SPI speed to 4MHz. Be cautious when using Serial.printlns for debugging. I got a lot of random behavior when trying to do prints at different times. Be cautious of using 57600bps for debugging. Arduino v22 seems to have an un-resolved bug. */ #include <SPI.h> #define MP3_XCS 6 //Control Chip Select Pin (for accessing SPI Control/Status registers) #define MP3_XDCS 7 //Data Chip Select / BSYNC Pin #define MP3_DREQ 2 //Data Request Pin: Player asks for more data //VS10xx SCI Registers #define SCI_MODE 0x00 #define SCI_STATUS 0x01 #define SCI_BASS 0x02 #define SCI_CLOCKF 0x03 #define SCI_DECODE_TIME 0x04 #define SCI_AUDATA 0x05 #define SCI_WRAM 0x06 #define SCI_WRAMADDR 0x07 #define SCI_HDAT0 0x08 #define SCI_HDAT1 0x09 #define SCI_AIADDR 0x0A #define SCI_VOL 0x0B #define SCI_AICTRL0 0x0C #define SCI_AICTRL1 0x0D #define SCI_AICTRL2 0x0E #define SCI_AICTRL3 0x0F // Write to VS10xx register // SCI: Data transfers are always 16bit. When a new SCI operation comes in // DREQ goes low. We then have to wait for DREQ to go high again. // XCS should be low for the full duration of operation. void Mp3WriteRegister( unsigned char addressbyte, unsigned char highbyte, unsigned char lowbyte) { // Wait for DREQ to go high indicating IC is available while( ! digitalRead( MP3_DREQ) ) ; // Select control digitalWrite( MP3_XCS, LOW ); // SCI consists of instruction byte, address byte, and 16-bit data word. SPI.transfer( MP3_XCS, 0x02 ); //Write instruction SPI.transfer( MP3_XCS, addressbyte ); SPI.transfer( MP3_XCS, highbyte ); SPI.transfer( MP3_XCS, lowbyte ); // Wait for DREQ to go high indicating command is complete while( ! digitalRead( MP3_DREQ )) ; // Deselect Control digitalWrite( MP3_XCS, HIGH ); } // Read the 16-bit value of a VS10xx register unsigned int Mp3ReadRegister( unsigned char addressbyte ) { // Wait for DREQ to go high indicating IC is available while( ! digitalRead( MP3_DREQ )) ; //Select control digitalWrite( MP3_XCS, LOW ); // SCI consists of instruction byte, address byte, and 16-bit data word. SPI.transfer( MP3_XCS, 0x03 ); //Read instruction SPI.transfer( MP3_XCS, addressbyte ); // Read the first byte char response1 = SPI.transfer( MP3_XCS, 0xFF ); // Wait for DREQ to go high indicating command is complete while( ! digitalRead( MP3_DREQ )) ; // Read the second byte char response2 = SPI.transfer( MP3_XCS, 0xFF ); // Wait for DREQ to go high indicating command is complete while( ! digitalRead( MP3_DREQ )) ; // Deselect Control digitalWrite( MP3_XCS, HIGH ); int resultvalue = response1 << 8; resultvalue |= response2; return resultvalue; } // Set VS10xx Volume Register void Mp3SetVolume( unsigned char leftchannel, unsigned char rightchannel ) { Mp3WriteRegister( SCI_VOL, leftchannel, rightchannel ); } unsigned char HelloMP3[] = { 0xFF,0xF2,0x40,0xC0,0x19,0xB7,0x00,0x14,0x02,0xE6,0x5C, /* ..@.......\ */ 0x01,0x92,0x68,0x01,0xF1,0x5E,0x03,0x08,0xF0,0x24,0x80, /* ..h..^...$. */ 0x05,0x9E,0x20,0xC6,0xFC,0x12,0x32,0x5C,0xBF,0xF9,0xB9, /* .. ...2\... */ 0x20,0x4A,0x7F,0x85,0xEC,0x4C,0xCD,0xC7,0x27,0xFE,0x5C, /* J...L..'.\ */ 0x34,0x25,0xCB,0xE6,0xFF,0xFF,0x8E,0x42,0xE1,0xA0,0x5E, /* 4%.....B..^ */ 0xCA,0x6E,0x30,0x9F,0xFF,0xF8,0xC2,0x12,0x84,0xB9,0x7C, /* .n0.......| */ 0xDC,0x61,0x09,0x4A,0x7F,0xFF,0xFF,0xF9,0x7D,0x32,0x51, /* .a.J....}2Q */ 0x09,0x7C,0xE1,0xA5,0x6E,0xB4,0xFF,0xFF,0xFF,0xFF,0xD3, /* .|..n...... */ 0x34,0x41,0x91,0xF0,0x11,0x8F,0x00,0x0F,0x81,0x9C,0x10, /* 4A......... */ 0xEE,0x59,0xCE,0x56,0x67,0xFF,0xF2,0x42,0xC0,0xEC,0x53, /* .Y.Vg..B..S */ 0x09,0x15,0xF9,0xAA,0xA8,0x0D,0xD9,0x40,0x00,0xCA,0x34, /* .......@..4 */ 0x53,0xD9,0x18,0xAB,0x7D,0xF7,0x89,0x3F,0x11,0x38,0x94, /* S...}..?.8. */ 0x82,0x59,0x93,0x20,0x6A,0x0C,0xEE,0x8E,0x58,0xFA,0x38, /* .Y. j...X.8 */ 0x82,0xCA,0xF0,0x58,0xBB,0xDA,0x0C,0x50,0x56,0x1F,0xBB, /* ...X...PV.. */ 0x18,0x5D,0x8B,0x9F,0xDA,0x71,0x4F,0xFF,0xBD,0xFE,0xEF, /* .]...qO.... */ 0x69,0x36,0x86,0x3C,0x50,0xBB,0x0A,0x07,0x89,0x54,0xF0, /* i6.<P....T. */ 0x88,0x9F,0x90,0x95,0x30,0x94,0x2E,0x7E,0xF0,0x64,0x96, /* ....0..~.d. */ 0x79,0x08,0x3E,0x20,0x97,0x28,0x34,0x9C,0x09,0x7F,0xD2, /* y.> .(4.... */ 0xC0,0x01,0x75,0xF8,0x05,0x6B,0x5F,0x41,0x17,0x0B,0xE7, /* ..u..k_A... */ 0xFF,0xF2,0x40,0xC0,0x61,0xE5,0x0B,0x16,0x09,0xC6,0xC5, /* ..@.a...... */ 0x74,0x7B,0xCC,0x94,0x7A,0xF7,0x80,0x76,0xB2,0xD2,0xF8, /* t{..z..v... */ 0x39,0x06,0x38,0xFD,0x71,0xC5,0xDE,0x3A,0x38,0xBF,0xD5, /* 9.8.q..:8.. */ 0xF7,0x12,0x37,0xCB,0xF5,0x63,0x0C,0x9B,0xCE,0x77,0x25, /* ..7..c...w% */ 0xED,0xFB,0x3D,0x6B,0x35,0xF9,0x6D,0xD7,0xF9,0x2C,0xD1, /* ..=k5.m..,. */ 0x97,0x15,0x87,0x93,0xA4,0x49,0x4A,0x18,0x16,0x07,0xA1, /* .....IJ.... */ 0x60,0xF7,0x52,0x94,0xDB,0x02,0x16,0x70,0xB2,0xD8,0x80, /*
.R….p… */
0x30,0xC2,0x94,0x40,0x81,0x74,0x5A,0x19,0x7A,0x80,0x60, /* 0..@.tZ.z.` */
0x41,0x21,0x46,0x95,0xD5,0xC4,0x40,0xD2,0x01,0xC0,0x01, /* A!F…@…. */
0xDA,0xD9,0xA0,0xB1,0x01,0xFF,0xF2,0x42,0xC0,0x82,0x10, /* …….B… */
0x0B,0x12,0xF9,0x9E,0xC9,0x7E,0x7A,0xC6,0x95,0x55,0x09, /* …..~z..U. */
0x8B,0x19,0x5E,0x8B,0x26,0xCA,0xEB,0x68,0x8A,0x05,0x8F, /* ..^.&..h… */
0x36,0xA5,0xA5,0x03,0xB8,0x9C,0xED,0x24,0x51,0x59,0x90, /* 6……$QY. */
0xF6,0xC5,0x7D,0xB5,0xAD,0xAF,0xF6,0x3B,0x18,0xEF,0x3F, /* ..}….;..? */
0xFF,0xFF,0x4E,0xDE,0x16,0x66,0x0B,0xAA,0x33,0x23,0xDD, /* ..N..f..3#. */
0x9C,0x4E,0x6E,0x55,0x22,0x9D,0xA2,0x40,0xA6,0x36,0x31, /* .NnU”..@.61 */
0x69,0xA5,0xE1,0xD9,0x7F,0xF7,0xC6,0xCC,0x48,0x00,0x0E, /* i…….H.. */
0x90,0x16,0x00,0x0F,0xDE,0x6E,0x80,0x11,0x0C,0x9A,0x4F, /* …..n….O */
0x56,0xDB,0x88,0xD3,0xB2,0x1C,0x00,0xE0,0x2E,0x3E,0xAC, /* V……..>. */
0xFF,0xF2,0x40,0xC0,0x1C,0xE5,0x19,0x13,0x31,0x4E,0xCD, /* ..@…..1N. */
0x9E,0xC3,0x06,0x71,0x03,0x85,0xE5,0xB5,0x6D,0x88,0x50, /* …q….m.P */
0x8E,0x0E,0x17,0x3B,0x19,0xFB,0x4E,0x3B,0x99,0xEF,0x4C, /* …;..N;..L */
0x9E,0xF7,0x7B,0x31,0x7C,0x3C,0x5F,0xFF,0xF4,0xF8,0xE3, /* ..{1|<_…. */
0x92,0x42,0x07,0x8E,0x83,0x8E,0x0F,0x05,0x08,0x91,0xA3, /* .B……… */
0x16,0xE2,0xDF,0xB7,0x62,0x60,0x48,0x31,0x3C,0xFF,0xD4, /* ….b`H1<.. */
0x9E,0x0C,0x68,0x00,0x77,0x54,0xE3,0x1E,0x05,0xC5,0xF8, /* ..h.wT….. */
0xEA,0x8D,0x82,0x9D,0x08,0xA9,0x06,0x8D,0x1E,0x5D,0x7C, /* ………]| */
0x7F,0x08,0xC0,0x50,0x45,0x42,0xD0,0x36,0xF8,0xB2,0x4D, /* …PEB.6..M */
0x53,0x0C,0x80,0x3B,0x4D,0xFF,0xF2,0x42,0xC0,0x2F,0x3C, /* S..;M..B./< */
0x25,0x19,0x29,0xFE,0xBC,0x2E,0xC4,0xD0,0x99,0x4C,0x48, /* %.)……LH */
0xB0,0x9C,0x49,0xD2,0x1A,0x2D,0x02,0xC2,0x79,0x69,0x16, /* ..I..-..yi. */
0x92,0xA8,0xC5,0xAB,0x45,0x5A,0x68,0xE8,0x75,0x57,0xCD, /* ….EZh.uW. */
0xF1,0xB9,0xAA,0x13,0x88,0xE4,0x87,0x42,0x15,0xB3,0x58, /* …….B..X */
0xF5,0xA3,0x46,0xB1,0xCF,0xD3,0x59,0x7E,0xBA,0xB5,0xA7, /* ..F…Y~… */
0x6B,0x0B,0x17,0x57,0x6B,0x5C,0x4A,0xCD,0x53,0x76,0x2A, /* k..Wk\J.Sv* */
0x1D,0x28,0xC5,0x1C,0x76,0x5C,0xDD,0x0A,0x00,0x4B,0xC0, /* .(..v\…K. */
0x1B,0xCA,0xA8,0xE9,0x81,0x5B,0xA6,0xDC,0xA4,0x59,0x13, /* …..[…Y. */
0xFC,0xBA,0x8F,0x98,0x79,0x44,0x25,0xC9,0x35,0x38,0xCA, /* ….yD%.58. */
0xFF,0xF2,0x40,0xC0,0xB9,0x7D,0x1A,0x13,0x79,0x6A,0xC8, /* ..@..}..yj. */
0x3E,0xC4,0x46,0x94,0x8D,0x3C,0x67,0x85,0xB1,0xA8,0x89, /* >.F..<g…. */
0xC0,0xF2,0xE6,0x2F,0x9D,0x7C,0xC9,0xB4,0xBE,0xCF,0xE1, /* …/.|….. */
0x7D,0xFE,0x1F,0x03,0x00,0x12,0x84,0x72,0x8C,0xE7,0xD8, /* }……r… */
0x5E,0xC9,0xA9,0x01,0xBA,0x9B,0xC4,0x10,0x5C,0x70,0x2E, /* ^…….\p. */
0x6C,0x48,0xE7,0x8C,0x15,0x0B,0x06,0x01,0xE5,0xFF,0xFF, /* lH……… */
0xD4,0x0D,0x00,0x0F,0xCE,0x58,0x95,0x61,0xA8,0x9E,0x7B, /* …..X.a..{ */
0x19,0x98,0xB0,0xF0,0xC6,0x72,0x82,0xD5,0x27,0x06,0x47, /* …..r..’.G */
0x41,0x22,0x0F,0x65,0x93,0xC9,0x8A,0x09,0x19,0x48,0x1B, /* A”.e…..H. */
0xBD,0xD6,0x64,0x1A,0xAC,0xFF,0xF2,0x42,0xC0,0xF1,0x11, /* ..d….B… */
0x25,0x14,0x22,0x06,0xBC,0x0E,0xD4,0x4E,0x99,0x90,0xA8, /* %.”….N… */
0xD8,0xB7,0xAD,0x5D,0x3E,0xAF,0x6E,0xBE,0x66,0x83,0xA4, /* …]>.n.f.. */
0xE3,0xC2,0xE0,0x29,0x43,0x87,0x5F,0x4F,0x27,0x9C,0x2C, /* …)C._O’., */
0xD0,0x91,0xF3,0x87,0x9B,0x54,0xED,0xD1,0xB4,0xF3,0x39, /* …..T….9 */
0x87,0x22,0x06,0x86,0x0D,0x71,0xE4,0x6F,0x2A,0x08,0x04, /* .”…q.o*.. */
0xC0,0x03,0x2A,0xB1,0xE2,0x05,0x4D,0x64,0xA1,0x9C,0xA6, /* ..*…Md… */
0x0D,0x41,0xA6,0xF2,0x7A,0xC1,0x30,0xC3,0x38,0x26,0x09, /* .A..z.0.8&. */
0x50,0x08,0xC4,0xF6,0x30,0x0C,0xA6,0xA9,0x17,0x00,0x13, /* P…0…… */
0x0C,0xDC,0xC4,0x2F,0x28,0xEB,0x3F,0xCD,0x7A,0x3D,0x2F, /* …/(.?.z=/ */
0xFF,0xF2,0x40,0xC0,0x18,0x6F,0x2E,0x13,0xA1,0xF2,0xBC, /* ..@..o….. */
0x36,0xCB,0x4E,0x99,0x6E,0xFC,0xEE,0xC5,0xF0,0xA0,0xB7, /* 6.N.n…… */
0x92,0xD4,0xEE,0x79,0x7C,0x50,0x5D,0xE5,0x04,0x94,0xA9, /* …y|P]…. */
0x76,0xCF,0x6C,0x70,0xDD,0x0D,0xD4,0xEE,0xED,0x98,0xE8, /* v.lp……. */
0xC8,0x35,0x36,0x7A,0x0C,0x05,0x80,0x03,0xBC,0xBE,0x91, /* .56z……. */
0x00,0x7C,0xAE,0x65,0xB8,0x91,0xA3,0x33,0xBA,0x68,0x60, /* .|.e…3.h` */
0xD4,0x1A,0x66,0xF8,0x43,0xA0,0x20,0x89,0xE7,0x80,0xD8, /* ..f.C. …. */
0x1E,0x4F,0xA0,0x04,0x60,0x06,0x0A,0xA4,0x91,0x24,0xFA, /* .O..`….$. */
0x9F,0x57,0x53,0xF4,0x7A,0xDB,0x5F,0x56,0xE3,0x6E,0x0B, /* .WS.z._V.n. */
0x8B,0x3A,0x1C,0xF9,0x5E,0xFF,0xF2,0x42,0xC0,0xB1,0x00, /* .:..^..B… */
0x38,0x14,0x09,0xEE,0xB4,0x36,0xD3,0x4E,0x99,0xA4,0x78, /* 8….6.N..x */
0x94,0x73,0xC4,0x66,0x30,0xF5,0xEA,0xDB,0xBA,0x67,0x67, /* .s.f0….gg */
0x95,0x6B,0xAB,0x68,0x5D,0x08,0xA1,0x39,0x56,0xAB,0x1E, /* .k.h]..9V.. */
0xD5,0x03,0xE8,0x01,0x70,0x00,0xB3,0x93,0x33,0x19,0x8C, /* ….p…3.. */
0x61,0x8F,0xBB,0x5D,0x24,0x12,0x63,0xD3,0x4B,0x5D,0x91, /* a..]$.c.K]. */
0x08,0x43,0x22,0x56,0x1A,0xC5,0x10,0x21,0x84,0xA8,0xEA, /* .C”V…!… */
0x80,0xBF,0x16,0x8E,0x3D,0x46,0x18,0x9C,0x6E,0x9A,0x91, /* ….=F..n.. */
0xE6,0xC9,0x6F,0xD2,0x7D,0x27,0xD7,0xE9,0x6B,0xFF,0x0A, /* ..o.}’..k.. */
0x03,0x43,0x89,0xD5,0xBF,0x52,0x97,0x0A,0x25,0x95,0x0D, /* .C…R..%.. */
0xFF,0xF2,0x40,0xC0,0xF5,0xC3,0x41,0x13,0x81,0xEE,0xA8, /* ..@…A…. */
0x5E,0xD3,0x44,0x98,0xFC,0xCF,0x97,0xF9,0x58,0xB5,0x33, /* ^.D…..X.3 */
0xB1,0x85,0x47,0x86,0xD7,0x98,0x01,0x3B,0xA3,0x4F,0x7E, /* ..G….;.O~ */
0x04,0xA6,0xC3,0x39,0x21,0x70,0x27,0x62,0xB5,0x18,0x10, /* …9!p’b… */
0x09,0x99,0x00,0x8B,0x7E,0xF2,0xBF,0x52,0x18,0x26,0x30, /* ….~..R.&0 */
0x1C,0xB0,0x01,0x49,0x30,0xE0,0xC3,0x11,0x46,0x05,0xCC, /* …I0…F.. */
0x49,0x14,0x28,0xB2,0xED,0x4B,0x57,0x5A,0x2F,0xB7,0x46, /* I.(..KWZ/.F */
0x63,0x34,0xD2,0xDA,0x9F,0x56,0x32,0xB7,0xA2,0x25,0xFF, /* c4…V2..%. */
0x94,0x28,0x33,0x7F,0x3B,0xC4,0x50,0xEC,0xB1,0xE2,0x26, /* .(3.;.P…& */
0xA1,0xB7,0x07,0x7F,0xFB,0xFF,0xF2,0x42,0xC0,0x67,0x6A, /* …….B.gj */
0x4C,0x13,0xF9,0x6A,0x90,0x7E,0xDB,0x44,0x94,0x3F,0xFF, /* L..j.~.D.?. */
0x14,0xD6,0x2A,0xFF,0xFF,0xC1,0x34,0x8C,0x48,0x22,0x00, /* ..*…4.H”. */
0x06,0x8F,0x21,0xFD,0x64,0x60,0x04,0x92,0x42,0xEA,0x74, /* ..!.d`..B.t */
0x32,0x37,0xAA,0x5A,0x9F,0x67,0x01,0x8B,0x3F,0x37,0x31, /* 27.Z.g..?71 */
0xDD,0x06,0x3C,0x01,0x34,0x30,0xE0,0x5C,0x78,0x78,0xCB, /* ..<.40.\xx. */
0xD6,0xF1,0x31,0x8A,0x69,0x61,0x93,0x92,0x42,0xCE,0x4B, /* ..1.ia..B.K */
0xC5,0x02,0x4E,0x73,0xC6,0x24,0x30,0xCD,0x08,0x66,0xC6, /* ..Ns.$0..f. */
0x35,0xAB,0xA2,0x3D,0x2F,0xB3,0xBD,0x34,0x87,0x13,0xEE, /* 5..=/..4… */
0x71,0x45,0x68,0xFA,0xEA,0x05,0x84,0x41,0x36,0x4C,0x9A, /* qEh….A6L. */
0xFF,0xF2,0x40,0xC0,0xC9,0x92,0x56,0x13,0xD0,0x6E,0x70, /* ..@…V..np */
0x54,0xD3,0xCC,0x28,0x06,0xD7,0x0E,0xA4,0x1D,0x9C,0x9D, /* T..(……. */
0xD9,0xA9,0x88,0x7B,0xB5,0xA3,0x56,0xB7,0x4B,0x4B,0x5A, /* …{..V.KKZ */
0x9B,0x2C,0xA9,0xAD,0x6F,0x99,0x6C,0xC0,0x4C,0x14,0x14, /* .,..o.l.L.. */
0xEF,0xB4,0x20,0x91,0x5F,0xBC,0x81,0x41,0x41,0x5D,0xD4, /* .. ._..AA]. */
0x20,0xBD,0x05,0x1A,0x6F,0xE2,0x68,0x56,0x41,0x41,0x57, /* …o.hVAAW */
0xF9,0xBF,0x89,0x82,0x8E,0xC7,0x8F,0x0A,0x0A,0x09,0x37, /* ……….7 */
0xF1,0x05,0x0A,0x0A,0x0A,0x0A,0x09,0x05,0x37,0xFF,0x10, /* ……..7.. */
0x50,0x50,0x53,0x65,0xFF,0xFF,0xFD,0x75,0xDF,0xFF,0xFF, /* PPSe…u… */
0x68,0x4F,0xFF,0x84,0x70,0xFF,0xF2,0x42,0xC0,0x27,0x50, /* hO..p..B.’P */
0x5F,0x17,0xE8,0x82,0x3C,0x11,0x58,0x18,0x01,0x55,0x48, /* _…<.X..UH */
0xBC,0x52,0xFC,0x4A,0x4C,0x3C,0xD5,0xF6,0x11,0x2D,0xBF, /* .R.JL<…-. */
0xEA,0x03,0x5C,0x57,0x29,0xBF,0xC3,0x75,0x1C,0xE6,0xDD, /* ..\W)..u… */
0xBF,0xED,0xEF,0xD0,0x98,0x77,0x71,0x95,0x73,0xFF,0xED, /* …..wq.s.. */
0x54,0xBE,0xD5,0xEE,0xAE,0xC2,0xD5,0x0B,0xFF,0xF1,0x97, /* T………. */
0x8A,0xE4,0x42,0x09,0x99,0xB1,0xEA,0x94,0xDC,0x78,0xB5, /* ..B……x. */
0x34,0x0F,0xF1,0x8F,0xFC,0x15,0xF6,0xFA,0xB1,0x47,0xA9, /* 4……..G. */
0x6C,0x67,0x43,0x8B,0xF2,0x76,0x22,0xED,0xDA,0x85,0xBA, /* lgC..v”…. */
0x2F,0xC7,0xF9,0xCF,0xFC,0xDB,0x46,0x2E,0x50,0x0A,0x84, /* /…..F.P.. */
0xFF,0xF2,0x40,0xC0,0xC6,0x4A,0x59,0x28,0x2B,0x19,0xE0, /* ..@..JY(+.. */
0x01,0x89,0x78,0x00,0x52,0x85,0x3C,0x8E,0x54,0x9A,0x48, /* ..x.R.<.T.H */
0x5A,0x72,0x32,0x94,0xBF,0x43,0x4F,0x24,0x53,0x4B,0xEC, /* Zr2..CO$SK. */
0x4B,0x99,0x0E,0x66,0x1F,0xFF,0xCE,0x7F,0xFF,0x3F,0x10, /* K..f…..?. */
0xAE,0x82,0x62,0x71,0x34,0x18,0x59,0x9B,0x51,0xC7,0x59, /* ..bq4.Y.Q.Y */
0xCE,0xEE,0xA5,0xFE,0x02,0xBB,0x30,0x91,0x49,0xD5,0x4B, /* ……0.I.K */
0xF3,0xDC,0x9A,0xA9,0x57,0x8E,0x72,0x10,0xC0,0x5D,0x60, /* ….W.r..]` */
0x67,0xFC,0x7D,0xD6,0xBA,0xDD,0xB3,0x8B,0x5A,0x0A,0x4C, /* g.}…..Z.L */
0x41,0x4D,0x45,0x33,0x2E,0x39,0x33,0xAA,0xAA,0xAA,0xAA, /* AME3.93…. */
0xAA,0xAA,0xAA,0xAA,0xAA,0x54,0x41,0x47,0x48,0x65,0x6C, /* …..TAGHel */
0x6C,0x6F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* lo */
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* */
0x20,0x20,0x20,0x20,0x20,0x50,0x61,0x6E,0x75,0x2D,0x4B, /* Panu-K */
0x72,0x69,0x73,0x74,0x69,0x61,0x6E,0x20,0x50,0x6F,0x69, /* ristian Poi */
0x6B,0x73,0x61,0x6C,0x6F,0x20,0x20,0x20,0x20,0x20,0x20, /* ksalo */
0x20,0x20,0x56,0x53,0x44,0x53,0x50,0x20,0x54,0x65,0x73, /* VSDSP Tes */
0x74,0x69,0x6E,0x67,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* ting */
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* */
0x20,0x20,0x20,0x4D,0x50,0x33,0x20,0x48,0x65,0x6C,0x6C, /* MP3 Hell */
0x6F,0x2C,0x20,0x57,0x6F,0x72,0x6C,0x64,0x21,0x20,0x20, /* o, World! */
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* */
0x00, /* . */
};void setup()
{
//
pinMode( MP3_DREQ, INPUT ); // pin 2
pinMode( MP3_XCS, OUTPUT ); // pin 6 : Control Select of VS1053 IC
pinMode( MP3_XDCS, OUTPUT ); // pin 7 : Data Chip Select of VS1053 IC
digitalWrite( MP3_XDCS, HIGH ); // Deselect Data// Control Select of SD card high
pinMode( 9, OUTPUT );
digitalWrite( 9, HIGH );// Control Select of Ethernet high
pinMode( 10, OUTPUT );
digitalWrite( 10, HIGH );// Control Select of SD card of Ethernet shield high
pinMode( 4, OUTPUT );
digitalWrite( 4, HIGH );// Use serial for debugging
Serial.begin( 115200 );
Serial.println( “MP3 Shield Example” );//Setup SPI for VS1053
SPI.begin( MP3_XCS );
SPI.setBitOrder( MP3_XCS, MSBFIRST );
SPI.setDataMode( MP3_XCS, SPI_MODE0 );// From page 12 of datasheet, max SCI reads are CLKI/7. Input clock is 12.288MHz.
// Internal clock multiplier is 1.0x after power up.
// Therefore, max SPI speed is 1.75MHz. We will use 1MHz to be safe.
SPI.setClockDivider( MP3_XCS, 84 ); // Set SPI bus speed to 1MHz (84MHz / 84 = 1MHz for Due)
//SPI.setClockDivider( SPI_CLOCK_DIV16 ); // Set SPI bus speed to 1MHz (16MHz / 16 = 1MHz)
SPI.transfer( MP3_XCS, 0xFF ); //Throw a dummy byte at the bus//Initialize VS1053 chip
digitalWrite( MP3_XCS, HIGH ); //Deselect Control
digitalWrite( MP3_XDCS, HIGH ); //Deselect DataMp3SetVolume( 20, 20 ); //Set initial volume (20 = -10dB)
// Let’s check the status of the VS1053
int MP3Mode = Mp3ReadRegister( SCI_MODE );
int MP3Status = Mp3ReadRegister( SCI_STATUS );
int MP3Clock = Mp3ReadRegister( SCI_CLOCKF );Serial.print( “SCI_Mode (0x4800) = 0x” );
Serial.println( MP3Mode, HEX );//Serial.print( “SCI_Status (0x48) = 0x” );
//Serial.println( MP3Status, HEX );int vsVersion = ( MP3Status >> 4 ) & 0x000F; //Mask out only the four version bits
Serial.print( “VS Version (VS1053 is 4) = ” );
Serial.println( vsVersion, DEC ); //The 1053B should respond with 4. VS1001 = 0, VS1011 = 1, VS1002 = 2, VS1003 = 3//Serial.print(“SCI_ClockF = 0x”);
//Serial.println(MP3Clock, HEX);// Now that we have the VS1053 up and running, increase the VS1053 internal clock multiplier and up our SPI rate
Mp3WriteRegister( SCI_CLOCKF, 0x60, 0x00 ); //Set multiplier to 3.0x//From page 12 of datasheet, max SCI reads are CLKI/7. Input clock is 12.288MHz.
//Internal clock multiplier is now 3x.
//Therefore, max SPI speed is 5MHz. 4MHz will be safe.
SPI.setClockDivider( MP3_XCS, 21 ); //Set SPI bus speed to 4MHz (8416MHz / 21 = 4MHz for Due)
//SPI.setClockDivider( SPI_CLOCK_DIV4 ); //Set SPI bus speed to 4MHz (16MHz / 4 = 4MHz)MP3Clock = Mp3ReadRegister( SCI_CLOCKF );
Serial.print( “SCI_ClockF = 0x” );
Serial.println( MP3Clock, HEX );
}#define MP3_BUF_LEN 1024
//unsigned char mp3Buf[ 2 * MP3_BUF_LEN ];
unsigned char mp3Buf[ 2048 ];volatile int f = 0;
volatile unsigned char *p;
unsigned char *p0, *p1, *p2, *p3, *s, *s1;
int b = 0;
int n = 0;void iniHello()
{
s = HelloMP3;
s1 = s + sizeof( HelloMP3 );
p0 = mp3Buf;
p1 = p0 + MP3_BUF_LEN;
p2 = p1 + MP3_BUF_LEN;
p3 = p2 + 1;
p = p0;
b = 0;
transfertBuf();
transfertBuf();
attachInterrupt( MP3_DREQ, transfertMp3, HIGH );
}void finHello()
{
detachInterrupt( MP3_DREQ );
digitalWrite( MP3_XDCS, HIGH ); // Deselect Data// Wait for DREQ to go high indicating transfer is complete
while( ! digitalRead( MP3_DREQ ))
;
}void transfertMp3()
{
digitalWrite( MP3_XDCS, LOW ); // Select Data
SPI.transfer( MP3_XCS, *p ); // Send SPI byte
p ++;
if( p >= p3 )
f = 2;
else if( p == p1 )
f = 1;
else if( p == p2 )
{
f = 1;
p = p0;
}
}void transfertBuf()
{
Serial.print( b );
unsigned char *p4 = b == 0 ? p0 : p1 ;
unsigned long ln = s1 – s;
if( ln < MP3_BUF_LEN )
p3 = p4 + ln;
else
ln = MP3_BUF_LEN;
memcpy( p4, s, ln );
// memcpy( ( b == 0 ? p0 : p1 ), s, ( ln < MP3_BUF_LEN ? ln : MP3_BUF_LEN ) );
s += ln;
b = 1 – b;
f = 0;
}void loop()
{
if( n == 0 )
{
// read any existing Serial data
while( Serial.read() >= 0 ) ;
Serial.print( “\nType any character to listen Hello\n” );
while( Serial.available() == 0 ) ;
n = 4;
iniHello();
}if( f == 2 )
{
finHello();
n = 0;
Serial.print( “Ok\n” );
}
else if( f == 1 )
transfertBuf();/*
if( p >= p1 )
{
finHello();
delay( 500 );
Serial.print( n );
n — ;
if( n > 0 )
iniHello();
}
*/
}
`August 11, 2013 at 2:29 pm #2836AnonymousInactiveSorry, I cannot use the “code” tag correctly, so I repeat my post:
Here is a short code than I get on Sparkfun site, if I remember well.
It only use SPI library. It does not use SD card, the mp3 data is in an array. I just modify it to run on Due. It must play with no modification on your board.
As there is no calls to external functions (except SPI), I think it is more easy to debug. Hope you would hear it says hello!
The code:
=======================================================================
/*
3-16-2011
Spark Fun Electronics 2011
Nathan SeidleThis code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
This code works with the MP3 Shield based on the VS1053 IC. I wrote it to work only with VS1053. Attach
the shield, attach head phones, load code, and you should hear ‘Hello’ four times. Debugging is done at 115200bps.This code is heavily based on Rui’s example code. Nice work Rui! You got me up and running. I just made some
low level improvements.
http://macauadventure.com/robotics/arduino/hello_world_2.pdeRui has embedded an MP3 file within the Arduino code so no external SD card is necessary.
There is a lot of comments here because these are all the gotchas I found using the VS1053.
The flow of data is controlled by two pins:
xDCS: Pull low to send data
xCS: Pull low to send control commands
From now on, xCS (aka *CS) will be called CS. The x just means it’s active low which will
be taken care of in firmware.We can also remove the need for DCS by setting SM_SDISHARE = 1. DCS signal is internally generated by
inverting CS input. However, if we want to hook up an external SD card, this is a bad idea. The reason is that
if we combine the two pins (CS and DCS) then we always have to be in one of the modes (either data or control).
This is bad since we need to get the VS1053 off the SPI bus so we can go grab data bytes from the SD card.Four pins are needed to control the VS1503:
DREQ
CS
DCS
Reset (optional but good to have access to)
Plus the SPI busPlease make not of what version of the MP3 shield you have:
1) Shield with VS1033 may not work with this code
2) Shield with VS1053 works with this code but requires the TX and RX traces to be cut in order to boot load an Arduino
3) This code works best with the newest MP3 shield with VS1053 and SD combinationSCI: Pull XCS low to send a command to the VS1053. When a new SCI operation is sent
the VS1053 pulls DREQ low. We then have to wait for VS1053 to let DREQ go high again.
SCI consists of instruction byte, address byte, and 16-bit data word.
XCS should be low for the full duration of operation.Size of audio FIFO is 2048 stereo (2×16 bit) samples. If DREQ is high,
VS1053B can take, at a minimum, 32 bytes of SDI data. DREQ is low when stream
buffer is full.The max SPI frequency of the VS1053 upon start up is 1.75MHz.
From the datasheet: “Max SDI clock freq = CLKI/7 and CLKI = 12.288″, hence the max
clock = 1.75MHz. Page 10, input clock is 12.288MHz. Internal clock multiplier
is 1x after power up. Therefore, max SPI speed is 1.75MHz. We will use 1MHz to be safe. Once we are up
and running, we increase the clock multiplier to 3x and increase SPI speed to 4MHz.Be cautious when using Serial.printlns for debugging. I got a lot of random behavior when trying to
do prints at different times.Be cautious of using 57600bps for debugging. Arduino v22 seems to have an un-resolved bug.
*/
#include <SPI.h>
#define MP3_XCS 6 //Control Chip Select Pin (for accessing SPI Control/Status registers)
#define MP3_XDCS 7 //Data Chip Select / BSYNC Pin
#define MP3_DREQ 2 //Data Request Pin: Player asks for more data//VS10xx SCI Registers
#define SCI_MODE 0x00
#define SCI_STATUS 0x01
#define SCI_BASS 0x02
#define SCI_CLOCKF 0x03
#define SCI_DECODE_TIME 0x04
#define SCI_AUDATA 0x05
#define SCI_WRAM 0x06
#define SCI_WRAMADDR 0x07
#define SCI_HDAT0 0x08
#define SCI_HDAT1 0x09
#define SCI_AIADDR 0x0A
#define SCI_VOL 0x0B
#define SCI_AICTRL0 0x0C
#define SCI_AICTRL1 0x0D
#define SCI_AICTRL2 0x0E
#define SCI_AICTRL3 0x0F// Write to VS10xx register
// SCI: Data transfers are always 16bit. When a new SCI operation comes in
// DREQ goes low. We then have to wait for DREQ to go high again.
// XCS should be low for the full duration of operation.void Mp3WriteRegister( unsigned char addressbyte, unsigned char highbyte, unsigned char lowbyte)
{
// Wait for DREQ to go high indicating IC is available
while( ! digitalRead( MP3_DREQ) )
;
// Select control
digitalWrite( MP3_XCS, LOW );// SCI consists of instruction byte, address byte, and 16-bit data word.
SPI.transfer( MP3_XCS, 0x02 ); //Write instruction
SPI.transfer( MP3_XCS, addressbyte );
SPI.transfer( MP3_XCS, highbyte );
SPI.transfer( MP3_XCS, lowbyte );// Wait for DREQ to go high indicating command is complete
while( ! digitalRead( MP3_DREQ ))
;
// Deselect Control
digitalWrite( MP3_XCS, HIGH );
}// Read the 16-bit value of a VS10xx register
unsigned int Mp3ReadRegister( unsigned char addressbyte )
{
// Wait for DREQ to go high indicating IC is available
while( ! digitalRead( MP3_DREQ ))
;
//Select control
digitalWrite( MP3_XCS, LOW );// SCI consists of instruction byte, address byte, and 16-bit data word.
SPI.transfer( MP3_XCS, 0x03 ); //Read instruction
SPI.transfer( MP3_XCS, addressbyte );// Read the first byte
char response1 = SPI.transfer( MP3_XCS, 0xFF );
// Wait for DREQ to go high indicating command is complete
while( ! digitalRead( MP3_DREQ ))
;
// Read the second byte
char response2 = SPI.transfer( MP3_XCS, 0xFF );
// Wait for DREQ to go high indicating command is complete
while( ! digitalRead( MP3_DREQ ))
;
// Deselect Control
digitalWrite( MP3_XCS, HIGH );int resultvalue = response1 << 8;
resultvalue |= response2;
return resultvalue;
}// Set VS10xx Volume Register
void Mp3SetVolume( unsigned char leftchannel, unsigned char rightchannel )
{
Mp3WriteRegister( SCI_VOL, leftchannel, rightchannel );
}unsigned char HelloMP3[] =
{
0xFF,0xF2,0x40,0xC0,0x19,0xB7,0x00,0x14,0x02,0xE6,0x5C, /* ..@…….\ */
0x01,0x92,0x68,0x01,0xF1,0x5E,0x03,0x08,0xF0,0x24,0x80, /* ..h..^…$. */
0x05,0x9E,0x20,0xC6,0xFC,0x12,0x32,0x5C,0xBF,0xF9,0xB9, /* .. …2\… */
0x20,0x4A,0x7F,0x85,0xEC,0x4C,0xCD,0xC7,0x27,0xFE,0x5C, /* J…L..’.\ */
0x34,0x25,0xCB,0xE6,0xFF,0xFF,0x8E,0x42,0xE1,0xA0,0x5E, /* 4%…..B..^ */
0xCA,0x6E,0x30,0x9F,0xFF,0xF8,0xC2,0x12,0x84,0xB9,0x7C, /* .n0…….| */
0xDC,0x61,0x09,0x4A,0x7F,0xFF,0xFF,0xF9,0x7D,0x32,0x51, /* .a.J….}2Q */
0x09,0x7C,0xE1,0xA5,0x6E,0xB4,0xFF,0xFF,0xFF,0xFF,0xD3, /* .|..n…… */
0x34,0x41,0x91,0xF0,0x11,0x8F,0x00,0x0F,0x81,0x9C,0x10, /* 4A……… */
0xEE,0x59,0xCE,0x56,0x67,0xFF,0xF2,0x42,0xC0,0xEC,0x53, /* .Y.Vg..B..S */
0x09,0x15,0xF9,0xAA,0xA8,0x0D,0xD9,0x40,0x00,0xCA,0x34, /* …….@..4 */
0x53,0xD9,0x18,0xAB,0x7D,0xF7,0x89,0x3F,0x11,0x38,0x94, /* S…}..?.8. */
0x82,0x59,0x93,0x20,0x6A,0x0C,0xEE,0x8E,0x58,0xFA,0x38, /* .Y. j…X.8 */
0x82,0xCA,0xF0,0x58,0xBB,0xDA,0x0C,0x50,0x56,0x1F,0xBB, /* …X…PV.. */
0x18,0x5D,0x8B,0x9F,0xDA,0x71,0x4F,0xFF,0xBD,0xFE,0xEF, /* .]…qO…. */
0x69,0x36,0x86,0x3C,0x50,0xBB,0x0A,0x07,0x89,0x54,0xF0, /* i6.<P….T. */
0x88,0x9F,0x90,0x95,0x30,0x94,0x2E,0x7E,0xF0,0x64,0x96, /* ….0..~.d. */
0x79,0x08,0x3E,0x20,0x97,0x28,0x34,0x9C,0x09,0x7F,0xD2, /* y.> .(4…. */
0xC0,0x01,0x75,0xF8,0x05,0x6B,0x5F,0x41,0x17,0x0B,0xE7, /* ..u..k_A… */
0xFF,0xF2,0x40,0xC0,0x61,0xE5,0x0B,0x16,0x09,0xC6,0xC5, /* ..@.a…… */
0x74,0x7B,0xCC,0x94,0x7A,0xF7,0x80,0x76,0xB2,0xD2,0xF8, /* t{..z..v… */
0x39,0x06,0x38,0xFD,0x71,0xC5,0xDE,0x3A,0x38,0xBF,0xD5, /* 9.8.q..:8.. */
0xF7,0x12,0x37,0xCB,0xF5,0x63,0x0C,0x9B,0xCE,0x77,0x25, /* ..7..c…w% */
0xED,0xFB,0x3D,0x6B,0x35,0xF9,0x6D,0xD7,0xF9,0x2C,0xD1, /* ..=k5.m..,. */
0x97,0x15,0x87,0x93,0xA4,0x49,0x4A,0x18,0x16,0x07,0xA1, /* …..IJ…. */
0x60,0xF7,0x52,0x94,0xDB,0x02,0x16,0x70,0xB2,0xD8,0x80, /* `.R….p… */
0x30,0xC2,0x94,0x40,0x81,0x74,0x5A,0x19,0x7A,0x80,0x60, /* 0..@.tZ.z.` */
0x41,0x21,0x46,0x95,0xD5,0xC4,0x40,0xD2,0x01,0xC0,0x01, /* A!F…@…. */
0xDA,0xD9,0xA0,0xB1,0x01,0xFF,0xF2,0x42,0xC0,0x82,0x10, /* …….B… */
0x0B,0x12,0xF9,0x9E,0xC9,0x7E,0x7A,0xC6,0x95,0x55,0x09, /* …..~z..U. */
0x8B,0x19,0x5E,0x8B,0x26,0xCA,0xEB,0x68,0x8A,0x05,0x8F, /* ..^.&..h… */
0x36,0xA5,0xA5,0x03,0xB8,0x9C,0xED,0x24,0x51,0x59,0x90, /* 6……$QY. */
0xF6,0xC5,0x7D,0xB5,0xAD,0xAF,0xF6,0x3B,0x18,0xEF,0x3F, /* ..}….;..? */
0xFF,0xFF,0x4E,0xDE,0x16,0x66,0x0B,0xAA,0x33,0x23,0xDD, /* ..N..f..3#. */
0x9C,0x4E,0x6E,0x55,0x22,0x9D,0xA2,0x40,0xA6,0x36,0x31, /* .NnU”..@.61 */
0x69,0xA5,0xE1,0xD9,0x7F,0xF7,0xC6,0xCC,0x48,0x00,0x0E, /* i…….H.. */
0x90,0x16,0x00,0x0F,0xDE,0x6E,0x80,0x11,0x0C,0x9A,0x4F, /* …..n….O */
0x56,0xDB,0x88,0xD3,0xB2,0x1C,0x00,0xE0,0x2E,0x3E,0xAC, /* V……..>. */
0xFF,0xF2,0x40,0xC0,0x1C,0xE5,0x19,0x13,0x31,0x4E,0xCD, /* ..@…..1N. */
0x9E,0xC3,0x06,0x71,0x03,0x85,0xE5,0xB5,0x6D,0x88,0x50, /* …q….m.P */
0x8E,0x0E,0x17,0x3B,0x19,0xFB,0x4E,0x3B,0x99,0xEF,0x4C, /* …;..N;..L */
0x9E,0xF7,0x7B,0x31,0x7C,0x3C,0x5F,0xFF,0xF4,0xF8,0xE3, /* ..{1|<_…. */
0x92,0x42,0x07,0x8E,0x83,0x8E,0x0F,0x05,0x08,0x91,0xA3, /* .B……… */
0x16,0xE2,0xDF,0xB7,0x62,0x60,0x48,0x31,0x3C,0xFF,0xD4, /* ….b`H1<.. */
0x9E,0x0C,0x68,0x00,0x77,0x54,0xE3,0x1E,0x05,0xC5,0xF8, /* ..h.wT….. */
0xEA,0x8D,0x82,0x9D,0x08,0xA9,0x06,0x8D,0x1E,0x5D,0x7C, /* ………]| */
0x7F,0x08,0xC0,0x50,0x45,0x42,0xD0,0x36,0xF8,0xB2,0x4D, /* …PEB.6..M */
0x53,0x0C,0x80,0x3B,0x4D,0xFF,0xF2,0x42,0xC0,0x2F,0x3C, /* S..;M..B./< */
0x25,0x19,0x29,0xFE,0xBC,0x2E,0xC4,0xD0,0x99,0x4C,0x48, /* %.)……LH */
0xB0,0x9C,0x49,0xD2,0x1A,0x2D,0x02,0xC2,0x79,0x69,0x16, /* ..I..-..yi. */
0x92,0xA8,0xC5,0xAB,0x45,0x5A,0x68,0xE8,0x75,0x57,0xCD, /* ….EZh.uW. */
0xF1,0xB9,0xAA,0x13,0x88,0xE4,0x87,0x42,0x15,0xB3,0x58, /* …….B..X */
0xF5,0xA3,0x46,0xB1,0xCF,0xD3,0x59,0x7E,0xBA,0xB5,0xA7, /* ..F…Y~… */
0x6B,0x0B,0x17,0x57,0x6B,0x5C,0x4A,0xCD,0x53,0x76,0x2A, /* k..Wk\J.Sv* */
0x1D,0x28,0xC5,0x1C,0x76,0x5C,0xDD,0x0A,0x00,0x4B,0xC0, /* .(..v\…K. */
0x1B,0xCA,0xA8,0xE9,0x81,0x5B,0xA6,0xDC,0xA4,0x59,0x13, /* …..[…Y. */
0xFC,0xBA,0x8F,0x98,0x79,0x44,0x25,0xC9,0x35,0x38,0xCA, /* ….yD%.58. */
0xFF,0xF2,0x40,0xC0,0xB9,0x7D,0x1A,0x13,0x79,0x6A,0xC8, /* ..@..}..yj. */
0x3E,0xC4,0x46,0x94,0x8D,0x3C,0x67,0x85,0xB1,0xA8,0x89, /* >.F..<g…. */
0xC0,0xF2,0xE6,0x2F,0x9D,0x7C,0xC9,0xB4,0xBE,0xCF,0xE1, /* …/.|….. */
0x7D,0xFE,0x1F,0x03,0x00,0x12,0x84,0x72,0x8C,0xE7,0xD8, /* }……r… */
0x5E,0xC9,0xA9,0x01,0xBA,0x9B,0xC4,0x10,0x5C,0x70,0x2E, /* ^…….\p. */
0x6C,0x48,0xE7,0x8C,0x15,0x0B,0x06,0x01,0xE5,0xFF,0xFF, /* lH……… */
0xD4,0x0D,0x00,0x0F,0xCE,0x58,0x95,0x61,0xA8,0x9E,0x7B, /* …..X.a..{ */
0x19,0x98,0xB0,0xF0,0xC6,0x72,0x82,0xD5,0x27,0x06,0x47, /* …..r..’.G */
0x41,0x22,0x0F,0x65,0x93,0xC9,0x8A,0x09,0x19,0x48,0x1B, /* A”.e…..H. */
0xBD,0xD6,0x64,0x1A,0xAC,0xFF,0xF2,0x42,0xC0,0xF1,0x11, /* ..d….B… */
0x25,0x14,0x22,0x06,0xBC,0x0E,0xD4,0x4E,0x99,0x90,0xA8, /* %.”….N… */
0xD8,0xB7,0xAD,0x5D,0x3E,0xAF,0x6E,0xBE,0x66,0x83,0xA4, /* …]>.n.f.. */
0xE3,0xC2,0xE0,0x29,0x43,0x87,0x5F,0x4F,0x27,0x9C,0x2C, /* …)C._O’., */
0xD0,0x91,0xF3,0x87,0x9B,0x54,0xED,0xD1,0xB4,0xF3,0x39, /* …..T….9 */
0x87,0x22,0x06,0x86,0x0D,0x71,0xE4,0x6F,0x2A,0x08,0x04, /* .”…q.o*.. */
0xC0,0x03,0x2A,0xB1,0xE2,0x05,0x4D,0x64,0xA1,0x9C,0xA6, /* ..*…Md… */
0x0D,0x41,0xA6,0xF2,0x7A,0xC1,0x30,0xC3,0x38,0x26,0x09, /* .A..z.0.8&. */
0x50,0x08,0xC4,0xF6,0x30,0x0C,0xA6,0xA9,0x17,0x00,0x13, /* P…0…… */
0x0C,0xDC,0xC4,0x2F,0x28,0xEB,0x3F,0xCD,0x7A,0x3D,0x2F, /* …/(.?.z=/ */
0xFF,0xF2,0x40,0xC0,0x18,0x6F,0x2E,0x13,0xA1,0xF2,0xBC, /* ..@..o….. */
0x36,0xCB,0x4E,0x99,0x6E,0xFC,0xEE,0xC5,0xF0,0xA0,0xB7, /* 6.N.n…… */
0x92,0xD4,0xEE,0x79,0x7C,0x50,0x5D,0xE5,0x04,0x94,0xA9, /* …y|P]…. */
0x76,0xCF,0x6C,0x70,0xDD,0x0D,0xD4,0xEE,0xED,0x98,0xE8, /* v.lp……. */
0xC8,0x35,0x36,0x7A,0x0C,0x05,0x80,0x03,0xBC,0xBE,0x91, /* .56z……. */
0x00,0x7C,0xAE,0x65,0xB8,0x91,0xA3,0x33,0xBA,0x68,0x60, /* .|.e…3.h` */
0xD4,0x1A,0x66,0xF8,0x43,0xA0,0x20,0x89,0xE7,0x80,0xD8, /* ..f.C. …. */
0x1E,0x4F,0xA0,0x04,0x60,0x06,0x0A,0xA4,0x91,0x24,0xFA, /* .O..`….$. */
0x9F,0x57,0x53,0xF4,0x7A,0xDB,0x5F,0x56,0xE3,0x6E,0x0B, /* .WS.z._V.n. */
0x8B,0x3A,0x1C,0xF9,0x5E,0xFF,0xF2,0x42,0xC0,0xB1,0x00, /* .:..^..B… */
0x38,0x14,0x09,0xEE,0xB4,0x36,0xD3,0x4E,0x99,0xA4,0x78, /* 8….6.N..x */
0x94,0x73,0xC4,0x66,0x30,0xF5,0xEA,0xDB,0xBA,0x67,0x67, /* .s.f0….gg */
0x95,0x6B,0xAB,0x68,0x5D,0x08,0xA1,0x39,0x56,0xAB,0x1E, /* .k.h]..9V.. */
0xD5,0x03,0xE8,0x01,0x70,0x00,0xB3,0x93,0x33,0x19,0x8C, /* ….p…3.. */
0x61,0x8F,0xBB,0x5D,0x24,0x12,0x63,0xD3,0x4B,0x5D,0x91, /* a..]$.c.K]. */
0x08,0x43,0x22,0x56,0x1A,0xC5,0x10,0x21,0x84,0xA8,0xEA, /* .C”V…!… */
0x80,0xBF,0x16,0x8E,0x3D,0x46,0x18,0x9C,0x6E,0x9A,0x91, /* ….=F..n.. */
0xE6,0xC9,0x6F,0xD2,0x7D,0x27,0xD7,0xE9,0x6B,0xFF,0x0A, /* ..o.}’..k.. */
0x03,0x43,0x89,0xD5,0xBF,0x52,0x97,0x0A,0x25,0x95,0x0D, /* .C…R..%.. */
0xFF,0xF2,0x40,0xC0,0xF5,0xC3,0x41,0x13,0x81,0xEE,0xA8, /* ..@…A…. */
0x5E,0xD3,0x44,0x98,0xFC,0xCF,0x97,0xF9,0x58,0xB5,0x33, /* ^.D…..X.3 */
0xB1,0x85,0x47,0x86,0xD7,0x98,0x01,0x3B,0xA3,0x4F,0x7E, /* ..G….;.O~ */
0x04,0xA6,0xC3,0x39,0x21,0x70,0x27,0x62,0xB5,0x18,0x10, /* …9!p’b… */
0x09,0x99,0x00,0x8B,0x7E,0xF2,0xBF,0x52,0x18,0x26,0x30, /* ….~..R.&0 */
0x1C,0xB0,0x01,0x49,0x30,0xE0,0xC3,0x11,0x46,0x05,0xCC, /* …I0…F.. */
0x49,0x14,0x28,0xB2,0xED,0x4B,0x57,0x5A,0x2F,0xB7,0x46, /* I.(..KWZ/.F */
0x63,0x34,0xD2,0xDA,0x9F,0x56,0x32,0xB7,0xA2,0x25,0xFF, /* c4…V2..%. */
0x94,0x28,0x33,0x7F,0x3B,0xC4,0x50,0xEC,0xB1,0xE2,0x26, /* .(3.;.P…& */
0xA1,0xB7,0x07,0x7F,0xFB,0xFF,0xF2,0x42,0xC0,0x67,0x6A, /* …….B.gj */
0x4C,0x13,0xF9,0x6A,0x90,0x7E,0xDB,0x44,0x94,0x3F,0xFF, /* L..j.~.D.?. */
0x14,0xD6,0x2A,0xFF,0xFF,0xC1,0x34,0x8C,0x48,0x22,0x00, /* ..*…4.H”. */
0x06,0x8F,0x21,0xFD,0x64,0x60,0x04,0x92,0x42,0xEA,0x74, /* ..!.d`..B.t */
0x32,0x37,0xAA,0x5A,0x9F,0x67,0x01,0x8B,0x3F,0x37,0x31, /* 27.Z.g..?71 */
0xDD,0x06,0x3C,0x01,0x34,0x30,0xE0,0x5C,0x78,0x78,0xCB, /* ..<.40.\xx. */
0xD6,0xF1,0x31,0x8A,0x69,0x61,0x93,0x92,0x42,0xCE,0x4B, /* ..1.ia..B.K */
0xC5,0x02,0x4E,0x73,0xC6,0x24,0x30,0xCD,0x08,0x66,0xC6, /* ..Ns.$0..f. */
0x35,0xAB,0xA2,0x3D,0x2F,0xB3,0xBD,0x34,0x87,0x13,0xEE, /* 5..=/..4… */
0x71,0x45,0x68,0xFA,0xEA,0x05,0x84,0x41,0x36,0x4C,0x9A, /* qEh….A6L. */
0xFF,0xF2,0x40,0xC0,0xC9,0x92,0x56,0x13,0xD0,0x6E,0x70, /* ..@…V..np */
0x54,0xD3,0xCC,0x28,0x06,0xD7,0x0E,0xA4,0x1D,0x9C,0x9D, /* T..(……. */
0xD9,0xA9,0x88,0x7B,0xB5,0xA3,0x56,0xB7,0x4B,0x4B,0x5A, /* …{..V.KKZ */
0x9B,0x2C,0xA9,0xAD,0x6F,0x99,0x6C,0xC0,0x4C,0x14,0x14, /* .,..o.l.L.. */
0xEF,0xB4,0x20,0x91,0x5F,0xBC,0x81,0x41,0x41,0x5D,0xD4, /* .. ._..AA]. */
0x20,0xBD,0x05,0x1A,0x6F,0xE2,0x68,0x56,0x41,0x41,0x57, /* …o.hVAAW */
0xF9,0xBF,0x89,0x82,0x8E,0xC7,0x8F,0x0A,0x0A,0x09,0x37, /* ……….7 */
0xF1,0x05,0x0A,0x0A,0x0A,0x0A,0x09,0x05,0x37,0xFF,0x10, /* ……..7.. */
0x50,0x50,0x53,0x65,0xFF,0xFF,0xFD,0x75,0xDF,0xFF,0xFF, /* PPSe…u… */
0x68,0x4F,0xFF,0x84,0x70,0xFF,0xF2,0x42,0xC0,0x27,0x50, /* hO..p..B.’P */
0x5F,0x17,0xE8,0x82,0x3C,0x11,0x58,0x18,0x01,0x55,0x48, /* _…<.X..UH */
0xBC,0x52,0xFC,0x4A,0x4C,0x3C,0xD5,0xF6,0x11,0x2D,0xBF, /* .R.JL<…-. */
0xEA,0x03,0x5C,0x57,0x29,0xBF,0xC3,0x75,0x1C,0xE6,0xDD, /* ..\W)..u… */
0xBF,0xED,0xEF,0xD0,0x98,0x77,0x71,0x95,0x73,0xFF,0xED, /* …..wq.s.. */
0x54,0xBE,0xD5,0xEE,0xAE,0xC2,0xD5,0x0B,0xFF,0xF1,0x97, /* T………. */
0x8A,0xE4,0x42,0x09,0x99,0xB1,0xEA,0x94,0xDC,0x78,0xB5, /* ..B……x. */
0x34,0x0F,0xF1,0x8F,0xFC,0x15,0xF6,0xFA,0xB1,0x47,0xA9, /* 4……..G. */
0x6C,0x67,0x43,0x8B,0xF2,0x76,0x22,0xED,0xDA,0x85,0xBA, /* lgC..v”…. */
0x2F,0xC7,0xF9,0xCF,0xFC,0xDB,0x46,0x2E,0x50,0x0A,0x84, /* /…..F.P.. */
0xFF,0xF2,0x40,0xC0,0xC6,0x4A,0x59,0x28,0x2B,0x19,0xE0, /* ..@..JY(+.. */
0x01,0x89,0x78,0x00,0x52,0x85,0x3C,0x8E,0x54,0x9A,0x48, /* ..x.R.<.T.H */
0x5A,0x72,0x32,0x94,0xBF,0x43,0x4F,0x24,0x53,0x4B,0xEC, /* Zr2..CO$SK. */
0x4B,0x99,0x0E,0x66,0x1F,0xFF,0xCE,0x7F,0xFF,0x3F,0x10, /* K..f…..?. */
0xAE,0x82,0x62,0x71,0x34,0x18,0x59,0x9B,0x51,0xC7,0x59, /* ..bq4.Y.Q.Y */
0xCE,0xEE,0xA5,0xFE,0x02,0xBB,0x30,0x91,0x49,0xD5,0x4B, /* ……0.I.K */
0xF3,0xDC,0x9A,0xA9,0x57,0x8E,0x72,0x10,0xC0,0x5D,0x60, /* ….W.r..]` */
0x67,0xFC,0x7D,0xD6,0xBA,0xDD,0xB3,0x8B,0x5A,0x0A,0x4C, /* g.}…..Z.L */
0x41,0x4D,0x45,0x33,0x2E,0x39,0x33,0xAA,0xAA,0xAA,0xAA, /* AME3.93…. */
0xAA,0xAA,0xAA,0xAA,0xAA,0x54,0x41,0x47,0x48,0x65,0x6C, /* …..TAGHel */
0x6C,0x6F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* lo */
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* */
0x20,0x20,0x20,0x20,0x20,0x50,0x61,0x6E,0x75,0x2D,0x4B, /* Panu-K */
0x72,0x69,0x73,0x74,0x69,0x61,0x6E,0x20,0x50,0x6F,0x69, /* ristian Poi */
0x6B,0x73,0x61,0x6C,0x6F,0x20,0x20,0x20,0x20,0x20,0x20, /* ksalo */
0x20,0x20,0x56,0x53,0x44,0x53,0x50,0x20,0x54,0x65,0x73, /* VSDSP Tes */
0x74,0x69,0x6E,0x67,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* ting */
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* */
0x20,0x20,0x20,0x4D,0x50,0x33,0x20,0x48,0x65,0x6C,0x6C, /* MP3 Hell */
0x6F,0x2C,0x20,0x57,0x6F,0x72,0x6C,0x64,0x21,0x20,0x20, /* o, World! */
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, /* */
0x00, /* . */
};void setup()
{
//
pinMode( MP3_DREQ, INPUT ); // pin 2
pinMode( MP3_XCS, OUTPUT ); // pin 6 : Control Select of VS1053 IC
pinMode( MP3_XDCS, OUTPUT ); // pin 7 : Data Chip Select of VS1053 IC
digitalWrite( MP3_XDCS, HIGH ); // Deselect Data// Control Select of SD card high
pinMode( 9, OUTPUT );
digitalWrite( 9, HIGH );// Control Select of Ethernet high
pinMode( 10, OUTPUT );
digitalWrite( 10, HIGH );// Control Select of SD card of Ethernet shield high
pinMode( 4, OUTPUT );
digitalWrite( 4, HIGH );// Use serial for debugging
Serial.begin( 115200 );
Serial.println( “MP3 Shield Example” );//Setup SPI for VS1053
SPI.begin( MP3_XCS );
SPI.setBitOrder( MP3_XCS, MSBFIRST );
SPI.setDataMode( MP3_XCS, SPI_MODE0 );// From page 12 of datasheet, max SCI reads are CLKI/7. Input clock is 12.288MHz.
// Internal clock multiplier is 1.0x after power up.
// Therefore, max SPI speed is 1.75MHz. We will use 1MHz to be safe.
SPI.setClockDivider( MP3_XCS, 84 ); // Set SPI bus speed to 1MHz (84MHz / 84 = 1MHz for Due)
//SPI.setClockDivider( SPI_CLOCK_DIV16 ); // Set SPI bus speed to 1MHz (16MHz / 16 = 1MHz)
SPI.transfer( MP3_XCS, 0xFF ); //Throw a dummy byte at the bus//Initialize VS1053 chip
digitalWrite( MP3_XCS, HIGH ); //Deselect Control
digitalWrite( MP3_XDCS, HIGH ); //Deselect DataMp3SetVolume( 20, 20 ); //Set initial volume (20 = -10dB)
// Let’s check the status of the VS1053
int MP3Mode = Mp3ReadRegister( SCI_MODE );
int MP3Status = Mp3ReadRegister( SCI_STATUS );
int MP3Clock = Mp3ReadRegister( SCI_CLOCKF );Serial.print( “SCI_Mode (0x4800) = 0x” );
Serial.println( MP3Mode, HEX );//Serial.print( “SCI_Status (0x48) = 0x” );
//Serial.println( MP3Status, HEX );int vsVersion = ( MP3Status >> 4 ) & 0x000F; //Mask out only the four version bits
Serial.print( “VS Version (VS1053 is 4) = ” );
Serial.println( vsVersion, DEC ); //The 1053B should respond with 4. VS1001 = 0, VS1011 = 1, VS1002 = 2, VS1003 = 3//Serial.print(“SCI_ClockF = 0x”);
//Serial.println(MP3Clock, HEX);// Now that we have the VS1053 up and running, increase the VS1053 internal clock multiplier and up our SPI rate
Mp3WriteRegister( SCI_CLOCKF, 0x60, 0x00 ); //Set multiplier to 3.0x//From page 12 of datasheet, max SCI reads are CLKI/7. Input clock is 12.288MHz.
//Internal clock multiplier is now 3x.
//Therefore, max SPI speed is 5MHz. 4MHz will be safe.
SPI.setClockDivider( MP3_XCS, 21 ); //Set SPI bus speed to 4MHz (8416MHz / 21 = 4MHz for Due)
//SPI.setClockDivider( SPI_CLOCK_DIV4 ); //Set SPI bus speed to 4MHz (16MHz / 4 = 4MHz)MP3Clock = Mp3ReadRegister( SCI_CLOCKF );
Serial.print( “SCI_ClockF = 0x” );
Serial.println( MP3Clock, HEX );
}#define MP3_BUF_LEN 1024
//unsigned char mp3Buf[ 2 * MP3_BUF_LEN ];
unsigned char mp3Buf[ 2048 ];volatile int f = 0;
volatile unsigned char *p;
unsigned char *p0, *p1, *p2, *p3, *s, *s1;
int b = 0;
int n = 0;void iniHello()
{
s = HelloMP3;
s1 = s + sizeof( HelloMP3 );
p0 = mp3Buf;
p1 = p0 + MP3_BUF_LEN;
p2 = p1 + MP3_BUF_LEN;
p3 = p2 + 1;
p = p0;
b = 0;
transfertBuf();
transfertBuf();
attachInterrupt( MP3_DREQ, transfertMp3, HIGH );
}void finHello()
{
detachInterrupt( MP3_DREQ );
digitalWrite( MP3_XDCS, HIGH ); // Deselect Data// Wait for DREQ to go high indicating transfer is complete
while( ! digitalRead( MP3_DREQ ))
;
}void transfertMp3()
{
digitalWrite( MP3_XDCS, LOW ); // Select Data
SPI.transfer( MP3_XCS, *p ); // Send SPI byte
p ++;
if( p >= p3 )
f = 2;
else if( p == p1 )
f = 1;
else if( p == p2 )
{
f = 1;
p = p0;
}
}void transfertBuf()
{
Serial.print( b );
unsigned char *p4 = b == 0 ? p0 : p1 ;
unsigned long ln = s1 – s;
if( ln < MP3_BUF_LEN )
p3 = p4 + ln;
else
ln = MP3_BUF_LEN;
memcpy( p4, s, ln );
// memcpy( ( b == 0 ? p0 : p1 ), s, ( ln < MP3_BUF_LEN ? ln : MP3_BUF_LEN ) );
s += ln;
b = 1 – b;
f = 0;
}void loop()
{
if( n == 0 )
{
// read any existing Serial data
while( Serial.read() >= 0 ) ;
Serial.print( “\nType any character to listen Hello\n” );
while( Serial.available() == 0 ) ;
n = 4;
iniHello();
}if( f == 2 )
{
finHello();
n = 0;
Serial.print( “Ok\n” );
}
else if( f == 1 )
transfertBuf();/*
if( p >= p1 )
{
finHello();
delay( 500 );
Serial.print( n );
n — ;
if( n > 0 )
iniHello();
}
*/
}August 13, 2013 at 12:35 pm #2838AnonymousInactiveThanks very much. You’ve been very kind. Based on what you have said it would seem that I have a hardware problem, perhaps a poor solder connection. I’ll have a look at it again later this week and will keep you updated.
-
AuthorPosts
- You must be logged in to reply to this topic.