gg

Dependencies:   mbed SDFileSystem

Files at this revision

API Documentation at this revision

Comitter:
Priunsh_N
Date:
Mon Oct 31 17:12:17 2016 +0000
Commit message:
gg

Changed in this revision

VS1053/MusicPlayer.cpp Show annotated file Show diff for this revision Revisions of this file
VS1053/MusicPlayer.h Show annotated file Show diff for this revision Revisions of this file
VS1053/SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
VS1053/VS1053.cpp Show annotated file Show diff for this revision Revisions of this file
VS1053/VS1053.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
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