Car stereo control using TDA7419 for input select, audio control. Adafruit 96x64 monochrome 0.96" display to show the audio selections four buttons to control selections. Next steps: take input from the car steering wheel controls!
Dependencies: Adafruit_GFX PinDetect_KL25Z PreampTDA7419 mbed
main.cpp
- Committer:
- danielashercohen
- Date:
- 2014-10-12
- Revision:
- 1:f5b8687f67b8
- Parent:
- 0:36eee45709c8
- Child:
- 2:2b0cf4d80668
File content as of revision 1:f5b8687f67b8:
#include "mbed.h"
#include "PinDetect.h"
#include "Adafruit_SSD1306.h"
PinDetect PinUp ( PTA1 );
PinDetect PinLeft ( PTD4 );
PinDetect PinRight ( PTA2 );
PinDetect PinDown ( PTA12 );
class SPI2 : public SPI
{
public:
SPI2(PinName mosi, PinName miso, PinName clk) : SPI(mosi,miso,clk)
{
format(8,3);
frequency(2000000);
};
};
SPI2 gSpi(PTD2,NC,PTD1);
Adafruit_SSD1306 display (gSpi, PTD0, PTD5, PTA13); // SPI obect, DC, RST, CS
void testfillrect(void) {
uint8_t color = 1;
for (int16_t i=0; i<display.height()/2; i+=3) {
// alternate colors
wait(0.05);
display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
display.display();
color++;
}
}
void displayWrite(char firstLine[], int value)
{
display.clearDisplay();
display.setCursor(0,0);
display.setTextSize(2);
display.printf("%s\r\n", firstLine);
display.setCursor(0,30);
display.setTextSize(5);
display.printf(" %d\r\n", value);
display.display();
}
///////////////////////////
// Variables for TDA7419 //
///////////////////////////
// I2C address for TDA7419
#define TDA7419_ADDRESS 0x44
////////////////////////////////////
// register addresses for TDA7419 //
////////////////////////////////////
char s_main_source = 0;
char s_main_loud = 1 | 0x40;
char s_softmute = 2 | 0x40;
char s_volume = 3 | 0x40;
char s_treble = 4 | 0x40;
char s_middle = 5 | 0x40;
char s_bass = 6 | 0x40;
char s_second_source = 7 | 0x40;
char s_sub_mid_bass = 8 | 0x40;
char s_mix_gain = 9 | 0x40;
char s_atten_lf = 10 | 0x40;
char s_atten_rf = 11 | 0x40;
char s_atten_lr = 12 | 0x40;
char s_atten_rr = 13 | 0x40;
char s_atten_mix = 14 | 0x40;
char s_atten_sub = 15 | 0x40;
char s_spectrum = 16 | 0x40;
char s_test = 17 | 0x40;
#define NUM_OPTIONS 12 // how many different options can be selected by the display?
char option = NUM_OPTIONS; // selectOption() in setup to
// set this to 0 and set up display
char volume = 4;
char input = 1;
char mute = 0;
char mix = 0;
// for register 4 Treble Filter
int referenceInE = 0;
int trebleCenterFreq = 0;
int treble;
// for middle frequecy filter
int middleSoftStep = 0;
int middleQ = 0;
int middle = 0;
// for bass frequecy filter
int bassSoftStep = 0;
int bassQ = 0;
int bass = 0;
// for output attenuators
char atten_lf = 8;
char atten_rf = 8;
char atten_lr = 8;
char atten_rr = 8;
char atten_mix = 8;
char atten_sub = 10;
void i2c_write(char device_address, char command, char value) {
// wait(0.3);
//display.printf("Transmitted!!");
//display.update();
}
void writeToTDA7419 (char address, char value) {
i2c_write(TDA7419_ADDRESS, 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)
void TDA7419SetAttenuation(int address, int attenuation) {
char regAtten;
if (volume == 11) {
regAtten = 13;
} else if (attenuation == 10) {
regAtten = 6;
} else {
regAtten = (99-(attenuation*9));
}
writeToTDA7419(address, regAtten);
}
// update all of the registers in the TDA7419
void updateReg() {
char regVolume;
char regTreble;
char regMiddle;
char regBass;
//////////////////////////////////////////////////////////////////
// Calculate actual register values from the variables that the //
// buttons control //
//////////////////////////////////////////////////////////////////
// set the master volume //
// need to calculate the regVolume from the global volume signal
// volume can be set from 0 to 11 and this is mapped to the
// values that the TDA7419 uses for it's volume register
// which are a little odd (11 is appropriate because 0->15 register
// values actually specify a gain, 16->96 specify attenuation)
if (volume == 11) {
regVolume = 13;
} else if (volume == 10) {
regVolume = 6;
} else {
regVolume = (99-(volume*9));
}
// 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));
TDA7419SetAttenuation(s_volume, regVolume );
writeToTDA7419(s_treble,
( (referenceInE & 0x1 ) << 7 ) |
( (trebleCenterFreq & 0x3 ) << 5 ) |
( (regTreble & 0x1f ) ) );
writeToTDA7419(s_middle,
( (middleSoftStep & 0x1 ) << 7 ) |
( (middleQ & 0x3 ) << 5 ) |
( (regMiddle & 0x1f ) ) );
writeToTDA7419(s_bass,
( (bassSoftStep & 0x1 ) << 7 ) |
( (bassQ & 0x3 ) << 5 ) |
( (regBass & 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));
}
TDA7419SetAttenuation(s_atten_lf, atten_lf );
TDA7419SetAttenuation(s_atten_rf, atten_rf );
TDA7419SetAttenuation(s_atten_lr, atten_lr );
TDA7419SetAttenuation(s_atten_rr, atten_rr );
TDA7419SetAttenuation(s_atten_mix, atten_mix );
TDA7419SetAttenuation(s_atten_sub, atten_sub );
writeToTDA7419 (s_spectrum, (0x09));
}
/////////////////////////////////////////////
// Helper functions for the serial display //
/////////////////////////////////////////////
void processButtonPress (int button) {
if (button == 0) {
if (option < (NUM_OPTIONS-1)) {
option++;
} else {
option = 0;
}
}
if (button == 1) {
if (option > 0) {
option--;
} else {
option = (NUM_OPTIONS-1);
}
}
switch (option) {
case (0): // if volume option is selected change volume when button 1 and 2 are pressed
if (button == 2) {
if (volume > 0 ) {
volume--;
}
}
if (button == 3) {
if (volume < 11) {
volume++;
}
}
displayWrite("Volume", volume );
break;
case (1): // manage the input - 1,2,3 are the standard single ended inputs
if (button == 2) {
if (input > 1) {
input--;
}
}
if (button == 3) {
if (input < 3) {
input++;
}
}
displayWrite("Input", input );
break;
case (2): // manage the treble value
if (button == 2) {
if (treble > -5) {
treble--;
}
}
if (button == 3) {
if (treble < 5) {
treble++;
}
}
displayWrite("Treble", treble );
break;
case (3): // manage the middle value
if (button == 2) {
if (middle > -5) {
middle--;
}
}
if (button == 3) {
if (middle < 5) {
middle++;
}
}
displayWrite("Middle", middle );
break;
case (4): // manage the bass value
if (button == 2) {
if (bass > -5) {
bass--;
}
}
if (button == 3) {
if (bass < 5) {
bass++;
}
}
displayWrite("Bass", bass );
break;
// Manage the attenuators
case (5): // manage the atten_lf value
if (button == 2) {
if (atten_lf > 0) {
atten_lf--;
}
}
if (button == 3) {
if (atten_lf < 11) {
atten_lf++;
}
}
displayWrite("LF", atten_lf );
break;
case (6): // manage the atten_rf value
if (button == 2) {
if (atten_rf > 0) {
atten_rf--;
}
}
if (button == 3) {
if (atten_rf < 11) {
atten_rf++;
}
}
displayWrite("RF", atten_rf );
break;
case (7): // manage the atten_lr value
if (button == 2) {
if (atten_lr > 0) {
atten_lr--;
}
}
if (button == 3) {
if (atten_lr < 11) {
atten_lr++;
}
}
displayWrite("LR", atten_lr );
break;
case (8): // manage the atten_rr value
if (button == 2) {
if (atten_rr > 0) {
atten_rr--;
}
}
if (button == 3) {
if (atten_rr < 11) {
atten_rr++;
}
}
displayWrite("RR", atten_rr );
break;
case (9): // manage the atten_mix value
if (button == 2) {
if (atten_mix > 0) {
atten_mix--;
}
}
if (button == 3) {
if (atten_mix < 11) {
atten_mix++;
}
}
displayWrite("Mix", atten_mix );
break;
case (10): // manage the atten_sub value
if (button == 2) {
if (atten_sub > 0) {
atten_sub--;
}
}
if (button == 3) {
if (atten_sub < 11) {
atten_sub++;
}
}
displayWrite("SUB", atten_sub );
break;
case (11): // manage the atten_sub value
if (button == 2) {
mix = 0;
}
if (button == 3) {
mix = 1;
}
displayWrite("Mix", mix );
break;
}
updateReg(); // update the TDA7419 registers to reflect any values changed above
}
void UpPressed( void )
{
processButtonPress(0);
}
void LeftPressed( void )
{
processButtonPress(2);
}
void RightPressed( void )
{
processButtonPress(3);
}
void DownPressed( void )
{
processButtonPress(1);
}
int main()
{
PinUp .mode( PullUp );
PinLeft .mode( PullUp );
PinRight.mode( PullUp );
PinDown .mode( PullUp );
PinUp .attach_asserted( &UpPressed );
PinLeft .attach_asserted( &LeftPressed );
PinRight.attach_asserted( &RightPressed );
PinDown .attach_asserted( &DownPressed );
display.clearDisplay();
// draw multiple rectangles
testfillrect();
wait(0.5);
display.display();
display.clearDisplay();
display.display();
// Sampling does not begin until you set a frequency.
// The default is 20ms. If you want a different frequency
// then pass the period in microseconds for example, for 10ms :-
// pin.setSampleFrequency( 10000 );
//
PinUp .setSampleFrequency(); // Defaults to 20ms.
PinLeft .setSampleFrequency(); // Defaults to 20ms.
PinRight.setSampleFrequency(); // Defaults to 20ms.
PinDown .setSampleFrequency(); // Defaults to 20ms.
processButtonPress(0);
while (1) {
wait(1);
}
}
// EOF