gg
Dependencies: mbed SDFileSystem
VS1053.cpp
00001 /*************************************************** 00002 This is a library for the Adafruit VS1053 Codec Breakout 00003 00004 Designed specifically to work with the Adafruit VS1053 Codec Breakout 00005 ----> https://www.adafruit.com/products/1381 00006 00007 Adafruit invests time and resources providing this open source code, 00008 please support Adafruit and open-source hardware by purchasing 00009 products from Adafruit! 00010 00011 Written by Limor Fried/Ladyada for Adafruit Industries. 00012 BSD license, all text above must be included in any redistribution 00013 ****************************************************/ 00014 00015 #include <Adafruit_VS1053.h> 00016 #include <SD.h> 00017 00018 static Adafruit_VS1053_FilePlayer *myself; 00019 00020 #ifndef _BV 00021 #define _BV(x) (1<<(x)) 00022 #endif 00023 00024 #if defined(__AVR__) 00025 SIGNAL(TIMER0_COMPA_vect) { 00026 myself->feedBuffer(); 00027 } 00028 #endif 00029 00030 static void feeder(void) { 00031 myself->feedBuffer(); 00032 } 00033 00034 #define VS1053_CONTROL_SPI_SETTING SPISettings(250000, MSBFIRST, SPI_MODE0) 00035 #define VS1053_DATA_SPI_SETTING SPISettings(8000000, MSBFIRST, SPI_MODE0) 00036 00037 00038 static const uint8_t dreqinttable[] = { 00039 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega8__) 00040 2, 0, 00041 3, 1, 00042 #elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) 00043 2, 0, 00044 3, 1, 00045 21, 2, 00046 20, 3, 00047 19, 4, 00048 18, 5, 00049 #elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY) 00050 5, 0, 00051 6, 1, 00052 7, 2, 00053 8, 3, 00054 #elif defined(__AVR_AT90USB1286__) && defined(CORE_TEENSY) 00055 0, 0, 00056 1, 1, 00057 2, 2, 00058 3, 3, 00059 36, 4, 00060 37, 5, 00061 18, 6, 00062 19, 7, 00063 #elif defined(__arm__) && defined(CORE_TEENSY) 00064 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 00065 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 00066 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 00067 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 00068 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 00069 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 00070 30, 30, 31, 31, 32, 32, 33, 33, 00071 #elif defined(__AVR_ATmega32U4__) 00072 3, 0, 00073 2, 1, 00074 0, 2, 00075 1, 3, 00076 7, 4, 00077 #elif defined(__AVR_ATmega256RFR2__) 00078 4, 0, 00079 5, 1, 00080 #elif defined(__SAM3X8E__) || defined(ARDUINO_ARCH_SAMD) 00081 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 00082 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 00083 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 00084 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 00085 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 00086 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 00087 30, 30, 31, 31, 32, 32, 33, 33, 00088 00089 #endif 00090 }; 00091 00092 boolean Adafruit_VS1053_FilePlayer::useInterrupt(uint8_t type) { 00093 myself = this; // oy vey 00094 00095 if (type == VS1053_FILEPLAYER_TIMER0_INT) { 00096 #if defined(__AVR__) 00097 OCR0A = 0xAF; 00098 TIMSK0 |= _BV(OCIE0A); 00099 return true; 00100 #elif defined(__arm__) && defined(CORE_TEENSY) 00101 IntervalTimer *t = new IntervalTimer(); 00102 return (t && t->begin(feeder, 1024)) ? true : false; 00103 #else 00104 return false; 00105 #endif 00106 } 00107 if (type == VS1053_FILEPLAYER_PIN_INT) { 00108 for (uint8_t i=0; i<sizeof(dreqinttable); i+=2) { 00109 //Serial.println(dreqinttable[i]); 00110 if (_dreq == dreqinttable[i]) { 00111 #ifdef SPI_HAS_TRANSACTION 00112 SPI.usingInterrupt(dreqinttable[i+1]); 00113 #endif 00114 attachInterrupt(dreqinttable[i+1], feeder, CHANGE); 00115 return true; 00116 } 00117 } 00118 } 00119 return false; 00120 } 00121 00122 Adafruit_VS1053_FilePlayer::Adafruit_VS1053_FilePlayer( 00123 int8_t rst, int8_t cs, int8_t dcs, int8_t dreq, 00124 int8_t cardcs) 00125 : Adafruit_VS1053(rst, cs, dcs, dreq) { 00126 00127 playingMusic = false; 00128 00129 // Set the card to be disabled while we get the VS1053 up 00130 pinMode(_cardCS, OUTPUT); 00131 digitalWrite(_cardCS, HIGH); 00132 } 00133 00134 Adafruit_VS1053_FilePlayer::Adafruit_VS1053_FilePlayer( 00135 int8_t cs, int8_t dcs, int8_t dreq, 00136 int8_t cardcs) 00137 : Adafruit_VS1053(-1, cs, dcs, dreq) { 00138 00139 playingMusic = false; 00140 00141 // Set the card to be disabled while we get the VS1053 up 00142 pinMode(_cardCS, OUTPUT); 00143 digitalWrite(_cardCS, HIGH); 00144 } 00145 00146 00147 Adafruit_VS1053_FilePlayer::Adafruit_VS1053_FilePlayer( 00148 int8_t mosi, int8_t miso, int8_t clk, 00149 int8_t rst, int8_t cs, int8_t dcs, int8_t dreq, 00150 int8_t cardcs) 00151 : Adafruit_VS1053(mosi, miso, clk, rst, cs, dcs, dreq) { 00152 00153 playingMusic = false; 00154 00155 // Set the card to be disabled while we get the VS1053 up 00156 pinMode(_cardCS, OUTPUT); 00157 digitalWrite(_cardCS, HIGH); 00158 } 00159 00160 boolean Adafruit_VS1053_FilePlayer::begin(void) { 00161 uint8_t v = Adafruit_VS1053::begin(); 00162 00163 //dumpRegs(); 00164 //Serial.print("Version = "); Serial.println(v); 00165 return (v == 4); 00166 } 00167 00168 00169 boolean Adafruit_VS1053_FilePlayer::playFullFile(const char *trackname) { 00170 if (! startPlayingFile(trackname)) return false; 00171 00172 while (playingMusic) { 00173 // twiddle thumbs 00174 feedBuffer(); 00175 } 00176 // music file finished! 00177 return true; 00178 } 00179 00180 void Adafruit_VS1053_FilePlayer::stopPlaying(void) { 00181 // cancel all playback 00182 sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | VS1053_MODE_SM_SDINEW | VS1053_MODE_SM_CANCEL); 00183 00184 // wrap it up! 00185 playingMusic = false; 00186 currentTrack.close(); 00187 } 00188 00189 void Adafruit_VS1053_FilePlayer::pausePlaying(boolean pause) { 00190 if (pause) 00191 playingMusic = false; 00192 else { 00193 playingMusic = true; 00194 feedBuffer(); 00195 } 00196 } 00197 00198 boolean Adafruit_VS1053_FilePlayer::paused(void) { 00199 return (!playingMusic && currentTrack); 00200 } 00201 00202 boolean Adafruit_VS1053_FilePlayer::stopped(void) { 00203 return (!playingMusic && !currentTrack); 00204 } 00205 00206 00207 boolean Adafruit_VS1053_FilePlayer::startPlayingFile(const char *trackname) { 00208 // reset playback 00209 sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | VS1053_MODE_SM_SDINEW); 00210 // resync 00211 sciWrite(VS1053_REG_WRAMADDR, 0x1e29); 00212 sciWrite(VS1053_REG_WRAM, 0); 00213 00214 currentTrack = SD.open(trackname); 00215 if (!currentTrack) { 00216 return false; 00217 } 00218 00219 // As explained in datasheet, set twice 0 in REG_DECODETIME to set time back to 0 00220 sciWrite(VS1053_REG_DECODETIME, 0x00); 00221 sciWrite(VS1053_REG_DECODETIME, 0x00); 00222 00223 00224 playingMusic = true; 00225 00226 // wait till its ready for data 00227 while (! readyForData() ); 00228 00229 00230 // fill it up! 00231 while (playingMusic && readyForData()) 00232 feedBuffer(); 00233 00234 // Serial.println("Ready"); 00235 00236 return true; 00237 } 00238 00239 void Adafruit_VS1053_FilePlayer::feedBuffer(void) { 00240 static uint8_t running = 0; 00241 uint8_t sregsave; 00242 00243 #if !defined (__SAM3X8E__) && !defined (ARDUINO_ARCH_SAMD) 00244 // Do not allow 2 copies of this code to run concurrently. 00245 // If an interrupt causes feedBuffer() to run while another 00246 // copy of feedBuffer() is already running in the main 00247 // program, havoc can occur. "running" detects this state 00248 // and safely returns. 00249 sregsave = SREG; 00250 cli(); 00251 if (running) { 00252 SREG = sregsave; 00253 return; // return safely, before touching hardware! :-) 00254 } else { 00255 running = 1; 00256 SREG = sregsave; 00257 } 00258 #endif 00259 00260 if (! playingMusic) { 00261 running = 0; 00262 return; // paused or stopped 00263 } 00264 if (! currentTrack) { 00265 running = 0; 00266 return; 00267 } 00268 if (! readyForData()) { 00269 running = 0; 00270 return; 00271 } 00272 00273 // Feed the hungry buffer! :) 00274 while (readyForData()) { 00275 //UDR0 = '.'; 00276 00277 // Read some audio data from the SD card file 00278 int bytesread = currentTrack.read(mp3buffer, VS1053_DATABUFFERLEN); 00279 00280 if (bytesread == 0) { 00281 // must be at the end of the file, wrap it up! 00282 playingMusic = false; 00283 currentTrack.close(); 00284 running = 0; 00285 return; 00286 } 00287 playData(mp3buffer, bytesread); 00288 } 00289 running = 0; 00290 return; 00291 } 00292 00293 00294 /***************************************************************/ 00295 00296 /* VS1053 'low level' interface */ 00297 #ifdef ARDUINO_ARCH_SAMD 00298 static volatile uint32_t *clkportreg, *misoportreg, *mosiportreg; 00299 static uint32_t clkpin, misopin, mosipin; 00300 #else 00301 static volatile PortReg *clkportreg, *misoportreg, *mosiportreg; 00302 static PortMask clkpin, misopin, mosipin; 00303 #endif 00304 00305 Adafruit_VS1053::Adafruit_VS1053(int8_t mosi, int8_t miso, int8_t clk, 00306 int8_t rst, int8_t cs, int8_t dcs, int8_t dreq) { 00307 _mosi = mosi; 00308 _miso = miso; 00309 _clk = clk; 00310 _reset = rst; 00311 _cs = cs; 00312 _dcs = dcs; 00313 _dreq = dreq; 00314 00315 useHardwareSPI = false; 00316 00317 clkportreg = portOutputRegister(digitalPinToPort(_clk)); 00318 clkpin = digitalPinToBitMask(_clk); 00319 misoportreg = portInputRegister(digitalPinToPort(_miso)); 00320 misopin = digitalPinToBitMask(_miso); 00321 mosiportreg = portOutputRegister(digitalPinToPort(_mosi)); 00322 mosipin = digitalPinToBitMask(_mosi); 00323 } 00324 00325 00326 Adafruit_VS1053::Adafruit_VS1053(int8_t rst, int8_t cs, int8_t dcs, int8_t dreq) { 00327 _mosi = 0; 00328 _miso = 0; 00329 _clk = 0; 00330 useHardwareSPI = true; 00331 _reset = rst; 00332 _cs = cs; 00333 _dcs = dcs; 00334 _dreq = dreq; 00335 } 00336 00337 00338 void Adafruit_VS1053::applyPatch(const uint16_t *patch, uint16_t patchsize) { 00339 uint16_t i = 0; 00340 00341 // Serial.print("Patch size: "); Serial.println(patchsize); 00342 while ( i < patchsize ) { 00343 uint16_t addr, n, val; 00344 00345 addr = pgm_read_word(patch++); 00346 n = pgm_read_word(patch++); 00347 i += 2; 00348 00349 //Serial.println(addr, HEX); 00350 if (n & 0x8000U) { // RLE run, replicate n samples 00351 n &= 0x7FFF; 00352 val = pgm_read_word(patch++); 00353 i++; 00354 while (n--) { 00355 sciWrite(addr, val); 00356 } 00357 } else { // Copy run, copy n samples 00358 while (n--) { 00359 val = pgm_read_word(patch++); 00360 i++; 00361 sciWrite(addr, val); 00362 } 00363 } 00364 } 00365 } 00366 00367 00368 uint16_t Adafruit_VS1053::loadPlugin(char *plugname) { 00369 00370 File plugin = SD.open(plugname); 00371 if (!plugin) { 00372 Serial.println("Couldn't open the plugin file"); 00373 Serial.println(plugin); 00374 return 0xFFFF; 00375 } 00376 00377 if ((plugin.read() != 'P') || 00378 (plugin.read() != '&') || 00379 (plugin.read() != 'H')) 00380 return 0xFFFF; 00381 00382 uint16_t type; 00383 00384 // Serial.print("Patch size: "); Serial.println(patchsize); 00385 while ((type = plugin.read()) >= 0) { 00386 uint16_t offsets[] = {0x8000UL, 0x0, 0x4000UL}; 00387 uint16_t addr, len; 00388 00389 //Serial.print("type: "); Serial.println(type, HEX); 00390 00391 if (type >= 4) { 00392 plugin.close(); 00393 return 0xFFFF; 00394 } 00395 00396 len = plugin.read(); len <<= 8; 00397 len |= plugin.read() & ~1; 00398 addr = plugin.read(); addr <<= 8; 00399 addr |= plugin.read(); 00400 //Serial.print("len: "); Serial.print(len); 00401 //Serial.print(" addr: $"); Serial.println(addr, HEX); 00402 00403 if (type == 3) { 00404 // execute rec! 00405 plugin.close(); 00406 return addr; 00407 } 00408 00409 // set address 00410 sciWrite(VS1053_REG_WRAMADDR, addr + offsets[type]); 00411 // write data 00412 do { 00413 uint16_t data; 00414 data = plugin.read(); data <<= 8; 00415 data |= plugin.read(); 00416 sciWrite(VS1053_REG_WRAM, data); 00417 } while ((len -=2)); 00418 } 00419 00420 plugin.close(); 00421 return 0xFFFF; 00422 } 00423 00424 00425 00426 00427 boolean Adafruit_VS1053::readyForData(void) { 00428 return digitalRead(_dreq); 00429 } 00430 00431 void Adafruit_VS1053::playData(uint8_t *buffer, uint8_t buffsiz) { 00432 #ifdef SPI_HAS_TRANSACTION 00433 if (useHardwareSPI) SPI.beginTransaction(VS1053_DATA_SPI_SETTING); 00434 #endif 00435 digitalWrite(_dcs, LOW); 00436 for (uint8_t i=0; i<buffsiz; i++) { 00437 spiwrite(buffer[i]); 00438 } 00439 digitalWrite(_dcs, HIGH); 00440 #ifdef SPI_HAS_TRANSACTION 00441 if (useHardwareSPI) SPI.endTransaction(); 00442 #endif 00443 } 00444 00445 void Adafruit_VS1053::setVolume(uint8_t left, uint8_t right) { 00446 uint16_t v; 00447 v = left; 00448 v <<= 8; 00449 v |= right; 00450 00451 noInterrupts(); //cli(); 00452 sciWrite(VS1053_REG_VOLUME, v); 00453 interrupts(); //sei(); 00454 } 00455 00456 uint16_t Adafruit_VS1053::decodeTime() { 00457 noInterrupts(); //cli(); 00458 uint16_t t = sciRead(VS1053_REG_DECODETIME); 00459 interrupts(); //sei(); 00460 return t; 00461 } 00462 00463 00464 void Adafruit_VS1053::softReset(void) { 00465 sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_SDINEW | VS1053_MODE_SM_RESET); 00466 delay(100); 00467 } 00468 00469 void Adafruit_VS1053::reset() { 00470 // TODO: http://www.vlsi.fi/player_vs1011_1002_1003/modularplayer/vs10xx_8c.html#a3 00471 // hardware reset 00472 if (_reset >= 0) { 00473 digitalWrite(_reset, LOW); 00474 delay(100); 00475 digitalWrite(_reset, HIGH); 00476 } 00477 digitalWrite(_cs, HIGH); 00478 digitalWrite(_dcs, HIGH); 00479 delay(100); 00480 softReset(); 00481 delay(100); 00482 00483 sciWrite(VS1053_REG_CLOCKF, 0x6000); 00484 00485 setVolume(40, 40); 00486 } 00487 00488 uint8_t Adafruit_VS1053::begin(void) { 00489 if (_reset >= 0) { 00490 pinMode(_reset, OUTPUT); 00491 digitalWrite(_reset, LOW); 00492 } 00493 00494 pinMode(_cs, OUTPUT); 00495 digitalWrite(_cs, HIGH); 00496 pinMode(_dcs, OUTPUT); 00497 digitalWrite(_dcs, HIGH); 00498 pinMode(_dreq, INPUT); 00499 00500 if (! useHardwareSPI) { 00501 pinMode(_mosi, OUTPUT); 00502 pinMode(_clk, OUTPUT); 00503 pinMode(_miso, INPUT); 00504 } else { 00505 SPI.begin(); 00506 SPI.setDataMode(SPI_MODE0); 00507 SPI.setBitOrder(MSBFIRST); 00508 SPI.setClockDivider(SPI_CLOCK_DIV128); 00509 } 00510 00511 reset(); 00512 00513 return (sciRead(VS1053_REG_STATUS) >> 4) & 0x0F; 00514 } 00515 00516 void Adafruit_VS1053::dumpRegs(void) { 00517 Serial.print("Mode = 0x"); Serial.println(sciRead(VS1053_REG_MODE), HEX); 00518 Serial.print("Stat = 0x"); Serial.println(sciRead(VS1053_REG_STATUS), HEX); 00519 Serial.print("ClkF = 0x"); Serial.println(sciRead(VS1053_REG_CLOCKF), HEX); 00520 Serial.print("Vol. = 0x"); Serial.println(sciRead(VS1053_REG_VOLUME), HEX); 00521 } 00522 00523 00524 uint16_t Adafruit_VS1053::recordedWordsWaiting(void) { 00525 return sciRead(VS1053_REG_HDAT1); 00526 } 00527 00528 uint16_t Adafruit_VS1053::recordedReadWord(void) { 00529 return sciRead(VS1053_REG_HDAT0); 00530 } 00531 00532 00533 boolean Adafruit_VS1053::prepareRecordOgg(char *plugname) { 00534 sciWrite(VS1053_REG_CLOCKF, 0xC000); // set max clock 00535 delay(1); while (! readyForData() ); 00536 00537 sciWrite(VS1053_REG_BASS, 0); // clear Bass 00538 00539 softReset(); 00540 delay(1); while (! readyForData() ); 00541 00542 sciWrite(VS1053_SCI_AIADDR, 0); 00543 // disable all interrupts except SCI 00544 sciWrite(VS1053_REG_WRAMADDR, VS1053_INT_ENABLE); 00545 sciWrite(VS1053_REG_WRAM, 0x02); 00546 00547 int pluginStartAddr = loadPlugin(plugname); 00548 if (pluginStartAddr == 0xFFFF) return false; 00549 Serial.print("Plugin at $"); Serial.println(pluginStartAddr, HEX); 00550 if (pluginStartAddr != 0x34) return false; 00551 00552 return true; 00553 } 00554 00555 void Adafruit_VS1053::stopRecordOgg(void) { 00556 sciWrite(VS1053_SCI_AICTRL3, 1); 00557 } 00558 00559 void Adafruit_VS1053::startRecordOgg(boolean mic) { 00560 /* Set VS1053 mode bits as instructed in the VS1053b Ogg Vorbis Encoder 00561 manual. Note: for microphone input, leave SMF_LINE1 unset! */ 00562 if (mic) { 00563 sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_ADPCM | VS1053_MODE_SM_SDINEW); 00564 } else { 00565 sciWrite(VS1053_REG_MODE, VS1053_MODE_SM_LINE1 | 00566 VS1053_MODE_SM_ADPCM | VS1053_MODE_SM_SDINEW); 00567 } 00568 sciWrite(VS1053_SCI_AICTRL0, 1024); 00569 /* Rec level: 1024 = 1. If 0, use AGC */ 00570 sciWrite(VS1053_SCI_AICTRL1, 1024); 00571 /* Maximum AGC level: 1024 = 1. Only used if SCI_AICTRL1 is set to 0. */ 00572 sciWrite(VS1053_SCI_AICTRL2, 0); 00573 /* Miscellaneous bits that also must be set before recording. */ 00574 sciWrite(VS1053_SCI_AICTRL3, 0); 00575 00576 sciWrite(VS1053_SCI_AIADDR, 0x34); 00577 delay(1); while (! readyForData() ); 00578 } 00579 00580 void Adafruit_VS1053::GPIO_pinMode(uint8_t i, uint8_t dir) { 00581 if (i > 7) return; 00582 00583 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_DDR); 00584 uint16_t ddr = sciRead(VS1053_REG_WRAM); 00585 00586 if (dir == INPUT) 00587 ddr &= ~_BV(i); 00588 if (dir == OUTPUT) 00589 ddr |= _BV(i); 00590 00591 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_DDR); 00592 sciWrite(VS1053_REG_WRAM, ddr); 00593 } 00594 00595 00596 void Adafruit_VS1053::GPIO_digitalWrite(uint8_t val) { 00597 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_ODATA); 00598 sciWrite(VS1053_REG_WRAM, val); 00599 } 00600 00601 void Adafruit_VS1053::GPIO_digitalWrite(uint8_t i, uint8_t val) { 00602 if (i > 7) return; 00603 00604 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_ODATA); 00605 uint16_t pins = sciRead(VS1053_REG_WRAM); 00606 00607 if (val == LOW) 00608 pins &= ~_BV(i); 00609 if (val == HIGH) 00610 pins |= _BV(i); 00611 00612 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_ODATA); 00613 sciWrite(VS1053_REG_WRAM, pins); 00614 } 00615 00616 uint16_t Adafruit_VS1053::GPIO_digitalRead(void) { 00617 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_IDATA); 00618 return sciRead(VS1053_REG_WRAM) & 0xFF; 00619 } 00620 00621 boolean Adafruit_VS1053::GPIO_digitalRead(uint8_t i) { 00622 if (i > 7) return 0; 00623 00624 sciWrite(VS1053_REG_WRAMADDR, VS1053_GPIO_IDATA); 00625 uint16_t val = sciRead(VS1053_REG_WRAM); 00626 if (val & _BV(i)) return true; 00627 return false; 00628 } 00629 00630 uint16_t Adafruit_VS1053::sciRead(uint8_t addr) { 00631 uint16_t data; 00632 00633 #ifdef SPI_HAS_TRANSACTION 00634 if (useHardwareSPI) SPI.beginTransaction(VS1053_CONTROL_SPI_SETTING); 00635 #endif 00636 digitalWrite(_cs, LOW); 00637 spiwrite(VS1053_SCI_READ); 00638 spiwrite(addr); 00639 delayMicroseconds(10); 00640 data = spiread(); 00641 data <<= 8; 00642 data |= spiread(); 00643 digitalWrite(_cs, HIGH); 00644 #ifdef SPI_HAS_TRANSACTION 00645 if (useHardwareSPI) SPI.endTransaction(); 00646 #endif 00647 00648 return data; 00649 } 00650 00651 00652 void Adafruit_VS1053::sciWrite(uint8_t addr, uint16_t data) { 00653 #ifdef SPI_HAS_TRANSACTION 00654 if (useHardwareSPI) SPI.beginTransaction(VS1053_CONTROL_SPI_SETTING); 00655 #endif 00656 digitalWrite(_cs, LOW); 00657 spiwrite(VS1053_SCI_WRITE); 00658 spiwrite(addr); 00659 spiwrite(data >> 8); 00660 spiwrite(data & 0xFF); 00661 digitalWrite(_cs, HIGH); 00662 #ifdef SPI_HAS_TRANSACTION 00663 if (useHardwareSPI) SPI.endTransaction(); 00664 #endif 00665 } 00666 00667 00668 00669 uint8_t Adafruit_VS1053::spiread(void) 00670 { 00671 int8_t i, x; 00672 x = 0; 00673 00674 // MSB first, clock low when inactive (CPOL 0), data valid on leading edge (CPHA 0) 00675 // Make sure clock starts low 00676 00677 if (useHardwareSPI) { 00678 x = SPI.transfer(0x00); 00679 } else { 00680 for (i=7; i>=0; i--) { 00681 if ((*misoportreg) & misopin) 00682 x |= (1<<i); 00683 *clkportreg |= clkpin; 00684 *clkportreg &= ~clkpin; 00685 // asm("nop; nop"); 00686 } 00687 // Make sure clock ends low 00688 *clkportreg &= ~clkpin; 00689 } 00690 return x; 00691 } 00692 00693 void Adafruit_VS1053::spiwrite(uint8_t c) 00694 { 00695 // MSB first, clock low when inactive (CPOL 0), data valid on leading edge (CPHA 0) 00696 // Make sure clock starts low 00697 00698 if (useHardwareSPI) { 00699 SPI.transfer(c); 00700 00701 } else { 00702 for (int8_t i=7; i>=0; i--) { 00703 *clkportreg &= ~clkpin; 00704 if (c & (1<<i)) { 00705 *mosiportreg |= mosipin; 00706 } else { 00707 *mosiportreg &= ~mosipin; 00708 } 00709 *clkportreg |= clkpin; 00710 } 00711 *clkportreg &= ~clkpin; // Make sure clock ends low 00712 } 00713 } 00714 00715 00716 00717 void Adafruit_VS1053::sineTest(uint8_t n, uint16_t ms) { 00718 reset(); 00719 00720 uint16_t mode = sciRead(VS1053_REG_MODE); 00721 mode |= 0x0020; 00722 sciWrite(VS1053_REG_MODE, mode); 00723 00724 while (!digitalRead(_dreq)); 00725 // delay(10); 00726 00727 #ifdef SPI_HAS_TRANSACTION 00728 if (useHardwareSPI) SPI.beginTransaction(VS1053_DATA_SPI_SETTING); 00729 #endif 00730 digitalWrite(_dcs, LOW); 00731 spiwrite(0x53); 00732 spiwrite(0xEF); 00733 spiwrite(0x6E); 00734 spiwrite(n); 00735 spiwrite(0x00); 00736 spiwrite(0x00); 00737 spiwrite(0x00); 00738 spiwrite(0x00); 00739 digitalWrite(_dcs, HIGH); 00740 #ifdef SPI_HAS_TRANSACTION 00741 if (useHardwareSPI) SPI.endTransaction(); 00742 #endif 00743 00744 delay(ms); 00745 00746 #ifdef SPI_HAS_TRANSACTION 00747 if (useHardwareSPI) SPI.beginTransaction(VS1053_DATA_SPI_SETTING); 00748 #endif 00749 digitalWrite(_dcs, LOW); 00750 spiwrite(0x45); 00751 spiwrite(0x78); 00752 spiwrite(0x69); 00753 spiwrite(0x74); 00754 spiwrite(0x00); 00755 spiwrite(0x00); 00756 spiwrite(0x00); 00757 spiwrite(0x00); 00758 digitalWrite(_dcs, HIGH); 00759 #ifdef SPI_HAS_TRANSACTION 00760 if (useHardwareSPI) SPI.endTransaction(); 00761 #endif 00762 }
Generated on Wed Jul 13 2022 03:20:06 by 1.7.2