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
Diff: main.cpp
- Revision:
- 0:36eee45709c8
- Child:
- 1:f5b8687f67b8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Oct 10 04:58:19 2014 +0000 @@ -0,0 +1,482 @@ +#include "mbed.h" +#include "PinDetect.h" +#include "ssd1306.h" +#include "standard_font.h" +#include "bold_font.h" + +PinDetect PinUp ( PTA1 ); +PinDetect PinLeft ( PTD4 ); +PinDetect PinRight ( PTA2 ); +PinDetect PinDown ( PTA12 ); + +DigitalOut led1( LED1 ); +DigitalOut led2( LED2 ); +DigitalOut led3( LED3 ); + +SSD1306 display (PTA13 /* cs */, PTD5 /* reset */, PTD0 /* dc */, PTD1 /* clock */, PTD2 /* data */); // KL25Z + +void displayWrite(char firstLine[], int value) +{ + display.clear(); + display.printf("%s\r\n", firstLine); + display.printf("%d", value); + display.update(); +} + +/////////////////////////// +// 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 ) +{ + led1 = 1; + led2 = 0; + led3 = 0; + displayWrite("Up", 1); + processButtonPress(0); +} + +void LeftPressed( void ) +{ + led1 = 0; + led2 = 1; + led3 = 0; + displayWrite("Left", 1); + processButtonPress(2); + +} + +void RightPressed( void ) +{ + led1 = 0; + led2 = 0; + led3 = 1; + displayWrite("Right", 1); + processButtonPress(3); +} + +void DownPressed( void ) +{ + led1 = 1; + led2 = 0; + led3 = 1; + displayWrite("Down", 1); + 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.initialise(); + display.clear(); + display.set_contrast(255); // max contrast + display.update(); + display.set_font(standard_font, 6); + display.printf("mbed audio!\r\n"); + display.update(); + + // 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. + + while (1) { + wait(5); + } + +} + + + +// EOF \ No newline at end of file