-
Notifications
You must be signed in to change notification settings - Fork 113
/
Adafruit_VS1053.h
423 lines (394 loc) · 13.9 KB
/
Adafruit_VS1053.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
/*!
* @file Adafruit_VS1053.h
*/
#ifndef ADAFRUIT_VS1053_H
#define ADAFRUIT_VS1053_H
#if (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#include <pins_arduino.h>
#endif
#if !defined(ARDUINO_STM32_FEATHER)
#include "pins_arduino.h"
#include "wiring_private.h"
#endif
#include <Adafruit_SPIDevice.h>
#if defined(PREFER_SDFAT_LIBRARY)
#include <SdFat.h>
extern SdFat SD;
#else
#include <SD.h>
#endif
// define here the size of a register!
#if defined(ARDUINO_STM32_FEATHER)
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;
#else
typedef volatile uint8_t RwReg; //!< 1-byte read-write register
typedef uint8_t PortMask; //!< Type definition for a bitmask that is used to
//!< specify the bit width
#endif
typedef volatile RwReg PortReg; //!< Type definition/alias used to specify the
//!< port register that a pin is in
#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 //!< Serial read address
#define VS1053_SCI_WRITE 0x02 //!< Serial write address
#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 //!< 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 //!< Interrupt enable
#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_WRAM 0x06 //!< RAM write/read
#define VS1053_SCI_WRAMADDR 0x07 //!< Base address for RAM write/read
#define VS1053_PARA_PLAYSPEED 0x1E04 //!< 0,1 = normal speed, 2 = 2x, 3 = 3x etc
#define VS1053_DATABUFFERLEN 32 //!< Length of the data buffer
/*!
* Driver for the Adafruit VS1053
*/
class Adafruit_VS1053 {
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 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
* @return Either returns 0xFFFF if there is an error, or the address of the
* plugin that was loaded
*/
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]; //!< mp3 buffer that gets sent to the
//!< device
#ifdef ARDUINO_ARCH_SAMD
protected:
uint32_t _dreq;
private:
Adafruit_SPIDevice *spi_dev_ctrl = NULL; ///< Pointer to SPI dev for control
Adafruit_SPIDevice *spi_dev_data = NULL; ///< Pointer to SPI dev for data
int32_t _mosi, _miso, _clk, _reset, _cs, _dcs;
boolean useHardwareSPI;
#else
protected:
uint8_t _dreq; //!< Data request pin
private:
Adafruit_SPIDevice *spi_dev_ctrl = NULL; ///< Pointer to SPI dev for control
Adafruit_SPIDevice *spi_dev_data = NULL; ///< Pointer to SPI dev for data
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:
/*!
* @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
* @param cardCS CS pin for the SD card on the SPI bus
*/
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
* @param cardCS CS pin for the SD card on the SPI bus
*/
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
* @param cardCS CS pin for the SD card on the SPI bus
*/
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
* @return Returs true/false for success/failure
*/
boolean useInterrupt(uint8_t type);
File currentTrack; //!< File that is currently playing
volatile boolean playingMusic; //!< Whether or not music is playing
/*!
* @brief Feeds the buffer. Reads mp3 file data from the SD card and file and
* puts it into the buffer that the decoder reads from to play a file
*/
void feedBuffer(void);
/*!
* @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);
/*!
* @brief Checks for an ID3 tag at the beginning of the file.
* @param mp3 File to read
* @return returns the seek position within the file where the mp3 data starts
*/
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); //!< 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);
/*!
* @brief Set state for playback looping
* @param loopState Sets playback loop state (Note: Only use with
* startPlayingFile, if used with playFullFile no subsequent code in the
* sketch executes)
*/
void playbackLoop(boolean loopState);
/*!
* @brief Retrieve playback loop state
* @return Returns true when looped playback is enabled
*/
boolean playbackLooped();
/*!
* @brief Determine current playback speed
* @return Returns playback speed, i.e. 1 for 1x, 2 for 2x, 3 for 3x
*/
uint16_t getPlaySpeed();
/*!
* @brief Set playback speed
* @param speed Set playback speed, i.e. 1 for 1x, 2 for 2x, 3 for 3x
*/
void setPlaySpeed(uint16_t speed);
private:
void feedBuffer_noLock(void);
uint8_t _cardCS;
};
#endif // ADAFRUIT_VS1053_H