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.

Dependents:   car_stereo

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);
+}
+
+