Library for VS1053 chip with non blocking call to check dreq and cancel playback function
Dependents: VS1053Player MP3_test MP3_final_S4P_ANDRIAMARO_RAKOTO_1
Fork of VS1053lib by
VLSIcodec.cpp
00001 /** mbed VLSIcodec library. To access VS1053 MPEG3 codec. 00002 00003 Copyright (c) 2010 NXP 3790 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 00024 #include "mbed.h" 00025 #include "VLSIcodec.h" 00026 #include "VLSIcodec_patch.h" 00027 00028 #ifdef __ENCODE_OGG 00029 #include "VLSIcodec_OGG.h" 00030 #endif 00031 00032 #ifdef __PLUGINGA 00033 #include "VLSIcodec_pluginGA.h" 00034 #define cBASE 0x1800 /* Base address of X-RAM for a VS1053 */ 00035 #endif 00036 00037 00038 //****************************************************************************** 00039 //****************************************************************************** 00040 // Section: Constants 00041 //****************************************************************************** 00042 //****************************************************************************** 00043 00044 #define VLSI_MODE 0x00 00045 #define VLSI_STATUS 0x01 00046 #define VLSI_BASS 0x02 00047 #define VLSI_CLOCKF 0x03 00048 #define VLSI_DECODE_TIME 0x04 00049 #define VLSI_AUDATA 0x05 00050 #define VLSI_WRAM 0x06 00051 #define VLSI_WRAMADDR 0x07 00052 #define VLSI_HDAT0 0x08 00053 #define VLSI_HDAT1 0x09 00054 #define VLSI_AIADDR 0x0A 00055 #define VLSI_VOL 0x0B 00056 #define VLSI_AICTRL0 0x0C 00057 #define VLSI_AICTRL1 0x0D 00058 #define VLSI_AICTRL2 0x0E 00059 #define VLSI_AICTRL3 0x0F 00060 00061 #define VLSI_STATUS_VER 0x00F0u 00062 #define VER_VS1001 (0u<<4) 00063 #define VER_VS1011 (1u<<4) 00064 #define VER_VS1002 (2u<<4) 00065 #define VER_VS1011E (2u<<4) 00066 #define VER_VS1003 (3u<<4) 00067 #define VER_VS1053 (4u<<4) 00068 #define VER_VS1033 (5u<<4) 00069 #define VER_VS1103 (7u<<4) 00070 00071 #define cWAIT_DREQ_1MS wait_ms( 1); while (!_dreq); 00072 #define cWAIT_DREQ while (!_dreq); 00073 00074 /* VLSI 1053, MODE Register bit configuration. */ 00075 #define SM_DIFF 0x01 00076 #define SM_LAYER12 0x02 00077 #define SM_RESET 0x04 00078 #define SM_CANCEL 0x08 00079 #define SM_EARSPEAKER_LO 0x10 00080 #define SM_TESTS 0x20 00081 #define SM_STREAM 0x40 00082 #define SM_EARSPEAKER_HI 0x80 00083 #define SM_DACT 0x100 00084 #define SM_SDIORD 0x200 00085 #define SM_SDISHARE 0x400 00086 #define SM_SDINEW 0x800 00087 #define SM_ADPCM 0x1000 00088 #define SM_NOTUSE 0x2000 00089 #define SM_LINE1 0x4000 00090 #define SM_CLK_RANGE 0x8000 00091 00092 /* SC MULT MASK CLKI */ 00093 #define SC_MULT_0 0x0000 /* XTALI */ 00094 #define SC_MULT_2 0x2000 /* XTALI×2.0 */ 00095 #define SC_MULT_2_5 0x4000 /* XTALI×2.5 */ 00096 #define SC_MULT_3 0x6000 /* XTALI×3.0 */ 00097 #define SC_MULT_3_5 0x8000 /* XTALI×3.5 */ 00098 #define SC_MULT_4 0xA000 /* XTALI×4.0 */ 00099 #define SC_MULT_4_5 0xC000 /* XTALI×4.5 */ 00100 #define SC_MULT_5 0xE000 /* XTALI×5.0 */ 00101 00102 /* 00103 SC ADD tells how much the decoder firmware is allowed to add to the multiplier specified by SC MULT 00104 if more cycles are temporarily needed to decode a WMA or AAC stream. The values are: 00105 SC ADD MASK Multiplier addition 00106 */ 00107 #define SC_ADD_NOMOD 0x0000 /* No modification is allowed */ 00108 #define SC_ADD_X1 0x0800 /* 1.0× */ 00109 #define SC_ADD_X1_5 0x1000 /* 1.5× */ 00110 #define SC_ADD_X2 0x1800 /* 2.0× */ 00111 00112 #define SC_FREQ 0x0000 /* 12.288 MHz clock. */ 00113 00114 /* 00115 */ 00116 #define cMODEREG_SET ( SM_SDINEW ) 00117 #define cCLOCK_SET ( SC_MULT_5 | SC_ADD_X1 | SC_FREQ) 00118 00119 #define VS1053_CS_ENABLE _cs=0; 00120 #define VS1053_CS_DISABLE _cs=1; 00121 #define VS1053_XDCS_ENABLE _xdcs=0; 00122 #define VS1053_XDCS_DISABLE _xdcs=1; 00123 #define VS1053_RST_ENABLE _rst=0; 00124 #define VS1053_RST_DISABLE _rst=1; 00125 00126 /* 00127 */ 00128 #define cVS1053_CS_DELAY 50 00129 00130 /** VS1053Codec 00131 */ 00132 VS1053Codec::VS1053Codec( PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dreq, PinName rst, PinName xdcs) : _spi( mosi, miso, sclk), _cs( cs), _dreq( dreq), _rst( rst), _xdcs( xdcs) { 00133 // defaults params 00134 VS1053_CS_DISABLE; 00135 VS1053_XDCS_DISABLE; 00136 } 00137 00138 /** Wait untile the dreq is released 00139 * @param none 00140 * @retval none 00141 */ 00142 void VS1053Codec::testdreq( void){ 00143 while( !_dreq); 00144 } 00145 00146 bool VS1053Codec::checkdreq(void) { 00147 return _dreq; 00148 } 00149 00150 /** Put the VS1053 in low power mode (RESET) 00151 * 00152 * @param none 00153 * @retval none 00154 */ 00155 void VS1053Codec::lowpower( void) 00156 { 00157 VS1053_RST_ENABLE; 00158 wait_ms( 10); 00159 } 00160 00161 /** Initialize the VS1053 00162 */ 00163 void VS1053Codec::init(void) 00164 { 00165 // 00166 VS1053_RST_DISABLE; 00167 VS1053_CS_DISABLE; 00168 VS1053_XDCS_DISABLE; 00169 // 00170 _spi.format( 8, 0); 00171 _spi.frequency( MP3_INIT_SPEED); 00172 00173 // Assert RESET 00174 VS1053_RST_ENABLE; 00175 wait_ms( 100); 00176 00177 // Deassert RESET (active low) 00178 VS1053_RST_DISABLE; 00179 VS1053_CS_DISABLE; 00180 VS1053_XDCS_DISABLE; 00181 wait_ms( 100); 00182 00183 // Wait 00184 while(!_dreq); 00185 00186 // Reset the vs1053 00187 writereg( VLSI_MODE, ( cMODEREG_SET | SM_RESET) ); 00188 wait_ms( 10); 00189 00190 // Wait... 00191 while(!_dreq); 00192 00193 /* 00194 * Write configuration MODE register in a loop to verify that the chip is 00195 * connected and running correctly 00196 */ 00197 do 00198 { 00199 writereg( VLSI_MODE, ( cMODEREG_SET )); 00200 wait_ms( 1); 00201 }while( readreg( VLSI_MODE) != ( cMODEREG_SET )); 00202 00203 // 00204 if((readreg( VLSI_STATUS) & VLSI_STATUS_VER) == VER_VS1053) 00205 { 00206 // Set the clock to maximum speed (VS1053 only) to allow all audio formats 00207 // to be decoded without glitching. Note that this increases power 00208 // consumption. 00209 // SC_MULT = XTALI*4.5, SC_ADD = noMod, SC_FREQ = 0 (12.288MHz) 00210 // VLSIWriteReg(VLSI_CLOCKF, SC_MULT_4_5 | SC_ADD_X1 | SC_FREQ); 00211 00212 writereg(VLSI_CLOCKF, cCLOCK_SET); 00213 00214 /* */ 00215 wait_ms( 2); 00216 while(!_dreq); 00217 } 00218 else if ((readreg( VLSI_STATUS) & VLSI_STATUS_VER) == VER_VS1011E) 00219 { 00220 // Nothing special to do 00221 ; 00222 } 00223 else 00224 { 00225 // VLSI Chip version not tested, not supported, halt program execution. 00226 // This trap should be caught during the design phase. 00227 while(1); 00228 } 00229 00230 _spi.frequency( MP3_RUN_SPEED); 00231 } 00232 00233 void VS1053Codec::loadpatch(void) 00234 /* Questa funzione carica una patch al firmware del codec */ 00235 { 00236 int i = 0, plgin_len; 00237 unsigned int addr, n, val; 00238 00239 plgin_len=sizeof( plugin)/sizeof(plugin[0]); 00240 while (i<plgin_len) { 00241 00242 addr = plugin[i++]; 00243 n = plugin[i++]; 00244 if (n & 0x8000U) { /* RLE run, replicate n samples */ 00245 n &= 0x7FFF; 00246 val = plugin[i++]; 00247 while (n--) { 00248 writeregnowait(addr, val); 00249 while(!_dreq); 00250 } 00251 } else { /* Copy run, copy n samples */ 00252 while (n--) { 00253 val = plugin[i++]; 00254 writeregnowait(addr, val); 00255 while(!_dreq); 00256 } 00257 } 00258 } 00259 // 00260 wait_ms( 1); 00261 while(!_dreq); 00262 } 00263 00264 #ifdef __PLUGINGA 00265 void VS1053Codec::loadgapatch(void) 00266 /* Questa funzione carica un plugin nel codec */ 00267 { 00268 int i = 0, plgin_len; 00269 unsigned int addr, n, val; 00270 00271 plgin_len=sizeof( gaplugin)/sizeof(gaplugin[0]); 00272 while (i<plgin_len) { 00273 00274 addr = gaplugin[i++]; 00275 n = gaplugin[i++]; 00276 if (n & 0x8000U) { /* RLE run, replicate n samples */ 00277 n &= 0x7FFF; 00278 val = gaplugin[i++]; 00279 while (n--) { 00280 writeregnowait(addr, val); 00281 while(!_dreq); 00282 } 00283 } else { /* Copy run, copy n samples */ 00284 while (n--) { 00285 val = gaplugin[i++]; 00286 writeregnowait(addr, val); 00287 while(!_dreq); 00288 } 00289 } 00290 } 00291 // 00292 wait_ms( 1); 00293 while(!_dreq); 00294 } 00295 #endif 00296 00297 #ifdef __ENCODE_OGG 00298 void VS1053Codec::loadoggpatch(void) 00299 /* Questa funzione carica una patch per gestire l'encoder OGG */ 00300 { 00301 int i = 0, plgin_len; 00302 unsigned int addr, n, val; 00303 00304 plgin_len=sizeof( ogg_enc)/sizeof(ogg_enc[0]); 00305 while (i<plgin_len) { 00306 00307 addr = ogg_enc[i++]; 00308 n = ogg_enc[i++]; 00309 if (n & 0x8000U) { /* RLE run, replicate n samples */ 00310 n &= 0x7FFF; 00311 val = ogg_enc[i++]; 00312 while (n--) { 00313 writeregnowait(addr, val); 00314 while(!_dreq); 00315 } 00316 } else { /* Copy run, copy n samples */ 00317 while (n--) { 00318 val = ogg_enc[i++]; 00319 writeregnowait(addr, val); 00320 while(!_dreq); 00321 } 00322 } 00323 } 00324 // 00325 wait_ms( 1); 00326 while(!_dreq); 00327 } 00328 #endif 00329 00330 #ifdef __PLUGINGA 00331 void VS1053Codec::readgavalue( unsigned char *currval, unsigned char *peak) 00332 { 00333 writereg( VLSI_WRAMADDR, cBASE+2); 00334 unsigned short bands = (unsigned short)readreg( VLSI_WRAM); 00335 // 00336 writereg( VLSI_WRAMADDR, cBASE+4); 00337 // 00338 for (int i=0;i<bands;i++) { 00339 short pv = readreg( VLSI_WRAM); 00340 /* current value in bits 5..0, normally 0..31 00341 peak value in bits 11..6, normally 0..31 */ 00342 currval[i]=(unsigned char)(pv&0x003F); 00343 peak[i]=(unsigned char)( (pv>>6)&0x003F); 00344 } 00345 } 00346 00347 unsigned short VS1053Codec::readgabands( void) 00348 { 00349 writereg( VLSI_WRAMADDR, cBASE+2); 00350 unsigned short bands = (unsigned short)readreg( VLSI_WRAM); 00351 /* */ 00352 return bands; 00353 } 00354 00355 #endif 00356 00357 void VS1053Codec::setvmeter( void) 00358 { 00359 unsigned short tmp; 00360 00361 tmp=(unsigned short)readreg( VLSI_STATUS); 00362 tmp|=(1<<9); 00363 writereg( VLSI_STATUS, tmp); 00364 } 00365 00366 void VS1053Codec::getvmeterval( unsigned char* left, unsigned char* right) 00367 { 00368 unsigned short tmp; 00369 00370 tmp=(unsigned short)readreg( VLSI_AICTRL3); 00371 00372 *right=(unsigned char)tmp&0x00FF; 00373 *left=(unsigned char)(tmp>>8); 00374 } 00375 00376 /**************************************************************************** 00377 Function: 00378 void VS1053Codec::setbassboost(BYTE bass, BYTE gfreq) 00379 00380 Description: 00381 This function sets the bass boost. 00382 00383 Precondition: 00384 None 00385 00386 Parameters: 00387 BYTE bass - Bass gain in dB, range from 0 to 15 (MSB nibble) 00388 BYTE gfreq - Limit frequency for bass boost, 10 Hz steps (range from 00389 20 to 150) (LSB nibble) 00390 00391 Returns: 00392 None 00393 00394 Remarks: 00395 None 00396 ***************************************************************************/ 00397 void VS1053Codec::setbassboost( unsigned char bass, unsigned char gfreq) 00398 { 00399 unsigned char templ; 00400 unsigned short tmp; 00401 00402 // 00403 if(bass > 15u) 00404 bass = 15; 00405 if(gfreq > 150u) 00406 gfreq = 150; 00407 if ( gfreq < 20) 00408 gfreq = 20; 00409 00410 00411 // 00412 templ = (unsigned char)gfreq/10; 00413 00414 // put bass boost value into the upper 4 bit 00415 templ |= (bass << 4); 00416 // 00417 tmp=(unsigned short)readreg( VLSI_BASS); 00418 tmp &= 0xFF00; 00419 tmp |= templ; 00420 // 00421 writereg( VLSI_BASS, tmp); 00422 } 00423 00424 /**************************************************************************** 00425 Function: 00426 void VS1053Codec::settrebleboost(BYTE bass, WORD gfreq) 00427 00428 Description: 00429 This function sets the bass boost. 00430 00431 Precondition: 00432 None 00433 00434 Parameters: 00435 BYTE treble - Bass gain in dB, range from -8 to 7 (MSB nibble) 00436 WORD gfreq - Limit frequency for bass boost, 1000 Hz steps (range from 00437 1000 to 15000) (LSB nibble) 00438 00439 Returns: 00440 None 00441 00442 Remarks: 00443 None 00444 ***************************************************************************/ 00445 void VS1053Codec::settrebleboost( char treble, unsigned int gfreq) 00446 { 00447 unsigned char templ; 00448 unsigned short tmp; 00449 00450 // 00451 if(treble > 7) 00452 treble = 7; 00453 if ( treble < (char)-8) 00454 treble = (char)-8; 00455 00456 if(gfreq > 15000u) 00457 gfreq = 15000; 00458 if(gfreq < 1000) 00459 gfreq = 1000; 00460 00461 // 00462 templ = (unsigned char)gfreq/1000; 00463 00464 // put treble boost value into the upper 4 bit 00465 templ |= (treble << 4); 00466 // 00467 tmp=(unsigned short)readreg( VLSI_BASS); 00468 tmp &= 0x00FF; 00469 tmp |= (templ << 8); 00470 // 00471 writereg( VLSI_BASS, tmp); 00472 } 00473 00474 void VS1053Codec::getplaytime(char *playtime) 00475 { 00476 unsigned short playTime; 00477 unsigned char minutes, seconds; 00478 00479 playTime = (unsigned short)readreg(VLSI_DECODE_TIME); 00480 minutes = playTime/60; 00481 seconds = playTime%60; 00482 *playtime++=('0'+minutes/10); 00483 *playtime++=('0'+minutes%10); 00484 *playtime++=(':'); 00485 *playtime++=('0'+seconds/10); 00486 *playtime++=('0'+seconds%10); 00487 } 00488 00489 void VS1053Codec::resetplaytime() { 00490 writereg(VLSI_DECODE_TIME, 0); 00491 writereg(VLSI_DECODE_TIME, 0); 00492 } 00493 00494 void VS1053Codec::cancelplayback() { 00495 unsigned int i = (unsigned short)readreg(VLSI_MODE); 00496 writereg( VLSI_MODE, ( i | SM_CANCEL )); 00497 } 00498 00499 /**************************************************************************** 00500 Function: 00501 void setvolume(unsigned char vRight, unsigned char vLeft) 00502 00503 Description: 00504 This function set volume for analog outputs on the VLSI codec. 00505 00506 Precondition: 00507 None 00508 00509 Parameters: 00510 unsigned char vRight - right channel attenuation from maximum volume, 0.5dB steps 00511 (0x00 = full volume, 0xFF = muted) 00512 unsigned char vLeft - left channel attenuation from maximum volume, 0.5dB steps 00513 (0x00 = full volume, 0xFF = muted) 00514 00515 Returns: 00516 None 00517 00518 Remarks: 00519 None 00520 ***************************************************************************/ 00521 void VS1053Codec::setvolume(unsigned char vRight, unsigned char vLeft) 00522 { 00523 writereg(VLSI_VOL, ((unsigned int)vLeft)<<8 | vRight); 00524 } 00525 00526 00527 void VS1053Codec::sinetest( unsigned char pitch) 00528 { 00529 unsigned int i; 00530 00531 while(!_dreq); 00532 00533 i=(unsigned short)readreg( VLSI_MODE); 00534 writereg( VLSI_MODE, ( i | SM_TESTS )); 00535 00536 VS1053_XDCS_ENABLE; 00537 00538 if ( pitch) { 00539 // START Sine Test 00540 _spi.write(0x53); 00541 _spi.write(0xEF); 00542 _spi.write(0x6E); 00543 _spi.write( pitch); 00544 _spi.write(0x00); 00545 _spi.write(0x00); 00546 _spi.write(0x00); 00547 _spi.write(0x00); 00548 } else { 00549 // STOP Sine Test 00550 _spi.write(0x45); 00551 _spi.write(0x78); 00552 _spi.write(0x69); 00553 _spi.write(0x74); 00554 _spi.write(0x00); 00555 _spi.write(0x00); 00556 _spi.write(0x00); 00557 _spi.write(0x00); 00558 } 00559 00560 VS1053_XDCS_DISABLE; 00561 00562 } 00563 00564 void VS1053Codec::writedata( unsigned char data) 00565 /* 00566 * Write data to SDI. 00567 */ 00568 { 00569 int i=0; 00570 00571 VS1053_XDCS_ENABLE; 00572 for( i=0; i<cVS1053_CS_DELAY; i++); 00573 00574 _spi.write( data); 00575 00576 for( i=0; i<cVS1053_CS_DELAY; i++); 00577 VS1053_XDCS_DISABLE; 00578 00579 } 00580 00581 //****************************************************************************** 00582 //****************************************************************************** 00583 //****************************************************************************** 00584 // Section: Internal Functions 00585 //****************************************************************************** 00586 //****************************************************************************** 00587 //****************************************************************************** 00588 00589 00590 unsigned short VS1053Codec::readreg(unsigned char vAddress) 00591 { 00592 unsigned short wValue; 00593 unsigned int i; 00594 00595 VS1053_CS_ENABLE; 00596 for ( i=0; i<cVS1053_CS_DELAY;i++); 00597 00598 _spi.write(0x03); // Read 00599 _spi.write(vAddress); // Register address 00600 ((unsigned char*)&wValue)[1] = _spi.write(0xFF); // 8 bit value high byte 00601 ((unsigned char*)&wValue)[0] = _spi.write(0xFF); // 8 bit value low byte 00602 00603 for ( i=0; i<cVS1053_CS_DELAY;i++); 00604 VS1053_CS_DISABLE; 00605 00606 return wValue; 00607 } 00608 00609 void VS1053Codec::writereg(unsigned char vAddress, unsigned int wValue) 00610 { 00611 int i; 00612 00613 while(!_dreq); 00614 00615 VS1053_CS_ENABLE; 00616 for ( i=0; i<cVS1053_CS_DELAY;i++); 00617 00618 _spi.write(0x02); // Write 00619 _spi.write(vAddress); // Register address 00620 _spi.write(((unsigned char*)&wValue)[1]); // 8 bit value to write high byte 00621 _spi.write(((unsigned char*)&wValue)[0]); // 8 bit value to write low byte 00622 00623 for ( i=0; i<cVS1053_CS_DELAY;i++); 00624 VS1053_CS_DISABLE; 00625 00626 } 00627 00628 00629 /* */ 00630 void VS1053Codec::reset( void) 00631 { 00632 // Reset the vs1053 00633 writereg(VLSI_MODE, ( cMODEREG_SET | SM_RESET) ); 00634 wait_ms( 5); 00635 // Wait... 00636 while(!_dreq); 00637 00638 // Configure CLOCK register. 00639 writereg(VLSI_CLOCKF, cCLOCK_SET); 00640 wait_ms( 5); 00641 // Wait... 00642 while(!_dreq); 00643 } 00644 00645 00646 void VS1053Codec::writeregnowait(unsigned char vAddress, unsigned int wValue) 00647 /* 00648 Write to SCI interface without waiting for the DREQ pin 00649 */ 00650 { 00651 int i; 00652 00653 VS1053_CS_ENABLE; 00654 for ( i=0; i<cVS1053_CS_DELAY;i++); 00655 00656 _spi.write(0x02); // Write 00657 _spi.write(vAddress); // Register address 00658 _spi.write(((unsigned char*)&wValue)[1]); // 8 bit value to write high byte 00659 _spi.write(((unsigned char*)&wValue)[0]); // 8 bit value to write low byte 00660 00661 for ( i=0; i<cVS1053_CS_DELAY;i++); 00662 VS1053_CS_DISABLE; 00663 00664 } 00665 00666 #ifdef __ENCODE_OGG 00667 void VS1053Codec::VoggEncoding_Start( void) 00668 /* VorbisEncoder160c pag. 9 */ 00669 { 00670 unsigned short temp; 00671 00672 /* 2. vs1053b at 55.3MHz */ 00673 writeregnowait( VLSI_CLOCKF, 0xC000); cWAIT_DREQ_1MS; 00674 /* 3. SCI_BASS to 0 */ 00675 writeregnowait( VLSI_BASS, 0x0000); cWAIT_DREQ_1MS; 00676 /* 4. Disable user application (no wait fot DREQ pin and no delay, as from the VLSI source file example */ 00677 /* record.c from playercode1053-Aug2009.zip */ 00678 writeregnowait( VLSI_AIADDR, 0x0000); 00679 /* 5. Disable all IRQ except the SCI IRQ */ 00680 writeregnowait( VLSI_WRAMADDR, 0xC01A); 00681 writeregnowait( VLSI_WRAM, 0x0002); 00682 /* 6. Load the plugin code... */ 00683 loadoggpatch(); 00684 /* 7. Set bit SM_ADPCM to 1. */ 00685 temp = (unsigned short)readreg( VLSI_MODE); cWAIT_DREQ_1MS; 00686 temp |= SM_ADPCM; 00687 writeregnowait( VLSI_MODE, temp); cWAIT_DREQ_1MS; 00688 writeregnowait( VLSI_AICTRL0, 0x0000); cWAIT_DREQ_1MS; 00689 /* 8. Set recording level. Value are for conservative AGC. */ 00690 writeregnowait( VLSI_AICTRL1, 0x0000); cWAIT_DREQ_1MS; 00691 writeregnowait( VLSI_AICTRL2, 4096); cWAIT_DREQ_1MS; 00692 /* 10. Set 0 to SCI_AICTRL3. */ 00693 writeregnowait( VLSI_AICTRL3, 0x0000); cWAIT_DREQ_1MS; 00694 /* 11. Active the encoder... */ 00695 wait_ms( 5); 00696 writeregnowait( VLSI_AIADDR, 0x0034); wait_ms( 1); 00697 /* 12. wait DREQ high. */ 00698 cWAIT_DREQ; /* Loop forever. */ 00699 00700 } 00701 00702 #if 0 00703 void VS1053Codec::VoggEncoding_ReadStatus( RUNTIME_VOGG_VALUE *status) 00704 /* VorbisEncoder160c par 2.3.4, pag. 11 */ 00705 /* see VLSICodec.h for RUNTIME_VOGG_VALUE struct data. */ 00706 { 00707 unsigned short temp, temph; 00708 00709 /* Recording Time */ 00710 writereg( VLSI_WRAMADDR, 0x0008); cWAIT_DREQ_1MS; 00711 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB recording Time */ 00712 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB recording Time */ 00713 status->rec_time = ((unsigned long)temph << 16) | temp; 00714 00715 /* Average bitrate */ 00716 writereg( VLSI_WRAMADDR, 0x000C); cWAIT_DREQ_1MS; 00717 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB Average bitrate */ 00718 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB Average bitrate */ 00719 status->average_bitrate = ((unsigned long)temph << 16) | temp; 00720 00721 /* Sample Counter */ 00722 writereg( VLSI_WRAMADDR, 0x1800); cWAIT_DREQ_1MS; 00723 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB Sample Counter */ 00724 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB Average bitrate */ 00725 status->sample_counter = ((unsigned long)temph << 16) | temp; 00726 } 00727 #endif 00728 00729 00730 /* 00731 * Questa funzione legge il registro SCI_HDAT1 per verificare la presenza di 00732 * sample disponibili. In caso ci siano li legge dal reg. SCI_HDAT0 00733 * salvandoli nel puntatore passatogli. Ritorna il numero di byte copiati. 00734 */ 00735 unsigned int VS1053Codec::VoggEncoding_ReadBuffer( unsigned char *voggSample) 00736 /* VorbisEncoder160c pag. 10 */ 00737 { 00738 unsigned int i; 00739 unsigned short temp, sample; 00740 00741 temp=0; 00742 i=0; 00743 sample=0; 00744 00745 // printf("readbuffer\r\n"); 00746 00747 do { 00748 /* reading the sample counter... */ 00749 temp = (unsigned short)readreg( VLSI_HDAT1); 00750 if ( temp ) { 00751 // printf("sample %d\r\n", temp); 00752 /* there are samples... */ 00753 i=0; 00754 while( i < temp) { 00755 /* read the sample as word */ 00756 sample=(unsigned short)readreg( VLSI_HDAT0); 00757 /* save it into the array as single byte. */ 00758 *voggSample++ = (unsigned char)(sample >> 8); /* MSB */ 00759 *voggSample++ = (unsigned char)(sample & 0x00FF); /* LSB */ 00760 i++; 00761 wait_ms( 1); 00762 } 00763 00764 /* Exit the loop. */ 00765 break; 00766 } else { 00767 // printf("no sample\r\n"); 00768 /* Exit the loop. */ 00769 break; 00770 } 00771 } while( 1); 00772 /* just relax... */ 00773 wait_ms( 1); 00774 /* Return the number of byte saved. */ 00775 return i*2; 00776 } 00777 00778 /* 00779 * Questa funzione esegue la procedura di fine encoding memorizzando i rimanenti sample 00780 * nel puntatore passatogli. Ritorna il numero di sample letti. 00781 */ 00782 unsigned int VS1053Codec::VoggEncoding_Stop( unsigned char *voggSample) 00783 /* VorbisEncoder160c pag. 11 */ 00784 { 00785 unsigned int res, i, ii; 00786 unsigned short temp, sample; 00787 res=0; 00788 temp=0; 00789 sample=0; 00790 00791 /* 1. set bit 0 to 1 */ 00792 temp = (unsigned short)readreg( VLSI_AICTRL3); 00793 temp |= 0x0001; 00794 writereg( VLSI_AICTRL3, temp); 00795 00796 /* 2. continue reading data but checking the bit 1 of VLSI_AICTRL3 reg. */ 00797 res=0; 00798 do { 00799 /* reading the sample counter... */ 00800 temp = (unsigned short)readreg( VLSI_HDAT1); 00801 if ( temp) { 00802 // printf("EncStop: %d\r\n", temp); 00803 i=0; 00804 while( i < temp ) { 00805 /* */ 00806 sample = (unsigned short)readreg( VLSI_HDAT0); 00807 *voggSample++ = (unsigned char)(sample >> 8); 00808 *voggSample++ = (unsigned char)sample & 0x00FF; 00809 i++; 00810 wait_ms( 1); 00811 } 00812 res+=i; 00813 } 00814 /* just relax... */ 00815 wait_ms( 1); 00816 temp = (unsigned short)readreg( VLSI_AICTRL3); 00817 /* verify the bit 1 of VLSI_AICTRL3 reg. */ 00818 if ( temp & 0x0002) { 00819 // printf("Encoding STOP\r\n"); 00820 /* encoding has finished. */ 00821 break; 00822 } 00823 } while( 1); /* Loop forever... */ 00824 /* 3. write the remaining word... */ 00825 ii=0; 00826 do { 00827 temp = (unsigned short)readreg( VLSI_HDAT1); 00828 if ( temp) { 00829 // printf("Flush %d\r\n", temp); 00830 /* there are samples... */ 00831 i=0; 00832 while( i < temp ) { /* con il numero precedente. */ 00833 /* */ 00834 sample = (unsigned short)readreg( VLSI_HDAT0); 00835 *voggSample++ = (unsigned char)(sample >> 8); 00836 *voggSample++ = (unsigned char)sample & 0x00FF; 00837 i++; 00838 wait_ms( 1); 00839 } 00840 res+=i; 00841 } else { 00842 wait_ms( 1); 00843 ii++; 00844 } 00845 } while( ii<5); /* Loops ... */ 00846 /* 4. read twise AICTRL3 */ 00847 temp = (unsigned short)readreg( VLSI_AICTRL3); 00848 temp = (unsigned short)readreg( VLSI_AICTRL3); 00849 // printf("last read %d\r\n", temp); 00850 if ( temp & 0x0004 ) { 00851 /* remove last byte ( bits 7:0) from the last word. */ 00852 voggSample--; 00853 *voggSample=0; 00854 res=(res*2)-1; 00855 } else { 00856 res=res*2; 00857 } 00858 /* 5. Reset the codec. */ 00859 00860 /* Ritorno il numero di sample, in byte, letti. */ 00861 return res; 00862 } 00863 #endif
Generated on Fri Jul 22 2022 21:24:21 by 1.7.2