Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Lab3_1 RTOS-VS1053b-mp3_semaphore RTOS-VS1053b-mp3_v01
Diff: VS1053.cpp
- Revision:
- 4:cacb5e663fa9
- Parent:
- 3:88a645490529
- Child:
- 5:ead95c0f7800
diff -r 88a645490529 -r cacb5e663fa9 VS1053.cpp
--- 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