Mohsen Samadani
/
Algorithm-testing
Code for measuring the signal with a specified length and sampling rate, and saving it on a SD card.
Audio/WM8731.cpp
- Committer:
- msamadani
- Date:
- 2017-10-05
- Revision:
- 2:8c5b6522139f
- Parent:
- 0:c05b00be2229
File content as of revision 2:8c5b6522139f:
/** * * @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 WM8731. Based on the WM8731 * code http://mbed.org/users/p07gbar/code/WM8731/ * */ #include "WM8731.h" #define WM8731_HP_VOL_DF_MASK 0x80 #define WM8731_DF_hp_vol_left 0.5 #define WM8731_DF_hp_vol_right 0.5 #define WM8731_DF_li_vol_left 0.5 #define WM8731_DF_li_vol_right 0.5 #define WM8731_DF_sdt_vol 0 const uint8_t base_address = 0x1A; WM8731::WM8731(PinName i2c_sda, PinName i2c_scl): i2c(i2c_sda,i2c_scl) { address = base_address; defaulter(); form_cmd(all); } WM8731::WM8731(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 WM8731::power(bool on_off) { device_all_pwr = on_off; form_cmd(power_control); } void WM8731::input_select(int input) { switch(input) { case WM8731_NO_IN: device_adc_pwr = false; device_mic_pwr = false; device_lni_pwr = false; form_cmd(power_control); break; case WM8731_LINE: device_adc_pwr = true; device_lni_pwr = true; device_mic_pwr = false; ADC_source = WM8731_LINE; form_cmd(power_control); form_cmd(path_analog); break; case WM8731_MIC: device_adc_pwr = true; device_lni_pwr = true; device_mic_pwr = true; ADC_source = WM8731_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 WM8731::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 WM8731::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 WM8731::microphone_boost(bool mic_boost) { mic_boost_ = mic_boost; } void WM8731::input_mute(bool mute) { if(ADC_source == WM8731_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 WM8731::output_mute(bool mute) { out_mute = mute; form_cmd(path_digital); } void WM8731::input_power(bool on_off) { device_adc_pwr = on_off; if(ADC_source == WM8731_MIC) { device_mic_pwr = on_off; device_lni_pwr = on_off; } else { device_mic_pwr = false; device_lni_pwr = on_off; } form_cmd(power_control); } void WM8731::output_power(bool on_off) { device_dac_pwr = on_off; device_out_pwr = on_off; form_cmd(power_control); } void WM8731::wordsize(int words) { device_bitlength = words; form_cmd(interface_format); } void WM8731::master(bool master) { device_master = master; form_cmd(interface_format); } void WM8731::frequency(int freq) { ADC_rate = freq; DAC_rate = freq; form_cmd(sample_rate); } void WM8731::input_highpass(bool enabled) { ADC_highpass_enable = enabled; form_cmd(path_digital); } void WM8731::output_softmute(bool enabled) { out_mute = enabled; form_cmd(path_digital); } void WM8731::interface_switch(bool on_off) { device_interface_active = on_off; form_cmd(interface_activation); } void WM8731::sidetone(float sidetone_vol) { sdt_vol = sidetone_vol; form_cmd(path_analog); } void WM8731::deemphasis(char code) { de_emph_code = code & 0x03; form_cmd(path_digital); } void WM8731::reset() { form_cmd(reset_reg); } void WM8731::start() { interface_switch(true); } void WM8731::bypass(bool enable) { bypass_ = enable; form_cmd(path_analog); } void WM8731::stop() { interface_switch(false); } void WM8731::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 WM8731::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 = WM8731_HP_VOL_DF_MASK; cmd |= temp & 0x7F; break; case headphone_vol_right: temp = int(hp_vol_right * 80) + 47; cmd = WM8731_HP_VOL_DF_MASK; cmd |= temp & 0x7F; break; case path_analog: temp = int(sdt_vol * 4); char vol_code = 0; switch(temp) { case 4: vol_code = 0x01; break; case 0: vol_code = 0x00; break; default: vol_code = (((0x04 - temp)&0x03) << 1) | 0x01; 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 & 0x1f) << 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 WM8731::defaulter() { hp_vol_left = WM8731_DF_hp_vol_left; hp_vol_right = WM8731_DF_hp_vol_right; li_vol_left = WM8731_DF_li_vol_left; li_vol_right = WM8731_DF_li_vol_right; sdt_vol = WM8731_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 WM8731::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 = 0x06; if(DAC_rate == 48000) temp = 0x04; break; default: temp = 0x00; break; } return temp; }