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

Dependencies:   mbed

Files at this revision

API Documentation at this revision

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

FATFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
TextLCD.lib Show annotated file Show diff for this revision Revisions of this file
VS1002.cpp Show annotated file Show diff for this revision Revisions of this file
VS1002.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /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
--- /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
--- /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
+}
--- /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
--- /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");
+    }
--- /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