modified for VS1033
Dependents: 11U68_MP3Player with TFTLCD 11U68_MP3Player-with-TFTLCD Mp3_1
Fork of VS1033 by
VS1053.cpp
- Committer:
- nameless129
- Date:
- 2015-07-30
- Revision:
- 11:da08a7b0947d
- Parent:
- 10:a8594af40a50
File content as of revision 11:da08a7b0947d:
// ==================================================== Dec 21 2013, kayeks == // VS1053.cpp // =========================================================================== // Just a simple library for VLSI's mp3/midi codec chip // - Minimal and simple implementation (and dirty too) #include "mbed.h" #include "VS1053.h" /** Constructor of class VS1053. */ VS1053::VS1053(PinName mosiPin, PinName misoPin, PinName sckPin, PinName csPin, PinName dcsPin, PinName dreqPin, PinName rstPin, uint32_t spiFrequency) : spi(mosiPin, misoPin, sckPin), cs(csPin), dcs(dcsPin), dreq(dreqPin), rst(rstPin) { useSpiFreq = spiFrequency; // Initialize outputs cs = 1; dcs = 1; rst = 1; } /** Destructor of class VS1053. */ VS1053::~VS1053() { } //SCI enable void VS1053::sci_en(void) { dcs = 1; cs = 0; } //SCI disable void VS1053::sci_dis(void) { dcs = 1; cs = 1; } //SDI enable void VS1053::sdi_en(void) { cs = 1; dcs = 0; } //SDI disable void VS1053::sdi_dis(void) { cs = 1; dcs = 1; } /** Make a hardware reset by hitting VS1053's RESET pin. */ void VS1053::hardwareReset() { rst = 0; wait(0.1); rst = 1; wait(0.1); } //Serial Command Interface(SCI) init void VS1053::sci_init() { spi.format(8, 0); spi.frequency(1000000); cs = 0; for(int i=0; i<4; i++) { spi.write(0xFF); //clock the chip a bit } cs = 1; dcs = 1; wait_us(5); writeReg(SCI_MODE,(SM_SDINEW)); writeReg(SCI_CLOCKF, 0x9800); } //Serial Data Interface(SDI) init void VS1053::sdi_init() { spi.format(8, 0); spi.frequency(useSpiFreq); writeReg(SCI_CLOCKF, 0xc000); // SC_MULT=6 (4.0x) wait(0.01); cs = 1; dcs = 1; } void VS1053::VolControl(uint16_t vol) { writeReg(SCI_VOL,vol); } /** SDI Send a data byte to VS1053. */ void VS1053::sendDataByte(uint8_t data) { sdi_en(); while (!dreq); spi.write(data); sdi_dis(); } bool VS1053::checkDREQ() { bool dreq_return = 0; dreq_return = dreq; return dreq_return; } /** SDI Send a data block specified as a pointer to VS1053. * @return Data length successfully sent. */ size_t VS1053::sendDataBlock(uint8_t* data, size_t length) { size_t n, sizeSent = 0; if (!data || !length) return 0; sdi_en(); while (length) { n = length < 32 ? length : 32; for (uint32_t i = 0; i < n; i++) { while (!dreq); spi.write(*data++); sizeSent++; length--; } } sdi_dis(); return sizeSent; } /** Attempt a termination of playing. * Please call this repeatedly during data stream tramsission until it successes. * @return Zero at failure, non-zero at success. */ bool VS1053::stop() { uint16_t n, length; // Send 0 2052 byte length = 256; sdi_en(); while (length) { n = length < 32 ? length : 32; for (uint32_t i = 0; i < n; i++) { while (!dreq); spi.write(0x00); length--; } } sdi_dis(); writeReg(SCI_MODE,( (SM_SDINEW)|(SM_RESET) ) ); writeReg(SCI_CLOCKF, 0x9800); // Check if both HDAT0 and HDAT1 are cleared return readReg(SCI_HDAT0) == 0x0000 && readReg(SCI_HDAT1) == 0x0000; } /** Write to an SCI (Serial Control Interface) register entry. */ void VS1053::writeReg(uint8_t addr, uint16_t word) { // If addr is out-of-range, do nothing if (addr > 0x0f) { return; } sci_en(); while (!dreq); spi.write(0x02); // Send a "Write SCI" instruction (02h), spi.write(addr); // target address, spi.write(word >> 8); // high byte, spi.write(word & 0xff); // then low byte sci_dis(); } /** Read an SCI (Serial Control Interface) register entry. * @return Register value or 0000h when invalid address was specified. */ uint16_t VS1053::readReg(uint8_t addr) { uint16_t word; // If addr is out-of-range, return 0000h if (addr > 0x0f) { return 0x0000; } sci_en(); while (!dreq); spi.write(0x03); // Send a "Read SCI" instruction (03h) spi.write(addr); // and target address word = spi.write(0xff) << 8; // Receive high byte with dummy data FFh word |= spi.write(0xff); // Receive low byte sci_dis(); return word; } void VS1053::sine_test_activate(unsigned char wave) { hardwareReset(); spi.format(8, 0); spi.frequency(1000000); writeReg(SCI_MODE,(SM_SDINEW+SM_TESTS)); sdi_en(); while(dreq == 0) { } //wait unitl data request is high spi.write(0x53); //SDI write spi.write(0xEF); //SDI write spi.write(0x6E); //SDI write spi.write(wave); //SDI write spi.write(0x00); //filler byte spi.write(0x00); //filler byte spi.write(0x00); //filler byte spi.write(0x00); //filler byte sdi_dis(); } void VS1053::sine_test_deactivate(void) { sdi_en(); while(dreq == 0) { } spi.write(0x45); //SDI write spi.write(0x78); //SDI write spi.write(0x69); //SDI write spi.write(0x74); //SDI write spi.write(0x00); //filler byte spi.write(0x00); //filler byte spi.write(0x00); //filler byte spi.write(0x00); //filler byte sdi_dis(); }