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

Files at this revision

API Documentation at this revision

Comitter:
danielashercohen
Date:
Fri Oct 10 04:58:19 2014 +0000
Child:
1:f5b8687f67b8
Commit message:
Working display and buttons;

Changed in this revision

PinDetect_KL25Z.lib Show annotated file Show diff for this revision Revisions of this file
SSD1306.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PinDetect_KL25Z.lib	Fri Oct 10 04:58:19 2014 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/danielashercohen/code/PinDetect_KL25Z/#054fc24ec446
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SSD1306.lib	Fri Oct 10 04:58:19 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/masato/code/SSD1306/#ec5add86f335
--- /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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Oct 10 04:58:19 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1
\ No newline at end of file