Moved to actions, doxygen

This commit is contained in:
dherrada 2020-06-12 14:54:35 -04:00
parent b52c4e3cda
commit 59f20a104f
No known key found for this signature in database
GPG key ID: CE2ADBAB8775CE81
6 changed files with 544 additions and 330 deletions

32
.github/workflows/githubci.yml vendored Normal file
View file

@ -0,0 +1,32 @@
name: Arduino Library CI
on: [pull_request, push, repository_dispatch]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v1
with:
python-version: '3.x'
- uses: actions/checkout@v2
- uses: actions/checkout@v2
with:
repository: adafruit/ci-arduino
path: ci
- name: pre-install
run: bash ci/actions_install.sh
- name: test platforms
run: python3 ci/build_platform.py main_platforms
- name: clang
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
- name: doxygen
env:
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
PRETTYNAME : "Adafruit VS1053 Arduino Library"
run: bash ci/doxy_gen_and_deploy.sh

View file

@ -1,34 +0,0 @@
language: c
sudo: false
cache:
directories:
- ~/arduino_ide
- ~/.arduino15/packages/
git:
depth: false
quiet: true
env:
global:
- PRETTYNAME="Adafruit VS1053 Arduino Library"
addons:
apt:
sources:
- llvm-toolchain-trusty-5.0
- key_url: 'http://apt.llvm.org/llvm-snapshot.gpg.key'
packages:
- clang-format-5.0
before_install:
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh)
- curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/run-clang-format.py > run-clang-format.py
install:
script:
#- python run-clang-format.py -r .
- build_main_platforms
# Generate and deploy documentation
after_success:
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh)
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh)

View file

@ -1,50 +1,58 @@
/***************************************************
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
****************************************************/
/*!
* @file Adafruit_VS1053.cpp
*
* @mainpage Adafruit VS1053 Library
*
* @section intro_sec Introduction
*
* 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!
*
* @section author Author
*
* Written by Limor Fried/Ladyada for Adafruit Industries.
*
* @section license License
*
* BSD license, all text above must be included in any redistribution
*/
#include <Adafruit_VS1053.h>
#if defined(ARDUINO_STM32_FEATHER)
#define digitalPinToInterrupt(x) x
#define digitalPinToInterrupt(x) x
#endif
static Adafruit_VS1053_FilePlayer *myself;
#ifndef _BV
#define _BV(x) (1<<(x))
#define _BV(x) (1 << (x)) //!< Macro that returns the "value" of a bit
#endif
#if defined(ARDUINO_ARCH_AVR)
SIGNAL(TIMER0_COMPA_vect) {
myself->feedBuffer();
}
SIGNAL(TIMER0_COMPA_vect) { myself->feedBuffer(); }
#endif
volatile boolean feedBufferLock = false;
volatile boolean feedBufferLock = false; //!< Locks feeding the buffer
#if defined(ESP8266)
ICACHE_RAM_ATTR
#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 void feeder(void) { myself->feedBuffer(); }
#define VS1053_CONTROL_SPI_SETTING \
SPISettings(250000, MSBFIRST, SPI_MODE0) //!< VS1053 SPI control settings
#define VS1053_DATA_SPI_SETTING \
SPISettings(8000000, MSBFIRST, SPI_MODE0) //!< VS1053 SPI data settings
boolean Adafruit_VS1053_FilePlayer::useInterrupt(uint8_t type) {
myself = this; // oy vey
myself = this; // oy vey
if (type == VS1053_FILEPLAYER_TIMER0_INT) {
#if defined(ARDUINO_ARCH_AVR)
@ -64,7 +72,7 @@ boolean Adafruit_VS1053_FilePlayer::useInterrupt(uint8_t type) {
// Set up an interrupt on channel 1
timer.setChannel1Mode(TIMER_OUTPUT_COMPARE);
timer.setCompare(TIMER_CH1, 1); // Interrupt 1 count after each update
timer.setCompare(TIMER_CH1, 1); // Interrupt 1 count after each update
timer.attachCompare1Interrupt(feeder);
// Refresh the timer's count, prescale, and overflow
@ -79,10 +87,11 @@ boolean Adafruit_VS1053_FilePlayer::useInterrupt(uint8_t type) {
}
if (type == VS1053_FILEPLAYER_PIN_INT) {
int8_t irq = digitalPinToInterrupt(_dreq);
//Serial.print("Using IRQ "); Serial.println(irq);
// Serial.print("Using IRQ "); Serial.println(irq);
if (irq == -1)
return false;
#if defined(SPI_HAS_TRANSACTION) && !defined(ESP8266) && !defined(ESP32) && !defined(ARDUINO_STM32_FEATHER)
#if defined(SPI_HAS_TRANSACTION) && !defined(ESP8266) && !defined(ESP32) && \
!defined(ARDUINO_STM32_FEATHER)
SPI.usingInterrupt(irq);
#endif
attachInterrupt(irq, feeder, CHANGE);
@ -91,30 +100,30 @@ boolean Adafruit_VS1053_FilePlayer::useInterrupt(uint8_t type) {
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) {
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;
_cardCS = cardcs;
}
Adafruit_VS1053_FilePlayer::Adafruit_VS1053_FilePlayer(
int8_t cs, int8_t dcs, int8_t dreq,
int8_t cardcs)
: Adafruit_VS1053(-1, cs, dcs, dreq) {
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;
_cardCS = cardcs;
}
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) {
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;
_cardCS = cardcs;
@ -125,21 +134,21 @@ boolean Adafruit_VS1053_FilePlayer::begin(void) {
pinMode(_cardCS, OUTPUT);
digitalWrite(_cardCS, HIGH);
uint8_t v = Adafruit_VS1053::begin();
uint8_t v = Adafruit_VS1053::begin();
//dumpRegs();
//Serial.print("Version = "); Serial.println(v);
// dumpRegs();
// Serial.print("Version = "); Serial.println(v);
return (v == 4);
}
boolean Adafruit_VS1053_FilePlayer::playFullFile(const char *trackname) {
if (! startPlayingFile(trackname)) return false;
if (!startPlayingFile(trackname))
return false;
while (playingMusic) {
// twiddle thumbs
feedBuffer();
delay(5); // give IRQs a chance
delay(5); // give IRQs a chance
}
// music file finished!
return true;
@ -147,7 +156,8 @@ boolean Adafruit_VS1053_FilePlayer::playFullFile(const char *trackname) {
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);
sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | VS1053_MODE_SM_SDINEW |
VS1053_MODE_SM_CANCEL);
// wrap it up!
playingMusic = false;
@ -170,8 +180,9 @@ boolean Adafruit_VS1053_FilePlayer::stopped(void) {
}
// Just checks to see if the name ends in ".mp3"
boolean Adafruit_VS1053_FilePlayer::isMP3File(const char* fileName) {
return (strlen(fileName) > 4) && !strcasecmp(fileName + strlen(fileName) - 4, ".mp3");
boolean Adafruit_VS1053_FilePlayer::isMP3File(const char *fileName) {
return (strlen(fileName) > 4) &&
!strcasecmp(fileName + strlen(fileName) - 4, ".mp3");
}
unsigned long Adafruit_VS1053_FilePlayer::mp3_ID3Jumper(File mp3) {
@ -182,38 +193,37 @@ unsigned long Adafruit_VS1053_FilePlayer::mp3_ID3Jumper(File mp3) {
start = 0;
if (mp3) {
current = mp3.position();
current = mp3.position();
if (mp3.seek(0)) {
if (mp3.read((uint8_t*) tag,3)) {
tag[3] = '\0';
if (mp3.read((uint8_t *)tag, 3)) {
tag[3] = '\0';
if (!strcmp(tag, "ID3")) {
if (mp3.seek(6)) {
start = 0ul ;
for (byte i = 0 ; i < 4 ; i++) {
start <<= 7 ;
start |= (0x7F & mp3.read()) ;
}
start = 0ul;
for (byte i = 0; i < 4; i++) {
start <<= 7;
start |= (0x7F & mp3.read());
}
} else {
//Serial.println("Second seek failed?");
// Serial.println("Second seek failed?");
}
} else {
//Serial.println("It wasn't the damn TAG.");
// Serial.println("It wasn't the damn TAG.");
}
} else {
//Serial.println("Read for the tag failed");
// Serial.println("Read for the tag failed");
}
} else {
//Serial.println("Seek failed? How can seek fail?");
// Serial.println("Seek failed? How can seek fail?");
}
mp3.seek(current); // Put you things away like you found 'em.
mp3.seek(current); // Put you things away like you found 'em.
} else {
//Serial.println("They handed us a NULL file!");
// Serial.println("They handed us a NULL file!");
}
//Serial.print("Jumper returning: "); Serial.println(start);
// Serial.print("Jumper returning: "); Serial.println(start);
return start;
}
boolean Adafruit_VS1053_FilePlayer::startPlayingFile(const char *trackname) {
// reset playback
sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | VS1053_MODE_SM_SDINEW);
@ -235,16 +245,17 @@ boolean Adafruit_VS1053_FilePlayer::startPlayingFile(const char *trackname) {
// 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
// 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() ) {
while (!readyForData()) {
#if defined(ESP8266)
yield();
yield();
#endif
}
@ -279,9 +290,8 @@ void Adafruit_VS1053_FilePlayer::feedBuffer(void) {
}
void Adafruit_VS1053_FilePlayer::feedBuffer_noLock(void) {
if ((! playingMusic) // paused or stopped
|| (! currentTrack)
|| (! readyForData())) {
if ((!playingMusic) // paused or stopped
|| (!currentTrack) || (!readyForData())) {
return; // paused or stopped
}
@ -301,7 +311,6 @@ void Adafruit_VS1053_FilePlayer::feedBuffer_noLock(void) {
}
}
/***************************************************************/
/* VS1053 'low level' interface */
@ -309,7 +318,8 @@ static volatile PortReg *clkportreg, *misoportreg, *mosiportreg;
static PortMask clkpin, misopin, mosipin;
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) {
int8_t rst, int8_t cs, int8_t dcs,
int8_t dreq) {
_mosi = mosi;
_miso = miso;
_clk = clk;
@ -328,8 +338,8 @@ Adafruit_VS1053::Adafruit_VS1053(int8_t mosi, int8_t miso, int8_t clk,
mosipin = digitalPinToBitMask(_mosi);
}
Adafruit_VS1053::Adafruit_VS1053(int8_t rst, int8_t cs, int8_t dcs, int8_t dreq) {
Adafruit_VS1053::Adafruit_VS1053(int8_t rst, int8_t cs, int8_t dcs,
int8_t dreq) {
_mosi = 0;
_miso = 0;
_clk = 0;
@ -340,37 +350,35 @@ Adafruit_VS1053::Adafruit_VS1053(int8_t rst, int8_t cs, int8_t dcs, int8_t dreq)
_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 ) {
// 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);
// 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);
sciWrite(addr, val);
}
} else { // Copy run, copy n samples
} else { // Copy run, copy n samples
while (n--) {
val = pgm_read_word(patch++);
i++;
sciWrite(addr, val);
val = pgm_read_word(patch++);
i++;
sciWrite(addr, val);
}
}
}
}
uint16_t Adafruit_VS1053::loadPlugin(char *plugname) {
File plugin = SD.open(plugname);
@ -380,31 +388,32 @@ uint16_t Adafruit_VS1053::loadPlugin(char *plugname) {
return 0xFFFF;
}
if ((plugin.read() != 'P') ||
(plugin.read() != '&') ||
if ((plugin.read() != 'P') || (plugin.read() != '&') ||
(plugin.read() != 'H'))
return 0xFFFF;
uint16_t type;
// Serial.print("Patch size: "); Serial.println(patchsize);
// 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);
// Serial.print("type: "); Serial.println(type, HEX);
if (type >= 4) {
plugin.close();
return 0xFFFF;
plugin.close();
return 0xFFFF;
}
len = plugin.read(); len <<= 8;
len = plugin.read();
len <<= 8;
len |= plugin.read() & ~1;
addr = plugin.read(); addr <<= 8;
addr = plugin.read();
addr <<= 8;
addr |= plugin.read();
//Serial.print("len: "); Serial.print(len);
//Serial.print(" addr: $"); Serial.println(addr, HEX);
// Serial.print("len: "); Serial.print(len);
// Serial.print(" addr: $"); Serial.println(addr, HEX);
if (type == 3) {
// execute rec!
@ -417,35 +426,33 @@ uint16_t Adafruit_VS1053::loadPlugin(char *plugname) {
// write data
do {
uint16_t data;
data = plugin.read(); data <<= 8;
data = plugin.read();
data <<= 8;
data |= plugin.read();
sciWrite(VS1053_REG_WRAM, data);
} while ((len -=2));
} while ((len -= 2));
}
plugin.close();
return 0xFFFF;
}
boolean Adafruit_VS1053::readyForData(void) {
return digitalRead(_dreq);
}
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
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI)
SPI.beginTransaction(VS1053_DATA_SPI_SETTING);
#endif
digitalWrite(_dcs, LOW);
spiwrite(buffer, buffsiz);
digitalWrite(_dcs, HIGH);
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI) SPI.endTransaction();
#endif
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI)
SPI.endTransaction();
#endif
}
void Adafruit_VS1053::setVolume(uint8_t left, uint8_t right) {
@ -455,26 +462,26 @@ void Adafruit_VS1053::setVolume(uint8_t left, uint8_t right) {
v <<= 8;
v |= right;
noInterrupts(); //cli();
noInterrupts(); // cli();
sciWrite(VS1053_REG_VOLUME, v);
interrupts(); //sei();
interrupts(); // sei();
}
uint16_t Adafruit_VS1053::decodeTime() {
noInterrupts(); //cli();
noInterrupts(); // cli();
uint16_t t = sciRead(VS1053_REG_DECODETIME);
interrupts(); //sei();
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
// TODO:
// http://www.vlsi.fi/player_vs1011_1002_1003/modularplayer/vs10xx_8c.html#a3
// hardware reset
if (_reset >= 0) {
digitalWrite(_reset, LOW);
@ -504,7 +511,7 @@ uint8_t Adafruit_VS1053::begin(void) {
digitalWrite(_dcs, HIGH);
pinMode(_dreq, INPUT);
if (! useHardwareSPI) {
if (!useHardwareSPI) {
pinMode(_mosi, OUTPUT);
pinMode(_clk, OUTPUT);
pinMode(_miso, INPUT);
@ -523,13 +530,16 @@ uint8_t Adafruit_VS1053::begin(void) {
}
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);
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);
}
@ -538,15 +548,18 @@ 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_CLOCKF, 0xC000); // set max clock
delay(1);
while (!readyForData())
;
sciWrite(VS1053_REG_BASS, 0); // clear Bass
sciWrite(VS1053_REG_BASS, 0); // clear Bass
softReset();
delay(1); while (! readyForData() );
delay(1);
while (!readyForData())
;
sciWrite(VS1053_SCI_AIADDR, 0);
// disable all interrupts except SCI
@ -554,16 +567,17 @@ boolean Adafruit_VS1053::prepareRecordOgg(char *plugname) {
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;
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::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
@ -571,8 +585,8 @@ void Adafruit_VS1053::startRecordOgg(boolean mic) {
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_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 */
@ -583,11 +597,14 @@ void Adafruit_VS1053::startRecordOgg(boolean mic) {
sciWrite(VS1053_SCI_AICTRL3, 0);
sciWrite(VS1053_SCI_AIADDR, 0x34);
delay(1); while (! readyForData() );
delay(1);
while (!readyForData())
;
}
void Adafruit_VS1053::GPIO_pinMode(uint8_t i, uint8_t dir) {
if (i > 7) return;
if (i > 7)
return;
sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_DDR);
uint16_t ddr = sciRead(VS1053_REG_WRAM);
@ -601,14 +618,14 @@ void Adafruit_VS1053::GPIO_pinMode(uint8_t i, uint8_t dir) {
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;
if (i > 7)
return;
sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_ODATA);
uint16_t pins = sciRead(VS1053_REG_WRAM);
@ -628,20 +645,23 @@ uint16_t Adafruit_VS1053::GPIO_digitalRead(void) {
}
boolean Adafruit_VS1053::GPIO_digitalRead(uint8_t i) {
if (i > 7) return 0;
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;
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
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI)
SPI.beginTransaction(VS1053_CONTROL_SPI_SETTING);
#endif
digitalWrite(_cs, LOW);
spiwrite(VS1053_SCI_READ);
spiwrite(addr);
@ -650,45 +670,44 @@ uint16_t Adafruit_VS1053::sciRead(uint8_t addr) {
data <<= 8;
data |= spiread();
digitalWrite(_cs, HIGH);
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI) SPI.endTransaction();
#endif
#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
#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
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI)
SPI.endTransaction();
#endif
}
uint8_t Adafruit_VS1053::spiread(void)
{
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
// 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--) {
for (i = 7; i >= 0; i--) {
if ((*misoportreg) & misopin)
x |= (1<<i);
x |= (1 << i);
*clkportreg |= clkpin;
*clkportreg &= ~clkpin;
// asm("nop; nop");
@ -699,18 +718,15 @@ uint8_t Adafruit_VS1053::spiread(void)
return x;
}
void Adafruit_VS1053::spiwrite(uint8_t c)
{
void Adafruit_VS1053::spiwrite(uint8_t c) {
uint8_t x __attribute__ ((aligned (32))) = c;
uint8_t x __attribute__((aligned(32))) = c;
spiwrite(&x, 1);
}
void Adafruit_VS1053::spiwrite(uint8_t *c, uint16_t num)
{
// MSB first, clock low when inactive (CPOL 0), data valid on leading edge (CPHA 0)
// Make sure clock starts low
void Adafruit_VS1053::spiwrite(uint8_t *c, uint16_t num) {
// MSB first, clock low when inactive (CPOL 0), data valid on leading edge
// (CPHA 0) Make sure clock starts low
if (useHardwareSPI) {
@ -726,24 +742,22 @@ void Adafruit_VS1053::spiwrite(uint8_t *c, uint16_t num)
} else {
while (num--) {
for (int8_t i=7; i>=0; i--) {
*clkportreg &= ~clkpin;
if (c[0] & (1<<i)) {
*mosiportreg |= mosipin;
} else {
*mosiportreg &= ~mosipin;
}
*clkportreg |= clkpin;
for (int8_t i = 7; i >= 0; i--) {
*clkportreg &= ~clkpin;
if (c[0] & (1 << i)) {
*mosiportreg |= mosipin;
} else {
*mosiportreg &= ~mosipin;
}
*clkportreg |= clkpin;
}
*clkportreg &= ~clkpin; // Make sure clock ends low
*clkportreg &= ~clkpin; // Make sure clock ends low
c++;
}
}
}
void Adafruit_VS1053::sineTest(uint8_t n, uint16_t ms) {
reset();
@ -751,12 +765,14 @@ void Adafruit_VS1053::sineTest(uint8_t n, uint16_t ms) {
mode |= 0x0020;
sciWrite(VS1053_REG_MODE, mode);
while (!digitalRead(_dreq));
// delay(10);
while (!digitalRead(_dreq))
;
// delay(10);
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI) SPI.beginTransaction(VS1053_DATA_SPI_SETTING);
#endif
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI)
SPI.beginTransaction(VS1053_DATA_SPI_SETTING);
#endif
digitalWrite(_dcs, LOW);
spiwrite(0x53);
spiwrite(0xEF);
@ -767,15 +783,17 @@ void Adafruit_VS1053::sineTest(uint8_t n, uint16_t ms) {
spiwrite(0x00);
spiwrite(0x00);
digitalWrite(_dcs, HIGH);
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI) SPI.endTransaction();
#endif
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI)
SPI.endTransaction();
#endif
delay(ms);
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI) SPI.beginTransaction(VS1053_DATA_SPI_SETTING);
#endif
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI)
SPI.beginTransaction(VS1053_DATA_SPI_SETTING);
#endif
digitalWrite(_dcs, LOW);
spiwrite(0x45);
spiwrite(0x78);
@ -786,7 +804,8 @@ void Adafruit_VS1053::sineTest(uint8_t n, uint16_t ms) {
spiwrite(0x00);
spiwrite(0x00);
digitalWrite(_dcs, HIGH);
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI) SPI.endTransaction();
#endif
#ifdef SPI_HAS_TRANSACTION
if (useHardwareSPI)
SPI.endTransaction();
#endif
}

391
Adafruit_VS1053.h Executable file → Normal file
View file

@ -1,24 +1,15 @@
/***************************************************
This is a library for the Adafruit VS1053 Codec Breakout
/*!
* @file Adafruit_VS1053.h
*/
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
#if (ARDUINO >= 100)
#include <Arduino.h>
#include <Arduino.h>
#else
#include <WProgram.h>
#include <pins_arduino.h>
#include <WProgram.h>
#include <pins_arduino.h>
#endif
#if !defined(ARDUINO_STM32_FEATHER)
@ -28,165 +19,369 @@
#include <SPI.h>
#if defined(PREFER_SDFAT_LIBRARY)
#include <SdFat.h>
extern SdFat SD;
#include <SdFat.h>
extern SdFat SD;
#else
#include <SD.h>
#include <SD.h>
#endif
// define here the size of a register!
#if defined(ARDUINO_STM32_FEATHER)
typedef volatile uint32 RwReg;
typedef uint32_t PortMask;
typedef volatile uint32 RwReg;
typedef uint32_t PortMask;
#elif defined(ARDUINO_ARCH_AVR)
typedef volatile uint8_t RwReg;
typedef uint8_t PortMask;
#elif defined (__arm__)
#if defined(TEENSYDUINO)
typedef volatile uint8_t RwReg;
typedef uint8_t PortMask;
#else
typedef volatile uint32_t RwReg;
typedef uint32_t PortMask;
#endif
#elif defined (ESP8266) || defined (ESP32)
typedef volatile uint32_t RwReg;
typedef uint32_t PortMask;
#elif defined (__ARDUINO_ARC__)
typedef volatile uint32_t RwReg;
typedef uint32_t PortMask;
typedef volatile uint8_t RwReg;
typedef uint8_t PortMask;
#elif defined(__arm__)
#if defined(TEENSYDUINO)
typedef volatile uint8_t RwReg;
typedef uint8_t PortMask;
#else
typedef volatile uint8_t RwReg;
typedef uint8_t PortMask;
typedef volatile uint32_t RwReg;
typedef uint32_t PortMask;
#endif
#elif defined(ESP8266) || defined(ESP32)
typedef volatile uint32_t RwReg;
typedef uint32_t PortMask;
#elif defined(__ARDUINO_ARC__)
typedef volatile uint32_t RwReg;
typedef uint32_t PortMask;
#else
typedef volatile uint8_t RwReg; //!< 1-byte read-write register
typedef uint8_t PortMask;
#endif
typedef volatile RwReg PortReg;
#define VS1053_FILEPLAYER_TIMER0_INT 255 // allows useInterrupt to accept pins 0 to 254
#define VS1053_FILEPLAYER_PIN_INT 5
#define VS1053_FILEPLAYER_TIMER0_INT \
255 //!< Allows useInterrupt to accept pins 0 to 254
#define VS1053_FILEPLAYER_PIN_INT \
5 //!< Allows useInterrupt to accept pins 0 to 4
#define VS1053_SCI_READ 0x03
#define VS1053_SCI_WRITE 0x02
#define VS1053_SCI_READ 0x03 //!< Serial read address
#define VS1053_SCI_WRITE 0x02 //!< Serial write address
#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_REG_MODE 0x00 //!< Mode control
#define VS1053_REG_STATUS 0x01 //!< Status of VS1053b
#define VS1053_REG_BASS 0x02 //!< Built-in bass/treble control
#define VS1053_REG_CLOCKF 0x03 //!< Clock frequency + multiplier
#define VS1053_REG_DECODETIME 0x04 //!< Decode time in seconds
#define VS1053_REG_AUDATA 0x05 //!< Misc. audio data
#define VS1053_REG_WRAM 0x06 //!< RAM write/read
#define VS1053_REG_WRAMADDR 0x07 //!< Base address for RAM write/read
#define VS1053_REG_HDAT0 0x08 //!< Stream header data 0
#define VS1053_REG_HDAT1 0x09 //!< Stream header data 1
#define VS1053_REG_VOLUME 0x0B //!< Volume control
#define VS1053_GPIO_DDR 0xC017
#define VS1053_GPIO_IDATA 0xC018
#define VS1053_GPIO_ODATA 0xC019
#define VS1053_GPIO_DDR 0xC017 //!< Direction
#define VS1053_GPIO_IDATA 0xC018 //!< Values read from pins
#define VS1053_GPIO_ODATA 0xC019 //!< Values set to the pins
#define VS1053_INT_ENABLE 0xC01A
#define VS1053_INT_ENABLE 0xC01A //!< Interrupt enable
#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_MODE_SM_DIFF \
0x0001 //!< Differential, 0: normal in-phase audio, 1: left channel inverted
#define VS1053_MODE_SM_LAYER12 0x0002 //!< Allow MPEG layers I & II
#define VS1053_MODE_SM_RESET 0x0004 //!< Soft reset
#define VS1053_MODE_SM_CANCEL 0x0008 //!< Cancel decoding current file
#define VS1053_MODE_SM_EARSPKLO 0x0010 //!< EarSpeaker low setting
#define VS1053_MODE_SM_TESTS 0x0020 //!< Allow SDI tests
#define VS1053_MODE_SM_STREAM 0x0040 //!< Stream mode
#define VS1053_MODE_SM_SDINEW 0x0800 //!< VS1002 native SPI modes
#define VS1053_MODE_SM_ADPCM 0x1000 //!< PCM/ADPCM recording active
#define VS1053_MODE_SM_LINE1 0x4000 //!< MIC/LINE1 selector, 0: MICP, 1: LINE1
#define VS1053_MODE_SM_CLKRANGE \
0x8000 //!< Input clock range, 0: 12..13 MHz, 1: 24..26 MHz
#define VS1053_SCI_AIADDR \
0x0A //!< Indicates the start address of the application code written earlier
//!< with SCI_WRAMADDR and SCI_WRAM registers.
#define VS1053_SCI_AICTRL0 \
0x0C //!< SCI_AICTRL register 0. Used to access the user's application program
#define VS1053_SCI_AICTRL1 \
0x0D //!< SCI_AICTRL register 1. Used to access the user's application program
#define VS1053_SCI_AICTRL2 \
0x0E //!< SCI_AICTRL register 2. Used to access the user's application program
#define VS1053_SCI_AICTRL3 \
0x0F //!< SCI_AICTRL register 3. Used to access the user's application program
#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
#define VS1053_DATABUFFERLEN 32 //!< Length of the data buffer
/*!
* Driver for the Adafruit VS1053
*/
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);
public:
/*!
* @brief Software SPI constructor - must specify all pins
* @param mosi MOSI (Microcontroller Out Serial In) pin
* @param miso MISO (Microcontroller In Serial Out) pin
* @param clk Clock pin
* @param rst Reset pin
* @param cs SCI Chip Select pin
* @param dcs SDI Chip Select pin
* @param dreq Data Request pin
*/
Adafruit_VS1053(int8_t mosi, int8_t miso, int8_t clk, int8_t rst, int8_t cs,
int8_t dcs, int8_t dreq);
/*!
* @brief Hardware SPI constructor - assumes hardware SPI pins
* @param rst Reset pin
* @param cs SCI Chip Select pin
* @param dcs SDI Chip Select pin
* @param dreq Data Request pin
*/
Adafruit_VS1053(int8_t rst, int8_t cs, int8_t dcs, int8_t dreq);
/*!
* @brief Initialize communication and (hard) reset the chip.
* @return Returns true if a VS1053 is found
*/
uint8_t begin(void);
/*!
* @brief Performs a hard reset of the chip
*/
void reset(void);
/*!
* @brief Attempts a soft reset of the chip
*/
void softReset(void);
/*!
* @brief Reads from the specified register on the chip
* @param addr Register address to read from
* @return Retuns the 16-bit data corresponding to the received address
*/
uint16_t sciRead(uint8_t addr);
/*!
* @brief Writes to the specified register on the chip
* @param addr Register address to write to
* @param data Data to write
*/
void sciWrite(uint8_t addr, uint16_t data);
/*!
* @brief Generate a sine-wave test signal
* @param n Defines the sine test to use
* @param ms Delay (in ms)
*/
void sineTest(uint8_t n, uint16_t ms);
/*!
* @brief Low-level SPI write operation
* @param d What to write
*/
void spiwrite(uint8_t d);
/*!
* @brief Low-level SPI write operation
*/
void spiwrite(uint8_t *c, uint16_t num);
/*!
* @brief Low-level SPI read operation
* @return Returns a byte read from SPI
*/
uint8_t spiread(void);
/*!
* @brief Reads the DECODETIME register from the chip
* @return Returns the decode time as an unsigned 16-bit integer
*/
uint16_t decodeTime(void);
/*!
* @brief Set the output volume for the chip
* @param left Desired left channel volume
* @param right Desired right channel volume
*/
void setVolume(uint8_t left, uint8_t right);
/*!
* @brief Prints the contents of the MODE, STATUS, CLOCKF and VOLUME registers
*/
void dumpRegs(void);
/*!
* @brief Decode and play the contents of the supplied buffer
* @param buffer Buffer to decode and play
* @param buffsiz Size to decode and play
*/
void playData(uint8_t *buffer, uint8_t buffsiz);
/*!
* @brief Test if ready for more data
* @return Returns true if it is ready for data
*/
boolean readyForData(void);
/*!
* @brief Apply a code patch
* @param patch Patch to apply
* @param patchsize Patch size
*/
void applyPatch(const uint16_t *patch, uint16_t patchsize);
/*!
* @brief Load the specified plug-in
* @param fn Plug-in to load
*/
uint16_t loadPlugin(char *fn);
/*!
* @brief Write to a GPIO pin
* @param i GPIO pin to write to
* @param val Value to write
*/
void GPIO_digitalWrite(uint8_t i, uint8_t val);
/*!
* @brief Write to all 8 GPIO pins at once
* @param i Value to write
*/
void GPIO_digitalWrite(uint8_t i);
/*!
* @brief Read all 8 GPIO pins at once
* @return Returns a 2 byte value with the reads from the 8 pins
*/
uint16_t GPIO_digitalRead(void);
/*!
* @brief Read a single GPIO pin
* @param i pin to read
* @return Returns the state of the specified GPIO pin
*/
boolean GPIO_digitalRead(uint8_t i);
/*!
* @brief Set the Pin Mode (INPUT/OUTPUT) for a GPIO pin.
* @param i Pin to set the mode for
* @param dir Mode to set
*/
void GPIO_pinMode(uint8_t i, uint8_t dir);
/*!
* @brief Initialize chip for OGG recording
* @param plugin Binary file of the plugin to use
* @return Returns true if the device is ready to record
*/
boolean prepareRecordOgg(char *plugin);
/*!
* @brief Start recording
* @param mic mic=true for microphone input
*/
void startRecordOgg(boolean mic);
/*!
* @brief Stop the recording
*/
void stopRecordOgg(void);
/*!
* @brief Returns the number of words recorded
* @return 2-byte unsigned int with the number of words
*/
uint16_t recordedWordsWaiting(void);
/*!
* @brief Reads the next word from the buffer of recorded words
* @return Returns the 16-bit data corresponding to the received address
*/
uint16_t recordedReadWord(void);
uint8_t mp3buffer[VS1053_DATABUFFERLEN];
uint8_t mp3buffer[VS1053_DATABUFFERLEN]; //!< mp3 buffer that gets sent to the
//!< device
#ifdef ARDUINO_ARCH_SAMD
protected:
uint32_t _dreq;
uint32_t _dreq;
private:
int32_t _mosi, _miso, _clk, _reset, _cs, _dcs;
boolean useHardwareSPI;
#else
protected:
uint8_t _dreq;
private:
protected:
uint8_t _dreq; //!< Data request pin
private:
int8_t _mosi, _miso, _clk, _reset, _cs, _dcs;
boolean useHardwareSPI;
#endif
};
/*!
* @brief File player for the Adafruit VS1053
*/
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);
public:
/*!
* @brief Software SPI constructor. Uses Software SPI, so you must specify all
* SPI pins
* @param mosi MOSI (Microcontroller Out Serial In) pin
* @param miso MISO (Microcontroller In Serial Out) pin
* @param clk Clock pin
* @param rst Reset pin
* @param cs SCI Chip Select pin
* @param dcs SDI Chip Select pin
* @param dreq Data Request pin
*/
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);
/*!
* @brief Hardware SPI constructor. Uses Hardware SPI and assumes the default
* SPI pins
* @param rst Reset pin
* @param cs SCI Chip Select pin
* @param dcs SDI Chip Select pin
* @param dreq Data Request pin
*/
Adafruit_VS1053_FilePlayer(int8_t rst, int8_t cs, int8_t dcs, int8_t dreq,
int8_t cardCS);
/*!
* @brief Hardware SPI constructor. Uses Hardware SPI and assumes the default
* SPI pins
* @param cs SCI Chip Select pin
* @param dcs SDI Chip Select pin
* @param dreq Data Request pin
*/
Adafruit_VS1053_FilePlayer(int8_t cs, int8_t dcs, int8_t dreq, int8_t cardCS);
/*!
* @brief Initialize communication and reset the chip.
* @return Returns true if a VS1053 is found
*/
boolean begin(void);
/*!
* @brief Specifies the argument to use for interrupt-driven playback
* @param type interrupt to use. Valid arguments are
* VS1053_FILEPLAYER_TIMER0_INT and VS1053_FILEPLAYER_PIN_INT
*/
boolean useInterrupt(uint8_t type);
File currentTrack;
volatile boolean playingMusic;
File currentTrack; //!< File that is currently playing
volatile boolean playingMusic; //!< Whether or not music is playing
void feedBuffer(void);
static boolean isMP3File(const char* fileName);
/*!
* @brief Checks if the inputted filename is an mp3
* @param fileName File to check
* @return Returns true or false
*/
static boolean isMP3File(const char *fileName);
unsigned long mp3_ID3Jumper(File mp3);
/*!
* @brief Begin playing the specified file from the SD card using
* interrupt-drive playback.
* @param *trackname File to play
* @return Returns true when file starts playing
*/
boolean startPlayingFile(const char *trackname);
/*!
* @brief Play the complete file. This function will not return until the
* playback is complete
* @param *trackname File to play
* @return Returns true when file starts playing
*/
boolean playFullFile(const char *trackname);
void stopPlaying(void);
void stopPlaying(void); //!< Stop playback
/*!
* @brief If playback is paused
* @return Returns true if playback is paused
*/
boolean paused(void);
/*!
* @brief If playback is stopped
* @return Returns true if playback is stopped
*/
boolean stopped(void);
/*!
* @brief Pause playback
* @param pause whether or not to pause playback
*/
void pausePlaying(boolean pause);
private:
private:
void feedBuffer_noLock(void);
uint8_t _cardCS;

View file

@ -1,3 +1,5 @@
# Adafruit VS1053 Breakout [![Build Status](https://github.com/adafruit/Adafruit_VS1053_Library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_VS1053_Library/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_VS1053_Library/html/index.html)
This is a library for the Adafruit VS1053 Codec Breakout
Designed specifically to work with the Adafruit VS1053 Codec Breakout

View file

@ -1,5 +1,5 @@
name=Adafruit VS1053 Library
version=1.0.8
version=1.1.0
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=This is a library for the Adafruit VS1053 Codec Breakout and Music Maker Shields