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

Dependents:   playback FTSESpeech i2s_audio_echo i2s_audio_sampler ... more

Files at this revision

API Documentation at this revision

Comitter:
d_worrall
Date:
Thu Aug 04 15:04:59 2011 +0000
Child:
1:7e76c6f56169
Commit message:
version 2.29

Changed in this revision

TLV320.cpp Show annotated file Show diff for this revision Revisions of this file
TLV320.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TLV320.cpp	Thu Aug 04 15:04:59 2011 +0000
@@ -0,0 +1,361 @@
+/**
+* @author Ioannis Kedros, Daniel Worrall
+*
+* @section LICENSE
+*
+* Copyright (c) 2011 mbed
+*
+* 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.
+*
+* @section DESCRIPTION
+*    Library for Texas instruments TLV320AIC23B library NXP LPC1768
+*
+*/ 
+
+#include "mbed.h"
+#include "TLV320.h"
+
+TLV320::TLV320(PinName sda, PinName scl, int addr, PinName tx_sda, PinName tx_ws, PinName clk, PinName rx_sda, PinName rx_ws)
+                         : mAddr(addr), mI2c_(sda, scl), mI2s_(tx_sda, tx_ws, clk, rx_sda, rx_ws){
+    mI2c_.frequency(150000);
+    reset();                                //TLV resets
+    power(0x07);                            //Power Up the TLV320, but not the MIC, ADC and LINE
+    format(16, STEREO);                     //16Bit I2S protocol format, STEREO
+    frequency(44100);                       //Default sample frequency is 44.1kHz
+    bypass(false);                          //Do not bypass device
+    mute(false);                            //Not muted
+    activateDigitalInterface_();            //The digital part of the chip is active
+    outputVolume(0.7, 0.7);                 //Headphone volume to the default state
+    rxBuffer = &mI2s_.rxBuffer[0];
+} 
+//Public Functions
+/******************************************************
+ * Function name:   inputVolume()
+ *
+ * Description:     set line in volume for left and right channels
+ *
+ * Parameters:      float leftVolumeIn, float rightVolumeIn
+ * Returns:         int 0 (success), -1 (value out of range)
+******************************************************/
+int TLV320::inputVolume(float leftVolumeIn, float rightVolumeIn){
+    //check values are in range
+    if((leftVolumeIn < 0.0)||leftVolumeIn > 1.0) return -1;
+    if((rightVolumeIn < 0.0)||rightVolumeIn > 1.0) return -1;
+    //convert float to encoded char
+    char left = (char)31*leftVolumeIn;          
+    char right = (char)31*rightVolumeIn;
+    //Left Channel
+    cmd[1] = left | (0 << 7);                           //set volume
+    cmd[0] = LEFT_LINE_INPUT_CHANNEL_VOLUME_CONTROL;    //set address
+    mI2c_.write(mAddr, cmd, 2);                         //send
+    //Right Channel
+    cmd[1] = right | (0 << 7);                          //set volume
+    cmd[0] = RIGHT_LINE_INPUT_CHANNEL_VOLUME_CONTROL;   //set address
+    mI2c_.write(mAddr, cmd, 2);                         //send
+    return 0;
+}
+/******************************************************
+ * Function name:   outputVolume()
+ *
+ * Description:     Set headphone (line out) volume for left an right channels
+ *
+ * Parameters:      float leftVolumeOut, float rightVolumeOut
+ * Returns:         int 0 (success), -1 (value out of range)
+******************************************************/
+int TLV320::outputVolume(float leftVolumeOut, float rightVolumeOut){
+    //check values are in range
+    if((leftVolumeOut < 0.0)||leftVolumeOut > 1.0) return -1;
+    if((rightVolumeOut < 0.0)||rightVolumeOut > 1.0) return -1;
+    //convert float to encoded char
+    char left = (char)(79*leftVolumeOut)+0x30;
+    char right = (char)(79*rightVolumeOut)+0x30;
+    //Left Channel
+    cmd[1] = left | (1 << 7);                           //set volume
+    cmd[0] = LEFT_CHANNEL_HEADPHONE_VOLUME_CONTROL;     //set address
+    mI2c_.write(mAddr, cmd, 2);                         //send
+    //Right Channel
+    cmd[1] = right | (1 << 7);                          //set volume
+    cmd[0] = RIGHT_CHANNEL_HEADPHONE_VOLUME_CONTROL;    //set address
+    mI2c_.write(mAddr, cmd, 2);                         //send
+    return 0;
+}
+/******************************************************
+ * Function name:   bypass()
+ *
+ * Description:     Send TLV320 into bypass mode, i.e. connect input to output 
+ *
+ * Parameters:      bool bypassVar
+ * Returns:         none
+******************************************************/
+void TLV320::bypass(bool bypassVar){
+    if(bypassVar == true)
+        cmd[1] = (1 << 3) | (0 << 4) | (0 << 5);//bypass enabled, DAC disabled, sidetone insertion disabled
+    else
+        cmd[1] = (0 << 3) | (1 << 4);           //bypass disabled, DAC enabled
+    cmd[1] |= (0 << 2);
+    cmd[0] = ANALOG_AUDIO_PATH_CONTROL;         //set address
+    mI2c_.write(mAddr, cmd, 2);                 //send
+}
+/******************************************************
+ * Function name:   mute()
+ *
+ * Description:     Send TLV320 into mute mode
+ *
+ * Parameters:      bool softMute
+ * Returns:         none
+******************************************************/
+void TLV320::mute(bool softMute){   
+    if(softMute == true) cmd[1] = 0x08;         //set instruction to mute
+    else cmd[1] = 0x00;                         //set instruction to NOT mute
+     
+    cmd[0] = DIGITAL_AUDIO_PATH_CONTROL;        //set address  
+    mI2c_.write(mAddr, cmd, 2);                 //send
+}    
+/******************************************************
+ * Function name:   power()
+ *
+ * Description:     Switch TLV320 on/off
+ *
+ * Parameters:      bool powerUp
+ * Returns:         none
+******************************************************/      
+void TLV320::power(bool powerUp){
+    if(powerUp == true) cmd[1] = 0x00;          //everything on
+    else cmd[1] = 0xFF;                         //everything off
+    
+    cmd[0] = POWER_DOWN_CONTROL;                //set address
+    mI2c_.write(mAddr, cmd, 2);                  //send
+}
+/******************************************************
+ * Function name:   power()
+ *
+ * Description:     Switch on individual devices on TLV320
+ *
+ * Parameters:      int device
+ * Returns:         none
+******************************************************/
+void TLV320::power(int device){
+    cmd[1] = (char)device;                      //set user defined commands
+    cmd[0] = POWER_DOWN_CONTROL;                //set address
+    mI2c_.write(mAddr, cmd, 2);                 //send
+}
+/******************************************************
+ * Function name:   format()
+ *
+ * Description:     Set interface format
+ *
+ * Parameters:      char length, bool mode
+ * Returns:         none
+******************************************************/      
+void TLV320::format(char length, bool mode){  
+    char modeSet = (1 << 6);   
+    modeSet |= (1 << 5);                        //swap left and right channels
+    
+    switch (length)                             //input data into instruction byte
+    {
+        case 16:
+            cmd[1] = modeSet | 0x02; 
+            break;
+        case 20:
+            cmd[1] = modeSet | 0x06;
+            break;
+        case 24:
+            cmd[1] = modeSet | 0x0A;
+            break;
+        case 32:
+            cmd[1] = modeSet | 0x0E;
+            break;
+        default:
+            break;
+    }
+    mI2s_.format(length, mode);
+    cmd[0] = DIGITAL_AUDIO_INTERFACE_FORMAT;        //set address
+    mI2c_.write(mAddr, cmd, 2);                     //send
+}
+/******************************************************
+ * Function name:   frequency()
+ *
+ * Description:     Set sample frequency
+ *
+ * Parameters:      int hz
+ * Returns:         int 0 (success), -1 (value not recognised)
+******************************************************/
+int TLV320::frequency(int hz){
+    char rate;
+    switch(hz){
+        case 8000:
+            rate = 0x03; 
+            break;
+        case 8021:
+            rate = 0x0B;
+            break;
+        case 32000:
+            rate = 0x06;
+            break;
+        case 44100:
+            rate = 0x08; 
+            break;
+        case 48000:
+            rate = 0x00; 
+            break;
+        case 88200:
+            rate = 0x0F;  
+            break;
+        case 96000:
+            rate = 0x07;
+            break;
+        default:
+            return -1;
+    }
+    char clockInChar = (0 << 6);
+    char clockModeChar = (1 << 0);
+
+    cmd[1] = (rate << 2) | clockInChar | clockModeChar;      //input data into instruciton byte
+    cmd[0] = SAMPLE_RATE_CONTROL;           //set address  
+    mI2c_.write(mAddr, cmd, 2);              //send
+    return 0;
+}   
+/******************************************************
+ * Function name:   reset()
+ *
+ * Description:     Reset TLV320
+ *
+ * Parameters:      none
+ * Returns:         none
+******************************************************/        
+void TLV320::reset(void){
+    cmd[0] = RESET_REGISTER;                //set address
+    cmd[1] = 0x00;                          //this resets the entire device
+    mI2c_.write(mAddr, cmd, 2);               
+}
+/******************************************************
+ * Function name:   start()
+ *
+ * Description:     Enable interrupts on the I2S port
+ *
+ * Parameters:      int mode
+ * Returns:         none
+******************************************************/
+void TLV320::start(int mode){
+    mI2s_.start(mode);
+}
+/******************************************************
+ * Function name:   stop()
+ *
+ * Description:     Disable interrupts on the I2S port
+ *
+ * Parameters:      none
+ * Returns:         none
+******************************************************/
+void TLV320::stop(void){
+    mI2s_.stop();
+}
+/******************************************************
+ * Function name:   write()
+ *
+ * Description:     Write (part of) a buffer to the I2S port
+ *
+ * Parameters:      int *buffer, int from, int length
+ * Returns:         none
+******************************************************/
+void TLV320::write(int *buffer, int from, int length){
+    mI2s_.write(buffer, from, length);
+}
+/******************************************************
+ * Function name:   read()
+ *
+ * Description:     Place I2SRXFIFO in rxBuffer
+ *
+ * Parameters:      none
+ * Returns:         none
+******************************************************/
+void TLV320::read(void){
+    mI2s_.read();
+}
+/******************************************************
+ * Function name:   attach()
+ *
+ * Description:     Attach a void/void function or void/void static member function to IRQHandler
+ *
+ * Parameters:      none
+ * Returns:         none
+******************************************************/
+void TLV320::attach(void(*fptr)(void)){
+    mI2s_.attach(fptr);
+}
+//Private Functions
+/******************************************************
+ * Function name:   setSampleRate_()
+ *
+ * Description:     Clocking control
+ *
+ * Parameters:      char rate, bool clockIn, bool clockMode, bool bOSR
+ * Returns:         none
+******************************************************/
+void TLV320::setSampleRate_(char rate, bool clockIn, bool clockMode, bool bOSR){
+    char clockInChar;
+    char clockModeChar;
+    char baseOverSamplingRate;
+    if(bOSR){
+        baseOverSamplingRate = (1 << 0);
+    } else {
+        baseOverSamplingRate = (0 << 0);
+    }
+    if(clockIn){
+        clockInChar = (1 << 6);
+    } else {
+        clockInChar = (0 << 6);
+    }
+    if(clockMode){
+        clockModeChar = 0x01;
+    } else {
+        clockModeChar = 0x00;
+    }
+    cmd[1] = (rate << 2) | clockInChar | clockModeChar | baseOverSamplingRate;      //input data into instruciton byte
+    cmd[0] = SAMPLE_RATE_CONTROL;               //set address  
+    mI2c_.write(mAddr, cmd, 2);                 //send
+}
+/******************************************************
+ * Function name:   activateDigitalInterface_()
+ *
+ * Description:     Activate digital part of chip
+ *
+ * Parameters:      none
+ * Returns:         none
+******************************************************/
+void TLV320::activateDigitalInterface_(void){
+    cmd[1] = 0x01;                          //Activate  
+    cmd[0] = DIGITAL_INTERFACE_ACTIVATION;  //set address
+    mI2c_.write(mAddr, cmd, 2);             //send
+}
+/******************************************************
+ * Function name:   deactivateDigitalInterface_
+ *
+ * Description:     Deactivate digital part of chip
+ *
+ * Parameters:      none
+ * Returns:         none
+******************************************************/
+//Digital interface deactivation 
+void TLV320::deactivateDigitalInterface_(void){
+    cmd[1] = 0x00;                          //Deactivate
+    cmd[0] = DIGITAL_INTERFACE_ACTIVATION;  //set address
+    mI2c_.write(mAddr, cmd, 2);             //send
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TLV320.h	Thu Aug 04 15:04:59 2011 +0000
@@ -0,0 +1,203 @@
+/**
+* @author Ioannis Kedros, Daniel Worrall
+*
+* @section LICENSE
+*
+* Copyright (c) 2011 mbed
+*
+* 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.
+*
+* @section DESCRIPTION
+*    Library for Texas instruments TLV320AIC23B library NXP LPC1768
+*
+*/
+
+#ifndef MBED_TLV320_H
+#define MBED_TLV320_H
+
+#include "mbed.h"
+#include "I2SSlave.h"
+
+/** TLV320 class, defined on the I2C master bus
+*
+*/
+
+class TLV320
+{        
+    public:
+        //constructor
+        /** Create a TLV320 object defined on the I2C port
+        *  
+        * @param sda Serial data pin (p9 or p28)
+        * @param scl Serial clock pin (p10 or p27)
+        * @param addr Object address
+        */
+        TLV320(PinName sda, PinName scl, int addr, PinName tx_sda, PinName tx_ws, PinName clk, PinName rx_sda, PinName rx_ws);
+        /** Power up/down
+        *
+        * @param powerUp 0 = power down, 1 = power up
+        */
+        void power(bool powerUp);
+        /** Overloaded power() function default = 0x07, record requires 0x02
+        *
+        * @param device Call individual devices to power up/down
+        * Device power      0x00 = On 0x80 = Off
+        * Clock             0x00 = On 0x40 = Off
+        * Oscillator        0x00 = On 0x20 = Off
+        * Outputs           0x00 = On 0x10 = Off
+        * DAC               0x00 = On 0x08 = Off
+        * ADC               0x00 = On 0x04 = Off
+        * Microphone input  0x00 = On 0x02 = Off
+        * Line input        0x00 = On 0x01 = Off
+        */
+        void power(int device);
+        /** Set I2S interface bit length and mode
+        *
+        * @param length Set bit length to 16, 20, 24 or 32 bits
+        * @param mode Set STEREO (0), MONO (1)
+        */
+        void format(char length, bool mode);
+        /** Set sample frequency
+         *
+         * @param frequency Sample frequency of data in Hz
+         * @return Returns an integer 0 = success, -1 = unrecognnised frequency
+         * 
+         * The TLV320 supports the following frequencies: 8kHz, 8.021kHz, 32kHz, 44.1kHz, 48kHz, 88.2kHz, 96kHz
+         * Default is 44.1kHz
+         */
+        int frequency(int hz);
+        /** Reset TLV320
+        *
+        */
+        void reset(void);
+        /** Start streaming i.e. enable interrupts
+         *
+         * @param mode Enable interrupts for NONE, TRANSMIT only, RECEIVE only, BOTH
+         */
+        void start(int mode);
+        /** Stop streaming i.e. disable all interrupts
+         *
+         */
+        void stop(void);
+        /** Write [length] 32 bit words in buffer to I2S port
+         *
+         * @param *buffer Address of buffer to be written
+         * @param from Start position in buffer to read from
+         * @param length Number of words to be written (MUST not exceed 4)
+         */
+        void write(int *buffer, int from, int length);
+        /** Read 4 x (32bit) words into rxBuffer
+         *
+         */
+        void read(void);
+        /** Attach a void/void function or void/void static member funciton to an interrupt generated by the I2SxxFIFOs
+         *
+         * @param function Function to attach
+         *
+         * e.g. myTlv320Object.attach(&myfunction);
+         * OR   myTlv320Object.attach(&myClass::myStaticMemberFunction);
+         */
+        void attach(void(*fptr)(void));
+        /** Attach a nonstatic void/void member function to an interrupt generated by the I2SxxFIFOs
+         *
+         * @param tptr Object pointer
+         * @param mptr Member function pointer
+         *
+         * e.g. myTlv320Object.attach(&myObject, &myClass::myNonstaticMemberFunction); where myObject is an object of myClass
+         */
+        template<typename T>
+        void attach(T *tptr, void(T::*mptr)(void)){
+            mI2s_.attach(tptr, mptr);
+        }
+                /** Line in volume control i.e. record volume
+        *
+        * @param leftVolumeIn Left line-in volume 
+        * @param rightVolumeIn Right line-in volume
+        * @return Returns 0 for success, -1 if parameters are out of range
+        * Parameters accept a value, where 0.0 < parameter < 1.0 and where 0.0 maps to -34.5dB 
+        * and 1.0 maps to +12dB (0.74 = 0 dB default).
+        */
+        int inputVolume(float leftVolumeIn, float rightVolumeIn);
+        /** Headphone out volume control
+        *
+        * @param leftVolumeOut Left line-out volume
+        * @param rightVolumeOut Right line-out volume
+        * @return Returns 0 for success, -1 if parameters are out of range
+        * Parameters accept a value, where 0.0 < parameter < 1.0 and where 0.0 maps to -73dB (mute) 
+        * and 1.0 maps to +6dB (0.5 = default)
+        */
+        int outputVolume(float leftVolumeOut, float rightVolumeOut);
+       /** Analog audio path control
+        *
+        * @param bypassVar Route analogue audio direct from line in to headphone out
+        */
+        void bypass(bool bypassVar);
+        /**Digital audio path control
+        *
+        * @param softMute Mute output
+        */
+        void mute(bool softMute);
+        //Receive buffer
+        
+        int *rxBuffer;
+        
+    protected:
+        char cmd[2];    //the address and command for TLV320 internal registers
+        int mAddr;      //register write address
+    private:
+        I2C mI2c_;      //MUST use the I2C port
+        I2SSlave mI2s_;
+        Ticker I2sTick;
+        void io(void);   
+       /** Sample rate control
+        *
+        * @param rate Set the sampling rate as per datasheet section 3.3.2
+        * @param clockIn Set the clock in divider MCLK, MCLK_DIV2
+        * @param clockMode Set clock mode CLOCK_NORMAL, CLOCK_USB
+        */
+        void setSampleRate_(char rate, bool clockIn, bool mode, bool bOSR); 
+       /** Digital interface activation
+        *
+        */
+        void activateDigitalInterface_(void);
+        /** Digital interface deactivation
+        *
+        */
+        void deactivateDigitalInterface_(void);
+
+        //TLV320AIC23B register addresses as defined in the TLV320AIC23B datasheet
+        #define LEFT_LINE_INPUT_CHANNEL_VOLUME_CONTROL  (0x00 << 1)
+        #define RIGHT_LINE_INPUT_CHANNEL_VOLUME_CONTROL (0x01 << 1)
+        #define LEFT_CHANNEL_HEADPHONE_VOLUME_CONTROL   (0x02 << 1)
+        #define RIGHT_CHANNEL_HEADPHONE_VOLUME_CONTROL  (0x03 << 1)
+        #define ANALOG_AUDIO_PATH_CONTROL               (0x04 << 1)
+        #define DIGITAL_AUDIO_PATH_CONTROL              (0x05 << 1)
+        #define POWER_DOWN_CONTROL                      (0x06 << 1)
+        #define DIGITAL_AUDIO_INTERFACE_FORMAT          (0x07 << 1)
+        #define SAMPLE_RATE_CONTROL                     (0x08 << 1)
+        #define DIGITAL_INTERFACE_ACTIVATION            (0x09 << 1)
+        #define RESET_REGISTER                          (0x0F << 1)
+        
+        #define CLOCK_NORMAL        0
+        #define CLOCK_USB           1
+        #define MCLK                0
+        #define MCLK_DIV2           1
+};
+
+#endif
\ No newline at end of file