gg

Dependencies:   mbed SDFileSystem

Committer:
Priunsh_N
Date:
Mon Oct 31 17:12:17 2016 +0000
Revision:
0:1d6e44094672
gg

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Priunsh_N 0:1d6e44094672 1 /***************************************************
Priunsh_N 0:1d6e44094672 2 This is a library for the Adafruit VS1053 Codec Breakout
Priunsh_N 0:1d6e44094672 3
Priunsh_N 0:1d6e44094672 4 Designed specifically to work with the Adafruit VS1053 Codec Breakout
Priunsh_N 0:1d6e44094672 5 ----> https://www.adafruit.com/products/1381
Priunsh_N 0:1d6e44094672 6
Priunsh_N 0:1d6e44094672 7 Adafruit invests time and resources providing this open source code,
Priunsh_N 0:1d6e44094672 8 please support Adafruit and open-source hardware by purchasing
Priunsh_N 0:1d6e44094672 9 products from Adafruit!
Priunsh_N 0:1d6e44094672 10
Priunsh_N 0:1d6e44094672 11 Written by Limor Fried/Ladyada for Adafruit Industries.
Priunsh_N 0:1d6e44094672 12 BSD license, all text above must be included in any redistribution
Priunsh_N 0:1d6e44094672 13 ****************************************************/
Priunsh_N 0:1d6e44094672 14
Priunsh_N 0:1d6e44094672 15 #include <Adafruit_VS1053.h>
Priunsh_N 0:1d6e44094672 16 #include <SD.h>
Priunsh_N 0:1d6e44094672 17
Priunsh_N 0:1d6e44094672 18 static Adafruit_VS1053_FilePlayer *myself;
Priunsh_N 0:1d6e44094672 19
Priunsh_N 0:1d6e44094672 20 #ifndef _BV
Priunsh_N 0:1d6e44094672 21 #define _BV(x) (1<<(x))
Priunsh_N 0:1d6e44094672 22 #endif
Priunsh_N 0:1d6e44094672 23
Priunsh_N 0:1d6e44094672 24 #if defined(__AVR__)
Priunsh_N 0:1d6e44094672 25 SIGNAL(TIMER0_COMPA_vect) {
Priunsh_N 0:1d6e44094672 26 myself->feedBuffer();
Priunsh_N 0:1d6e44094672 27 }
Priunsh_N 0:1d6e44094672 28 #endif
Priunsh_N 0:1d6e44094672 29
Priunsh_N 0:1d6e44094672 30 static void feeder(void) {
Priunsh_N 0:1d6e44094672 31 myself->feedBuffer();
Priunsh_N 0:1d6e44094672 32 }
Priunsh_N 0:1d6e44094672 33
Priunsh_N 0:1d6e44094672 34 #define VS1053_CONTROL_SPI_SETTING SPISettings(250000, MSBFIRST, SPI_MODE0)
Priunsh_N 0:1d6e44094672 35 #define VS1053_DATA_SPI_SETTING SPISettings(8000000, MSBFIRST, SPI_MODE0)
Priunsh_N 0:1d6e44094672 36
Priunsh_N 0:1d6e44094672 37
Priunsh_N 0:1d6e44094672 38 static const uint8_t dreqinttable[] = {
Priunsh_N 0:1d6e44094672 39 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega8__)
Priunsh_N 0:1d6e44094672 40 2, 0,
Priunsh_N 0:1d6e44094672 41 3, 1,
Priunsh_N 0:1d6e44094672 42 #elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
Priunsh_N 0:1d6e44094672 43 2, 0,
Priunsh_N 0:1d6e44094672 44 3, 1,
Priunsh_N 0:1d6e44094672 45 21, 2,
Priunsh_N 0:1d6e44094672 46 20, 3,
Priunsh_N 0:1d6e44094672 47 19, 4,
Priunsh_N 0:1d6e44094672 48 18, 5,
Priunsh_N 0:1d6e44094672 49 #elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
Priunsh_N 0:1d6e44094672 50 5, 0,
Priunsh_N 0:1d6e44094672 51 6, 1,
Priunsh_N 0:1d6e44094672 52 7, 2,
Priunsh_N 0:1d6e44094672 53 8, 3,
Priunsh_N 0:1d6e44094672 54 #elif defined(__AVR_AT90USB1286__) && defined(CORE_TEENSY)
Priunsh_N 0:1d6e44094672 55 0, 0,
Priunsh_N 0:1d6e44094672 56 1, 1,
Priunsh_N 0:1d6e44094672 57 2, 2,
Priunsh_N 0:1d6e44094672 58 3, 3,
Priunsh_N 0:1d6e44094672 59 36, 4,
Priunsh_N 0:1d6e44094672 60 37, 5,
Priunsh_N 0:1d6e44094672 61 18, 6,
Priunsh_N 0:1d6e44094672 62 19, 7,
Priunsh_N 0:1d6e44094672 63 #elif defined(__arm__) && defined(CORE_TEENSY)
Priunsh_N 0:1d6e44094672 64 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
Priunsh_N 0:1d6e44094672 65 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
Priunsh_N 0:1d6e44094672 66 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
Priunsh_N 0:1d6e44094672 67 15, 15, 16, 16, 17, 17, 18, 18, 19, 19,
Priunsh_N 0:1d6e44094672 68 20, 20, 21, 21, 22, 22, 23, 23, 24, 24,
Priunsh_N 0:1d6e44094672 69 25, 25, 26, 26, 27, 27, 28, 28, 29, 29,
Priunsh_N 0:1d6e44094672 70 30, 30, 31, 31, 32, 32, 33, 33,
Priunsh_N 0:1d6e44094672 71 #elif defined(__AVR_ATmega32U4__)
Priunsh_N 0:1d6e44094672 72 3, 0,
Priunsh_N 0:1d6e44094672 73 2, 1,
Priunsh_N 0:1d6e44094672 74 0, 2,
Priunsh_N 0:1d6e44094672 75 1, 3,
Priunsh_N 0:1d6e44094672 76 7, 4,
Priunsh_N 0:1d6e44094672 77 #elif defined(__AVR_ATmega256RFR2__)
Priunsh_N 0:1d6e44094672 78 4, 0,
Priunsh_N 0:1d6e44094672 79 5, 1,
Priunsh_N 0:1d6e44094672 80 #elif defined(__SAM3X8E__) || defined(ARDUINO_ARCH_SAMD)
Priunsh_N 0:1d6e44094672 81 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
Priunsh_N 0:1d6e44094672 82 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
Priunsh_N 0:1d6e44094672 83 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
Priunsh_N 0:1d6e44094672 84 15, 15, 16, 16, 17, 17, 18, 18, 19, 19,
Priunsh_N 0:1d6e44094672 85 20, 20, 21, 21, 22, 22, 23, 23, 24, 24,
Priunsh_N 0:1d6e44094672 86 25, 25, 26, 26, 27, 27, 28, 28, 29, 29,
Priunsh_N 0:1d6e44094672 87 30, 30, 31, 31, 32, 32, 33, 33,
Priunsh_N 0:1d6e44094672 88
Priunsh_N 0:1d6e44094672 89 #endif
Priunsh_N 0:1d6e44094672 90 };
Priunsh_N 0:1d6e44094672 91
Priunsh_N 0:1d6e44094672 92 boolean Adafruit_VS1053_FilePlayer::useInterrupt(uint8_t type) {
Priunsh_N 0:1d6e44094672 93 myself = this; // oy vey
Priunsh_N 0:1d6e44094672 94
Priunsh_N 0:1d6e44094672 95 if (type == VS1053_FILEPLAYER_TIMER0_INT) {
Priunsh_N 0:1d6e44094672 96 #if defined(__AVR__)
Priunsh_N 0:1d6e44094672 97 OCR0A = 0xAF;
Priunsh_N 0:1d6e44094672 98 TIMSK0 |= _BV(OCIE0A);
Priunsh_N 0:1d6e44094672 99 return true;
Priunsh_N 0:1d6e44094672 100 #elif defined(__arm__) && defined(CORE_TEENSY)
Priunsh_N 0:1d6e44094672 101 IntervalTimer *t = new IntervalTimer();
Priunsh_N 0:1d6e44094672 102 return (t && t->begin(feeder, 1024)) ? true : false;
Priunsh_N 0:1d6e44094672 103 #else
Priunsh_N 0:1d6e44094672 104 return false;
Priunsh_N 0:1d6e44094672 105 #endif
Priunsh_N 0:1d6e44094672 106 }
Priunsh_N 0:1d6e44094672 107 if (type == VS1053_FILEPLAYER_PIN_INT) {
Priunsh_N 0:1d6e44094672 108 for (uint8_t i=0; i<sizeof(dreqinttable); i+=2) {
Priunsh_N 0:1d6e44094672 109 //Serial.println(dreqinttable[i]);
Priunsh_N 0:1d6e44094672 110 if (_dreq == dreqinttable[i]) {
Priunsh_N 0:1d6e44094672 111 #ifdef SPI_HAS_TRANSACTION
Priunsh_N 0:1d6e44094672 112 SPI.usingInterrupt(dreqinttable[i+1]);
Priunsh_N 0:1d6e44094672 113 #endif
Priunsh_N 0:1d6e44094672 114 attachInterrupt(dreqinttable[i+1], feeder, CHANGE);
Priunsh_N 0:1d6e44094672 115 return true;
Priunsh_N 0:1d6e44094672 116 }
Priunsh_N 0:1d6e44094672 117 }
Priunsh_N 0:1d6e44094672 118 }
Priunsh_N 0:1d6e44094672 119 return false;
Priunsh_N 0:1d6e44094672 120 }
Priunsh_N 0:1d6e44094672 121
Priunsh_N 0:1d6e44094672 122 Adafruit_VS1053_FilePlayer::Adafruit_VS1053_FilePlayer(
Priunsh_N 0:1d6e44094672 123 int8_t rst, int8_t cs, int8_t dcs, int8_t dreq,
Priunsh_N 0:1d6e44094672 124 int8_t cardcs)
Priunsh_N 0:1d6e44094672 125 : Adafruit_VS1053(rst, cs, dcs, dreq) {
Priunsh_N 0:1d6e44094672 126
Priunsh_N 0:1d6e44094672 127 playingMusic = false;
Priunsh_N 0:1d6e44094672 128
Priunsh_N 0:1d6e44094672 129 // Set the card to be disabled while we get the VS1053 up
Priunsh_N 0:1d6e44094672 130 pinMode(_cardCS, OUTPUT);
Priunsh_N 0:1d6e44094672 131 digitalWrite(_cardCS, HIGH);
Priunsh_N 0:1d6e44094672 132 }
Priunsh_N 0:1d6e44094672 133
Priunsh_N 0:1d6e44094672 134 Adafruit_VS1053_FilePlayer::Adafruit_VS1053_FilePlayer(
Priunsh_N 0:1d6e44094672 135 int8_t cs, int8_t dcs, int8_t dreq,
Priunsh_N 0:1d6e44094672 136 int8_t cardcs)
Priunsh_N 0:1d6e44094672 137 : Adafruit_VS1053(-1, cs, dcs, dreq) {
Priunsh_N 0:1d6e44094672 138
Priunsh_N 0:1d6e44094672 139 playingMusic = false;
Priunsh_N 0:1d6e44094672 140
Priunsh_N 0:1d6e44094672 141 // Set the card to be disabled while we get the VS1053 up
Priunsh_N 0:1d6e44094672 142 pinMode(_cardCS, OUTPUT);
Priunsh_N 0:1d6e44094672 143 digitalWrite(_cardCS, HIGH);
Priunsh_N 0:1d6e44094672 144 }
Priunsh_N 0:1d6e44094672 145
Priunsh_N 0:1d6e44094672 146
Priunsh_N 0:1d6e44094672 147 Adafruit_VS1053_FilePlayer::Adafruit_VS1053_FilePlayer(
Priunsh_N 0:1d6e44094672 148 int8_t mosi, int8_t miso, int8_t clk,
Priunsh_N 0:1d6e44094672 149 int8_t rst, int8_t cs, int8_t dcs, int8_t dreq,
Priunsh_N 0:1d6e44094672 150 int8_t cardcs)
Priunsh_N 0:1d6e44094672 151 : Adafruit_VS1053(mosi, miso, clk, rst, cs, dcs, dreq) {
Priunsh_N 0:1d6e44094672 152
Priunsh_N 0:1d6e44094672 153 playingMusic = false;
Priunsh_N 0:1d6e44094672 154
Priunsh_N 0:1d6e44094672 155 // Set the card to be disabled while we get the VS1053 up
Priunsh_N 0:1d6e44094672 156 pinMode(_cardCS, OUTPUT);
Priunsh_N 0:1d6e44094672 157 digitalWrite(_cardCS, HIGH);
Priunsh_N 0:1d6e44094672 158 }
Priunsh_N 0:1d6e44094672 159
Priunsh_N 0:1d6e44094672 160 boolean Adafruit_VS1053_FilePlayer::begin(void) {
Priunsh_N 0:1d6e44094672 161 uint8_t v = Adafruit_VS1053::begin();
Priunsh_N 0:1d6e44094672 162
Priunsh_N 0:1d6e44094672 163 //dumpRegs();
Priunsh_N 0:1d6e44094672 164 //Serial.print("Version = "); Serial.println(v);
Priunsh_N 0:1d6e44094672 165 return (v == 4);
Priunsh_N 0:1d6e44094672 166 }
Priunsh_N 0:1d6e44094672 167
Priunsh_N 0:1d6e44094672 168
Priunsh_N 0:1d6e44094672 169 boolean Adafruit_VS1053_FilePlayer::playFullFile(const char *trackname) {
Priunsh_N 0:1d6e44094672 170 if (! startPlayingFile(trackname)) return false;
Priunsh_N 0:1d6e44094672 171
Priunsh_N 0:1d6e44094672 172 while (playingMusic) {
Priunsh_N 0:1d6e44094672 173 // twiddle thumbs
Priunsh_N 0:1d6e44094672 174 feedBuffer();
Priunsh_N 0:1d6e44094672 175 }
Priunsh_N 0:1d6e44094672 176 // music file finished!
Priunsh_N 0:1d6e44094672 177 return true;
Priunsh_N 0:1d6e44094672 178 }
Priunsh_N 0:1d6e44094672 179
Priunsh_N 0:1d6e44094672 180 void Adafruit_VS1053_FilePlayer::stopPlaying(void) {
Priunsh_N 0:1d6e44094672 181 // cancel all playback
Priunsh_N 0:1d6e44094672 182 sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | VS1053_MODE_SM_SDINEW | VS1053_MODE_SM_CANCEL);
Priunsh_N 0:1d6e44094672 183
Priunsh_N 0:1d6e44094672 184 // wrap it up!
Priunsh_N 0:1d6e44094672 185 playingMusic = false;
Priunsh_N 0:1d6e44094672 186 currentTrack.close();
Priunsh_N 0:1d6e44094672 187 }
Priunsh_N 0:1d6e44094672 188
Priunsh_N 0:1d6e44094672 189 void Adafruit_VS1053_FilePlayer::pausePlaying(boolean pause) {
Priunsh_N 0:1d6e44094672 190 if (pause)
Priunsh_N 0:1d6e44094672 191 playingMusic = false;
Priunsh_N 0:1d6e44094672 192 else {
Priunsh_N 0:1d6e44094672 193 playingMusic = true;
Priunsh_N 0:1d6e44094672 194 feedBuffer();
Priunsh_N 0:1d6e44094672 195 }
Priunsh_N 0:1d6e44094672 196 }
Priunsh_N 0:1d6e44094672 197
Priunsh_N 0:1d6e44094672 198 boolean Adafruit_VS1053_FilePlayer::paused(void) {
Priunsh_N 0:1d6e44094672 199 return (!playingMusic && currentTrack);
Priunsh_N 0:1d6e44094672 200 }
Priunsh_N 0:1d6e44094672 201
Priunsh_N 0:1d6e44094672 202 boolean Adafruit_VS1053_FilePlayer::stopped(void) {
Priunsh_N 0:1d6e44094672 203 return (!playingMusic && !currentTrack);
Priunsh_N 0:1d6e44094672 204 }
Priunsh_N 0:1d6e44094672 205
Priunsh_N 0:1d6e44094672 206
Priunsh_N 0:1d6e44094672 207 boolean Adafruit_VS1053_FilePlayer::startPlayingFile(const char *trackname) {
Priunsh_N 0:1d6e44094672 208 // reset playback
Priunsh_N 0:1d6e44094672 209 sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | VS1053_MODE_SM_SDINEW);
Priunsh_N 0:1d6e44094672 210 // resync
Priunsh_N 0:1d6e44094672 211 sciWrite(VS1053_REG_WRAMADDR, 0x1e29);
Priunsh_N 0:1d6e44094672 212 sciWrite(VS1053_REG_WRAM, 0);
Priunsh_N 0:1d6e44094672 213
Priunsh_N 0:1d6e44094672 214 currentTrack = SD.open(trackname);
Priunsh_N 0:1d6e44094672 215 if (!currentTrack) {
Priunsh_N 0:1d6e44094672 216 return false;
Priunsh_N 0:1d6e44094672 217 }
Priunsh_N 0:1d6e44094672 218
Priunsh_N 0:1d6e44094672 219 // As explained in datasheet, set twice 0 in REG_DECODETIME to set time back to 0
Priunsh_N 0:1d6e44094672 220 sciWrite(VS1053_REG_DECODETIME, 0x00);
Priunsh_N 0:1d6e44094672 221 sciWrite(VS1053_REG_DECODETIME, 0x00);
Priunsh_N 0:1d6e44094672 222
Priunsh_N 0:1d6e44094672 223
Priunsh_N 0:1d6e44094672 224 playingMusic = true;
Priunsh_N 0:1d6e44094672 225
Priunsh_N 0:1d6e44094672 226 // wait till its ready for data
Priunsh_N 0:1d6e44094672 227 while (! readyForData() );
Priunsh_N 0:1d6e44094672 228
Priunsh_N 0:1d6e44094672 229
Priunsh_N 0:1d6e44094672 230 // fill it up!
Priunsh_N 0:1d6e44094672 231 while (playingMusic && readyForData())
Priunsh_N 0:1d6e44094672 232 feedBuffer();
Priunsh_N 0:1d6e44094672 233
Priunsh_N 0:1d6e44094672 234 // Serial.println("Ready");
Priunsh_N 0:1d6e44094672 235
Priunsh_N 0:1d6e44094672 236 return true;
Priunsh_N 0:1d6e44094672 237 }
Priunsh_N 0:1d6e44094672 238
Priunsh_N 0:1d6e44094672 239 void Adafruit_VS1053_FilePlayer::feedBuffer(void) {
Priunsh_N 0:1d6e44094672 240 static uint8_t running = 0;
Priunsh_N 0:1d6e44094672 241 uint8_t sregsave;
Priunsh_N 0:1d6e44094672 242
Priunsh_N 0:1d6e44094672 243 #if !defined (__SAM3X8E__) && !defined (ARDUINO_ARCH_SAMD)
Priunsh_N 0:1d6e44094672 244 // Do not allow 2 copies of this code to run concurrently.
Priunsh_N 0:1d6e44094672 245 // If an interrupt causes feedBuffer() to run while another
Priunsh_N 0:1d6e44094672 246 // copy of feedBuffer() is already running in the main
Priunsh_N 0:1d6e44094672 247 // program, havoc can occur. "running" detects this state
Priunsh_N 0:1d6e44094672 248 // and safely returns.
Priunsh_N 0:1d6e44094672 249 sregsave = SREG;
Priunsh_N 0:1d6e44094672 250 cli();
Priunsh_N 0:1d6e44094672 251 if (running) {
Priunsh_N 0:1d6e44094672 252 SREG = sregsave;
Priunsh_N 0:1d6e44094672 253 return; // return safely, before touching hardware! :-)
Priunsh_N 0:1d6e44094672 254 } else {
Priunsh_N 0:1d6e44094672 255 running = 1;
Priunsh_N 0:1d6e44094672 256 SREG = sregsave;
Priunsh_N 0:1d6e44094672 257 }
Priunsh_N 0:1d6e44094672 258 #endif
Priunsh_N 0:1d6e44094672 259
Priunsh_N 0:1d6e44094672 260 if (! playingMusic) {
Priunsh_N 0:1d6e44094672 261 running = 0;
Priunsh_N 0:1d6e44094672 262 return; // paused or stopped
Priunsh_N 0:1d6e44094672 263 }
Priunsh_N 0:1d6e44094672 264 if (! currentTrack) {
Priunsh_N 0:1d6e44094672 265 running = 0;
Priunsh_N 0:1d6e44094672 266 return;
Priunsh_N 0:1d6e44094672 267 }
Priunsh_N 0:1d6e44094672 268 if (! readyForData()) {
Priunsh_N 0:1d6e44094672 269 running = 0;
Priunsh_N 0:1d6e44094672 270 return;
Priunsh_N 0:1d6e44094672 271 }
Priunsh_N 0:1d6e44094672 272
Priunsh_N 0:1d6e44094672 273 // Feed the hungry buffer! :)
Priunsh_N 0:1d6e44094672 274 while (readyForData()) {
Priunsh_N 0:1d6e44094672 275 //UDR0 = '.';
Priunsh_N 0:1d6e44094672 276
Priunsh_N 0:1d6e44094672 277 // Read some audio data from the SD card file
Priunsh_N 0:1d6e44094672 278 int bytesread = currentTrack.read(mp3buffer, VS1053_DATABUFFERLEN);
Priunsh_N 0:1d6e44094672 279
Priunsh_N 0:1d6e44094672 280 if (bytesread == 0) {
Priunsh_N 0:1d6e44094672 281 // must be at the end of the file, wrap it up!
Priunsh_N 0:1d6e44094672 282 playingMusic = false;
Priunsh_N 0:1d6e44094672 283 currentTrack.close();
Priunsh_N 0:1d6e44094672 284 running = 0;
Priunsh_N 0:1d6e44094672 285 return;
Priunsh_N 0:1d6e44094672 286 }
Priunsh_N 0:1d6e44094672 287 playData(mp3buffer, bytesread);
Priunsh_N 0:1d6e44094672 288 }
Priunsh_N 0:1d6e44094672 289 running = 0;
Priunsh_N 0:1d6e44094672 290 return;
Priunsh_N 0:1d6e44094672 291 }
Priunsh_N 0:1d6e44094672 292
Priunsh_N 0:1d6e44094672 293
Priunsh_N 0:1d6e44094672 294 /***************************************************************/
Priunsh_N 0:1d6e44094672 295
Priunsh_N 0:1d6e44094672 296 /* VS1053 'low level' interface */
Priunsh_N 0:1d6e44094672 297 #ifdef ARDUINO_ARCH_SAMD
Priunsh_N 0:1d6e44094672 298 static volatile uint32_t *clkportreg, *misoportreg, *mosiportreg;
Priunsh_N 0:1d6e44094672 299 static uint32_t clkpin, misopin, mosipin;
Priunsh_N 0:1d6e44094672 300 #else
Priunsh_N 0:1d6e44094672 301 static volatile PortReg *clkportreg, *misoportreg, *mosiportreg;
Priunsh_N 0:1d6e44094672 302 static PortMask clkpin, misopin, mosipin;
Priunsh_N 0:1d6e44094672 303 #endif
Priunsh_N 0:1d6e44094672 304
Priunsh_N 0:1d6e44094672 305 Adafruit_VS1053::Adafruit_VS1053(int8_t mosi, int8_t miso, int8_t clk,
Priunsh_N 0:1d6e44094672 306 int8_t rst, int8_t cs, int8_t dcs, int8_t dreq) {
Priunsh_N 0:1d6e44094672 307 _mosi = mosi;
Priunsh_N 0:1d6e44094672 308 _miso = miso;
Priunsh_N 0:1d6e44094672 309 _clk = clk;
Priunsh_N 0:1d6e44094672 310 _reset = rst;
Priunsh_N 0:1d6e44094672 311 _cs = cs;
Priunsh_N 0:1d6e44094672 312 _dcs = dcs;
Priunsh_N 0:1d6e44094672 313 _dreq = dreq;
Priunsh_N 0:1d6e44094672 314
Priunsh_N 0:1d6e44094672 315 useHardwareSPI = false;
Priunsh_N 0:1d6e44094672 316
Priunsh_N 0:1d6e44094672 317 clkportreg = portOutputRegister(digitalPinToPort(_clk));
Priunsh_N 0:1d6e44094672 318 clkpin = digitalPinToBitMask(_clk);
Priunsh_N 0:1d6e44094672 319 misoportreg = portInputRegister(digitalPinToPort(_miso));
Priunsh_N 0:1d6e44094672 320 misopin = digitalPinToBitMask(_miso);
Priunsh_N 0:1d6e44094672 321 mosiportreg = portOutputRegister(digitalPinToPort(_mosi));
Priunsh_N 0:1d6e44094672 322 mosipin = digitalPinToBitMask(_mosi);
Priunsh_N 0:1d6e44094672 323 }
Priunsh_N 0:1d6e44094672 324
Priunsh_N 0:1d6e44094672 325
Priunsh_N 0:1d6e44094672 326 Adafruit_VS1053::Adafruit_VS1053(int8_t rst, int8_t cs, int8_t dcs, int8_t dreq) {
Priunsh_N 0:1d6e44094672 327 _mosi = 0;
Priunsh_N 0:1d6e44094672 328 _miso = 0;
Priunsh_N 0:1d6e44094672 329 _clk = 0;
Priunsh_N 0:1d6e44094672 330 useHardwareSPI = true;
Priunsh_N 0:1d6e44094672 331 _reset = rst;
Priunsh_N 0:1d6e44094672 332 _cs = cs;
Priunsh_N 0:1d6e44094672 333 _dcs = dcs;
Priunsh_N 0:1d6e44094672 334 _dreq = dreq;
Priunsh_N 0:1d6e44094672 335 }
Priunsh_N 0:1d6e44094672 336
Priunsh_N 0:1d6e44094672 337
Priunsh_N 0:1d6e44094672 338 void Adafruit_VS1053::applyPatch(const uint16_t *patch, uint16_t patchsize) {
Priunsh_N 0:1d6e44094672 339 uint16_t i = 0;
Priunsh_N 0:1d6e44094672 340
Priunsh_N 0:1d6e44094672 341 // Serial.print("Patch size: "); Serial.println(patchsize);
Priunsh_N 0:1d6e44094672 342 while ( i < patchsize ) {
Priunsh_N 0:1d6e44094672 343 uint16_t addr, n, val;
Priunsh_N 0:1d6e44094672 344
Priunsh_N 0:1d6e44094672 345 addr = pgm_read_word(patch++);
Priunsh_N 0:1d6e44094672 346 n = pgm_read_word(patch++);
Priunsh_N 0:1d6e44094672 347 i += 2;
Priunsh_N 0:1d6e44094672 348
Priunsh_N 0:1d6e44094672 349 //Serial.println(addr, HEX);
Priunsh_N 0:1d6e44094672 350 if (n & 0x8000U) { // RLE run, replicate n samples
Priunsh_N 0:1d6e44094672 351 n &= 0x7FFF;
Priunsh_N 0:1d6e44094672 352 val = pgm_read_word(patch++);
Priunsh_N 0:1d6e44094672 353 i++;
Priunsh_N 0:1d6e44094672 354 while (n--) {
Priunsh_N 0:1d6e44094672 355 sciWrite(addr, val);
Priunsh_N 0:1d6e44094672 356 }
Priunsh_N 0:1d6e44094672 357 } else { // Copy run, copy n samples
Priunsh_N 0:1d6e44094672 358 while (n--) {
Priunsh_N 0:1d6e44094672 359 val = pgm_read_word(patch++);
Priunsh_N 0:1d6e44094672 360 i++;
Priunsh_N 0:1d6e44094672 361 sciWrite(addr, val);
Priunsh_N 0:1d6e44094672 362 }
Priunsh_N 0:1d6e44094672 363 }
Priunsh_N 0:1d6e44094672 364 }
Priunsh_N 0:1d6e44094672 365 }
Priunsh_N 0:1d6e44094672 366
Priunsh_N 0:1d6e44094672 367
Priunsh_N 0:1d6e44094672 368 uint16_t Adafruit_VS1053::loadPlugin(char *plugname) {
Priunsh_N 0:1d6e44094672 369
Priunsh_N 0:1d6e44094672 370 File plugin = SD.open(plugname);
Priunsh_N 0:1d6e44094672 371 if (!plugin) {
Priunsh_N 0:1d6e44094672 372 Serial.println("Couldn't open the plugin file");
Priunsh_N 0:1d6e44094672 373 Serial.println(plugin);
Priunsh_N 0:1d6e44094672 374 return 0xFFFF;
Priunsh_N 0:1d6e44094672 375 }
Priunsh_N 0:1d6e44094672 376
Priunsh_N 0:1d6e44094672 377 if ((plugin.read() != 'P') ||
Priunsh_N 0:1d6e44094672 378 (plugin.read() != '&') ||
Priunsh_N 0:1d6e44094672 379 (plugin.read() != 'H'))
Priunsh_N 0:1d6e44094672 380 return 0xFFFF;
Priunsh_N 0:1d6e44094672 381
Priunsh_N 0:1d6e44094672 382 uint16_t type;
Priunsh_N 0:1d6e44094672 383
Priunsh_N 0:1d6e44094672 384 // Serial.print("Patch size: "); Serial.println(patchsize);
Priunsh_N 0:1d6e44094672 385 while ((type = plugin.read()) >= 0) {
Priunsh_N 0:1d6e44094672 386 uint16_t offsets[] = {0x8000UL, 0x0, 0x4000UL};
Priunsh_N 0:1d6e44094672 387 uint16_t addr, len;
Priunsh_N 0:1d6e44094672 388
Priunsh_N 0:1d6e44094672 389 //Serial.print("type: "); Serial.println(type, HEX);
Priunsh_N 0:1d6e44094672 390
Priunsh_N 0:1d6e44094672 391 if (type >= 4) {
Priunsh_N 0:1d6e44094672 392 plugin.close();
Priunsh_N 0:1d6e44094672 393 return 0xFFFF;
Priunsh_N 0:1d6e44094672 394 }
Priunsh_N 0:1d6e44094672 395
Priunsh_N 0:1d6e44094672 396 len = plugin.read(); len <<= 8;
Priunsh_N 0:1d6e44094672 397 len |= plugin.read() & ~1;
Priunsh_N 0:1d6e44094672 398 addr = plugin.read(); addr <<= 8;
Priunsh_N 0:1d6e44094672 399 addr |= plugin.read();
Priunsh_N 0:1d6e44094672 400 //Serial.print("len: "); Serial.print(len);
Priunsh_N 0:1d6e44094672 401 //Serial.print(" addr: $"); Serial.println(addr, HEX);
Priunsh_N 0:1d6e44094672 402
Priunsh_N 0:1d6e44094672 403 if (type == 3) {
Priunsh_N 0:1d6e44094672 404 // execute rec!
Priunsh_N 0:1d6e44094672 405 plugin.close();
Priunsh_N 0:1d6e44094672 406 return addr;
Priunsh_N 0:1d6e44094672 407 }
Priunsh_N 0:1d6e44094672 408
Priunsh_N 0:1d6e44094672 409 // set address
Priunsh_N 0:1d6e44094672 410 sciWrite(VS1053_REG_WRAMADDR, addr + offsets[type]);
Priunsh_N 0:1d6e44094672 411 // write data
Priunsh_N 0:1d6e44094672 412 do {
Priunsh_N 0:1d6e44094672 413 uint16_t data;
Priunsh_N 0:1d6e44094672 414 data = plugin.read(); data <<= 8;
Priunsh_N 0:1d6e44094672 415 data |= plugin.read();
Priunsh_N 0:1d6e44094672 416 sciWrite(VS1053_REG_WRAM, data);
Priunsh_N 0:1d6e44094672 417 } while ((len -=2));
Priunsh_N 0:1d6e44094672 418 }
Priunsh_N 0:1d6e44094672 419
Priunsh_N 0:1d6e44094672 420 plugin.close();
Priunsh_N 0:1d6e44094672 421 return 0xFFFF;
Priunsh_N 0:1d6e44094672 422 }
Priunsh_N 0:1d6e44094672 423
Priunsh_N 0:1d6e44094672 424
Priunsh_N 0:1d6e44094672 425
Priunsh_N 0:1d6e44094672 426
Priunsh_N 0:1d6e44094672 427 boolean Adafruit_VS1053::readyForData(void) {
Priunsh_N 0:1d6e44094672 428 return digitalRead(_dreq);
Priunsh_N 0:1d6e44094672 429 }
Priunsh_N 0:1d6e44094672 430
Priunsh_N 0:1d6e44094672 431 void Adafruit_VS1053::playData(uint8_t *buffer, uint8_t buffsiz) {
Priunsh_N 0:1d6e44094672 432 #ifdef SPI_HAS_TRANSACTION
Priunsh_N 0:1d6e44094672 433 if (useHardwareSPI) SPI.beginTransaction(VS1053_DATA_SPI_SETTING);
Priunsh_N 0:1d6e44094672 434 #endif
Priunsh_N 0:1d6e44094672 435 digitalWrite(_dcs, LOW);
Priunsh_N 0:1d6e44094672 436 for (uint8_t i=0; i<buffsiz; i++) {
Priunsh_N 0:1d6e44094672 437 spiwrite(buffer[i]);
Priunsh_N 0:1d6e44094672 438 }
Priunsh_N 0:1d6e44094672 439 digitalWrite(_dcs, HIGH);
Priunsh_N 0:1d6e44094672 440 #ifdef SPI_HAS_TRANSACTION
Priunsh_N 0:1d6e44094672 441 if (useHardwareSPI) SPI.endTransaction();
Priunsh_N 0:1d6e44094672 442 #endif
Priunsh_N 0:1d6e44094672 443 }
Priunsh_N 0:1d6e44094672 444
Priunsh_N 0:1d6e44094672 445 void Adafruit_VS1053::setVolume(uint8_t left, uint8_t right) {
Priunsh_N 0:1d6e44094672 446 uint16_t v;
Priunsh_N 0:1d6e44094672 447 v = left;
Priunsh_N 0:1d6e44094672 448 v <<= 8;
Priunsh_N 0:1d6e44094672 449 v |= right;
Priunsh_N 0:1d6e44094672 450
Priunsh_N 0:1d6e44094672 451 noInterrupts(); //cli();
Priunsh_N 0:1d6e44094672 452 sciWrite(VS1053_REG_VOLUME, v);
Priunsh_N 0:1d6e44094672 453 interrupts(); //sei();
Priunsh_N 0:1d6e44094672 454 }
Priunsh_N 0:1d6e44094672 455
Priunsh_N 0:1d6e44094672 456 uint16_t Adafruit_VS1053::decodeTime() {
Priunsh_N 0:1d6e44094672 457 noInterrupts(); //cli();
Priunsh_N 0:1d6e44094672 458 uint16_t t = sciRead(VS1053_REG_DECODETIME);
Priunsh_N 0:1d6e44094672 459 interrupts(); //sei();
Priunsh_N 0:1d6e44094672 460 return t;
Priunsh_N 0:1d6e44094672 461 }
Priunsh_N 0:1d6e44094672 462
Priunsh_N 0:1d6e44094672 463
Priunsh_N 0:1d6e44094672 464 void Adafruit_VS1053::softReset(void) {
Priunsh_N 0:1d6e44094672 465 sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_SDINEW | VS1053_MODE_SM_RESET);
Priunsh_N 0:1d6e44094672 466 delay(100);
Priunsh_N 0:1d6e44094672 467 }
Priunsh_N 0:1d6e44094672 468
Priunsh_N 0:1d6e44094672 469 void Adafruit_VS1053::reset() {
Priunsh_N 0:1d6e44094672 470 // TODO: http://www.vlsi.fi/player_vs1011_1002_1003/modularplayer/vs10xx_8c.html#a3
Priunsh_N 0:1d6e44094672 471 // hardware reset
Priunsh_N 0:1d6e44094672 472 if (_reset >= 0) {
Priunsh_N 0:1d6e44094672 473 digitalWrite(_reset, LOW);
Priunsh_N 0:1d6e44094672 474 delay(100);
Priunsh_N 0:1d6e44094672 475 digitalWrite(_reset, HIGH);
Priunsh_N 0:1d6e44094672 476 }
Priunsh_N 0:1d6e44094672 477 digitalWrite(_cs, HIGH);
Priunsh_N 0:1d6e44094672 478 digitalWrite(_dcs, HIGH);
Priunsh_N 0:1d6e44094672 479 delay(100);
Priunsh_N 0:1d6e44094672 480 softReset();
Priunsh_N 0:1d6e44094672 481 delay(100);
Priunsh_N 0:1d6e44094672 482
Priunsh_N 0:1d6e44094672 483 sciWrite(VS1053_REG_CLOCKF, 0x6000);
Priunsh_N 0:1d6e44094672 484
Priunsh_N 0:1d6e44094672 485 setVolume(40, 40);
Priunsh_N 0:1d6e44094672 486 }
Priunsh_N 0:1d6e44094672 487
Priunsh_N 0:1d6e44094672 488 uint8_t Adafruit_VS1053::begin(void) {
Priunsh_N 0:1d6e44094672 489 if (_reset >= 0) {
Priunsh_N 0:1d6e44094672 490 pinMode(_reset, OUTPUT);
Priunsh_N 0:1d6e44094672 491 digitalWrite(_reset, LOW);
Priunsh_N 0:1d6e44094672 492 }
Priunsh_N 0:1d6e44094672 493
Priunsh_N 0:1d6e44094672 494 pinMode(_cs, OUTPUT);
Priunsh_N 0:1d6e44094672 495 digitalWrite(_cs, HIGH);
Priunsh_N 0:1d6e44094672 496 pinMode(_dcs, OUTPUT);
Priunsh_N 0:1d6e44094672 497 digitalWrite(_dcs, HIGH);
Priunsh_N 0:1d6e44094672 498 pinMode(_dreq, INPUT);
Priunsh_N 0:1d6e44094672 499
Priunsh_N 0:1d6e44094672 500 if (! useHardwareSPI) {
Priunsh_N 0:1d6e44094672 501 pinMode(_mosi, OUTPUT);
Priunsh_N 0:1d6e44094672 502 pinMode(_clk, OUTPUT);
Priunsh_N 0:1d6e44094672 503 pinMode(_miso, INPUT);
Priunsh_N 0:1d6e44094672 504 } else {
Priunsh_N 0:1d6e44094672 505 SPI.begin();
Priunsh_N 0:1d6e44094672 506 SPI.setDataMode(SPI_MODE0);
Priunsh_N 0:1d6e44094672 507 SPI.setBitOrder(MSBFIRST);
Priunsh_N 0:1d6e44094672 508 SPI.setClockDivider(SPI_CLOCK_DIV128);
Priunsh_N 0:1d6e44094672 509 }
Priunsh_N 0:1d6e44094672 510
Priunsh_N 0:1d6e44094672 511 reset();
Priunsh_N 0:1d6e44094672 512
Priunsh_N 0:1d6e44094672 513 return (sciRead(VS1053_REG_STATUS) >> 4) & 0x0F;
Priunsh_N 0:1d6e44094672 514 }
Priunsh_N 0:1d6e44094672 515
Priunsh_N 0:1d6e44094672 516 void Adafruit_VS1053::dumpRegs(void) {
Priunsh_N 0:1d6e44094672 517 Serial.print("Mode = 0x"); Serial.println(sciRead(VS1053_REG_MODE), HEX);
Priunsh_N 0:1d6e44094672 518 Serial.print("Stat = 0x"); Serial.println(sciRead(VS1053_REG_STATUS), HEX);
Priunsh_N 0:1d6e44094672 519 Serial.print("ClkF = 0x"); Serial.println(sciRead(VS1053_REG_CLOCKF), HEX);
Priunsh_N 0:1d6e44094672 520 Serial.print("Vol. = 0x"); Serial.println(sciRead(VS1053_REG_VOLUME), HEX);
Priunsh_N 0:1d6e44094672 521 }
Priunsh_N 0:1d6e44094672 522
Priunsh_N 0:1d6e44094672 523
Priunsh_N 0:1d6e44094672 524 uint16_t Adafruit_VS1053::recordedWordsWaiting(void) {
Priunsh_N 0:1d6e44094672 525 return sciRead(VS1053_REG_HDAT1);
Priunsh_N 0:1d6e44094672 526 }
Priunsh_N 0:1d6e44094672 527
Priunsh_N 0:1d6e44094672 528 uint16_t Adafruit_VS1053::recordedReadWord(void) {
Priunsh_N 0:1d6e44094672 529 return sciRead(VS1053_REG_HDAT0);
Priunsh_N 0:1d6e44094672 530 }
Priunsh_N 0:1d6e44094672 531
Priunsh_N 0:1d6e44094672 532
Priunsh_N 0:1d6e44094672 533 boolean Adafruit_VS1053::prepareRecordOgg(char *plugname) {
Priunsh_N 0:1d6e44094672 534 sciWrite(VS1053_REG_CLOCKF, 0xC000); // set max clock
Priunsh_N 0:1d6e44094672 535 delay(1); while (! readyForData() );
Priunsh_N 0:1d6e44094672 536
Priunsh_N 0:1d6e44094672 537 sciWrite(VS1053_REG_BASS, 0); // clear Bass
Priunsh_N 0:1d6e44094672 538
Priunsh_N 0:1d6e44094672 539 softReset();
Priunsh_N 0:1d6e44094672 540 delay(1); while (! readyForData() );
Priunsh_N 0:1d6e44094672 541
Priunsh_N 0:1d6e44094672 542 sciWrite(VS1053_SCI_AIADDR, 0);
Priunsh_N 0:1d6e44094672 543 // disable all interrupts except SCI
Priunsh_N 0:1d6e44094672 544 sciWrite(VS1053_REG_WRAMADDR, VS1053_INT_ENABLE);
Priunsh_N 0:1d6e44094672 545 sciWrite(VS1053_REG_WRAM, 0x02);
Priunsh_N 0:1d6e44094672 546
Priunsh_N 0:1d6e44094672 547 int pluginStartAddr = loadPlugin(plugname);
Priunsh_N 0:1d6e44094672 548 if (pluginStartAddr == 0xFFFF) return false;
Priunsh_N 0:1d6e44094672 549 Serial.print("Plugin at $"); Serial.println(pluginStartAddr, HEX);
Priunsh_N 0:1d6e44094672 550 if (pluginStartAddr != 0x34) return false;
Priunsh_N 0:1d6e44094672 551
Priunsh_N 0:1d6e44094672 552 return true;
Priunsh_N 0:1d6e44094672 553 }
Priunsh_N 0:1d6e44094672 554
Priunsh_N 0:1d6e44094672 555 void Adafruit_VS1053::stopRecordOgg(void) {
Priunsh_N 0:1d6e44094672 556 sciWrite(VS1053_SCI_AICTRL3, 1);
Priunsh_N 0:1d6e44094672 557 }
Priunsh_N 0:1d6e44094672 558
Priunsh_N 0:1d6e44094672 559 void Adafruit_VS1053::startRecordOgg(boolean mic) {
Priunsh_N 0:1d6e44094672 560 /* Set VS1053 mode bits as instructed in the VS1053b Ogg Vorbis Encoder
Priunsh_N 0:1d6e44094672 561 manual. Note: for microphone input, leave SMF_LINE1 unset! */
Priunsh_N 0:1d6e44094672 562 if (mic) {
Priunsh_N 0:1d6e44094672 563 sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_ADPCM | VS1053_MODE_SM_SDINEW);
Priunsh_N 0:1d6e44094672 564 } else {
Priunsh_N 0:1d6e44094672 565 sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 |
Priunsh_N 0:1d6e44094672 566 VS1053_MODE_SM_ADPCM | VS1053_MODE_SM_SDINEW);
Priunsh_N 0:1d6e44094672 567 }
Priunsh_N 0:1d6e44094672 568 sciWrite(VS1053_SCI_AICTRL0, 1024);
Priunsh_N 0:1d6e44094672 569 /* Rec level: 1024 = 1. If 0, use AGC */
Priunsh_N 0:1d6e44094672 570 sciWrite(VS1053_SCI_AICTRL1, 1024);
Priunsh_N 0:1d6e44094672 571 /* Maximum AGC level: 1024 = 1. Only used if SCI_AICTRL1 is set to 0. */
Priunsh_N 0:1d6e44094672 572 sciWrite(VS1053_SCI_AICTRL2, 0);
Priunsh_N 0:1d6e44094672 573 /* Miscellaneous bits that also must be set before recording. */
Priunsh_N 0:1d6e44094672 574 sciWrite(VS1053_SCI_AICTRL3, 0);
Priunsh_N 0:1d6e44094672 575
Priunsh_N 0:1d6e44094672 576 sciWrite(VS1053_SCI_AIADDR, 0x34);
Priunsh_N 0:1d6e44094672 577 delay(1); while (! readyForData() );
Priunsh_N 0:1d6e44094672 578 }
Priunsh_N 0:1d6e44094672 579
Priunsh_N 0:1d6e44094672 580 void Adafruit_VS1053::GPIO_pinMode(uint8_t i, uint8_t dir) {
Priunsh_N 0:1d6e44094672 581 if (i > 7) return;
Priunsh_N 0:1d6e44094672 582
Priunsh_N 0:1d6e44094672 583 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_DDR);
Priunsh_N 0:1d6e44094672 584 uint16_t ddr = sciRead(VS1053_REG_WRAM);
Priunsh_N 0:1d6e44094672 585
Priunsh_N 0:1d6e44094672 586 if (dir == INPUT)
Priunsh_N 0:1d6e44094672 587 ddr &= ~_BV(i);
Priunsh_N 0:1d6e44094672 588 if (dir == OUTPUT)
Priunsh_N 0:1d6e44094672 589 ddr |= _BV(i);
Priunsh_N 0:1d6e44094672 590
Priunsh_N 0:1d6e44094672 591 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_DDR);
Priunsh_N 0:1d6e44094672 592 sciWrite(VS1053_REG_WRAM, ddr);
Priunsh_N 0:1d6e44094672 593 }
Priunsh_N 0:1d6e44094672 594
Priunsh_N 0:1d6e44094672 595
Priunsh_N 0:1d6e44094672 596 void Adafruit_VS1053::GPIO_digitalWrite(uint8_t val) {
Priunsh_N 0:1d6e44094672 597 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_ODATA);
Priunsh_N 0:1d6e44094672 598 sciWrite(VS1053_REG_WRAM, val);
Priunsh_N 0:1d6e44094672 599 }
Priunsh_N 0:1d6e44094672 600
Priunsh_N 0:1d6e44094672 601 void Adafruit_VS1053::GPIO_digitalWrite(uint8_t i, uint8_t val) {
Priunsh_N 0:1d6e44094672 602 if (i > 7) return;
Priunsh_N 0:1d6e44094672 603
Priunsh_N 0:1d6e44094672 604 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_ODATA);
Priunsh_N 0:1d6e44094672 605 uint16_t pins = sciRead(VS1053_REG_WRAM);
Priunsh_N 0:1d6e44094672 606
Priunsh_N 0:1d6e44094672 607 if (val == LOW)
Priunsh_N 0:1d6e44094672 608 pins &= ~_BV(i);
Priunsh_N 0:1d6e44094672 609 if (val == HIGH)
Priunsh_N 0:1d6e44094672 610 pins |= _BV(i);
Priunsh_N 0:1d6e44094672 611
Priunsh_N 0:1d6e44094672 612 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_ODATA);
Priunsh_N 0:1d6e44094672 613 sciWrite(VS1053_REG_WRAM, pins);
Priunsh_N 0:1d6e44094672 614 }
Priunsh_N 0:1d6e44094672 615
Priunsh_N 0:1d6e44094672 616 uint16_t Adafruit_VS1053::GPIO_digitalRead(void) {
Priunsh_N 0:1d6e44094672 617 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_IDATA);
Priunsh_N 0:1d6e44094672 618 return sciRead(VS1053_REG_WRAM) & 0xFF;
Priunsh_N 0:1d6e44094672 619 }
Priunsh_N 0:1d6e44094672 620
Priunsh_N 0:1d6e44094672 621 boolean Adafruit_VS1053::GPIO_digitalRead(uint8_t i) {
Priunsh_N 0:1d6e44094672 622 if (i > 7) return 0;
Priunsh_N 0:1d6e44094672 623
Priunsh_N 0:1d6e44094672 624 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_IDATA);
Priunsh_N 0:1d6e44094672 625 uint16_t val = sciRead(VS1053_REG_WRAM);
Priunsh_N 0:1d6e44094672 626 if (val & _BV(i)) return true;
Priunsh_N 0:1d6e44094672 627 return false;
Priunsh_N 0:1d6e44094672 628 }
Priunsh_N 0:1d6e44094672 629
Priunsh_N 0:1d6e44094672 630 uint16_t Adafruit_VS1053::sciRead(uint8_t addr) {
Priunsh_N 0:1d6e44094672 631 uint16_t data;
Priunsh_N 0:1d6e44094672 632
Priunsh_N 0:1d6e44094672 633 #ifdef SPI_HAS_TRANSACTION
Priunsh_N 0:1d6e44094672 634 if (useHardwareSPI) SPI.beginTransaction(VS1053_CONTROL_SPI_SETTING);
Priunsh_N 0:1d6e44094672 635 #endif
Priunsh_N 0:1d6e44094672 636 digitalWrite(_cs, LOW);
Priunsh_N 0:1d6e44094672 637 spiwrite(VS1053_SCI_READ);
Priunsh_N 0:1d6e44094672 638 spiwrite(addr);
Priunsh_N 0:1d6e44094672 639 delayMicroseconds(10);
Priunsh_N 0:1d6e44094672 640 data = spiread();
Priunsh_N 0:1d6e44094672 641 data <<= 8;
Priunsh_N 0:1d6e44094672 642 data |= spiread();
Priunsh_N 0:1d6e44094672 643 digitalWrite(_cs, HIGH);
Priunsh_N 0:1d6e44094672 644 #ifdef SPI_HAS_TRANSACTION
Priunsh_N 0:1d6e44094672 645 if (useHardwareSPI) SPI.endTransaction();
Priunsh_N 0:1d6e44094672 646 #endif
Priunsh_N 0:1d6e44094672 647
Priunsh_N 0:1d6e44094672 648 return data;
Priunsh_N 0:1d6e44094672 649 }
Priunsh_N 0:1d6e44094672 650
Priunsh_N 0:1d6e44094672 651
Priunsh_N 0:1d6e44094672 652 void Adafruit_VS1053::sciWrite(uint8_t addr, uint16_t data) {
Priunsh_N 0:1d6e44094672 653 #ifdef SPI_HAS_TRANSACTION
Priunsh_N 0:1d6e44094672 654 if (useHardwareSPI) SPI.beginTransaction(VS1053_CONTROL_SPI_SETTING);
Priunsh_N 0:1d6e44094672 655 #endif
Priunsh_N 0:1d6e44094672 656 digitalWrite(_cs, LOW);
Priunsh_N 0:1d6e44094672 657 spiwrite(VS1053_SCI_WRITE);
Priunsh_N 0:1d6e44094672 658 spiwrite(addr);
Priunsh_N 0:1d6e44094672 659 spiwrite(data >> 8);
Priunsh_N 0:1d6e44094672 660 spiwrite(data & 0xFF);
Priunsh_N 0:1d6e44094672 661 digitalWrite(_cs, HIGH);
Priunsh_N 0:1d6e44094672 662 #ifdef SPI_HAS_TRANSACTION
Priunsh_N 0:1d6e44094672 663 if (useHardwareSPI) SPI.endTransaction();
Priunsh_N 0:1d6e44094672 664 #endif
Priunsh_N 0:1d6e44094672 665 }
Priunsh_N 0:1d6e44094672 666
Priunsh_N 0:1d6e44094672 667
Priunsh_N 0:1d6e44094672 668
Priunsh_N 0:1d6e44094672 669 uint8_t Adafruit_VS1053::spiread(void)
Priunsh_N 0:1d6e44094672 670 {
Priunsh_N 0:1d6e44094672 671 int8_t i, x;
Priunsh_N 0:1d6e44094672 672 x = 0;
Priunsh_N 0:1d6e44094672 673
Priunsh_N 0:1d6e44094672 674 // MSB first, clock low when inactive (CPOL 0), data valid on leading edge (CPHA 0)
Priunsh_N 0:1d6e44094672 675 // Make sure clock starts low
Priunsh_N 0:1d6e44094672 676
Priunsh_N 0:1d6e44094672 677 if (useHardwareSPI) {
Priunsh_N 0:1d6e44094672 678 x = SPI.transfer(0x00);
Priunsh_N 0:1d6e44094672 679 } else {
Priunsh_N 0:1d6e44094672 680 for (i=7; i>=0; i--) {
Priunsh_N 0:1d6e44094672 681 if ((*misoportreg) & misopin)
Priunsh_N 0:1d6e44094672 682 x |= (1<<i);
Priunsh_N 0:1d6e44094672 683 *clkportreg |= clkpin;
Priunsh_N 0:1d6e44094672 684 *clkportreg &= ~clkpin;
Priunsh_N 0:1d6e44094672 685 // asm("nop; nop");
Priunsh_N 0:1d6e44094672 686 }
Priunsh_N 0:1d6e44094672 687 // Make sure clock ends low
Priunsh_N 0:1d6e44094672 688 *clkportreg &= ~clkpin;
Priunsh_N 0:1d6e44094672 689 }
Priunsh_N 0:1d6e44094672 690 return x;
Priunsh_N 0:1d6e44094672 691 }
Priunsh_N 0:1d6e44094672 692
Priunsh_N 0:1d6e44094672 693 void Adafruit_VS1053::spiwrite(uint8_t c)
Priunsh_N 0:1d6e44094672 694 {
Priunsh_N 0:1d6e44094672 695 // MSB first, clock low when inactive (CPOL 0), data valid on leading edge (CPHA 0)
Priunsh_N 0:1d6e44094672 696 // Make sure clock starts low
Priunsh_N 0:1d6e44094672 697
Priunsh_N 0:1d6e44094672 698 if (useHardwareSPI) {
Priunsh_N 0:1d6e44094672 699 SPI.transfer(c);
Priunsh_N 0:1d6e44094672 700
Priunsh_N 0:1d6e44094672 701 } else {
Priunsh_N 0:1d6e44094672 702 for (int8_t i=7; i>=0; i--) {
Priunsh_N 0:1d6e44094672 703 *clkportreg &= ~clkpin;
Priunsh_N 0:1d6e44094672 704 if (c & (1<<i)) {
Priunsh_N 0:1d6e44094672 705 *mosiportreg |= mosipin;
Priunsh_N 0:1d6e44094672 706 } else {
Priunsh_N 0:1d6e44094672 707 *mosiportreg &= ~mosipin;
Priunsh_N 0:1d6e44094672 708 }
Priunsh_N 0:1d6e44094672 709 *clkportreg |= clkpin;
Priunsh_N 0:1d6e44094672 710 }
Priunsh_N 0:1d6e44094672 711 *clkportreg &= ~clkpin; // Make sure clock ends low
Priunsh_N 0:1d6e44094672 712 }
Priunsh_N 0:1d6e44094672 713 }
Priunsh_N 0:1d6e44094672 714
Priunsh_N 0:1d6e44094672 715
Priunsh_N 0:1d6e44094672 716
Priunsh_N 0:1d6e44094672 717 void Adafruit_VS1053::sineTest(uint8_t n, uint16_t ms) {
Priunsh_N 0:1d6e44094672 718 reset();
Priunsh_N 0:1d6e44094672 719
Priunsh_N 0:1d6e44094672 720 uint16_t mode = sciRead(VS1053_REG_MODE);
Priunsh_N 0:1d6e44094672 721 mode |= 0x0020;
Priunsh_N 0:1d6e44094672 722 sciWrite(VS1053_REG_MODE, mode);
Priunsh_N 0:1d6e44094672 723
Priunsh_N 0:1d6e44094672 724 while (!digitalRead(_dreq));
Priunsh_N 0:1d6e44094672 725 // delay(10);
Priunsh_N 0:1d6e44094672 726
Priunsh_N 0:1d6e44094672 727 #ifdef SPI_HAS_TRANSACTION
Priunsh_N 0:1d6e44094672 728 if (useHardwareSPI) SPI.beginTransaction(VS1053_DATA_SPI_SETTING);
Priunsh_N 0:1d6e44094672 729 #endif
Priunsh_N 0:1d6e44094672 730 digitalWrite(_dcs, LOW);
Priunsh_N 0:1d6e44094672 731 spiwrite(0x53);
Priunsh_N 0:1d6e44094672 732 spiwrite(0xEF);
Priunsh_N 0:1d6e44094672 733 spiwrite(0x6E);
Priunsh_N 0:1d6e44094672 734 spiwrite(n);
Priunsh_N 0:1d6e44094672 735 spiwrite(0x00);
Priunsh_N 0:1d6e44094672 736 spiwrite(0x00);
Priunsh_N 0:1d6e44094672 737 spiwrite(0x00);
Priunsh_N 0:1d6e44094672 738 spiwrite(0x00);
Priunsh_N 0:1d6e44094672 739 digitalWrite(_dcs, HIGH);
Priunsh_N 0:1d6e44094672 740 #ifdef SPI_HAS_TRANSACTION
Priunsh_N 0:1d6e44094672 741 if (useHardwareSPI) SPI.endTransaction();
Priunsh_N 0:1d6e44094672 742 #endif
Priunsh_N 0:1d6e44094672 743
Priunsh_N 0:1d6e44094672 744 delay(ms);
Priunsh_N 0:1d6e44094672 745
Priunsh_N 0:1d6e44094672 746 #ifdef SPI_HAS_TRANSACTION
Priunsh_N 0:1d6e44094672 747 if (useHardwareSPI) SPI.beginTransaction(VS1053_DATA_SPI_SETTING);
Priunsh_N 0:1d6e44094672 748 #endif
Priunsh_N 0:1d6e44094672 749 digitalWrite(_dcs, LOW);
Priunsh_N 0:1d6e44094672 750 spiwrite(0x45);
Priunsh_N 0:1d6e44094672 751 spiwrite(0x78);
Priunsh_N 0:1d6e44094672 752 spiwrite(0x69);
Priunsh_N 0:1d6e44094672 753 spiwrite(0x74);
Priunsh_N 0:1d6e44094672 754 spiwrite(0x00);
Priunsh_N 0:1d6e44094672 755 spiwrite(0x00);
Priunsh_N 0:1d6e44094672 756 spiwrite(0x00);
Priunsh_N 0:1d6e44094672 757 spiwrite(0x00);
Priunsh_N 0:1d6e44094672 758 digitalWrite(_dcs, HIGH);
Priunsh_N 0:1d6e44094672 759 #ifdef SPI_HAS_TRANSACTION
Priunsh_N 0:1d6e44094672 760 if (useHardwareSPI) SPI.endTransaction();
Priunsh_N 0:1d6e44094672 761 #endif
Priunsh_N 0:1d6e44094672 762 }