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