Moved to actions, doxygen
This commit is contained in:
parent
b52c4e3cda
commit
59f20a104f
6 changed files with 544 additions and 330 deletions
32
.github/workflows/githubci.yml
vendored
Normal file
32
.github/workflows/githubci.yml
vendored
Normal 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
|
||||
34
.travis.yml
34
.travis.yml
|
|
@ -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)
|
||||
|
|
@ -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
391
Adafruit_VS1053.h
Executable file → Normal 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;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# Adafruit VS1053 Breakout [](https://github.com/adafruit/Adafruit_VS1053_Library/actions)[](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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue