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