gg
Dependencies: mbed SDFileSystem
Revision 0:1d6e44094672, committed 2016-10-31
- Comitter:
- Priunsh_N
- Date:
- Mon Oct 31 17:12:17 2016 +0000
- Commit message:
- gg
Changed in this revision
diff -r 000000000000 -r 1d6e44094672 VS1053/MusicPlayer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VS1053/MusicPlayer.cpp Mon Oct 31 17:12:17 2016 +0000 @@ -0,0 +1,11 @@ +/* + * Mbed class that creates a music player using the VS1053 + SD breakout + * Created by Priunsh Nagru and Rahul Maran + */ + + MusicPlayer::MusicPlayer(PinName sclk, PinName miso, PinName mosi, PinName cs, PinName rst, PinName xdcs, PinName sdcs, PinName dreq) : + _spi(mosi, miso, sclk), _cs(cs), _rst(rst), _xdcs(xdcs), _sdcs(sdcs), _dreq(dreq) { + _cs = 1 +} + + \ No newline at end of file
diff -r 000000000000 -r 1d6e44094672 VS1053/MusicPlayer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VS1053/MusicPlayer.h Mon Oct 31 17:12:17 2016 +0000 @@ -0,0 +1,25 @@ +/* + * Mbed class that creates a music player using the VS1053 + SD breakout + * Created by Priunsh Nagru and Rahul Maran + */ + + +#include "mbed.h" +#include "SDFileSystem.h" + +class MusicPlayer { + + public: + MusicPlayer(PinName clk, PinName miso, PinName mosi, PinName cs, PinName rst, PinName xdcs, PinName sdcs, PinName dreq); + void playMusic(string fileName); + void stopMusic(); + void reset(); + private: + bool playing; + DigitalOut _rst; + DigitalOut _cs; + DigitalOut _xdcs; + DigitalOut _sdcs; + DigitalOut _dreq; + SPI _spi; +};
diff -r 000000000000 -r 1d6e44094672 VS1053/SDFileSystem.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VS1053/SDFileSystem.lib Mon Oct 31 17:12:17 2016 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/mbed_official/code/SDFileSystem/#8db0d3b02cec
diff -r 000000000000 -r 1d6e44094672 VS1053/VS1053.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VS1053/VS1053.cpp Mon Oct 31 17:12:17 2016 +0000 @@ -0,0 +1,762 @@ +/*************************************************** + This is a library for the Adafruit VS1053 Codec Breakout + + Designed specifically to work with the Adafruit VS1053 Codec Breakout + ----> https://www.adafruit.com/products/1381 + + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +#include <Adafruit_VS1053.h> +#include <SD.h> + +static Adafruit_VS1053_FilePlayer *myself; + +#ifndef _BV + #define _BV(x) (1<<(x)) +#endif + +#if defined(__AVR__) +SIGNAL(TIMER0_COMPA_vect) { + myself->feedBuffer(); +} +#endif + +static void feeder(void) { + myself->feedBuffer(); +} + +#define VS1053_CONTROL_SPI_SETTING SPISettings(250000, MSBFIRST, SPI_MODE0) +#define VS1053_DATA_SPI_SETTING SPISettings(8000000, MSBFIRST, SPI_MODE0) + + +static const uint8_t dreqinttable[] = { +#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega8__) + 2, 0, + 3, 1, +#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) + 2, 0, + 3, 1, + 21, 2, + 20, 3, + 19, 4, + 18, 5, +#elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY) + 5, 0, + 6, 1, + 7, 2, + 8, 3, +#elif defined(__AVR_AT90USB1286__) && defined(CORE_TEENSY) + 0, 0, + 1, 1, + 2, 2, + 3, 3, + 36, 4, + 37, 5, + 18, 6, + 19, 7, +#elif defined(__arm__) && defined(CORE_TEENSY) + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, + 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, + 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, + 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, + 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, + 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, + 30, 30, 31, 31, 32, 32, 33, 33, +#elif defined(__AVR_ATmega32U4__) + 3, 0, + 2, 1, + 0, 2, + 1, 3, + 7, 4, +#elif defined(__AVR_ATmega256RFR2__) + 4, 0, + 5, 1, +#elif defined(__SAM3X8E__) || defined(ARDUINO_ARCH_SAMD) + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, + 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, + 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, + 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, + 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, + 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, + 30, 30, 31, 31, 32, 32, 33, 33, + +#endif +}; + +boolean Adafruit_VS1053_FilePlayer::useInterrupt(uint8_t type) { + myself = this; // oy vey + + if (type == VS1053_FILEPLAYER_TIMER0_INT) { +#if defined(__AVR__) + OCR0A = 0xAF; + TIMSK0 |= _BV(OCIE0A); + return true; +#elif defined(__arm__) && defined(CORE_TEENSY) + IntervalTimer *t = new IntervalTimer(); + return (t && t->begin(feeder, 1024)) ? true : false; +#else + return false; +#endif + } + if (type == VS1053_FILEPLAYER_PIN_INT) { + for (uint8_t i=0; i<sizeof(dreqinttable); i+=2) { + //Serial.println(dreqinttable[i]); + if (_dreq == dreqinttable[i]) { + #ifdef SPI_HAS_TRANSACTION + SPI.usingInterrupt(dreqinttable[i+1]); + #endif + attachInterrupt(dreqinttable[i+1], feeder, CHANGE); + return true; + } + } + } + return false; +} + +Adafruit_VS1053_FilePlayer::Adafruit_VS1053_FilePlayer( + int8_t rst, int8_t cs, int8_t dcs, int8_t dreq, + int8_t cardcs) + : Adafruit_VS1053(rst, cs, dcs, dreq) { + + playingMusic = false; + + // Set the card to be disabled while we get the VS1053 up + pinMode(_cardCS, OUTPUT); + digitalWrite(_cardCS, HIGH); +} + +Adafruit_VS1053_FilePlayer::Adafruit_VS1053_FilePlayer( + int8_t cs, int8_t dcs, int8_t dreq, + int8_t cardcs) + : Adafruit_VS1053(-1, cs, dcs, dreq) { + + playingMusic = false; + + // Set the card to be disabled while we get the VS1053 up + pinMode(_cardCS, OUTPUT); + digitalWrite(_cardCS, HIGH); +} + + +Adafruit_VS1053_FilePlayer::Adafruit_VS1053_FilePlayer( + int8_t mosi, int8_t miso, int8_t clk, + int8_t rst, int8_t cs, int8_t dcs, int8_t dreq, + int8_t cardcs) + : Adafruit_VS1053(mosi, miso, clk, rst, cs, dcs, dreq) { + + playingMusic = false; + + // Set the card to be disabled while we get the VS1053 up + pinMode(_cardCS, OUTPUT); + digitalWrite(_cardCS, HIGH); +} + +boolean Adafruit_VS1053_FilePlayer::begin(void) { + uint8_t v = Adafruit_VS1053::begin(); + + //dumpRegs(); + //Serial.print("Version = "); Serial.println(v); + return (v == 4); +} + + +boolean Adafruit_VS1053_FilePlayer::playFullFile(const char *trackname) { + if (! startPlayingFile(trackname)) return false; + + while (playingMusic) { + // twiddle thumbs + feedBuffer(); + } + // music file finished! + return true; +} + +void Adafruit_VS1053_FilePlayer::stopPlaying(void) { + // cancel all playback + sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | VS1053_MODE_SM_SDINEW | VS1053_MODE_SM_CANCEL); + + // wrap it up! + playingMusic = false; + currentTrack.close(); +} + +void Adafruit_VS1053_FilePlayer::pausePlaying(boolean pause) { + if (pause) + playingMusic = false; + else { + playingMusic = true; + feedBuffer(); + } +} + +boolean Adafruit_VS1053_FilePlayer::paused(void) { + return (!playingMusic && currentTrack); +} + +boolean Adafruit_VS1053_FilePlayer::stopped(void) { + return (!playingMusic && !currentTrack); +} + + +boolean Adafruit_VS1053_FilePlayer::startPlayingFile(const char *trackname) { + // reset playback + sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | VS1053_MODE_SM_SDINEW); + // resync + sciWrite(VS1053_REG_WRAMADDR, 0x1e29); + sciWrite(VS1053_REG_WRAM, 0); + + currentTrack = SD.open(trackname); + if (!currentTrack) { + return false; + } + + // As explained in datasheet, set twice 0 in REG_DECODETIME to set time back to 0 + sciWrite(VS1053_REG_DECODETIME, 0x00); + sciWrite(VS1053_REG_DECODETIME, 0x00); + + + playingMusic = true; + + // wait till its ready for data + while (! readyForData() ); + + + // fill it up! + while (playingMusic && readyForData()) + feedBuffer(); + +// Serial.println("Ready"); + + return true; +} + +void Adafruit_VS1053_FilePlayer::feedBuffer(void) { + static uint8_t running = 0; + uint8_t sregsave; + +#if !defined (__SAM3X8E__) && !defined (ARDUINO_ARCH_SAMD) + // Do not allow 2 copies of this code to run concurrently. + // If an interrupt causes feedBuffer() to run while another + // copy of feedBuffer() is already running in the main + // program, havoc can occur. "running" detects this state + // and safely returns. + sregsave = SREG; + cli(); + if (running) { + SREG = sregsave; + return; // return safely, before touching hardware! :-) + } else { + running = 1; + SREG = sregsave; + } +#endif + + if (! playingMusic) { + running = 0; + return; // paused or stopped + } + if (! currentTrack) { + running = 0; + return; + } + if (! readyForData()) { + running = 0; + return; + } + + // Feed the hungry buffer! :) + while (readyForData()) { + //UDR0 = '.'; + + // Read some audio data from the SD card file + int bytesread = currentTrack.read(mp3buffer, VS1053_DATABUFFERLEN); + + if (bytesread == 0) { + // must be at the end of the file, wrap it up! + playingMusic = false; + currentTrack.close(); + running = 0; + return; + } + playData(mp3buffer, bytesread); + } + running = 0; + return; +} + + +/***************************************************************/ + +/* VS1053 'low level' interface */ +#ifdef ARDUINO_ARCH_SAMD +static volatile uint32_t *clkportreg, *misoportreg, *mosiportreg; +static uint32_t clkpin, misopin, mosipin; +#else +static volatile PortReg *clkportreg, *misoportreg, *mosiportreg; +static PortMask clkpin, misopin, mosipin; +#endif + +Adafruit_VS1053::Adafruit_VS1053(int8_t mosi, int8_t miso, int8_t clk, + int8_t rst, int8_t cs, int8_t dcs, int8_t dreq) { + _mosi = mosi; + _miso = miso; + _clk = clk; + _reset = rst; + _cs = cs; + _dcs = dcs; + _dreq = dreq; + + useHardwareSPI = false; + + clkportreg = portOutputRegister(digitalPinToPort(_clk)); + clkpin = digitalPinToBitMask(_clk); + misoportreg = portInputRegister(digitalPinToPort(_miso)); + misopin = digitalPinToBitMask(_miso); + mosiportreg = portOutputRegister(digitalPinToPort(_mosi)); + mosipin = digitalPinToBitMask(_mosi); +} + + +Adafruit_VS1053::Adafruit_VS1053(int8_t rst, int8_t cs, int8_t dcs, int8_t dreq) { + _mosi = 0; + _miso = 0; + _clk = 0; + useHardwareSPI = true; + _reset = rst; + _cs = cs; + _dcs = dcs; + _dreq = dreq; +} + + +void Adafruit_VS1053::applyPatch(const uint16_t *patch, uint16_t patchsize) { + uint16_t i = 0; + + // Serial.print("Patch size: "); Serial.println(patchsize); + while ( i < patchsize ) { + uint16_t addr, n, val; + + addr = pgm_read_word(patch++); + n = pgm_read_word(patch++); + i += 2; + + //Serial.println(addr, HEX); + if (n & 0x8000U) { // RLE run, replicate n samples + n &= 0x7FFF; + val = pgm_read_word(patch++); + i++; + while (n--) { + sciWrite(addr, val); + } + } else { // Copy run, copy n samples + while (n--) { + val = pgm_read_word(patch++); + i++; + sciWrite(addr, val); + } + } + } +} + + +uint16_t Adafruit_VS1053::loadPlugin(char *plugname) { + + File plugin = SD.open(plugname); + if (!plugin) { + Serial.println("Couldn't open the plugin file"); + Serial.println(plugin); + return 0xFFFF; + } + + if ((plugin.read() != 'P') || + (plugin.read() != '&') || + (plugin.read() != 'H')) + return 0xFFFF; + + uint16_t type; + + // Serial.print("Patch size: "); Serial.println(patchsize); + while ((type = plugin.read()) >= 0) { + uint16_t offsets[] = {0x8000UL, 0x0, 0x4000UL}; + uint16_t addr, len; + + //Serial.print("type: "); Serial.println(type, HEX); + + if (type >= 4) { + plugin.close(); + return 0xFFFF; + } + + len = plugin.read(); len <<= 8; + len |= plugin.read() & ~1; + addr = plugin.read(); addr <<= 8; + addr |= plugin.read(); + //Serial.print("len: "); Serial.print(len); + //Serial.print(" addr: $"); Serial.println(addr, HEX); + + if (type == 3) { + // execute rec! + plugin.close(); + return addr; + } + + // set address + sciWrite(VS1053_REG_WRAMADDR, addr + offsets[type]); + // write data + do { + uint16_t data; + data = plugin.read(); data <<= 8; + data |= plugin.read(); + sciWrite(VS1053_REG_WRAM, data); + } while ((len -=2)); + } + + plugin.close(); + return 0xFFFF; +} + + + + +boolean Adafruit_VS1053::readyForData(void) { + return digitalRead(_dreq); +} + +void Adafruit_VS1053::playData(uint8_t *buffer, uint8_t buffsiz) { + #ifdef SPI_HAS_TRANSACTION + if (useHardwareSPI) SPI.beginTransaction(VS1053_DATA_SPI_SETTING); + #endif + digitalWrite(_dcs, LOW); + for (uint8_t i=0; i<buffsiz; i++) { + spiwrite(buffer[i]); + } + digitalWrite(_dcs, HIGH); + #ifdef SPI_HAS_TRANSACTION + if (useHardwareSPI) SPI.endTransaction(); + #endif +} + +void Adafruit_VS1053::setVolume(uint8_t left, uint8_t right) { + uint16_t v; + v = left; + v <<= 8; + v |= right; + + noInterrupts(); //cli(); + sciWrite(VS1053_REG_VOLUME, v); + interrupts(); //sei(); +} + +uint16_t Adafruit_VS1053::decodeTime() { + noInterrupts(); //cli(); + uint16_t t = sciRead(VS1053_REG_DECODETIME); + interrupts(); //sei(); + return t; +} + + +void Adafruit_VS1053::softReset(void) { + sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_SDINEW | VS1053_MODE_SM_RESET); + delay(100); +} + +void Adafruit_VS1053::reset() { + // TODO: http://www.vlsi.fi/player_vs1011_1002_1003/modularplayer/vs10xx_8c.html#a3 + // hardware reset + if (_reset >= 0) { + digitalWrite(_reset, LOW); + delay(100); + digitalWrite(_reset, HIGH); + } + digitalWrite(_cs, HIGH); + digitalWrite(_dcs, HIGH); + delay(100); + softReset(); + delay(100); + + sciWrite(VS1053_REG_CLOCKF, 0x6000); + + setVolume(40, 40); +} + +uint8_t Adafruit_VS1053::begin(void) { + if (_reset >= 0) { + pinMode(_reset, OUTPUT); + digitalWrite(_reset, LOW); + } + + pinMode(_cs, OUTPUT); + digitalWrite(_cs, HIGH); + pinMode(_dcs, OUTPUT); + digitalWrite(_dcs, HIGH); + pinMode(_dreq, INPUT); + + if (! useHardwareSPI) { + pinMode(_mosi, OUTPUT); + pinMode(_clk, OUTPUT); + pinMode(_miso, INPUT); + } else { + SPI.begin(); + SPI.setDataMode(SPI_MODE0); + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV128); + } + + reset(); + + return (sciRead(VS1053_REG_STATUS) >> 4) & 0x0F; +} + +void Adafruit_VS1053::dumpRegs(void) { + Serial.print("Mode = 0x"); Serial.println(sciRead(VS1053_REG_MODE), HEX); + Serial.print("Stat = 0x"); Serial.println(sciRead(VS1053_REG_STATUS), HEX); + Serial.print("ClkF = 0x"); Serial.println(sciRead(VS1053_REG_CLOCKF), HEX); + Serial.print("Vol. = 0x"); Serial.println(sciRead(VS1053_REG_VOLUME), HEX); +} + + +uint16_t Adafruit_VS1053::recordedWordsWaiting(void) { + return sciRead(VS1053_REG_HDAT1); +} + +uint16_t Adafruit_VS1053::recordedReadWord(void) { + return sciRead(VS1053_REG_HDAT0); +} + + +boolean Adafruit_VS1053::prepareRecordOgg(char *plugname) { + sciWrite(VS1053_REG_CLOCKF, 0xC000); // set max clock + delay(1); while (! readyForData() ); + + sciWrite(VS1053_REG_BASS, 0); // clear Bass + + softReset(); + delay(1); while (! readyForData() ); + + sciWrite(VS1053_SCI_AIADDR, 0); + // disable all interrupts except SCI + sciWrite(VS1053_REG_WRAMADDR, VS1053_INT_ENABLE); + sciWrite(VS1053_REG_WRAM, 0x02); + + int pluginStartAddr = loadPlugin(plugname); + if (pluginStartAddr == 0xFFFF) return false; + Serial.print("Plugin at $"); Serial.println(pluginStartAddr, HEX); + if (pluginStartAddr != 0x34) return false; + + return true; +} + +void Adafruit_VS1053::stopRecordOgg(void) { + sciWrite(VS1053_SCI_AICTRL3, 1); +} + +void Adafruit_VS1053::startRecordOgg(boolean mic) { + /* Set VS1053 mode bits as instructed in the VS1053b Ogg Vorbis Encoder + manual. Note: for microphone input, leave SMF_LINE1 unset! */ + if (mic) { + sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_ADPCM | VS1053_MODE_SM_SDINEW); + } else { + sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | + VS1053_MODE_SM_ADPCM | VS1053_MODE_SM_SDINEW); + } + sciWrite(VS1053_SCI_AICTRL0, 1024); + /* Rec level: 1024 = 1. If 0, use AGC */ + sciWrite(VS1053_SCI_AICTRL1, 1024); + /* Maximum AGC level: 1024 = 1. Only used if SCI_AICTRL1 is set to 0. */ + sciWrite(VS1053_SCI_AICTRL2, 0); + /* Miscellaneous bits that also must be set before recording. */ + sciWrite(VS1053_SCI_AICTRL3, 0); + + sciWrite(VS1053_SCI_AIADDR, 0x34); + delay(1); while (! readyForData() ); +} + +void Adafruit_VS1053::GPIO_pinMode(uint8_t i, uint8_t dir) { + if (i > 7) return; + + sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_DDR); + uint16_t ddr = sciRead(VS1053_REG_WRAM); + + if (dir == INPUT) + ddr &= ~_BV(i); + if (dir == OUTPUT) + ddr |= _BV(i); + + sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_DDR); + sciWrite(VS1053_REG_WRAM, ddr); +} + + +void Adafruit_VS1053::GPIO_digitalWrite(uint8_t val) { + sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_ODATA); + sciWrite(VS1053_REG_WRAM, val); +} + +void Adafruit_VS1053::GPIO_digitalWrite(uint8_t i, uint8_t val) { + if (i > 7) return; + + sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_ODATA); + uint16_t pins = sciRead(VS1053_REG_WRAM); + + if (val == LOW) + pins &= ~_BV(i); + if (val == HIGH) + pins |= _BV(i); + + sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_ODATA); + sciWrite(VS1053_REG_WRAM, pins); +} + +uint16_t Adafruit_VS1053::GPIO_digitalRead(void) { + sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_IDATA); + return sciRead(VS1053_REG_WRAM) & 0xFF; +} + +boolean Adafruit_VS1053::GPIO_digitalRead(uint8_t i) { + if (i > 7) return 0; + + sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_IDATA); + uint16_t val = sciRead(VS1053_REG_WRAM); + if (val & _BV(i)) return true; + return false; +} + +uint16_t Adafruit_VS1053::sciRead(uint8_t addr) { + uint16_t data; + + #ifdef SPI_HAS_TRANSACTION + if (useHardwareSPI) SPI.beginTransaction(VS1053_CONTROL_SPI_SETTING); + #endif + digitalWrite(_cs, LOW); + spiwrite(VS1053_SCI_READ); + spiwrite(addr); + delayMicroseconds(10); + data = spiread(); + data <<= 8; + data |= spiread(); + digitalWrite(_cs, HIGH); + #ifdef SPI_HAS_TRANSACTION + if (useHardwareSPI) SPI.endTransaction(); + #endif + + return data; +} + + +void Adafruit_VS1053::sciWrite(uint8_t addr, uint16_t data) { + #ifdef SPI_HAS_TRANSACTION + if (useHardwareSPI) SPI.beginTransaction(VS1053_CONTROL_SPI_SETTING); + #endif + digitalWrite(_cs, LOW); + spiwrite(VS1053_SCI_WRITE); + spiwrite(addr); + spiwrite(data >> 8); + spiwrite(data & 0xFF); + digitalWrite(_cs, HIGH); + #ifdef SPI_HAS_TRANSACTION + if (useHardwareSPI) SPI.endTransaction(); + #endif +} + + + +uint8_t Adafruit_VS1053::spiread(void) +{ + int8_t i, x; + x = 0; + + // MSB first, clock low when inactive (CPOL 0), data valid on leading edge (CPHA 0) + // Make sure clock starts low + + if (useHardwareSPI) { + x = SPI.transfer(0x00); + } else { + for (i=7; i>=0; i--) { + if ((*misoportreg) & misopin) + x |= (1<<i); + *clkportreg |= clkpin; + *clkportreg &= ~clkpin; + // asm("nop; nop"); + } + // Make sure clock ends low + *clkportreg &= ~clkpin; + } + return x; +} + +void Adafruit_VS1053::spiwrite(uint8_t c) +{ + // MSB first, clock low when inactive (CPOL 0), data valid on leading edge (CPHA 0) + // Make sure clock starts low + + if (useHardwareSPI) { + SPI.transfer(c); + + } else { + for (int8_t i=7; i>=0; i--) { + *clkportreg &= ~clkpin; + if (c & (1<<i)) { + *mosiportreg |= mosipin; + } else { + *mosiportreg &= ~mosipin; + } + *clkportreg |= clkpin; + } + *clkportreg &= ~clkpin; // Make sure clock ends low + } +} + + + +void Adafruit_VS1053::sineTest(uint8_t n, uint16_t ms) { + reset(); + + uint16_t mode = sciRead(VS1053_REG_MODE); + mode |= 0x0020; + sciWrite(VS1053_REG_MODE, mode); + + while (!digitalRead(_dreq)); + // delay(10); + + #ifdef SPI_HAS_TRANSACTION + if (useHardwareSPI) SPI.beginTransaction(VS1053_DATA_SPI_SETTING); + #endif + digitalWrite(_dcs, LOW); + spiwrite(0x53); + spiwrite(0xEF); + spiwrite(0x6E); + spiwrite(n); + spiwrite(0x00); + spiwrite(0x00); + spiwrite(0x00); + spiwrite(0x00); + digitalWrite(_dcs, HIGH); + #ifdef SPI_HAS_TRANSACTION + if (useHardwareSPI) SPI.endTransaction(); + #endif + + delay(ms); + + #ifdef SPI_HAS_TRANSACTION + if (useHardwareSPI) SPI.beginTransaction(VS1053_DATA_SPI_SETTING); + #endif + digitalWrite(_dcs, LOW); + spiwrite(0x45); + spiwrite(0x78); + spiwrite(0x69); + spiwrite(0x74); + spiwrite(0x00); + spiwrite(0x00); + spiwrite(0x00); + spiwrite(0x00); + digitalWrite(_dcs, HIGH); + #ifdef SPI_HAS_TRANSACTION + if (useHardwareSPI) SPI.endTransaction(); + #endif +}
diff -r 000000000000 -r 1d6e44094672 VS1053/VS1053.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VS1053/VS1053.h Mon Oct 31 17:12:17 2016 +0000 @@ -0,0 +1,154 @@ +/*************************************************** + This is a library for the Adafruit VS1053 Codec Breakout + + Designed specifically to work with the Adafruit VS1053 Codec Breakout + ----> https://www.adafruit.com/products/1381 + + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ +#ifndef ADAFRUIT_VS1053_H +#define ADAFRUIT_VS1053_H + + +#include "mbed.h" + +#ifdef __SAM3X8E__ +typedef volatile RwReg PortReg; +typedef uint32_t PortMask; +#else +typedef volatile uint8_t PortReg; +typedef uint8_t PortMask; +#endif + + +#define VS1053_FILEPLAYER_TIMER0_INT 255 // allows useInterrupt to accept pins 0 to 254 +#define VS1053_FILEPLAYER_PIN_INT 5 + +#define VS1053_SCI_READ 0x03 +#define VS1053_SCI_WRITE 0x02 + +#define VS1053_REG_MODE 0x00 +#define VS1053_REG_STATUS 0x01 +#define VS1053_REG_BASS 0x02 +#define VS1053_REG_CLOCKF 0x03 +#define VS1053_REG_DECODETIME 0x04 +#define VS1053_REG_AUDATA 0x05 +#define VS1053_REG_WRAM 0x06 +#define VS1053_REG_WRAMADDR 0x07 +#define VS1053_REG_HDAT0 0x08 +#define VS1053_REG_HDAT1 0x09 +#define VS1053_REG_VOLUME 0x0B + +#define VS1053_GPIO_DDR 0xC017 +#define VS1053_GPIO_IDATA 0xC018 +#define VS1053_GPIO_ODATA 0xC019 + +#define VS1053_INT_ENABLE 0xC01A + +#define VS1053_MODE_SM_DIFF 0x0001 +#define VS1053_MODE_SM_LAYER12 0x0002 +#define VS1053_MODE_SM_RESET 0x0004 +#define VS1053_MODE_SM_CANCEL 0x0008 +#define VS1053_MODE_SM_EARSPKLO 0x0010 +#define VS1053_MODE_SM_TESTS 0x0020 +#define VS1053_MODE_SM_STREAM 0x0040 +#define VS1053_MODE_SM_SDINEW 0x0800 +#define VS1053_MODE_SM_ADPCM 0x1000 +#define VS1053_MODE_SM_LINE1 0x4000 +#define VS1053_MODE_SM_CLKRANGE 0x8000 + + +#define VS1053_SCI_AIADDR 0x0A +#define VS1053_SCI_AICTRL0 0x0C +#define VS1053_SCI_AICTRL1 0x0D +#define VS1053_SCI_AICTRL2 0x0E +#define VS1053_SCI_AICTRL3 0x0F + +#define VS1053_DATABUFFERLEN 32 + + +class Adafruit_VS1053 { + public: + Adafruit_VS1053(int8_t mosi, int8_t miso, int8_t clk, + int8_t rst, int8_t cs, int8_t dcs, int8_t dreq); + Adafruit_VS1053(int8_t rst, int8_t cs, int8_t dcs, int8_t dreq); + uint8_t begin(void); + void reset(void); + void softReset(void); + uint16_t sciRead(uint8_t addr); + void sciWrite(uint8_t addr, uint16_t data); + void sineTest(uint8_t n, uint16_t ms); + void spiwrite(uint8_t d); + uint8_t spiread(void); + + uint16_t decodeTime(void); + void setVolume(uint8_t left, uint8_t right); + void dumpRegs(void); + + void playData(uint8_t *buffer, uint8_t buffsiz); + boolean readyForData(void); + void applyPatch(const uint16_t *patch, uint16_t patchsize); + uint16_t loadPlugin(char *fn); + + void GPIO_digitalWrite(uint8_t i, uint8_t val); + void GPIO_digitalWrite(uint8_t i); + uint16_t GPIO_digitalRead(void); + boolean GPIO_digitalRead(uint8_t i); + void GPIO_pinMode(uint8_t i, uint8_t dir); + + boolean prepareRecordOgg(char *plugin); + void startRecordOgg(boolean mic); + void stopRecordOgg(void); + uint16_t recordedWordsWaiting(void); + uint16_t recordedReadWord(void); + + uint8_t mp3buffer[VS1053_DATABUFFERLEN]; + +#ifdef ARDUINO_ARCH_SAMD +protected: + uint32_t _dreq; +private: + int32_t _mosi, _miso, _clk, _reset, _cs, _dcs; + boolean useHardwareSPI; +#else + protected: + uint8_t _dreq; + private: + int8_t _mosi, _miso, _clk, _reset, _cs, _dcs; + boolean useHardwareSPI; +#endif +}; + + +class Adafruit_VS1053_FilePlayer : public Adafruit_VS1053 { + public: + Adafruit_VS1053_FilePlayer (int8_t mosi, int8_t miso, int8_t clk, + int8_t rst, int8_t cs, int8_t dcs, int8_t dreq, + int8_t cardCS); + Adafruit_VS1053_FilePlayer (int8_t rst, int8_t cs, int8_t dcs, int8_t dreq, + int8_t cardCS); + Adafruit_VS1053_FilePlayer (int8_t cs, int8_t dcs, int8_t dreq, + int8_t cardCS); + + boolean begin(void); + boolean useInterrupt(uint8_t type); + File currentTrack; + volatile boolean playingMusic; + void feedBuffer(void); + boolean startPlayingFile(const char *trackname); + boolean playFullFile(const char *trackname); + void stopPlaying(void); + boolean paused(void); + boolean stopped(void); + void pausePlaying(boolean pause); + + private: + uint8_t _cardCS; +}; + +#endif // ADAFRUIT_VS1053_H
diff -r 000000000000 -r 1d6e44094672 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Oct 31 17:12:17 2016 +0000 @@ -0,0 +1,12 @@ +#include "mbed.h" + +DigitalOut myled(LED1); + +int main() { + while(1) { + myled = 1; + wait(0.2); + myled = 0; + wait(0.2); + } +}
diff -r 000000000000 -r 1d6e44094672 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Oct 31 17:12:17 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/9bcdf88f62b0 \ No newline at end of file