Add the RTOS processing. for the Network radio streaming receiver.
Fork of VS1053b by
Diff: VS1053.cpp
- Revision:
- 1:ced2c297cc1b
- Parent:
- 0:7728d9c6c487
- Child:
- 2:5bab956cb59e
--- a/VS1053.cpp Tue Dec 14 18:22:54 2010 +0000 +++ b/VS1053.cpp Thu Dec 16 21:54:03 2010 +0000 @@ -1,3 +1,31 @@ +/* mbed VLSI VS1053b library + * Copyright (c) 2010 Christian Schmiljun + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* This code based on: + * mbeduino_MP3_Shield_MP3Player + * http://mbed.org/users/xshige/programs/mbeduino_MP3_Shield_MP3Player/lgcx63 + * 2010-10-16 + */ + #include "VS1053.h" #include "mbed.h" @@ -5,8 +33,8 @@ #include "Patches/VS1053b_patch_1_5.c" #include "Patches/VS1053b_patch_1_5_flac.c" #include "Patches/VS1053b_patch_1_4_flac.c" -// spectrum analyzer binary -#include "Patches/VS1053b_specana.c" +#include "Patches/VS1053b_specana_0_9.c" +#include "Patches/VS1053b_pcm_recorder_0_9.c" /* ================================================================== @@ -20,8 +48,9 @@ _CS(cs), _RST(rst), _DREQ(dreq), - _DCS(dcs) { - firstTime=-1; + _DCS(dcs) { + _volume = DEFAULT_VOLUME; + _balance = DEFAULT_BALANCE_DIFERENCE_LEFT_RIGHT; } /*=================================================================== @@ -75,7 +104,7 @@ wait(0.01); reset(); } -void VS1053::sci_initialise(void) { +void VS1053::spi_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 @@ -91,12 +120,7 @@ wait_us(5); } void VS1053::sdi_initialise(void) { - _spi.format(8,0); -// _spi.frequency(7000000); //set to 7MHz -// _spi.frequency(12000000); //set to 12MHz to make fast transfer - _spi.frequency(18000000); //set to 18MHz to make fast transfer -//NG does not work// _spi.frequency(24000000); //set to 24MHz to make fast transfer - + _spi.frequency(8000000); //set to 8 MHz to make fast transfer cs_high(); dcs_high(); } @@ -121,7 +145,7 @@ //? sci_dis(); sdi_dis(); } -unsigned short int VS1053::sci_read(unsigned short int address) { +unsigned short VS1053::sci_read(unsigned short int address) { cs_low(); //enables SCI/disables SDI while (!_DREQ); //wait unitl data request is high @@ -164,7 +188,7 @@ _spi.write(0x00); //filler byte } -void VS1053::writeStream(unsigned char *array, int size) { +void VS1053::writeStream(unsigned char *array, unsigned int size) { for (int i=0; i<size; i++) { sdi_write(array[i]); } @@ -200,18 +224,58 @@ return; } +void VS1053::setPlaySpeed(unsigned short speed) +{ + wram_write(para_playSpeed, speed); +#ifdef DEBUG + printf("VS1053b: Change speed. New speed: %d\r\n", speed); +#endif +} void VS1053::terminateStream(void) { -#if 1 - unsigned int endFillByte=wram_read(para_endFillByte); -// printf("endFillByte:%04X\r\n",endFillByte); // debug - for (int n=0; n<2052; n++) sdi_write(0xFF&endFillByte); - sci_write(SCI_MODE,(SM_SDINEW+SM_CANCEL)); - for (int n=0; n<2048; n++) sdi_write(0xFF&endFillByte); - // don't reset if you don't want to lose the patch - // sci_write(SCI_MODE,(SM_SDINEW+SM_RESET)); // set mode reg. - // wait_ms(10); -#endif + // send at least 2052 bytes of endFillByte[7:0]. + // read endFillByte (0 .. 15) from wram + unsigned short endFillByte=wram_read(para_endFillByte); + // clear endFillByte (8 .. 15) + endFillByte = endFillByte ^0x00FF; + for (int n = 0; n < 2052; n++) + sdi_write(endFillByte); + + // set SCI MODE bit SM CANCEL + unsigned short sciModeByte = sci_read(SCI_MODE); + sciModeByte |= SM_CANCEL; + sci_write(SCI_MODE, sciModeByte); + + // send up 2048 bytes of endFillByte[7:0]. + for (int i = 0; i < 64; i++) + { + // send at least 32 bytes of endFillByte[7:0] + for (int n = 0; n < 32; n++) + sdi_write(endFillByte); + // read SCI MODE; if SM CANCEL is still set, repeat + sciModeByte = sci_read(SCI_MODE); + if ((sciModeByte & SM_CANCEL) == 0x0000) + { + break; + } + } + + if ((sciModeByte & SM_CANCEL) == 0x0000) + { +#ifdef DEBUG + printf("VS1053b: Song sucessfully sent. Terminating OK\r\n"); + printf("VS1053b: SCI MODE = %#x, SM_CANCEL = %#x\r\n", sciModeByte, sciModeByte & SM_CANCEL); +#endif + } + else + { +#ifdef DEBUG + printf("VS1053b: SM CANCEL hasn't cleared after sending 2048 bytes, do software reset\r\n"); + printf("VS1053b: SCI MODE = %#x, SM_CANCEL = %#x\r\n", sciModeByte, sciModeByte & SM_CANCEL); +#endif + //TODO: testing + initialize(); + } } void VS1053::write_plugin(const unsigned short *plugin, unsigned int len) { @@ -239,45 +303,91 @@ } -void VS1053::initialize(void) { +bool VS1053::initialize(void) { _RST = 1; cs_high(); //chip disabled - sci_initialise(); //initialise MBED - sci_write(SCI_MODE,(SM_SDINEW+SM_RESET)); // set mode reg. + spi_initialise(); //initialise MBED + + sci_write(SCI_MODE, (SM_SDINEW+SM_RESET)); // set mode reg. wait_ms(10); -#if 1 - // debug - unsigned int chipID_0=wram_read(para_chipID_0); - if (firstTime) printf("chipID_0:%04X\r\n",chipID_0); // debug - unsigned int chipID_1=wram_read(para_chipID_1); - if (firstTime) printf("chipID_1:%04X\r\n",chipID_1); // debug - unsigned int struct_version=wram_read(para_version); - if (firstTime) printf("structure version:%04X\r\n",struct_version); // debug + +#ifdef DEBUG + unsigned int info = wram_read(para_chipID_0); + printf("VS1053b: ChipID_0:%04X\r\n", info); + info = wram_read(para_chipID_1); + printf("VS1053b: ChipID_1:%04X\r\n", info); + info = wram_read(para_version); + printf("VS1053b: Structure version:%04X\r\n", info); #endif + //get chip version, set clock multiplier and load patch - int i = (sci_read(SCI_STATUS)&0xF0)>>4; + int i = (sci_read(SCI_STATUS) & 0xF0) >> 4; if (i == 4) { - if (firstTime) printf("Installed Chip is: VS1053\r\n"); - sci_write(SCI_CLOCKF, (SC_MULT_XTALIx50+SC_ADD_20x)); +#ifdef DEBUG + printf("VS1053b: Installed Chip is: VS1053\r\n"); +#endif + sci_write(SCI_CLOCKF, (SC_MULT_XTALIx50)); + wait_ms(10); #ifdef VS_PATCH // loading patch - write_plugin(vs1053b_patch, sizeof(vs1053b_patch)/2); - if (firstTime) { - printf("VS1053b patch loaded.\r\n"); - printf("patch size:%d bytes\r\n",sizeof(vs1053b_patch)); - } + write_plugin(vs1053b_patch, sizeof(vs1053b_patch)/2); + +#ifdef DEBUG + printf("VS1053b: Patch is loaded.\r\n"); + printf("VS1053b: Patch size:%d bytes\r\n",sizeof(vs1053b_patch)); #endif -#ifdef VS_SPECANA - // loading plugin(spectrum analyzer) - write_plugin(vs1053b_specana, sizeof(vs1053b_specana)/2); - if (firstTime) printf("VS1053b specana loaded.\r\n"); -#endif - } else printf("??? Not Supported Chip???\r\n"); - sdi_initialise(); - firstTime=0; // disable message when init after 1st time + +#endif // VS_PATCH + } + else + { +#ifdef DEBUG + printf("VS1053b: Not Supported Chip\r\n"); +#endif + return false; + } + + // change spi to higher speed + sdi_initialise(); + changeVolume(); + return true; } -void VS1053::setVolume(unsigned short int vol) { - while (!_DREQ); - sci_write(0x0B, vol); +void VS1053::setVolume(float vol) +{ + if (vol > -0.5) + _volume = -0.5; + else + _volume = vol; + + changeVolume(); +} + +float VS1053::getVolume(void) +{ + return _volume; } + +void VS1053::setBalance(float balance) +{ + _balance = balance; + + changeVolume(); +} + +float VS1053::getBalance(void) +{ + return _balance; +} + +void VS1053::changeVolume(void) +{ + // volume calculation + unsigned short volCalced = (((char)(_volume / -0.5f)) << 8) + (char)((_volume - _balance) / -0.5f); + + sci_write(0x0B, volCalced); + +#ifdef DEBUG + printf("VS1053b: Change volume to %#x (%f, Balance = %f)\r\n", volCalced, _volume, _balance); +#endif +}