gg

Dependencies:   mbed SDFileSystem

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers VS1053.cpp Source File

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 }