This library controls a ST TDA7419 audio control IC. This is part of a project to implement an mbed controlled car stereo. The TDA7419 will take in stereo and output four channels of audio plus a subwoofer channel.
Diff: PreampTDA7419.cpp
- Revision:
- 1:69c37f1ab7df
- Parent:
- 0:86ea14016b10
- Child:
- 2:34a58356394c
diff -r 86ea14016b10 -r 69c37f1ab7df PreampTDA7419.cpp --- a/PreampTDA7419.cpp Sun Oct 19 04:30:22 2014 +0000 +++ b/PreampTDA7419.cpp Mon Oct 20 05:54:52 2014 +0000 @@ -9,31 +9,264 @@ #include <string.h> #include <inttypes.h> - - PreampTDA7419::PreampTDA7419(PinName sda, PinName scl): _device(sda, scl) { _address = (TDA7419_ADDRESS<<1); - // _device.frequency(100000); - //_device.frequency(10000); - //_Comdelay=70; + + _volume = 6; + _input = 1; + + _mute = 0; + _mix = 0; + + // for register 4 Treble Filter + _referenceInE = 0; + _trebleCenterFreq = 0; + _treble = 0; + + // for middle frequecy filter + _middleSoftStep = 0; + _middleQ = 0; + _middle = 0; } - void PreampTDA7419::setI2CAddress(uint8_t add) { _address = (add<<1); } - -int PreampTDA7419::i2c_write(char command, char value) { +int PreampTDA7419::i2c_write(int command, int value) { int transmissionSuccessful; _device.start(); - _device.write(_address); - _device.write(command); - _device.write(value); + transmissionSuccessful = _device.write(_address); + transmissionSuccessful |= _device.write(command); + transmissionSuccessful |= _device.write(value); _device.stop(); return (transmissionSuccessful); } +void PreampTDA7419::writeToTDA7419 (int address, int value) { + i2c_write(address, value); +} + +///////////////////////////////// +// set the speaker attenuators // +///////////////////////////////// +// attenuation can be set from 0 to 11 and this is mapped to the +// values that the TDA7419 uses for it's attenuation (0->h60) + +// +// (FL/FR/RL/RR/SWL/SWR) (13-18) +int PreampTDA7419::calcAttenuationReg(int attenuation) { + int regAtten; + if (attenuation == 11) { + regAtten = 13; + } else if (attenuation == 10) { + regAtten = 6; + } else { + regAtten = (99-(attenuation*9)); + } + return (regAtten); +} + +int PreampTDA7419::calcToneAttenuationReg(int attenuation) { + int regAtten; + if (attenuation > 0) { + regAtten = 16 + (attenuation * 3); + } else if (attenuation == 0) { + regAtten = 0; + } else if (attenuation < 0) { + regAtten = 0 - (attenuation * 3); + } + return (regAtten); +} + +// update all of the registers in the TDA7419 +void PreampTDA7419::updateTDA7419Reg() { + + int regVolume; + int regTreble; + int regMiddle; + int regBass; + + int s_main_source = 0; + int s_main_loud = 1 | 0x40; + int s_softmute = 2 | 0x40; + int s_volume = 3 | 0x40; + int s_treble = 4 | 0x40; + int s_middle = 5 | 0x40; + int s_bass = 6 | 0x40; + int s_second_source = 7 | 0x40; + int s_sub_mid_bass = 8 | 0x40; + int s_mix_gain = 9 | 0x40; + int s_atten_lf = 10 | 0x40; + int s_atten_rf = 11 | 0x40; + int s_atten_lr = 12 | 0x40; + int s_atten_rr = 13 | 0x40; + int s_atten_mix = 14 | 0x40; + int s_atten_sub = 15 | 0x40; + int s_spectrum = 16 | 0x40; + int s_test = 17 | 0x40; + + ////////////////////////////////////////////////////////////////// + // Calculate actual register values from the variables that the // + // buttons control // + ////////////////////////////////////////////////////////////////// + + + +/* + // set the tone controls // + // Expect treble to have the values -5 to +5 // + // Expect trebleCenterFreq to be 0 to 3 // + // Expect referenceInE to be 0 or 1 // + // we define treble as -5 to +5 the TDA7419 register value is more complex + if (treble > 0) { + regTreble = 16 + (treble * 3); + } else if (treble == 0) { + regTreble = 0; + } else if (treble < 0) { + regTreble = 0 - (treble * 3); + } + + if (middle > 0) { + regMiddle = 16 + (middle * 3); + } else if (middle == 0) { + regMiddle = 0; + } else if (middle < 0) { + regMiddle = 0 - (middle * 3); + } + + if (bass > 0) { + regBass = 16 + (bass * 3); + } else if (bass == 0) { + regBass = 0; + } else if (bass < 0) { + regBass = 0 - (bass * 3); + } +*/ + ////////////////////////// + // update the registers // + ////////////////////////// + writeToTDA7419(s_main_source, ( (0x78) | (_input & 0x3) ) ); + writeToTDA7419(s_main_loud, (0xc0)); + writeToTDA7419(s_softmute, (0xa7)); + writeToTDA7419(s_volume, calcAttenuationReg(_volume)); + + // tone register attenuation isn't simple so moving that + // calculation to a separate function + // locking softwtep as '0' because that is on and I think we + // want soft step! + writeToTDA7419(s_treble, + ( (0 & 0x1 ) << 7 ) | + ( (1 & 0x3 ) << 5 ) | + ( (calcToneAttenuationReg(_treble) & 0x1f ) ) ); + + writeToTDA7419(s_middle, + ( (0 & 0x1 ) << 7 ) | + ( (1 & 0x3 ) << 5 ) | + ( (calcToneAttenuationReg(_middle) & 0x1f ) ) ); + + writeToTDA7419(s_bass, + ( (0 & 0x1 ) << 7 ) | + ( (1 & 0x3 ) << 5 ) | + ( (calcToneAttenuationReg(_bass) & 0x1f ) ) ); + + // this register allows the second source to be routed to the rear speakers + // not useful in the context of this project + writeToTDA7419(s_second_source, (0x07)); + + // this is the subwoofer cut-off frequency + // 11 which is 160Khz) + writeToTDA7419(s_sub_mid_bass, (0x63)); + + // mix to the front speakers, enable the sub, no gain + if (_mix == 1) { + writeToTDA7419(s_mix_gain, (0xf7)); + } else { + writeToTDA7419(s_mix_gain, (0xf0)); + } + + s_atten_lf = calcAttenuationReg(_atten_lf ); + s_atten_rf = calcAttenuationReg(_atten_rf ); + s_atten_lr = calcAttenuationReg(_atten_lr ); + s_atten_rr = calcAttenuationReg(_atten_rr ); + + s_atten_mix = calcAttenuationReg(_atten_mix ); + s_atten_sub = calcAttenuationReg(_atten_sub ); + + writeToTDA7419 (s_spectrum, (0x09)); + +} + +/* setVolume: This sets the volume within the valid range of 0->11 + return indicates it was successfully set */ +void PreampTDA7419::setVolume(int volume) { + if (volume > 11) { + _volume = 11; + } + else if (volume < 0) { + volume = 0; + } + else { + _volume = volume; + } + updateTDA7419Reg(); +} + +/* readVolume: return the volume level that is currently set */ +int PreampTDA7419::readVolume() { + return (_volume); +} +/* readVolume: return the volume level that is currently set */ +int PreampTDA7419::increaseVolume() { + _volume++; + setVolume(_volume); + return (_volume); +} +/* readVolume: return the volume level that is currently set */ +int PreampTDA7419::decreaseVolume() { + _volume--; + setVolume(_volume); + return (_volume); +} + +void PreampTDA7419::setInput(int input) { + if (input > 3) { + _input = 3; + } + else if (input < 0) { + input = 0; + } + else { + _input = input; + } + updateTDA7419Reg(); +} + +int PreampTDA7419::readInput() { + return (_input); +} + +int PreampTDA7419::increaseTreble() { + if (_treble < 5) { + _treble++; + } + updateTDA7419Reg(); + return(_treble); +} + +int PreampTDA7419::decreaseTreble() { + if (_treble > -5) { + _treble--; + } + updateTDA7419Reg(); + return(_treble); +} + +int PreampTDA7419::readTreble() { + return (_treble); +} + +