Arduino MP3 Shield MP3Player This program comes from http://mbed.org/cookbook/VS1002-MP3-Decoder (Very small modification done to fit latest libs) **Additional small mods to xshige\'s code by mpetersen3 and kbuck3 to add a user interface
Revision 0:9cb0b3d1b9e6, committed 2010-10-12
- Comitter:
- mpetersen3
- Date:
- Tue Oct 12 21:25:35 2010 +0000
- Commit message:
- This revision adds a user interface for the mp3 player
Changed in this revision
diff -r 000000000000 -r 9cb0b3d1b9e6 FATFileSystem.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FATFileSystem.lib Tue Oct 12 21:25:35 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_unsupported/code/fatfilesystem/ \ No newline at end of file
diff -r 000000000000 -r 9cb0b3d1b9e6 TextLCD.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Tue Oct 12 21:25:35 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/simon/code/TextLCD/#a53b3e2d6f1e
diff -r 000000000000 -r 9cb0b3d1b9e6 VS1002.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VS1002.cpp Tue Oct 12 21:25:35 2010 +0000 @@ -0,0 +1,283 @@ +#include "VS1002.h" +#include "mbed.h" +#include "TextLCD.h" +AnalogIn rotary1(p19); +DigitalIn pause1(p28); +TextLCD lcd(p10, p18, p24, p23, p22, p21, TextLCD::LCD16x2 ); // rs, e, d0-d3 + + +/* ================================================================== + * Constructor + * =================================================================*/ +VS1002::VS1002( +PinName mmosi, PinName mmiso, PinName ssck, PinName ccs, const char *name, + PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, + PinName dreq, PinName dcs, PinName vol) + : + _sd(mmosi, mmiso, ssck, ccs, name), + _spi(mosi, miso, sck), + _CS(cs), + _RST(rst), + _DREQ(dreq), + _DCS(dcs), + _VOL(vol) { + + } + +/*=================================================================== + * Functions + *==================================================================*/ + +void VS1002::cs_low(void) +{ + _CS = 0; +} +void VS1002::cs_high(void) +{ + _CS = 1; +} +void VS1002::dcs_low(void) +{ + _DCS = 0; +} +void VS1002::dcs_high(void) +{ + _DCS = 1; +} +void VS1002::sci_en(void) //SCI enable +{ + cs_high(); + dcs_high(); + cs_low(); +} +void VS1002::sci_dis(void) //SCI disable +{ + cs_high(); +} +void VS1002::sdi_en(void) //SDI enable +{ + dcs_high(); + cs_high(); + dcs_low(); +} +void VS1002::sdi_dis(void) //SDI disable +{ + dcs_high(); +} +void VS1002::reset(void) //hardware reset +{ + wait(0.01); + _RST = 0; + wait(0.01); + _RST = 1; + wait(0.10); +} +void VS1002::power_down(void) //hardware and software reset +{ + cs_low(); + reset(); + sci_write(0x00, SM_PDOWN); + wait(0.01); + reset(); +} +void VS1002::sci_initialise(void) +{ + _RST = 1; //no reset + _spi.format(8,0); //spi 8bit interface, steady state low + _spi.frequency(1000000); //rising edge data record, freq. 1Mhz + + cs_low(); + for(int i=0; i<4; i++) + { + _spi.write(0xFF); //clock the chip a bit + } + cs_high(); + dcs_high(); + wait_us(5); +} +void VS1002::sdi_initialise(void) +{ + _spi.format(8,0); + _spi.frequency(7000000); //set to 7MHz + + cs_high(); + dcs_high(); +} +void VS1002::sci_write(unsigned char address, unsigned short int data) +{ + sci_en(); //enables SCI/disables SDI + + while(!_DREQ); //wait unitl data request is high + _spi.write(0x02); //SCI write + _spi.write(address); //register address + _spi.write((data >> 8) & 0xFF); //write out first half of data word + _spi.write(data & 0xFF); //write out second half of data word + + sci_dis(); //enables SDI/disables SCI + wait_us(5); +} +void VS1002::sdi_write(unsigned char datum) +{ + sdi_en(); + + while(!_DREQ); + _spi.write(datum); + + sci_dis(); +} +unsigned short int VS1002::read(unsigned short int address) +{ + cs_low(); //enables SCI/disables SDI + + while(!_DREQ); //wait unitl data request is high + _spi.write(0x03); //SCI write + _spi.write(address); //register address + unsigned short int received = _spi.write(0x00); //write out dummy byte + received <<= 8; + received += _spi.write(0x00); //write out dummy byte + + cs_high(); //enables SDI/disables SCI + + return received; //return received word +} +void VS1002::sine_test_activate(unsigned char wave) +{ + cs_high(); //enables SDI/disables SCI + + while(!_DREQ); //wait unitl data request is high + _spi.write(0x53); //SDI write + _spi.write(0xEF); //SDI write + _spi.write(0x6E); //SDI write + _spi.write(wave); //SDI write + _spi.write(0x00); //filler byte + _spi.write(0x00); //filler byte + _spi.write(0x00); //filler byte + _spi.write(0x00); //filler byte + + cs_low(); //enables SCI/disables SDI +} +void VS1002::sine_test_deactivate(void) +{ + cs_high(); + + while(!_DREQ); + _spi.write(0x45); //SDI write + _spi.write(0x78); //SDI write + _spi.write(0x69); //SDI write + _spi.write(0x74); //SDI write + _spi.write(0x00); //filler byte + _spi.write(0x00); //filler byte + _spi.write(0x00); //filler byte + _spi.write(0x00); //filler byte +} +void VS1002::volume(void) +{ + #ifdef FIXED_VOL + unsigned char volumize = (0 * 255); // FIXED VOL (not support volume input) + #else + unsigned char volumize = (_VOL * 255); + #endif + while(!_DREQ); + + unsigned short int attenuation = ((256 * volumize) + volumize); + sci_write(0x0B, attenuation); + +} + +void VS1002::play_song(int song_number) +{ + /*====== Song Select ======*/ + +// char list[10000] = {0}; + char list[1000] = {0}; + char str[16] = {"/sd/"}; + unsigned int startplace = 0; + unsigned int endplace = 0; + unsigned int play = 0; + num_of_files = 0; + + DIR *d; + struct dirent *p; + d = opendir("/sd"); + if(d != NULL) + { + while((p = readdir(d)) != NULL) + { + strcat(list, "*"); + strcat(list, p->d_name); + num_of_files++; + } + } + else + { + perror("Could not open directory!"); + } + strcat(list, "*"); //terminating * + if(num_of_files < song_number) + { + return; + } + while(play != song_number) + { + char symbol = list[startplace]; + startplace++; + if(symbol == 0x2A) //0x2A = "*" + { + play++; + } + } + play = 0; + while(play != (song_number+1)) + { + char symbol = list[endplace]; + endplace++; + if(symbol == 0x2A) //0x2A = "*" + { + play++; + } + } + + strncat(str, &list[startplace], endplace-startplace); + str[(endplace-startplace)+3] = '\0'; + +//printf("list: %s\r\n",list); //debug + + /*====== File Transfer ======*/ + + // return if not MP3 file + if (!((strstr(str,"MP3")!=NULL)||(strstr(str,"mp3")!=NULL))) return; + // display filename.mp3 to the lcd screen + lcd.printf("Now Playing: %s\r\n",str); + + FILE *song; + unsigned char array[512]; + + song = fopen(str, "rb"); + + if(!song) + { + exit(1); + } + + while((!feof(song))&&!pause1) + { + fread(&array, 1, 512, song); + for(int i=0; i<512; i++) + { +#ifndef FS_ONLY + sdi_write(array[i]); + // printf("."); +#endif + } +#ifndef FS_ONLY + volume(); +#endif + } + for(int n=0; n<2048; n++) + { +#ifndef FS_ONLY + sdi_write(0x00); +#endif + } + fclose(song); //close the file +}
diff -r 000000000000 -r 9cb0b3d1b9e6 VS1002.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VS1002.h Tue Oct 12 21:25:35 2010 +0000 @@ -0,0 +1,74 @@ +#ifndef VS1002_H +#define VS1002_H + +//#define FS_ONLY +#define FIXED_VOL + +#include "mbed.h" +#include "SDFileSystem.h" +#include "string" +#include "string.h" + +//SCI_MODE register bits as of p.26 of the datasheet +#define SM_DIFF 0x0001 +#define SM_SETTOZERO 0x0002 +#define SM_RESET 0x0004 +#define SM_OUTOFWAV 0x0008 +#define SM_PDOWN 0x0010 +#define SM_TESTS 0x0020 +#define SM_STREAM 0x0040 +#define SM_PLUSV 0x0080 +#define SM_DACT 0x0100 +#define SM_SDIORD 0x0200 +#define SM_SDISHARE 0x0400 +#define SM_SDINEW 0x0800 +#define SM_ADPCM 0x1000 +#define SM_ADPCM_HP 0x2000 + + +class VS1002 { + +public: +// VS1002(int _mmosi, int _mmiso, int _ssck, int _ccs, const char* _name, +// int _mosi, int _miso, int _sck, int _cs, int _rst, int _dreq, int _dcs, int _vol); + VS1002(PinName _mmosi, PinName _mmiso, PinName _ssck, PinName _ccs, const char* _name, + PinName _mosi, PinName _miso, PinName _sck, PinName _cs, PinName _rst, PinName _dreq, + PinName _dcs, PinName _vol); + + void cs_low(void); + void cs_high(void); + void dcs_low(void); + void dcs_high(void); + void sci_en(void); + void sci_dis(void); + void sdi_en(void); + void sdi_dis(void); + + void sci_initialise(void); + void sdi_initialise(void); + void reset(void); + void power_down(void); + + void sci_write(unsigned char, unsigned short int); + void sdi_write(unsigned char); + unsigned short int read(unsigned short int); + void sine_test_activate(unsigned char); + void volume(void); + void sine_test_deactivate(void); + void play_song(int); + + int num_of_files; + + DigitalIn _DREQ; + DigitalOut _RST; + AnalogIn _VOL; + +protected: + + SPI _spi; + DigitalOut _CS; + DigitalOut _DCS; + SDFileSystem _sd; + +}; +#endif
diff -r 000000000000 -r 9cb0b3d1b9e6 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Oct 12 21:25:35 2010 +0000 @@ -0,0 +1,114 @@ + +#include "mbed.h" +#include "VS1002.h" +#include "TextLCD.h" + +TextLCD lcd2(p10, p18, p24, p23, p22, p21, TextLCD::LCD16x2 ); // rs, e, d0-d3 + + +/* + + Arduino MP3 Shield MP3Player_UI + 2010/10/10 + This program comes from http://mbed.org/cookbook/VS1002-MP3-Decoder and is the work of xshige. + (Very small modification done to fit latest libs) +**more small modifications done to add a small user interface via LCD screen, rotary encoder and dipswitch, +see http://mbed.org/cookbook/MP3-Player for more information on pinout for these devices, these UI mods by (mpetersen3 and kbuck3) + + Pin Assigenment for Arduino MP3 Shield + (VS1053 employed, issued by sparkfun.com) + + MP3 Sheild Side | mbed Side + --------------------------------------- + D2(BSYNC)------------17 + D3(DREQ)-------------16 + + D9(CS)---------------14 + + D11(MOSI)------------5 + D12(MISO)------------6 + D13(SCK)-------------7 + + GND------------------GND(1) + 5V-------------------VU(39) + RESET----------------15 + + Volume will not used. (pin20 will not used) + +*/ + + +//PinName mmosi, PinName mmiso, PinName ssck, PinName ccs, const char *name, +// PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, +// PinName dreq, PinName dcs, PinName vol) +VS1002 mp3(p11, p12, p13, p8, "sd", + p5, p6, p7, p14, p15, + p16, p17, p20); //p14 in BoB non-functional so replace with p18 +AnalogIn rotary(p19); +DigitalIn pause(p28); + +int main () { + // make debug port Fast + Serial pc(USBTX, USBRX); + pc.baud(9600); + + + // pc.baud(115200); +// pc.baud(230400); + + /*============================================================ + * MP3 Initialising + *==========================================================*/ +#ifndef FS_ONLY + mp3._RST = 1; + mp3.cs_high(); //chip disabled + mp3.sci_initialise(); //initialise MBED + mp3.sci_write(0x00,(SM_SDINEW+SM_STREAM+SM_DIFF)); + mp3.sci_write(0x03, 0x9800); + mp3.sdi_initialise(); +#endif + /*============================================================ + * This is the good part + *==========================================================*/ + int a=0; + printf("%i\n",a); + while (true) { + + + + + mp3.play_song(a); + a++; + wait(1); + + if (pause) { + while (pause) { + // shows you which song number you have chosen using the rotary dial + lcd2.printf("You have chosen the %i song\n",a); + if ((rotary>0)&&(rotary<=0.1)) { + a=1; + + } else if ((rotary>0.1)&&(rotary<=0.2)) { + a=2; + } else if ((rotary>0.2)&&(rotary<=0.3)) { + a=3; + } else if ((rotary>0.3)&&(rotary<=0.4)) { + a=4; + } else if ((rotary>0.4)&&(rotary<=0.5)) { + a=5; + } else if ((rotary>0.5)&&(rotary<=0.6)) { + a=6; + } else if ((rotary>0.6)&&(rotary<=0.7)) { + a=7; + } else if ((rotary>0.7)&&(rotary<=0.8)) { + a=8; + } else if ((rotary>0.8)&&(rotary<=0.9)) { + a=9; + } else if ((rotary>0.9)&&(rotary<=1.0)) { + a=10; + } + } + } + } + printf("Done.\r\n"); + }
diff -r 000000000000 -r 9cb0b3d1b9e6 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Oct 12 21:25:35 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e