Add the RTOS processing. for the Network radio streaming receiver.

Fork of VS1053b by Christian Schmiljun

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    
+}