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

PreampTDA7419.cpp

Committer:
danielashercohen
Date:
2014-10-20
Revision:
1:69c37f1ab7df
Parent:
0:86ea14016b10
Child:
2:34a58356394c

File content as of revision 1:69c37f1ab7df:

/** PreampTDA7419 Library
 *
 * @Author: Dan Cohen
 */
 
#include "mbed.h"
#include "PreampTDA7419.h"
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

PreampTDA7419::PreampTDA7419(PinName sda, PinName scl):
    _device(sda, scl)
{
    _address = (TDA7419_ADDRESS<<1);
 
    _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(int command, int value) {
  int transmissionSuccessful;
  _device.start();
  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);
}