Add the RTOS processing. for the Network radio streaming receiver.
Fork of VS1053b by
Diff: VS1053.cpp
- 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