Library for VS1053 chip
Embed:
(wiki syntax)
Show/hide line numbers
VLSIcodec.c
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 /** Put the VS1053 in low power mode (RESET) 00147 * 00148 * @param none 00149 * @retval none 00150 */ 00151 void VS1053Codec::lowpower( void) 00152 { 00153 VS1053_RST_ENABLE; 00154 wait_ms( 10); 00155 } 00156 00157 /** Initialize the VS1053 00158 */ 00159 void VS1053Codec::init(void) 00160 { 00161 // 00162 VS1053_RST_DISABLE; 00163 VS1053_CS_DISABLE; 00164 VS1053_XDCS_DISABLE; 00165 // 00166 _spi.format( 8, 0); 00167 _spi.frequency( MP3_INIT_SPEED); 00168 00169 // Assert RESET 00170 VS1053_RST_ENABLE; 00171 wait_ms( 100); 00172 00173 // Deassert RESET (active low) 00174 VS1053_RST_DISABLE; 00175 VS1053_CS_DISABLE; 00176 VS1053_XDCS_DISABLE; 00177 wait_ms( 100); 00178 00179 // Wait 00180 while(!_dreq); 00181 00182 // Reset the vs1053 00183 writereg( VLSI_MODE, ( cMODEREG_SET | SM_RESET) ); 00184 wait_ms( 10); 00185 00186 // Wait... 00187 while(!_dreq); 00188 00189 /* 00190 * Write configuration MODE register in a loop to verify that the chip is 00191 * connected and running correctly 00192 */ 00193 do 00194 { 00195 writereg( VLSI_MODE, ( cMODEREG_SET )); 00196 wait_ms( 1); 00197 }while( readreg( VLSI_MODE) != ( cMODEREG_SET )); 00198 00199 // 00200 if((readreg( VLSI_STATUS) & VLSI_STATUS_VER) == VER_VS1053) 00201 { 00202 // Set the clock to maximum speed (VS1053 only) to allow all audio formats 00203 // to be decoded without glitching. Note that this increases power 00204 // consumption. 00205 // SC_MULT = XTALI*4.5, SC_ADD = noMod, SC_FREQ = 0 (12.288MHz) 00206 // VLSIWriteReg(VLSI_CLOCKF, SC_MULT_4_5 | SC_ADD_X1 | SC_FREQ); 00207 00208 writereg(VLSI_CLOCKF, cCLOCK_SET); 00209 00210 /* */ 00211 wait_ms( 2); 00212 while(!_dreq); 00213 } 00214 else if ((readreg( VLSI_STATUS) & VLSI_STATUS_VER) == VER_VS1011E) 00215 { 00216 // Nothing special to do 00217 ; 00218 } 00219 else 00220 { 00221 // VLSI Chip version not tested, not supported, halt program execution. 00222 // This trap should be caught during the design phase. 00223 while(1); 00224 } 00225 00226 _spi.frequency( MP3_RUN_SPEED); 00227 } 00228 00229 void VS1053Codec::loadpatch(void) 00230 /* Questa funzione carica una patch al firmware del codec */ 00231 { 00232 int i = 0, plgin_len; 00233 unsigned int addr, n, val; 00234 00235 plgin_len=sizeof( plugin)/sizeof(plugin[0]); 00236 while (i<plgin_len) { 00237 00238 addr = plugin[i++]; 00239 n = plugin[i++]; 00240 if (n & 0x8000U) { /* RLE run, replicate n samples */ 00241 n &= 0x7FFF; 00242 val = plugin[i++]; 00243 while (n--) { 00244 writeregnowait(addr, val); 00245 while(!_dreq); 00246 } 00247 } else { /* Copy run, copy n samples */ 00248 while (n--) { 00249 val = plugin[i++]; 00250 writeregnowait(addr, val); 00251 while(!_dreq); 00252 } 00253 } 00254 } 00255 // 00256 wait_ms( 1); 00257 while(!_dreq); 00258 } 00259 00260 #ifdef __PLUGINGA 00261 void VS1053Codec::loadgapatch(void) 00262 /* Questa funzione carica un plugin nel codec */ 00263 { 00264 int i = 0, plgin_len; 00265 unsigned int addr, n, val; 00266 00267 plgin_len=sizeof( gaplugin)/sizeof(gaplugin[0]); 00268 while (i<plgin_len) { 00269 00270 addr = gaplugin[i++]; 00271 n = gaplugin[i++]; 00272 if (n & 0x8000U) { /* RLE run, replicate n samples */ 00273 n &= 0x7FFF; 00274 val = gaplugin[i++]; 00275 while (n--) { 00276 writeregnowait(addr, val); 00277 while(!_dreq); 00278 } 00279 } else { /* Copy run, copy n samples */ 00280 while (n--) { 00281 val = gaplugin[i++]; 00282 writeregnowait(addr, val); 00283 while(!_dreq); 00284 } 00285 } 00286 } 00287 // 00288 wait_ms( 1); 00289 while(!_dreq); 00290 } 00291 #endif 00292 00293 #ifdef __ENCODE_OGG 00294 void VS1053Codec::loadoggpatch(void) 00295 /* Questa funzione carica una patch per gestire l'encoder OGG */ 00296 { 00297 int i = 0, plgin_len; 00298 unsigned int addr, n, val; 00299 00300 plgin_len=sizeof( ogg_enc)/sizeof(ogg_enc[0]); 00301 while (i<plgin_len) { 00302 00303 addr = ogg_enc[i++]; 00304 n = ogg_enc[i++]; 00305 if (n & 0x8000U) { /* RLE run, replicate n samples */ 00306 n &= 0x7FFF; 00307 val = ogg_enc[i++]; 00308 while (n--) { 00309 writeregnowait(addr, val); 00310 while(!_dreq); 00311 } 00312 } else { /* Copy run, copy n samples */ 00313 while (n--) { 00314 val = ogg_enc[i++]; 00315 writeregnowait(addr, val); 00316 while(!_dreq); 00317 } 00318 } 00319 } 00320 // 00321 wait_ms( 1); 00322 while(!_dreq); 00323 } 00324 #endif 00325 00326 #ifdef __PLUGINGA 00327 void VS1053Codec::readgavalue( unsigned char *currval, unsigned char *peak) 00328 { 00329 writereg( VLSI_WRAMADDR, cBASE+2); 00330 unsigned short bands = (unsigned short)readreg( VLSI_WRAM); 00331 // 00332 writereg( VLSI_WRAMADDR, cBASE+4); 00333 // 00334 for (int i=0;i<bands;i++) { 00335 short pv = readreg( VLSI_WRAM); 00336 /* current value in bits 5..0, normally 0..31 00337 peak value in bits 11..6, normally 0..31 */ 00338 currval[i]=(unsigned char)(pv&0x003F); 00339 peak[i]=(unsigned char)( (pv>>6)&0x003F); 00340 } 00341 } 00342 00343 unsigned short VS1053Codec::readgabands( void) 00344 { 00345 writereg( VLSI_WRAMADDR, cBASE+2); 00346 unsigned short bands = (unsigned short)readreg( VLSI_WRAM); 00347 /* */ 00348 return bands; 00349 } 00350 00351 #endif 00352 00353 void VS1053Codec::setvmeter( void) 00354 { 00355 unsigned short tmp; 00356 00357 tmp=(unsigned short)readreg( VLSI_STATUS); 00358 tmp|=(1<<9); 00359 writereg( VLSI_STATUS, tmp); 00360 } 00361 00362 void VS1053Codec::getvmeterval( unsigned char* left, unsigned char* right) 00363 { 00364 unsigned short tmp; 00365 00366 tmp=(unsigned short)readreg( VLSI_AICTRL3); 00367 00368 *right=(unsigned char)tmp&0x00FF; 00369 *left=(unsigned char)(tmp>>8); 00370 } 00371 00372 /**************************************************************************** 00373 Function: 00374 void VS1053Codec::setbassboost(BYTE bass, BYTE gfreq) 00375 00376 Description: 00377 This function sets the bass boost. 00378 00379 Precondition: 00380 None 00381 00382 Parameters: 00383 BYTE bass - Bass gain in dB, range from 0 to 15 (MSB nibble) 00384 BYTE gfreq - Limit frequency for bass boost, 10 Hz steps (range from 00385 20 to 150) (LSB nibble) 00386 00387 Returns: 00388 None 00389 00390 Remarks: 00391 None 00392 ***************************************************************************/ 00393 void VS1053Codec::setbassboost( unsigned char bass, unsigned char gfreq) 00394 { 00395 unsigned char templ; 00396 unsigned short tmp; 00397 00398 // 00399 if(bass > 15u) 00400 bass = 15; 00401 if(gfreq > 150u) 00402 gfreq = 150; 00403 if ( gfreq < 20) 00404 gfreq = 20; 00405 00406 00407 // 00408 templ = (unsigned char)gfreq/10; 00409 00410 // put bass boost value into the upper 4 bit 00411 templ |= (bass << 4); 00412 // 00413 tmp=(unsigned short)readreg( VLSI_BASS); 00414 tmp &= 0xFF00; 00415 tmp |= templ; 00416 // 00417 writereg( VLSI_BASS, tmp); 00418 } 00419 00420 /**************************************************************************** 00421 Function: 00422 void VS1053Codec::settrebleboost(BYTE bass, WORD gfreq) 00423 00424 Description: 00425 This function sets the bass boost. 00426 00427 Precondition: 00428 None 00429 00430 Parameters: 00431 BYTE treble - Bass gain in dB, range from -8 to 7 (MSB nibble) 00432 WORD gfreq - Limit frequency for bass boost, 1000 Hz steps (range from 00433 1000 to 15000) (LSB nibble) 00434 00435 Returns: 00436 None 00437 00438 Remarks: 00439 None 00440 ***************************************************************************/ 00441 void VS1053Codec::settrebleboost( char treble, unsigned int gfreq) 00442 { 00443 unsigned char templ; 00444 unsigned short tmp; 00445 00446 // 00447 if(treble > 7) 00448 treble = 7; 00449 if ( treble < (char)-8) 00450 treble = (char)-8; 00451 00452 if(gfreq > 15000u) 00453 gfreq = 15000; 00454 if(gfreq < 1000) 00455 gfreq = 1000; 00456 00457 // 00458 templ = (unsigned char)gfreq/1000; 00459 00460 // put treble boost value into the upper 4 bit 00461 templ |= (treble << 4); 00462 // 00463 tmp=(unsigned short)readreg( VLSI_BASS); 00464 tmp &= 0x00FF; 00465 tmp |= (templ << 8); 00466 // 00467 writereg( VLSI_BASS, tmp); 00468 } 00469 00470 void VS1053Codec::getplaytime(char *playtime) 00471 { 00472 unsigned short playTime; 00473 unsigned char minutes, seconds; 00474 00475 playTime = (unsigned short)readreg(VLSI_DECODE_TIME); 00476 minutes = playTime/60; 00477 seconds = playTime%60; 00478 *playtime++=('0'+minutes/10); 00479 *playtime++=('0'+minutes%10); 00480 *playtime++=(':'); 00481 *playtime++=('0'+seconds/10); 00482 *playtime++=('0'+seconds%10); 00483 } 00484 00485 00486 /**************************************************************************** 00487 Function: 00488 void setvolume(unsigned char vRight, unsigned char vLeft) 00489 00490 Description: 00491 This function set volume for analog outputs on the VLSI codec. 00492 00493 Precondition: 00494 None 00495 00496 Parameters: 00497 unsigned char vRight - right channel attenuation from maximum volume, 0.5dB steps 00498 (0x00 = full volume, 0xFF = muted) 00499 unsigned char vLeft - left channel attenuation from maximum volume, 0.5dB steps 00500 (0x00 = full volume, 0xFF = muted) 00501 00502 Returns: 00503 None 00504 00505 Remarks: 00506 None 00507 ***************************************************************************/ 00508 void VS1053Codec::setvolume(unsigned char vRight, unsigned char vLeft) 00509 { 00510 writereg(VLSI_VOL, ((unsigned int)vLeft)<<8 | vRight); 00511 } 00512 00513 00514 void VS1053Codec::sinetest( unsigned char pitch) 00515 { 00516 unsigned int i; 00517 00518 while(!_dreq); 00519 00520 i=(unsigned short)readreg( VLSI_MODE); 00521 writereg( VLSI_MODE, ( i | SM_TESTS )); 00522 00523 VS1053_XDCS_ENABLE; 00524 00525 if ( pitch) { 00526 // START Sine Test 00527 _spi.write(0x53); 00528 _spi.write(0xEF); 00529 _spi.write(0x6E); 00530 _spi.write( pitch); 00531 _spi.write(0x00); 00532 _spi.write(0x00); 00533 _spi.write(0x00); 00534 _spi.write(0x00); 00535 } else { 00536 // STOP Sine Test 00537 _spi.write(0x45); 00538 _spi.write(0x78); 00539 _spi.write(0x69); 00540 _spi.write(0x74); 00541 _spi.write(0x00); 00542 _spi.write(0x00); 00543 _spi.write(0x00); 00544 _spi.write(0x00); 00545 } 00546 00547 VS1053_XDCS_DISABLE; 00548 00549 } 00550 00551 void VS1053Codec::writedata( unsigned char data) 00552 /* 00553 * Write data to SDI. 00554 */ 00555 { 00556 int i=0; 00557 00558 VS1053_XDCS_ENABLE; 00559 for( i=0; i<cVS1053_CS_DELAY; i++); 00560 00561 _spi.write( data); 00562 00563 for( i=0; i<cVS1053_CS_DELAY; i++); 00564 VS1053_XDCS_DISABLE; 00565 00566 } 00567 00568 //****************************************************************************** 00569 //****************************************************************************** 00570 //****************************************************************************** 00571 // Section: Internal Functions 00572 //****************************************************************************** 00573 //****************************************************************************** 00574 //****************************************************************************** 00575 00576 00577 unsigned short VS1053Codec::readreg(unsigned char vAddress) 00578 { 00579 unsigned short wValue; 00580 unsigned int i; 00581 00582 VS1053_CS_ENABLE; 00583 for ( i=0; i<cVS1053_CS_DELAY;i++); 00584 00585 _spi.write(0x03); // Read 00586 _spi.write(vAddress); // Register address 00587 ((unsigned char*)&wValue)[1] = _spi.write(0xFF); // 8 bit value high byte 00588 ((unsigned char*)&wValue)[0] = _spi.write(0xFF); // 8 bit value low byte 00589 00590 for ( i=0; i<cVS1053_CS_DELAY;i++); 00591 VS1053_CS_DISABLE; 00592 00593 return wValue; 00594 } 00595 00596 void VS1053Codec::writereg(unsigned char vAddress, unsigned int wValue) 00597 { 00598 int i; 00599 00600 while(!_dreq); 00601 00602 VS1053_CS_ENABLE; 00603 for ( i=0; i<cVS1053_CS_DELAY;i++); 00604 00605 _spi.write(0x02); // Write 00606 _spi.write(vAddress); // Register address 00607 _spi.write(((unsigned char*)&wValue)[1]); // 8 bit value to write high byte 00608 _spi.write(((unsigned char*)&wValue)[0]); // 8 bit value to write low byte 00609 00610 for ( i=0; i<cVS1053_CS_DELAY;i++); 00611 VS1053_CS_DISABLE; 00612 00613 } 00614 00615 00616 /* */ 00617 void VS1053Codec::reset( void) 00618 { 00619 // Reset the vs1053 00620 writereg(VLSI_MODE, ( cMODEREG_SET | SM_RESET) ); 00621 wait_ms( 5); 00622 // Wait... 00623 while(!_dreq); 00624 00625 // Configure CLOCK register. 00626 writereg(VLSI_CLOCKF, cCLOCK_SET); 00627 wait_ms( 5); 00628 // Wait... 00629 while(!_dreq); 00630 } 00631 00632 00633 void VS1053Codec::writeregnowait(unsigned char vAddress, unsigned int wValue) 00634 /* 00635 Write to SCI interface without waiting for the DREQ pin 00636 */ 00637 { 00638 int i; 00639 00640 VS1053_CS_ENABLE; 00641 for ( i=0; i<cVS1053_CS_DELAY;i++); 00642 00643 _spi.write(0x02); // Write 00644 _spi.write(vAddress); // Register address 00645 _spi.write(((unsigned char*)&wValue)[1]); // 8 bit value to write high byte 00646 _spi.write(((unsigned char*)&wValue)[0]); // 8 bit value to write low byte 00647 00648 for ( i=0; i<cVS1053_CS_DELAY;i++); 00649 VS1053_CS_DISABLE; 00650 00651 } 00652 00653 #ifdef __ENCODE_OGG 00654 void VS1053Codec::VoggEncoding_Start( void) 00655 /* VorbisEncoder160c pag. 9 */ 00656 { 00657 unsigned short temp; 00658 00659 /* 2. vs1053b at 55.3MHz */ 00660 writeregnowait( VLSI_CLOCKF, 0xC000); cWAIT_DREQ_1MS; 00661 /* 3. SCI_BASS to 0 */ 00662 writeregnowait( VLSI_BASS, 0x0000); cWAIT_DREQ_1MS; 00663 /* 4. Disable user application (no wait fot DREQ pin and no delay, as from the VLSI source file example */ 00664 /* record.c from playercode1053-Aug2009.zip */ 00665 writeregnowait( VLSI_AIADDR, 0x0000); 00666 /* 5. Disable all IRQ except the SCI IRQ */ 00667 writeregnowait( VLSI_WRAMADDR, 0xC01A); 00668 writeregnowait( VLSI_WRAM, 0x0002); 00669 /* 6. Load the plugin code... */ 00670 loadoggpatch(); 00671 /* 7. Set bit SM_ADPCM to 1. */ 00672 temp = (unsigned short)readreg( VLSI_MODE); cWAIT_DREQ_1MS; 00673 temp |= SM_ADPCM; 00674 writeregnowait( VLSI_MODE, temp); cWAIT_DREQ_1MS; 00675 writeregnowait( VLSI_AICTRL0, 0x0000); cWAIT_DREQ_1MS; 00676 /* 8. Set recording level. Value are for conservative AGC. */ 00677 writeregnowait( VLSI_AICTRL1, 0x0000); cWAIT_DREQ_1MS; 00678 writeregnowait( VLSI_AICTRL2, 4096); cWAIT_DREQ_1MS; 00679 /* 10. Set 0 to SCI_AICTRL3. */ 00680 writeregnowait( VLSI_AICTRL3, 0x0000); cWAIT_DREQ_1MS; 00681 /* 11. Active the encoder... */ 00682 wait_ms( 5); 00683 writeregnowait( VLSI_AIADDR, 0x0034); wait_ms( 1); 00684 /* 12. wait DREQ high. */ 00685 cWAIT_DREQ; /* Loop forever. */ 00686 00687 } 00688 00689 #if 0 00690 void VS1053Codec::VoggEncoding_ReadStatus( RUNTIME_VOGG_VALUE *status) 00691 /* VorbisEncoder160c par 2.3.4, pag. 11 */ 00692 /* see VLSICodec.h for RUNTIME_VOGG_VALUE struct data. */ 00693 { 00694 unsigned short temp, temph; 00695 00696 /* Recording Time */ 00697 writereg( VLSI_WRAMADDR, 0x0008); cWAIT_DREQ_1MS; 00698 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB recording Time */ 00699 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB recording Time */ 00700 status->rec_time = ((unsigned long)temph << 16) | temp; 00701 00702 /* Average bitrate */ 00703 writereg( VLSI_WRAMADDR, 0x000C); cWAIT_DREQ_1MS; 00704 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB Average bitrate */ 00705 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB Average bitrate */ 00706 status->average_bitrate = ((unsigned long)temph << 16) | temp; 00707 00708 /* Sample Counter */ 00709 writereg( VLSI_WRAMADDR, 0x1800); cWAIT_DREQ_1MS; 00710 temp = (unsigned short)readreg( VLSI_WRAM); /* LSB Sample Counter */ 00711 temph= (unsigned short)readreg( VLSI_WRAM); /* MSB Average bitrate */ 00712 status->sample_counter = ((unsigned long)temph << 16) | temp; 00713 } 00714 #endif 00715 00716 00717 /* 00718 * Questa funzione legge il registro SCI_HDAT1 per verificare la presenza di 00719 * sample disponibili. In caso ci siano li legge dal reg. SCI_HDAT0 00720 * salvandoli nel puntatore passatogli. Ritorna il numero di byte copiati. 00721 */ 00722 unsigned int VS1053Codec::VoggEncoding_ReadBuffer( unsigned char *voggSample) 00723 /* VorbisEncoder160c pag. 10 */ 00724 { 00725 unsigned int i; 00726 unsigned short temp, sample; 00727 00728 temp=0; 00729 i=0; 00730 sample=0; 00731 00732 // printf("readbuffer\r\n"); 00733 00734 do { 00735 /* reading the sample counter... */ 00736 temp = (unsigned short)readreg( VLSI_HDAT1); 00737 if ( temp ) { 00738 // printf("sample %d\r\n", temp); 00739 /* there are samples... */ 00740 i=0; 00741 while( i < temp) { 00742 /* read the sample as word */ 00743 sample=(unsigned short)readreg( VLSI_HDAT0); 00744 /* save it into the array as single byte. */ 00745 *voggSample++ = (unsigned char)(sample >> 8); /* MSB */ 00746 *voggSample++ = (unsigned char)(sample & 0x00FF); /* LSB */ 00747 i++; 00748 wait_ms( 1); 00749 } 00750 00751 /* Exit the loop. */ 00752 break; 00753 } else { 00754 // printf("no sample\r\n"); 00755 /* Exit the loop. */ 00756 break; 00757 } 00758 } while( 1); 00759 /* just relax... */ 00760 wait_ms( 1); 00761 /* Return the number of byte saved. */ 00762 return i*2; 00763 } 00764 00765 /* 00766 * Questa funzione esegue la procedura di fine encoding memorizzando i rimanenti sample 00767 * nel puntatore passatogli. Ritorna il numero di sample letti. 00768 */ 00769 unsigned int VS1053Codec::VoggEncoding_Stop( unsigned char *voggSample) 00770 /* VorbisEncoder160c pag. 11 */ 00771 { 00772 unsigned int res, i, ii; 00773 unsigned short temp, sample; 00774 res=0; 00775 temp=0; 00776 sample=0; 00777 00778 /* 1. set bit 0 to 1 */ 00779 temp = (unsigned short)readreg( VLSI_AICTRL3); 00780 temp |= 0x0001; 00781 writereg( VLSI_AICTRL3, temp); 00782 00783 /* 2. continue reading data but checking the bit 1 of VLSI_AICTRL3 reg. */ 00784 res=0; 00785 do { 00786 /* reading the sample counter... */ 00787 temp = (unsigned short)readreg( VLSI_HDAT1); 00788 if ( temp) { 00789 // printf("EncStop: %d\r\n", temp); 00790 i=0; 00791 while( i < temp ) { 00792 /* */ 00793 sample = (unsigned short)readreg( VLSI_HDAT0); 00794 *voggSample++ = (unsigned char)(sample >> 8); 00795 *voggSample++ = (unsigned char)sample & 0x00FF; 00796 i++; 00797 wait_ms( 1); 00798 } 00799 res+=i; 00800 } 00801 /* just relax... */ 00802 wait_ms( 1); 00803 temp = (unsigned short)readreg( VLSI_AICTRL3); 00804 /* verify the bit 1 of VLSI_AICTRL3 reg. */ 00805 if ( temp & 0x0002) { 00806 // printf("Encoding STOP\r\n"); 00807 /* encoding has finished. */ 00808 break; 00809 } 00810 } while( 1); /* Loop forever... */ 00811 /* 3. write the remaining word... */ 00812 ii=0; 00813 do { 00814 temp = (unsigned short)readreg( VLSI_HDAT1); 00815 if ( temp) { 00816 // printf("Flush %d\r\n", temp); 00817 /* there are samples... */ 00818 i=0; 00819 while( i < temp ) { /* con il numero precedente. */ 00820 /* */ 00821 sample = (unsigned short)readreg( VLSI_HDAT0); 00822 *voggSample++ = (unsigned char)(sample >> 8); 00823 *voggSample++ = (unsigned char)sample & 0x00FF; 00824 i++; 00825 wait_ms( 1); 00826 } 00827 res+=i; 00828 } else { 00829 wait_ms( 1); 00830 ii++; 00831 } 00832 } while( ii<5); /* Loops ... */ 00833 /* 4. read twise AICTRL3 */ 00834 temp = (unsigned short)readreg( VLSI_AICTRL3); 00835 temp = (unsigned short)readreg( VLSI_AICTRL3); 00836 // printf("last read %d\r\n", temp); 00837 if ( temp & 0x0004 ) { 00838 /* remove last byte ( bits 7:0) from the last word. */ 00839 voggSample--; 00840 *voggSample=0; 00841 res=(res*2)-1; 00842 } else { 00843 res=res*2; 00844 } 00845 /* 5. Reset the codec. */ 00846 00847 /* Ritorno il numero di sample, in byte, letti. */ 00848 return res; 00849 } 00850 #endif
Generated on Thu Jul 14 2022 02:00:36 by 1.7.2