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

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