Mohsen Samadani
/
Algorithm-testing
Code for measuring the signal with a specified length and sampling rate, and saving it on a SD card.
Diff: Audio/WM8731.cpp
- Revision:
- 0:c05b00be2229
diff -r 000000000000 -r c05b00be2229 Audio/WM8731.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Audio/WM8731.cpp Thu Jul 13 19:33:37 2017 +0000 @@ -0,0 +1,424 @@ +/** +* +* @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; +}