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 clemente di caprio

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers VLSIcodec.cpp Source File

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