A library which allows the playing of Wav files using the TLV320

Dependents:   RSALB_hbridge_helloworld RSALB_lobster WavPlayer_test AudioCODEC_HelloWorld

TLV320/TLV320.cpp

Committer:
p07gbar
Date:
2012-09-21
Revision:
3:a7380cfc1987
Parent:
1:3eb96771bbee

File content as of revision 3:a7380cfc1987:

#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;
}