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);
            }
        }
    }
}
Пример #2
0
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;
}
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;
}
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 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);
}
void Adafruit_VS1053_FilePlayer::stopSong(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;
}
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;
}
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;
  }
    
  // We know we have a valid file. Check if .mp3
  // If so, check for ID3 tag and jump it if present.
  if (isMP3File(trackname)) {
    currentTrack.seek(mp3_ID3Jumper(currentTrack));
  }

  // don't let the IRQ get triggered by accident here
  noInterrupts();

  // 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() ) {
#if defined(ESP8266)
	yield();
#endif
  }

  // fill it up!
  while (playingMusic && readyForData()) {
    feedBuffer();
  }
  
  // ok going forward, we can use the IRQ
  interrupts();

  return true;
}
Пример #9
0
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();
}
Пример #10
0
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;
}
Пример #11
0
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
}
Пример #12
0
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);
}
Пример #13
0
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_digitalWrite(uint8_t val) {
    sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_ODATA);
    sciWrite(VS1053_REG_WRAM, val);
}
Пример #15
0
void Adafruit_VS1053::softReset(void) {
    sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_SDINEW | VS1053_MODE_SM_RESET);
    delay(100);
}
void Adafruit_VS1053::stopPlaying(void) {
    // cancel all playback
    sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | VS1053_MODE_SM_SDINEW | VS1053_MODE_SM_CANCEL);
}
void Adafruit_VS1053::stopRecordOgg(void) {
    sciWrite(VS1053_SCI_AICTRL3, 1);
}
uint16_t Adafruit_VS1053::GPIO_digitalRead(void) {
    sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_IDATA);
    return sciRead(VS1053_REG_WRAM) & 0xFF;
}