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-10
- Revision:
- 0:36eee45709c8
- Child:
- 1:f5b8687f67b8
File content as of revision 0:36eee45709c8:
#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