A fairly well tested TLV320 library for I2C configuration and control of the TI TLV320 part

Dependents:   TLV320_Write_test

Files at this revision

API Documentation at this revision

Comitter:
p07gbar
Date:
Wed Sep 19 10:56:31 2012 +0000
Child:
1:3ee50344f8f4
Commit message:
Working stably

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	Wed Sep 19 10:56:31 2012 +0000
@@ -0,0 +1,396 @@
+#include "TLV320.h"
+
+#define TLV320_HP_VOL_DF_MASK 0x80
+
+
+#define TLV320_DF_hp_vol_left     0.5
+#define TLV320_DF_hp_vol_right     0.5
+#define TLV320_DF_li_vol_left     0.5
+#define TLV320_DF_li_vol_right    0.5
+#define TLV320_DF_sdt_vol         0
+
+const uint8_t base_address = 0x1A;
+
+
+TLV320::TLV320(PinName i2c_sda, PinName i2c_scl): i2c(i2c_sda,i2c_scl)  {
+    address = base_address;
+    defaulter();
+    form_cmd(all);
+}
+
+TLV320::TLV320(PinName i2c_sda, PinName i2c_scl, bool cs_level): i2c(i2c_sda,i2c_scl)  {
+    address = base_address + (1*cs_level);
+    defaulter();
+    form_cmd(all);
+}
+
+void TLV320::power(bool on_off) {
+    device_all_pwr = on_off;
+    form_cmd(power_control);
+}
+
+void TLV320::input_select(int input) {
+
+    switch(input)
+    {
+        case TLV320_NO_IN:
+            device_adc_pwr = false;
+            device_mic_pwr = false;
+            device_lni_pwr = false;
+            form_cmd(power_control);
+            break;
+        case TLV320_LINE:
+            device_adc_pwr = true;
+            device_lni_pwr = true;
+            device_mic_pwr = false;
+            ADC_source = TLV320_LINE;
+            form_cmd(power_control);
+            form_cmd(path_analog);
+            break;
+        case TLV320_MIC:
+            device_adc_pwr = true;
+            device_lni_pwr = false;
+            device_mic_pwr = true;
+            ADC_source = TLV320_MIC;
+            form_cmd(power_control);
+            form_cmd(path_analog);
+            break;
+        default:
+            device_adc_pwr     = df_device_adc_pwr;
+            device_mic_pwr     = df_device_mic_pwr;
+            device_lni_pwr     = df_device_lni_pwr;
+            ADC_source         = df_ADC_source;
+            form_cmd(power_control);
+            form_cmd(path_analog);
+            break;
+    }
+    ADC_source_old = ADC_source;
+}
+
+void TLV320::headphone_volume(float h_volume) {
+    hp_vol_left = h_volume;
+    hp_vol_right = h_volume;
+    form_cmd(headphone_vol_left);
+    form_cmd(headphone_vol_right);
+}
+
+void TLV320::linein_volume(float li_volume) {
+    li_vol_left = li_volume;
+    li_vol_right = li_volume;
+    form_cmd(line_in_vol_left);
+    form_cmd(line_in_vol_right);
+}
+
+void TLV320::microphone_boost(bool mic_boost) {
+    mic_boost_ = mic_boost;
+}
+
+void TLV320::input_mute(bool mute) {
+    if(ADC_source == TLV320_MIC)
+    {
+        mic_mute = mute;
+        form_cmd(path_analog);
+    }
+    else
+    {
+        li_mute_left = mute;
+        li_mute_right = mute;
+        form_cmd(line_in_vol_left);
+        form_cmd(line_in_vol_right);
+    }
+}
+
+void TLV320::output_mute(bool mute) {
+    out_mute = mute;
+    form_cmd(path_digital);
+}
+
+void TLV320::input_power(bool on_off) {
+    
+    device_adc_pwr = on_off;
+    
+    if(ADC_source == TLV320_MIC)
+    {
+        device_mic_pwr = on_off;
+        device_lni_pwr = false;
+    }
+    else
+    {
+        device_mic_pwr = false;
+        device_lni_pwr = on_off;
+    }
+    
+    form_cmd(power_control);
+}
+
+void TLV320::output_power(bool on_off) {
+    device_dac_pwr = on_off;
+    device_out_pwr = on_off;
+    
+    form_cmd(power_control);
+}
+
+void TLV320::wordsize(int words) {
+    device_bitlength = words;
+    form_cmd(interface_format);
+}
+
+void TLV320::master(bool master) {
+    device_master = master;
+    form_cmd(interface_format);
+}
+
+void TLV320::frequency(int freq) {
+    ADC_rate = freq;
+    DAC_rate = freq;
+    form_cmd(sample_rate);
+}
+
+void TLV320::input_highpass(bool enabled) {
+    ADC_highpass_enable = enabled;
+    form_cmd(path_digital);
+}
+
+void TLV320::output_softmute(bool enabled) {
+    out_mute = enabled;
+    form_cmd(path_digital);
+}
+
+void TLV320::interface_switch(bool on_off) {
+    device_interface_active = on_off;
+    form_cmd(interface_activation);
+}
+
+void TLV320::sidetone(float sidetone_vol) {
+    sdt_vol = sidetone_vol;
+    form_cmd(path_analog);
+}
+
+void TLV320::deemphasis(char code) {
+    de_emph_code = code & 0x03;
+    form_cmd(path_digital);
+}
+
+void TLV320::reset() {
+    form_cmd(reset_reg);
+}
+
+void TLV320::start() {
+    interface_switch(true);
+}
+
+void TLV320::bypass(bool enable) {
+    bypass_ = enable;
+    form_cmd(path_analog);
+}
+
+void TLV320::stop() {
+    interface_switch(false);
+}
+
+void TLV320::command(reg_address add, uint16_t cmd) {
+    char temp[2];
+    temp[0] = (char(add)<<1) | ((cmd >> 6) & 0x01);
+    temp[1] = (cmd & 0xFF);
+    i2c.write((address<<1), temp, 2);
+}
+
+void TLV320::form_cmd(reg_address add) {
+    uint16_t cmd = 0;
+    int temp = 0;
+    bool mute;
+    switch(add)
+    {
+        case line_in_vol_left:
+            temp = int(li_vol_left * 32) - 1;
+            mute = li_mute_left;
+            
+            if(temp < 0) 
+            {
+                temp = 0; 
+                mute = true;
+            }
+            cmd = temp & 0x1F;
+            cmd |= mute << 7;
+            break;
+        case line_in_vol_right:
+            temp = int(li_vol_right * 32) - 1;
+            mute = li_mute_right;
+            if(temp < 0) 
+            {
+                temp = 0; 
+                mute = true;
+            }
+            cmd = temp & 0x1F;
+            cmd |= mute << 7;
+            break;
+            
+        case headphone_vol_left:
+            temp = int(hp_vol_left * 80) + 47;
+            cmd = TLV320_HP_VOL_DF_MASK;
+            cmd |= temp & 0x7F;
+            break;
+        case headphone_vol_right:
+            temp = int(hp_vol_right * 80) + 47;
+            cmd = TLV320_HP_VOL_DF_MASK;
+            cmd |= temp & 0x7F;
+            break;
+        
+        case path_analog:
+            temp = int(sdt_vol * 5);
+            char vol_code = 0;
+            switch(temp)
+            {
+                case 5:
+                    vol_code = 0x0C;
+                    break;
+                case 0:
+                    vol_code = 0x00;
+                    break;
+                default:
+                    vol_code = ((0x04 - temp)&0x07) | 0x08;
+                    break;
+            }
+            cmd = vol_code << 5;
+            cmd |= 1 << 4;
+            cmd |= bypass_ << 3;
+            cmd |= ADC_source << 2;
+            cmd |= mic_mute << 1;
+            cmd |= mic_boost_;
+            break;
+            
+        case path_digital:
+            cmd |= out_mute << 3;
+            cmd |= ((de_emph_code & 0x3) << 1);
+            cmd |= ADC_highpass_enable;
+            break;
+        
+        case power_control:
+            cmd |= !device_all_pwr << 7;
+            cmd |= !device_clk_pwr << 6;
+            cmd |= !device_osc_pwr << 5;
+            cmd |= !device_out_pwr << 4;
+            cmd |= !device_dac_pwr << 3;
+            cmd |= !device_adc_pwr << 2;
+            cmd |= !device_mic_pwr << 1;
+            cmd |= !device_lni_pwr << 0;
+            break;
+            
+        case interface_format:
+            cmd |= device_master << 6;
+            cmd |= device_lrswap << 5;
+            cmd |= device_lrws     << 4;
+            temp = 0;
+            switch(device_bitlength)
+            {
+                case 16:
+                    temp = 0;
+                    break;
+                case 20:
+                    temp =  1;
+                    break;
+                case 24:
+                    temp = 2;
+                    break;
+                case 32:
+                    temp = 3;
+                    break;
+            }
+            cmd |= (temp & 0x03) << 2;
+            cmd |= (device_data_form & 0x03);
+            break;
+        
+        case sample_rate:
+            temp = gen_samplerate();
+            cmd = device_usb_mode;
+            cmd |= (temp & 0x03) << 1;
+            cmd |= device_clk_in_div << 6;
+            cmd |= device_clk_out_div << 7;
+            break;
+            
+        case interface_activation:
+            cmd = device_interface_active;
+            break;
+            
+        case reset_reg:
+            cmd = 0;
+            break;
+        
+        case all:
+            for( int i = line_in_vol_left; i <= reset_reg; i++)
+            {
+                form_cmd((reg_address)i);
+            }
+            break;
+    }
+    if(add != all) command(add , cmd);
+}
+
+void TLV320::defaulter() {
+    hp_vol_left = TLV320_DF_hp_vol_left;
+    hp_vol_right = TLV320_DF_hp_vol_right;
+    li_vol_left = TLV320_DF_li_vol_left;
+    li_vol_right = TLV320_DF_li_vol_right;
+    sdt_vol = TLV320_DF_sdt_vol;
+    bypass_ = df_bypass_;
+    
+    ADC_source = df_ADC_source;
+    ADC_source_old = df_ADC_source;
+    
+    mic_mute = df_mic_mute;
+    li_mute_left = df_li_mute_left;
+    li_mute_right = df_li_mute_right;
+    
+    
+    mic_boost_ = df_mic_boost_;
+    out_mute = df_out_mute;
+    de_emph_code = df_de_emph_code;
+    ADC_highpass_enable = df_ADC_highpass_enable;
+    
+    device_all_pwr = df_device_all_pwr;
+    device_clk_pwr = df_device_clk_pwr;
+    device_osc_pwr = df_device_osc_pwr;
+    device_out_pwr = df_device_out_pwr;
+    device_dac_pwr = df_device_dac_pwr;
+    device_adc_pwr = df_device_dac_pwr;
+    device_mic_pwr = df_device_mic_pwr;
+    device_lni_pwr = df_device_lni_pwr;
+    
+    device_master         = df_device_master;
+    device_lrswap         = df_device_lrswap;
+    device_lrws         = df_device_lrws;
+    device_bitlength      = df_device_bitlength;
+
+    
+    ADC_rate  = df_ADC_rate;
+    DAC_rate  = df_DAC_rate;
+
+    device_interface_active  = df_device_interface_active;
+}
+
+char TLV320::gen_samplerate() {
+    char temp = 0;
+    switch(ADC_rate)
+    {
+        case 96000:
+            temp = 0x0E;
+            break;
+        case 48000:
+            temp = 0x00;
+            if(DAC_rate == 8000) temp = 0x02;
+            break;
+        case 32000:
+            temp = 0x0C;
+            break;
+        case 8000:
+            temp = 0x03;
+            if(DAC_rate == 48000) temp = 0x04;
+            break;
+        default:
+            temp = 0x00;
+            break;
+    }
+    return temp;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TLV320.h	Wed Sep 19 10:56:31 2012 +0000
@@ -0,0 +1,305 @@
+/**
+* @author Giles Barton-Owen
+*
+* @section LICENSE
+*
+* Copyright (c) 2012 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
+*    A Driver set for the I2C half of the TLV320
+*
+*/ 
+
+
+#ifndef TLV320_H
+#define TLV320_H
+#include "mbed.h"
+
+#define TLV320_CS_HIGH                 true
+#define TLV320_CS_LOW                false
+
+#define TLV320_ON                     true
+#define TLV320_OFF                     false
+
+#define TLV320_MUTE                 true
+#define TLV320_UNMUTE                false
+
+#define TLV320_MASTER                 true
+#define TLV320_SLAVE                 false
+
+#define TLV320_LINE                    0
+#define TLV320_MIC                    1
+#define TLV320_NO_IN                -1
+
+#define TLV320_DE_EMPH_DISABLED        0
+#define TLV320_DE_EMPH_32KHZ        1
+#define TLV320_DE_EMPH_44KHZ        2
+#define TLV320_DE_EMPH_48KHZ        3
+
+/** A class to control the I2C part of the TLV320
+ * 
+ */
+class TLV320
+{
+    public:
+    /** Create an instance of the TLV320 class
+     *
+     * @param i2c_sda The SDA pin of the I2C
+     * @param i2c_scl The SCL pin of the I2C
+     */
+    TLV320(PinName i2c_sda, PinName i2c_scl);
+    
+    /** Create an instance of the TLV320 class
+     *
+     * @param i2c_sda The SDA pin of the I2C
+     * @param i2c_scl The SCL pin of the I2C
+     * @param cs_level The level of the CS pin on the TLV320
+     */
+    TLV320(PinName i2c_sda, PinName i2c_scl, bool cs_level);
+    
+    /** Control the power of the device
+     *
+     * @param on_off The power state
+     */
+    void power(bool on_off);
+    
+    /** Control the input source of the device
+     *
+     * @param input Select the source of the input of the device: TLV320_LINE, TLV320_MIC, TLV320_NO_IN
+     */
+    void input_select(int input);
+    
+    /** Set the headphone volume
+     *
+     * @param h_volume The desired headphone volume: 0->1
+     */
+    void headphone_volume(float h_volume);
+    
+    /** Set the line in pre-amp volume
+     *
+     * @param li_volume The desired line in volume: 0->1
+     */
+    void linein_volume(float li_volume);
+    
+    /** Turn on/off the microphone pre-amp boost
+     * 
+     * @param mic_boost Boost on or off
+     */
+    void microphone_boost(bool mic_boost);
+    
+    /** Mute the input
+     *
+     * @param mute Mute on/off
+     */
+    void input_mute(bool mute);
+    
+    /** Mute the output
+     *
+     * @param mute Mute on/off
+     */
+    void output_mute(bool mute);
+    
+    /** Turn on/off the input stage
+     *
+     * @param on_off Input stage on(true)/off(false)
+     */
+    void input_power(bool on_off);
+    
+    /** Turn on/off the output stage
+     *
+     * @param on_off Output stage on(true)/off(false)
+     */
+    void output_power(bool on_off);
+    
+    /** Select the word size
+     *
+     * @param words 16/20/24/32 bits
+     */
+    void wordsize(int words);
+    
+    /** Select interface mode: Master or Slave
+     *
+     * @param master Interface mode: master(true)/slave
+     */
+    void master(bool master);
+    
+    /** Select the sample rate
+     *
+     * @param freq Frequency: 96/48/32/8 kHz
+     */
+    void frequency(int freq);
+    
+    /** Enable the input highpass filter
+     *
+     * @param enabled Input highpass filter enabled
+     */
+    void input_highpass(bool enabled);
+    
+    /** Enable the output soft mute
+     *
+     * @param enabled Output soft mute enabled
+     */
+    void output_softmute(bool enabled);
+    
+    /** Turn on and off the I2S
+     * 
+     * @param on_off Switch the I2S interface on(true)/off(false)
+     */
+    void interface_switch(bool on_off);
+    
+    /** Reset the device and settings
+     *
+     */
+    void reset();
+    
+    /** Set the microphone sidetone volume
+     *
+     * @param sidetone_volume The volume of the sidetone: 0->1
+     */
+    void sidetone(float sidetone_vol);
+    
+    /** Set the analog bypass
+     * 
+     * @param bypass_en Enable the bypass: enabled(true)
+     */
+    void bypass(bool bypass_en);
+    
+    /** Set the deemphasis frequency
+     *
+     * @param code The deemphasis code: TLV320_DE_EMPH_DISABLED, TLV320_DE_EMPH_32KHZ, TLV320_DE_EMPH_44KHZ, TLV320_DE_EMPH_48KHZ
+     */
+    void deemphasis(char code);
+    
+    /** Enable the input highpass filter
+     *
+     * @param enable Enable the input highpass filter enabled(true)
+     */
+     
+    void adc_highpass(bool enable);
+    
+    /** Start the device sending/recieving etc
+    */
+    void start();
+    
+    /** Stop the device sending/recieving etc
+    */
+    void stop();
+    
+    private:
+    
+    enum reg_address {
+        line_in_vol_left         = 0x00,
+        line_in_vol_right         = 0x01,
+        headphone_vol_left        = 0x02,
+        headphone_vol_right        = 0x03,
+        path_analog                = 0x04,
+        path_digital            = 0x05,
+        power_control            = 0x06,
+        interface_format        = 0x07,
+        sample_rate                = 0x08,
+        interface_activation    = 0x09,
+        reset_reg                = 0x0A,
+        all                        = 0xFF
+    };
+    
+    enum tlv320_defaults{
+        df_bypass_         = 0,
+        df_ADC_source     = TLV320_LINE,
+        df_mic_mute     = TLV320_UNMUTE,
+        df_li_mute_left = 0,
+        df_li_mute_right = 0,
+        df_mic_boost_     = 0,
+        df_out_mute     = TLV320_UNMUTE,
+        
+        df_de_emph_code         = 0x00,
+        df_ADC_highpass_enable     = 0,
+        
+        df_device_all_pwr     = 1,
+        df_device_clk_pwr     = 1,
+        df_device_osc_pwr     = 1,
+        df_device_out_pwr     = 1,
+        df_device_dac_pwr     = 1,
+        df_device_adc_pwr     = 1,
+        df_device_mic_pwr     = 0,
+        df_device_lni_pwr     = 1,
+        
+        df_device_master         = 0,
+        df_device_lrswap         = 0,
+        df_device_lrws            = 0,
+        df_device_bitlength        = 32,
+
+        df_ADC_rate            = 32000,
+        df_DAC_rate            = 32000,
+
+        df_device_interface_active = 0
+    };
+    
+    
+    I2C i2c;
+    uint8_t address;
+    void command(reg_address add, uint16_t byte);
+    void form_cmd(reg_address add);
+    void defaulter();
+    
+    char gen_samplerate();
+    
+    //I2S i2s_tx(I2S_TRANSMIT, p5, p6 , p7);
+    //I2S i2s_rx(I2S_RECIEVE , p8, p29, p30);
+    
+    float hp_vol_left, hp_vol_right;
+    float li_vol_left, li_vol_right;
+    float sdt_vol;
+    bool li_mute_left, li_mute_right;
+    bool bypass_;
+    bool ADC_source;
+    bool ADC_source_old;
+    bool mic_mute;
+    bool mic_boost_;
+    bool out_mute;
+    char de_emph_code;
+    bool ADC_highpass_enable;
+    
+    bool device_all_pwr;
+    bool device_clk_pwr;
+    bool device_osc_pwr;
+    bool device_out_pwr;
+    bool device_dac_pwr;
+    bool device_adc_pwr;
+    bool device_mic_pwr;
+    bool device_lni_pwr;
+    
+    bool device_master;
+    bool device_lrswap;
+    bool device_lrws;
+    char device_bitlength;
+    static const char device_data_form = 0x02;
+    
+    int ADC_rate;
+    int DAC_rate;
+    static const bool device_usb_mode = false;
+    static const bool device_clk_in_div = false;
+    static const bool device_clk_out_div = false;
+    bool device_interface_active;
+    
+};
+
+
+#endif
\ No newline at end of file