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-26
Revision:
2:34a58356394c
Parent:
1:69c37f1ab7df

File content as of revision 2:34a58356394c:

/** PreampTDA7419 Library
 *
 * @Author: Dan Cohen
 *
 */

#include "mbed.h"
#include "PreampTDA7419.h"
#include <stdio.h>
#include <string.h>

PreampTDA7419::PreampTDA7419(PinName sda, PinName scl):
    _device(sda, scl)
{
    _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;
    
    _atten_lf         =  9;
    _atten_rf         =  9;
    _atten_lr         =  9;
    _atten_rr         =  9;
    _atten_mix        =  9;
    _atten_sub        =  9;
    
}

void PreampTDA7419::writeToTDA7419 (int command, int value)
{
    int transmissionSuccessful;
    _device.start();
    transmissionSuccessful  = _device.write(TDA7419_ADDRESS<<1);
    transmissionSuccessful |= _device.write(command);
    transmissionSuccessful |= _device.write(value);
    _device.stop();
    // return (transmissionSuccessful);
}

/////////////////////////////////
// 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)
void PreampTDA7419::setAttenuationReg(int regAddr, int attenuation)
{
    int regAtten;
    if (attenuation == 11) {
        regAtten = 13;
    } else if (attenuation == 10) {
        regAtten = 6;
    } else {
        regAtten = (99-(attenuation*9));
    }
    writeToTDA7419(regAddr, 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 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                                              //
    //////////////////////////////////////////////////////////////////

    //////////////////////////
    // update the registers //
    //////////////////////////
    writeToTDA7419(s_main_source,  ( (0x78) | (_input & 0x3) ) );
    writeToTDA7419(s_main_loud,      (0xc0));
    writeToTDA7419(s_softmute,       (0xa7));
    setAttenuationReg(s_volume, _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));
    }

    setAttenuationReg(s_atten_lf  , _atten_lf  );
    setAttenuationReg(s_atten_rf  , _atten_rf  );
    setAttenuationReg(s_atten_lr  , _atten_lr  );
    setAttenuationReg(s_atten_rr  , _atten_rr  );

    setAttenuationReg(s_atten_mix , _atten_mix );
    setAttenuationReg(s_atten_sub , _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);
}

int  PreampTDA7419::increaseMiddle()
{
    if (_middle < 5) {
        _middle++;
    }
    updateTDA7419Reg();
    return(_middle);
}

int  PreampTDA7419::decreaseMiddle()
{
    if (_middle > -5) {
        _middle--;
    }
    updateTDA7419Reg();
    return(_middle);
}

int PreampTDA7419::readMiddle()
{
    return (_middle);
}

int  PreampTDA7419::increaseBass()
{
    if (_bass < 5) {
        _bass++;
    }
    updateTDA7419Reg();
    return(_bass);
}

int  PreampTDA7419::decreaseBass()
{
    if (_bass > -5) {
        _bass--;
    }
    updateTDA7419Reg();
    return(_bass);
}

int PreampTDA7419::readBass()
{
    return (_bass);
}

int  PreampTDA7419::increaseSpeaker (int speakerNumber) {
  switch (speakerNumber) {
    case (1): if (_atten_lf  < 11) { _atten_lf++;  }; updateTDA7419Reg(); return( _atten_lf  );  
    case (2): if (_atten_rf  < 11) { _atten_rf++;  }; updateTDA7419Reg(); return( _atten_rf  );  
    case (3): if (_atten_lr  < 11) { _atten_lr++;  }; updateTDA7419Reg(); return( _atten_lr  );  
    case (4): if (_atten_rr  < 11) { _atten_rr++;  }; updateTDA7419Reg(); return( _atten_rr  );  
    case (5): if (_atten_sub < 11) { _atten_sub++; }; updateTDA7419Reg(); return( _atten_sub );    
    case (6): if (_atten_mix < 11) { _atten_mix++; }; updateTDA7419Reg(); return( _atten_mix );   
  }
  return (_atten_lf );
}

int  PreampTDA7419::decreaseSpeaker (int speakerNumber) {
  switch (speakerNumber) {
    case (1): if (_atten_lf  >  0) { _atten_lf--;  }; updateTDA7419Reg(); return( _atten_lf  );  
    case (2): if (_atten_rf  >  0) { _atten_rf--;  }; updateTDA7419Reg(); return( _atten_rf  );  
    case (3): if (_atten_lr  >  0) { _atten_lr--;  }; updateTDA7419Reg(); return( _atten_lr  );  
    case (4): if (_atten_rr  >  0) { _atten_rr--;  }; updateTDA7419Reg(); return( _atten_rr  );  
    case (5): if (_atten_sub >  0) { _atten_sub--; }; updateTDA7419Reg(); return( _atten_sub );    
    case (6): if (_atten_mix >  0) { _atten_mix--; }; updateTDA7419Reg(); return( _atten_mix );   
  }
  return (_atten_lf );
}

int  PreampTDA7419::readSpeaker (int speakerNumber) {
  switch (speakerNumber) {
    case (1):  return( _atten_lf  );  
    case (2):  return( _atten_rf  ); 
    case (3):  return( _atten_lr  ); 
    case (4):  return( _atten_rr  ); 
    case (5):  return( _atten_sub ); 
    case (6):  return( _atten_mix ); 
  }
  return (_atten_lf );
}

int PreampTDA7419::toggleMix() {
  _mix = !_mix;   
  updateTDA7419Reg();
  return (_mix);   
}
    
int PreampTDA7419::readMix() {
  return (_mix);   
}