News_Reader

Dependencies:   FatFileSystem HTTPClient NetServices RPG SDFileSystem TextLCD mbed spxml

Fork of Arduino_MP3_Shield_MP3Player_UI by Matthew Petersen

VS1002.cpp

Committer:
cwang365
Date:
2013-03-06
Revision:
2:447591cbba27
Parent:
1:0014879fa94f

File content as of revision 2:447591cbba27:

#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
    lcd.printf("Done Playing: %s\r\n\n",str);
    lcd.printf("                                                    \n");
}