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

Fork of VS1053b by Christian Schmiljun

Revision:
4:cacb5e663fa9
Parent:
3:88a645490529
Child:
5:ead95c0f7800
--- a/VS1053.cpp	Wed Dec 22 21:15:22 2010 +0000
+++ b/VS1053.cpp	Fri Dec 24 23:52:55 2010 +0000
@@ -37,6 +37,12 @@
 #include "Patches/VS1053b_pcm_recorder_0_9.c"
 
 
+void test(void)
+{
+//    DEBUGOUT("Interupt\r\n");
+}
+
+
 /* ==================================================================
  * Constructor
  * =================================================================*/
@@ -47,15 +53,19 @@
         _spi(mosi, miso, sck),
         _CS(cs),
         _RST(rst),
-        _DREQ(dreq),
-        _DCS(dcs) 
+        _DCS(dcs),
+        _DREQ(dreq),        
+        _DREQ_INTERUPT_IN(dreq) 
 {           
         _volume = DEFAULT_VOLUME;
         _balance = DEFAULT_BALANCE_DIFERENCE_LEFT_RIGHT;
         _sb_amplitude = DEFAULT_BASS_AMPLITUDE;
         _sb_freqlimit = DEFAULT_BASS_FREQUENCY;
         _st_amplitude = DEFAULT_TREBLE_AMPLITUDE;
-        _st_freqlimit = DEFAULT_TREBLE_FREQUENCY;
+        _st_freqlimit = DEFAULT_TREBLE_FREQUENCY;   
+        _DREQ_INTERUPT_IN.mode(PullDown);
+        INTERRUPT_HANDLER_DISABLE;
+        bufferReset();
 }
 
 /*===================================================================
@@ -92,13 +102,11 @@
     dcs_high();
 }
 void VS1053::reset(void) {                  //hardware reset
-//    wait(0.01);
+    INTERRUPT_HANDLER_DISABLE;
     wait_ms(10);
     _RST = 0;
-//    wait(0.01);
     wait_ms(5);
     _RST = 1;
-//    wait(0.10);
     wait_ms(10);
 }
 void VS1053::power_down(void) {              //hardware and software reset
@@ -130,6 +138,8 @@
     dcs_high();
 }
 void VS1053::sci_write(unsigned char address, unsigned short int data) {
+    // TODO disable all interrupts
+    __disable_irq();
     sci_en();                                //enables SCI/disables SDI
 
     while (!_DREQ);                           //wait unitl data request is high
@@ -140,17 +150,23 @@
 
     sci_dis();                                //enables SDI/disables SCI
     wait_us(5);
+    
+    // TODO enable all interrupts
+    __enable_irq();
 }
-void VS1053::sdi_write(unsigned char datum) {
+void VS1053::sdi_write(unsigned char datum) {    
+    
     sdi_en();
 
     while (!_DREQ);
     _spi.write(datum);
 
-//?    sci_dis();
-    sdi_dis();
+    sdi_dis();    
 }
 unsigned short VS1053::sci_read(unsigned short int address) {
+    // TODO disable all interrupts
+    __disable_irq();
+    
     cs_low();                                //enables SCI/disables SDI
 
     while (!_DREQ);                           //wait unitl data request is high
@@ -158,10 +174,12 @@
     _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
+    received |= _spi.write(0x00);            //write out dummy byte
 
     cs_high();                                //enables SDI/disables SCI
 
+    // TODO enable all interrupts
+    __enable_irq();
     return received;                        //return received word
 }
 void VS1053::sine_test_activate(unsigned char wave) {
@@ -199,14 +217,6 @@
     }
 }
 
-#if 0
-// this function does not work
-// because of function call overhead
-void VS1053::putcStream(unsigned char datum) {
-    sdi_write(datum);
-}
-#endif
-
 unsigned short int VS1053::wram_read(unsigned short int address) {
     unsigned short int tmp1,tmp2;
     sci_write(SCI_WRAMADDR,address);
@@ -236,6 +246,9 @@
 }
 
 void VS1053::terminateStream(void) {
+    while(bufferCount() > 0) 
+        ;
+    DEBUGOUT("VS1053b: Song terminating..\r\n");
     // send at least 2052 bytes of endFillByte[7:0].
     // read endFillByte  (0 .. 15) from wram 
     unsigned short endFillByte=wram_read(para_endFillByte);
@@ -345,7 +358,8 @@
     // change spi to higher speed 
     sdi_initialise();                
     changeVolume();
-    changeBass();
+    changeBass();    
+    _isIdle = true;
     return true;
 }
 
@@ -480,3 +494,177 @@
     DEBUGOUT("VS1053b: --Treble: Amplitude=%i, Frequency=%i\r\n", getTrebleAmplitude(), getTrebleFrequency());
     DEBUGOUT("VS1053b: --Bass:   Amplitude=%i, Frequency=%i\r\n", getBassAmplitude(), getBassFrequency());
 }
+
+/*===================================================================
+ * Buffer handling
+ *==================================================================*/
+
+unsigned char VS1053::bufferGetByte(void)
+{    
+    unsigned char retVal = 0x00;
+    if (bufferCount() > 0x00)
+    {        
+        retVal = *_bufferReadPointer++;         
+        if (_bufferReadPointer >= _buffer + BUFFER_SIZE)
+        {
+            _bufferReadPointer = _buffer;
+        }     
+    }
+    return retVal;
+}
+
+bool VS1053::bufferSetByte(unsigned char c)
+{
+    if (bufferFree() > 0x00)
+    {        
+        *_bufferWritePointer++ = c;        
+        if (_bufferWritePointer >= _buffer + BUFFER_SIZE)
+        {
+            _bufferWritePointer = _buffer;
+        }        
+        return true;
+    }
+    return false;
+}
+
+bool VS1053::bufferPutStream(const unsigned char *s, unsigned int length)
+{
+    if (bufferFree() >= length)
+    {
+        while (length--)
+        {
+            *_bufferWritePointer++ = *s++;                        
+            if (_bufferWritePointer >= _buffer + BUFFER_SIZE)
+            {
+                _bufferWritePointer = _buffer;
+            }
+        }
+        return true;
+    }
+    return false;
+}
+    
+unsigned int VS1053::bufferFree(void)
+{
+    if(_bufferReadPointer > _bufferWritePointer)
+    {
+        return _bufferReadPointer - _bufferWritePointer - 1;
+    }
+    else if(_bufferReadPointer < _bufferWritePointer)
+    {
+        return BUFFER_SIZE - (_bufferWritePointer - _bufferReadPointer) - 1;
+    }        
+    return BUFFER_SIZE - 1;
+}
+
+unsigned int VS1053::bufferCount(void)
+{    
+    return BUFFER_SIZE - bufferFree() - 1;
+}
+
+void VS1053::bufferReset(void)
+{
+    _bufferReadPointer = _buffer;
+    _bufferWritePointer = _buffer;            
+}
+
+
+void VS1053::dataRequestHandler(void)
+{    
+    if (_isIdle && _DREQ) 
+    {
+        _isIdle = false;
+        // write buffer to vs1053b
+        unsigned length = bufferCount();        
+        int i = 0;   
+        sdi_en();
+          
+        while (length > 0)
+        {
+            int l2 = (length > 32) ? 32 : length;        
+            //DEBUGOUT("L2: %i\r\n", l2);    
+            for( ; l2 != 0; l2--)
+            {
+                _spi.write(bufferGetByte());            
+            }
+            
+            length -= l2;
+    
+            if (!_DREQ || i > 4)
+                break;    
+            i++;
+        }
+        
+        sdi_dis();   
+        
+        _isIdle = true;
+    }               
+}
+
+void VS1053::play(void)
+{
+    INTERRUPT_HANDLER_ENABLE;
+    DEBUGOUT("VS1053b: Play.\r\n");
+}
+
+void VS1053::pause(void)
+{
+    INTERRUPT_HANDLER_DISABLE;
+    DEBUGOUT("VS1053b: Pause.\r\n");
+}
+
+void VS1053::stop(void)
+{
+    INTERRUPT_HANDLER_DISABLE;
+    __disable_irq();
+    DEBUGOUT("VS1053b: Song stoping..\r\n");
+    while(!_isIdle) 
+        ;
+        
+    // 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 audio data. 
+    for (int i = 0; i < 64; i++) 
+    { 
+        // send at least 32 bytes of audio data
+        int z = bufferCount();
+        if (z > 32)
+            z = 32;
+        for (int n = 0; n < z; n++) 
+        {            
+            _spi.write(bufferGetByte()); 
+        }
+        // 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)
+    {    
+        // 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); 
+        DEBUGOUT("VS1053b: Song sucessfully stopped.\r\n");
+        DEBUGOUT("VS1053b: SCI MODE = %#x, SM_CANCEL = %#x\r\n", sciModeByte, sciModeByte & SM_CANCEL);
+    }
+    else
+    {
+        DEBUGOUT("VS1053b: SM CANCEL hasn't cleared after sending 2048 bytes, do software reset\r\n");
+        DEBUGOUT("VS1053b: SCI MODE = %#x, SM_CANCEL = %#x\r\n", sciModeByte, sciModeByte & SM_CANCEL);        
+        //TODO: testing
+        initialize();
+    }
+            
+    bufferReset();  
+    __enable_irq();  
+}
\ No newline at end of file