Library for VS1053 chip

VLSIcodec.h

Committer:
clemente
Date:
2012-05-24
Revision:
1:399afe8151de
Parent:
0:e97876f96d4b

File content as of revision 1:399afe8151de:

/* mbed VLSIcodec library. To access VS1053 MPEG3 codec.

    Copyright (c) 2010 NXP 3790 
 
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
 
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
 
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
*/

#ifndef __VLSICODEC_H
#define __VLSICODEC_H

#include "mbed.h"

/* */
#define __PLUGINGA  1
/* */
#define   MP3_INIT_SPEED        2000000        /* 2Mbit */
#define   MP3_RUN_SPEED         3000000        /* 3Mbit */
#define   MP3_BUS_MODE          3

/** This library drive a VS1053 codec to play VAW/MP3/Ogg audio file.
 * 
 * @code
 *
 * VS1053Codec codec( p11, p12, p13, p21, p22, p23, p24);
 *
 * int main( void)
 * {
 *   codec.init();                      // initialize the codec
 *   codec.loadpatch();                 // load the patch code (rev 1.5)
 *   codec.setbassboost( 15, 150);      // set the bass boost value
 *   codec.settrebleboost( 7, 15000);   // set the treable boost value
 *   codec.setvolume( 0x0, 0x0);        // set the volume
 *
 *   // snd_piano is a Ogg file stored in flash memory. 
 *   int cnt=sizeof(snd_piano)/sizeof(snd_piano[0]);
 *   //
 *   printf("Start playing file snd_piano [%d]\n\r", cnt);
 *   //
 *   int iSize=0;
 *   while( iSize < cnt) {
 *       int count=32;
 *       codec.testdreq();
 *       while( count--) {
 *           codec.writedata( snd_piano[ iSize++]);
 *           if ( iSize > cnt)
 *               break;
 *       }
 *   }
 * }
 *
 * @endcode
 *
 */
 
//
class VS1053Codec {

public:

    /** Initialize the SPI connection to the codec and other services pins.
     *
     * @param mosi, miso, sclk the SPI connection pins
     * @param cs    the chip select SPI pin
     * @param dreq  If DREQ is high, VS1053b can take at least 32 bytes of SDI data or one SCI command. DREQ is turned
     *              low when the stream buffer is too full and for the duration of a SCI command.
     * @param rst   hardware reset, active low
     * @param xdcs  the xdcs pin is the "data chip select".
     */
    VS1053Codec( PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dreq, PinName rst, PinName xdcs);
    
    /** Initialize the connection to the VS1053 codec.
     *  Never return if fail.
     */
    void init(void);
    
    /** Test the dreq pin. If high the VS1053 can take data.
     *  The function never return until the pin goes high.
     */
    void testdreq( void);
    
    /** Reset the codec
     */
    void reset( void);
    
    /** write a byte to the codec
     *
     * @param data 
     */    
    void writedata( unsigned char data);
    
    /** Set the bass boost value
     *
     * @param bass  Bass gain in dB, range from 0 to 15 
     * @param freq  Limit frequency for bass boost, 10 Hz steps (range from
     *              20 to 150) 
     */
    void setbassboost(unsigned char bass, unsigned char gfreq);
    
    /** Set treable boost value
     *
     * @param treable Bass gain in dB, range from -8 to 7
     * @param freq    Limit frequency for bass boost, 1000 Hz steps (range from
     *                1000 to 15000)
     */
    void settrebleboost( char treble, unsigned int gfreq);
    
    /** Set the volume.
     *  Note, that after hardware reset the volume is set to full volume. Resetting the software does not reset the
     *  volume setting.
     *
     * @param right vol right channel attenuation from maximum volume, 0.5dB steps
     *                  (0x00 = full volume, 0xFE= muted, 0xFF analog power down mode)
     * @param left  vol left channel attenuation from maximum volume, 0.5dB steps
     *                  (0x00 = full volume, 0xFE= muted, 0xFF analog power down mode)
     *
     */
    void setvolume(unsigned char vRight, unsigned char vLeft);
    
    /** Get the current decodet time
     *
     * @param playtime a pointer to a string where the function will write the time in the format
     *                 MM:SS
     */
    void getplaytime(char *playtime);
    
    /** Start a sine test to verify codec functionality
     *
     * @param pitch is a composite value. Use 0x7E to play a tone at 5KHz sampled at 22050Hz.
     *              Use zero to stop to play.
     * @code
     * codec.sinetest( 0x7E); // start the sine test...
     * wait( 1);              // wait 1 sec..
     * codec.sinetest( 0x00); // stop the sine test...
     * @endcode
     */
    void sinetest(unsigned char pitch);
    
    /** Load a VLSI patch code inside the codec. The library is rev 1.5 
     *  This patch enable some features like VMeter.
     */
    void loadpatch(void);

#ifdef __ENCODE_OGG    
    /** Load a VLSI patch code to encode OGG audio file.
     *  This file will encode at fixed quality. Read the VLSIcodec_OGG.h for more...
     */
    void loadoggpatch(void);
#endif

#ifdef __PLUGINGA    
    /** Load a VLSI patch code that add a 23 band Graphics Analizer.
     *  
     */
    void loadgapatch(void);
    void readgavalue( unsigned char *currval, unsigned char *peak);
    unsigned short readgabands( void);
#endif

    
    /** Start the Vmeter functionallity.
     *
     */
    void setvmeter( void);
    
    /** Get vmeter values. Values from 0 to 31 are valid for both channels
     *  Calculates the peak sample value from both channels and returns the values in 3 dB
     *
     * @param left   left channel value
     * @param right  right channel value
     */
    void getvmeterval( unsigned char* left, unsigned char* right);
    
    /** Put the codec in reset for reduce power consuption.
     * Re-init the codec for wake-up.
     */
    void lowpower( void);

#ifdef __ENCODE_OGG
    /** Start the encoding. Reset and then load the patch to record a audio stream.
     */
    void VoggEncoding_Start( void);
    
    /** Read the encoded samples.
     *
     * @param *voggSample pointer to array to store the sample
     * @return number of byte write.
     */
    unsigned int VoggEncoding_ReadBuffer( unsigned char *voggSample);
    
    /** Stop the encoding and return the last buffer encoded.
     *
     * @param *voggSample pointer to array to store the sample
     * @return number of byte write.
     */
    unsigned int VoggEncoding_Stop( unsigned char *voggSample);
#endif
    
protected:    
    //
    unsigned short readreg(unsigned char vAddress);    
     void writereg(unsigned char vAddress, unsigned int wValue);
    void writeregnowait(unsigned char vAddress, unsigned int wValue);
    //
    SPI _spi;
    DigitalOut  _cs;
    DigitalIn   _dreq;
    DigitalOut  _rst;
    DigitalOut  _xdcs;
    
};

#endif