I2C headphone amp no output [solved] - Page 1
Forum section: electronics / projects

author: m98
author_rank: Frequent Contributor
timestamp: May 22, 2015, 07:55:04 pm
content: Hi,I'm working on an device, which outputs sounds over a headphone. I designed a custom PCB, where the sound section consists of an Atmega 328p and an TI TPA6130A2 headphone amp. The Atmega runs the Mozzi sound synthesis library (http://sensorium.github.io/Mozzi/learn/output/) with dual-PWM-output.My issue is, that there is no output on the headphone amp, here the code I used for testing so far:Code:#include <MozziGuts.h> // Mozzi main library#include <Oscil.h> // Mozzi template for an oscillator#include <tables/sin2048_int8.h> // Mozzi wavetable holding a sine wave#include <twi_nonblock.h> // Mozzi non-blocking I2C Library// --- Mozzi definitions ---Oscil <2048, AUDIO_RATE> aSin(SIN2048_DATA); // defines an sine tone oscillator with the sin2048 wavetable. Structure: Oscil <table_size, update_rate> name(table_data);#define CONTROL_RATE 64 // number of control updates, only powers of 2int audioFrequency = 440;// --- Audio Amplifier I2C definitions ---#define AMP_ADDRESS 0x60 // TPA6130A2 device address// Register 1: HP_EN_L, HP_EN_R, Mode, Mode, Reserved, Reserved, Reserved, Thermal, SWS#define AMP_REG1 0x1 // TPA6130A2 register 1 address#define AMP_REG1_SETUP 0xc0 // default configuration: 11000000 - both channels enabled// Register 2: Mute_L, Mute_R, Volume[5-0]#define AMP_REG2 0x2 // TPA6130A2 register 2 address#define AMP_REG2_SETUP 0x34 // default configuration: 00110100 - both channels on -0.3 dB Gainvoid setup() {startMozzi(CONTROL_RATE);initialize_twi_nonblock(); // initialize I2C library and join I2C-BusinitializeAmp();}void initializeAmp() {amp_writeTo(AMP_REG1, AMP_REG1_SETUP);amp_writeTo(AMP_REG2, AMP_REG2_SETUP);}void updateControl(){aSin.setFreq(audioFrequency);}int updateAudio(){return aSin.next();}void amp_writeTo(byte address, byte val) {twowire_beginTransmission(AMP_ADDRESS); // start transmission to devicetwowire_send( address ); // send register addresstwowire_send( val ); // send value to writetwowire_endTransmission(); // end transmission}void loop() {audioHook();}And this is the relevant part of the schematic:Sorry for cross-posting here, there's also a thread in the arduino forum, where I've got no answer since some days:http://forum.arduino.cc/index.php?topic=323450.0Thanks for your repliesm98

author: AndreasF
author_rank: Frequent Contributor
timestamp: May 23, 2015, 09:16:17 am
content: You could check what status code twowire_endTransmission() returns to see if any error happened during the I2C transmission (address NACK, data NACK etc.)

author: m98
author_rank: Frequent Contributor
timestamp: May 25, 2015, 10:55:14 am
content: Thanks for the replies. The problem is, that the function doesn't return anything, as they're defined in that way: void twowire_send( uint8_t data ).The analog signal is working, it has a strange waveform, but I think that this is intended. Also tried a Signal from a function generator, but that also wasn't successfull. And I don't know of a way to test if the I2C communication is actually successfull.Maybe there is just something wrong with those definitions:Code:#define AMP_ADDRESS 0x60 // TPA6130A2 device address// Register 1: HP_EN_L, HP_EN_R, Mode, Mode, Reserved, Reserved, Reserved, Thermal, SWS#define AMP_REG1 0x1 // TPA6130A2 register 1 address#define AMP_REG1_SETUP 0xc0 // default configuration: 11000000 - both channels enabled// Register 2: Mute_L, Mute_R, Volume[5-0]#define AMP_REG2 0x2 // TPA6130A2 register 2 address#define AMP_REG2_SETUP 0x34 // default configuration: 00110100 - both channels on -0.3 dB GainWrote that according to thisDatasheet section. I can't find an error, but it must be there.

author: m98
author_rank: Frequent Contributor
timestamp: May 25, 2015, 04:19:40 pm
content: Wrote the following Code to test. It uses the standard arduino wire library, just to be sure, that this part works.After sending the defined values to the amp, it reads the value of the first register. It outputs the device address, register address, register value, a test char and a test string over Serial.Code:/*#include <Wire.h> // I2C Library// --- Audio Amplifier I2C definitions ---#define AMP_ADDRESS 0x60 // TPA6130A2 device address// Register 1: HP_EN_L, HP_EN_R, Mode, Mode, Reserved, Reserved, Reserved, Thermal, SWS#define AMP_REG1 0x1 // TPA6130A2 register 1 address#define AMP_REG1_SETUP 0xc0 // default configuration: 11000000 - both channels enabled// Register 2: Mute_L, Mute_R, Volume[5-0]#define AMP_REG2 0x2 // TPA6130A2 register 2 address#define AMP_REG2_SETUP 0x34 // default configuration: 00110100 - both channels on –0.3 dB Gainvoid setup() {delay(200);Serial.begin(9600);Wire.begin();initializeAmp();}void initializeAmp() {amp_writeTo(AMP_REG1, AMP_REG1_SETUP);amp_writeTo(AMP_REG2, AMP_REG2_SETUP);Wire.beginTransmission(AMP_ADDRESS); // start transmission to deviceSerial.println(AMP_ADDRESS,BIN);Wire.write( AMP_REG1 ); // send register addressSerial.println(AMP_REG1,BIN);Wire.requestFrom(AMP_ADDRESS, 8); // request 8 bytes from devicewhile(Wire.available()) // slave may send less than requested{byte c = Wire.read(); // receive a byteSerial.print(c,BIN); // print the byte as binarySerial.print("."); // print test character}Wire.endTransmission();Serial.println();Serial.println("Amplifier Initialized!");}void amp_writeTo(byte address, byte val) {Wire.beginTransmission(AMP_ADDRESS); // start transmission to deviceWire.write( address ); // send register addressWire.write( val ); // send value to writeWire.endTransmission(); // end transmission}void loop() {}The output looks like that:Code:11000001Amplifier Initialized!Now it seems like the amp is not responding to the request, because it doesn't send anything back. Is there a method to request the address of all devices on the I2C-bus to see, if I just got that wrong?

author: AndreasF
author_rank: Frequent Contributor
timestamp: May 25, 2015, 06:39:08 pm
content: I just noticed that in your schematic you left the shutdown pin unconnected. Is that indeed the case and done on purpose? I would think you want to connect it to logic high.

author: m98
author_rank: Frequent Contributor
timestamp: May 25, 2015, 08:03:25 pm
content: Quote from: AndreasF on May 25, 2015, 06:39:08 pmWell, that's a bit bad design from my side, maybe I thought that I could leave that pin floating... But to shutdown, it must have an internal pull-down, which would be strange on an active low input. Is there a neat way to solder mod-wires to a QFN-Package?But first, I'll try the other address.

author: AndreasF
author_rank: Frequent Contributor
timestamp: May 26, 2015, 09:57:05 am
content: Quote from: m98 on May 25, 2015, 08:03:25 pmIt may not have a pull-down but simply naturally float to a logic low level. Adding a mod wire to the QFN pad should be possible. I would probably try to use hot air and a single strand of copper from multi-stranded wire. Add some hot glue for mechanical support.

author: m98
author_rank: Frequent Contributor
timestamp: May 28, 2015, 08:07:13 pm
content: Ok, I added the mod-wire and it worked. The software worked, the device address I had was right.Just for people searching a neat way to add a mod-wire to a QFN-Package:Align the very thin copper wire roughly with the pad and tape it down 1-2cm from the chip. Then add a bit of solder paste to the pad and align the wire precisely to it, pair of sharp pliers might help. Finally solder with hot air. To fix it in place, a small drop of super glue looks better than hot glue.Thanks for your help.