Library for Texas Instruments TLV320AIC23B hi-def audio chip note: requires I2SSlave abstraction library

Dependents:   playback FTSESpeech i2s_audio_echo i2s_audio_sampler ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TLV320.cpp Source File

TLV320.cpp

00001 /**
00002 * @author Ioannis Kedros, Daniel Worrall
00003 *
00004 * @section LICENSE
00005 *
00006 * Copyright (c) 2011 mbed
00007 *
00008 * Permission is hereby granted, free of charge, to any person obtaining a copy
00009 * of this software and associated documentation files (the "Software"), to deal
00010 * in the Software without restriction, including without limitation the rights
00011 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00012 * copies of the Software, and to permit persons to whom the Software is
00013 * furnished to do so, subject to the following conditions:
00014 *
00015 * The above copyright notice and this permission notice shall be included in
00016 * all copies or substantial portions of the Software.
00017 *
00018 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00019 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00021 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00022 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00023 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00024 * THE SOFTWARE.
00025 *
00026 * @section DESCRIPTION
00027 *    Library for Texas instruments TLV320AIC23B library NXP LPC1768
00028 *
00029 */ 
00030 
00031 #include "mbed.h"
00032 #include "TLV320.h"
00033 
00034 TLV320::TLV320(PinName sda, PinName scl, int addr, PinName tx_sda, PinName tx_ws, PinName clk, PinName rx_sda, PinName rx_ws)
00035                          : mAddr(addr), mI2c_(sda, scl), mI2s_(tx_sda, tx_ws, clk, rx_sda, rx_ws){
00036     mI2c_.frequency(150000);
00037     reset();                                //TLV resets
00038     power(0x07);                            //Power Up the TLV320, but not the MIC, ADC and LINE
00039     format(16, STEREO);                     //16Bit I2S protocol format, STEREO
00040     frequency(44100);                       //Default sample frequency is 44.1kHz
00041     bypass(false);                          //Do not bypass device
00042     mute(false);                            //Not muted
00043     activateDigitalInterface_();            //The digital part of the chip is active
00044     outputVolume(0.7, 0.7);                 //Headphone volume to the default state
00045     rxBuffer = &mI2s_.rxBuffer[0];
00046 } 
00047 //Public Functions
00048 /******************************************************
00049  * Function name:   inputVolume()
00050  *
00051  * Description:     set line in volume for left and right channels
00052  *
00053  * Parameters:      float leftVolumeIn, float rightVolumeIn
00054  * Returns:         int 0 (success), -1 (value out of range)
00055 ******************************************************/
00056 int TLV320::inputVolume(float leftVolumeIn, float rightVolumeIn){
00057     //check values are in range
00058     if((leftVolumeIn < 0.0)||leftVolumeIn > 1.0) return -1;
00059     if((rightVolumeIn < 0.0)||rightVolumeIn > 1.0) return -1;
00060     //convert float to encoded char
00061     char left = (char)31*leftVolumeIn;          
00062     char right = (char)31*rightVolumeIn;
00063     //Left Channel
00064     cmd[1] = left | (0 << 7);                           //set volume
00065     cmd[0] = LEFT_LINE_INPUT_CHANNEL_VOLUME_CONTROL;    //set address
00066     mI2c_.write(mAddr, cmd, 2);                         //send
00067     //Right Channel
00068     cmd[1] = right | (0 << 7);                          //set volume
00069     cmd[0] = RIGHT_LINE_INPUT_CHANNEL_VOLUME_CONTROL;   //set address
00070     mI2c_.write(mAddr, cmd, 2);                         //send
00071     return 0;
00072 }
00073 /******************************************************
00074  * Function name:   outputVolume()
00075  *
00076  * Description:     Set headphone (line out) volume for left an right channels
00077  *
00078  * Parameters:      float leftVolumeOut, float rightVolumeOut
00079  * Returns:         int 0 (success), -1 (value out of range)
00080 ******************************************************/
00081 int TLV320::outputVolume(float leftVolumeOut, float rightVolumeOut){
00082     //check values are in range
00083     if((leftVolumeOut < 0.0)||leftVolumeOut > 1.0) return -1;
00084     if((rightVolumeOut < 0.0)||rightVolumeOut > 1.0) return -1;
00085     //convert float to encoded char
00086     char left = (char)(79*leftVolumeOut)+0x30;
00087     char right = (char)(79*rightVolumeOut)+0x30;
00088     //Left Channel
00089     cmd[1] = left | (1 << 7);                           //set volume
00090     cmd[0] = LEFT_CHANNEL_HEADPHONE_VOLUME_CONTROL;     //set address
00091     mI2c_.write(mAddr, cmd, 2);                         //send
00092     //Right Channel
00093     cmd[1] = right | (1 << 7);                          //set volume
00094     cmd[0] = RIGHT_CHANNEL_HEADPHONE_VOLUME_CONTROL;    //set address
00095     mI2c_.write(mAddr, cmd, 2);                         //send
00096     return 0;
00097 }
00098 /******************************************************
00099  * Function name:   bypass()
00100  *
00101  * Description:     Send TLV320 into bypass mode, i.e. connect input to output 
00102  *
00103  * Parameters:      bool bypassVar
00104  * Returns:         none
00105 ******************************************************/
00106 void TLV320::bypass(bool bypassVar){
00107     if(bypassVar == true)
00108         cmd[1] = (1 << 3) | (0 << 4) | (0 << 5);//bypass enabled, DAC disabled, sidetone insertion disabled
00109     else
00110         cmd[1] = (0 << 3) | (1 << 4);           //bypass disabled, DAC enabled
00111     cmd[1] |= (0 << 2);
00112     cmd[0] = ANALOG_AUDIO_PATH_CONTROL;         //set address
00113     mI2c_.write(mAddr, cmd, 2);                 //send
00114 }
00115 /******************************************************
00116  * Function name:   mute()
00117  *
00118  * Description:     Send TLV320 into mute mode
00119  *
00120  * Parameters:      bool softMute
00121  * Returns:         none
00122 ******************************************************/
00123 void TLV320::mute(bool softMute){   
00124     if(softMute == true) cmd[1] = 0x08;         //set instruction to mute
00125     else cmd[1] = 0x00;                         //set instruction to NOT mute
00126      
00127     cmd[0] = DIGITAL_AUDIO_PATH_CONTROL;        //set address  
00128     mI2c_.write(mAddr, cmd, 2);                 //send
00129 }    
00130 /******************************************************
00131  * Function name:   power()
00132  *
00133  * Description:     Switch TLV320 on/off
00134  *
00135  * Parameters:      bool powerUp
00136  * Returns:         none
00137 ******************************************************/      
00138 void TLV320::power(bool powerUp){
00139     if(powerUp == true) cmd[1] = 0x00;          //everything on
00140     else cmd[1] = 0xFF;                         //everything off
00141     
00142     cmd[0] = POWER_DOWN_CONTROL;                //set address
00143     mI2c_.write(mAddr, cmd, 2);                  //send
00144 }
00145 /******************************************************
00146  * Function name:   power()
00147  *
00148  * Description:     Switch on individual devices on TLV320
00149  *
00150  * Parameters:      int device
00151  * Returns:         none
00152 ******************************************************/
00153 void TLV320::power(int device){
00154     cmd[1] = (char)device;                      //set user defined commands
00155     cmd[0] = POWER_DOWN_CONTROL;                //set address
00156     mI2c_.write(mAddr, cmd, 2);                 //send
00157 }
00158 /******************************************************
00159  * Function name:   format()
00160  *
00161  * Description:     Set interface format
00162  *
00163  * Parameters:      char length, bool mode
00164  * Returns:         none
00165 ******************************************************/      
00166 void TLV320::format(char length, bool mode){  
00167     char modeSet = (1 << 6);   
00168     modeSet |= (1 << 5);                        //swap left and right channels
00169     
00170     switch (length)                             //input data into instruction byte
00171     {
00172         case 16:
00173             cmd[1] = modeSet | 0x02; 
00174             break;
00175         case 20:
00176             cmd[1] = modeSet | 0x06;
00177             break;
00178         case 24:
00179             cmd[1] = modeSet | 0x0A;
00180             break;
00181         case 32:
00182             cmd[1] = modeSet | 0x0E;
00183             break;
00184         default:
00185             break;
00186     }
00187     mI2s_.format(length, mode);
00188     cmd[0] = DIGITAL_AUDIO_INTERFACE_FORMAT;        //set address
00189     mI2c_.write(mAddr, cmd, 2);                     //send
00190 }
00191 /******************************************************
00192  * Function name:   frequency()
00193  *
00194  * Description:     Set sample frequency
00195  *
00196  * Parameters:      int hz
00197  * Returns:         int 0 (success), -1 (value not recognised)
00198 ******************************************************/
00199 int TLV320::frequency(int hz){
00200     char rate;
00201     switch(hz){
00202         case 8000:
00203             rate = 0x03; 
00204             break;
00205         case 8021:
00206             rate = 0x0B;
00207             break;
00208         case 32000:
00209             rate = 0x06;
00210             break;
00211         case 44100:
00212             rate = 0x08; 
00213             break;
00214         case 48000:
00215             rate = 0x00; 
00216             break;
00217         case 88200:
00218             rate = 0x0F;  
00219             break;
00220         case 96000:
00221             rate = 0x07;
00222             break;
00223         default:
00224             return -1;
00225     }
00226     char clockInChar = (0 << 6);
00227     char clockModeChar = (1 << 0);
00228 
00229     cmd[1] = (rate << 2) | clockInChar | clockModeChar;      //input data into instruciton byte
00230     cmd[0] = SAMPLE_RATE_CONTROL;           //set address  
00231     mI2c_.write(mAddr, cmd, 2);              //send
00232     return 0;
00233 }   
00234 /******************************************************
00235  * Function name:   reset()
00236  *
00237  * Description:     Reset TLV320
00238  *
00239  * Parameters:      none
00240  * Returns:         none
00241 ******************************************************/        
00242 void TLV320::reset(void){
00243     cmd[0] = RESET_REGISTER;                //set address
00244     cmd[1] = 0x00;                          //this resets the entire device
00245     mI2c_.write(mAddr, cmd, 2);               
00246 }
00247 /******************************************************
00248  * Function name:   start()
00249  *
00250  * Description:     Enable interrupts on the I2S port
00251  *
00252  * Parameters:      int mode
00253  * Returns:         none
00254 ******************************************************/
00255 void TLV320::start(int mode){
00256     mI2s_.start(mode);
00257 }
00258 /******************************************************
00259  * Function name:   stop()
00260  *
00261  * Description:     Disable interrupts on the I2S port
00262  *
00263  * Parameters:      none
00264  * Returns:         none
00265 ******************************************************/
00266 void TLV320::stop(void){
00267     mI2s_.stop();
00268 }
00269 /******************************************************
00270  * Function name:   write()
00271  *
00272  * Description:     Write (part of) a buffer to the I2S port
00273  *
00274  * Parameters:      int *buffer, int from, int length
00275  * Returns:         none
00276 ******************************************************/
00277 void TLV320::write(int *buffer, int from, int length){
00278     mI2s_.write(buffer, from, length);
00279 }
00280 /******************************************************
00281  * Function name:   read()
00282  *
00283  * Description:     Place I2SRXFIFO in rxBuffer
00284  *
00285  * Parameters:      none
00286  * Returns:         none
00287 ******************************************************/
00288 void TLV320::read(void){
00289     mI2s_.read();
00290 }
00291 /******************************************************
00292  * Function name:   attach()
00293  *
00294  * Description:     Attach a void/void function or void/void static member function to IRQHandler
00295  *
00296  * Parameters:      none
00297  * Returns:         none
00298 ******************************************************/
00299 void TLV320::attach(void(*fptr)(void)){
00300     mI2s_.attach(fptr);
00301 }
00302 //Private Functions
00303 /******************************************************
00304  * Function name:   setSampleRate_()
00305  *
00306  * Description:     Clocking control
00307  *
00308  * Parameters:      char rate, bool clockIn, bool clockMode, bool bOSR
00309  * Returns:         none
00310 ******************************************************/
00311 void TLV320::setSampleRate_(char rate, bool clockIn, bool clockMode, bool bOSR){
00312     char clockInChar;
00313     char clockModeChar;
00314     char baseOverSamplingRate;
00315     if(bOSR){
00316         baseOverSamplingRate = (1 << 0);
00317     } else {
00318         baseOverSamplingRate = (0 << 0);
00319     }
00320     if(clockIn){
00321         clockInChar = (1 << 6);
00322     } else {
00323         clockInChar = (0 << 6);
00324     }
00325     if(clockMode){
00326         clockModeChar = 0x01;
00327     } else {
00328         clockModeChar = 0x00;
00329     }
00330     cmd[1] = (rate << 2) | clockInChar | clockModeChar | baseOverSamplingRate;      //input data into instruciton byte
00331     cmd[0] = SAMPLE_RATE_CONTROL;               //set address  
00332     mI2c_.write(mAddr, cmd, 2);                 //send
00333 }
00334 /******************************************************
00335  * Function name:   activateDigitalInterface_()
00336  *
00337  * Description:     Activate digital part of chip
00338  *
00339  * Parameters:      none
00340  * Returns:         none
00341 ******************************************************/
00342 void TLV320::activateDigitalInterface_(void){
00343     cmd[1] = 0x01;                          //Activate  
00344     cmd[0] = DIGITAL_INTERFACE_ACTIVATION;  //set address
00345     mI2c_.write(mAddr, cmd, 2);             //send
00346 }
00347 /******************************************************
00348  * Function name:   deactivateDigitalInterface_
00349  *
00350  * Description:     Deactivate digital part of chip
00351  *
00352  * Parameters:      none
00353  * Returns:         none
00354 ******************************************************/
00355 //Digital interface deactivation 
00356 void TLV320::deactivateDigitalInterface_(void){
00357     cmd[1] = 0x00;                          //Deactivate
00358     cmd[0] = DIGITAL_INTERFACE_ACTIVATION;  //set address
00359     mI2c_.write(mAddr, cmd, 2);             //send
00360 }
00361