Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: TLV320AIC3110 Codec breakout

  1. #1
    Junior Member
    Join Date
    Dec 2020
    Posts
    13

    TLV320AIC3110 Codec breakout

    After soliciting wisdom in this post about a codec to try, suitable for a small speaker, microphone and headphones, I made a breakout for the Texas Instruments TLV320AIC3110.

    I managed to assemble it yesterday and decided to use the Teensy Audio tutorial materials as a way to start testing it.
    Click image for larger version. 

Name:	IMG_20210119_142835198.jpg 
Views:	15 
Size:	100.0 KB 
ID:	23351

    So far the main hardware error I have found is that the reset pin was not connected to anything. Thus, when I scanned the I2C bus I got no response. However, I greenwired to Teensy pin 16/A2 and set it up as a reset pin (pull to ground for a millisecond, pull up for the rest of the time). This allowed me to find the codec at 0x18 on the I2C bus.

    I am totally naive when it comes to codecs so I had hoped that the device would default to some kind of enabled state but sadly no output was on headphones or speaker terminals when I uploaded Part_1_02_Hardware_Test with the reset pin code added in and the SGTL5000 elements commented out.

    Fortunately, the TLV320AIC3110 datasheet has pseudocode for an example output mode initialisation, so I converted to Arduino and it is nicely beeping away on both headphones and stereo speakers and updating the serial monitor when I move the potentiometer.

    Code:
    const uint8_t resetPin = 16; // Teensy 3.2 codec shield reset pin v1.0 hardware
    const uint8_t codecAddress = 0x18; // TLV320AIC3110
    
    void setup() {
      pinMode(resetPin, OUTPUT); // comment out if not Teensy diy audio codec
      digitalWrite(resetPin, LOW); // comment out if not Teensy diy audio codec
      delay(1);
      digitalWrite(resetPin, HIGH); // comment out if not Teensy diy audio codec
    
      init_codec(); // start up the codec
    ...
    
    
    void init_codec()
    {
      Wire.begin();
      writeCodec(0x0, 0x0); //  select page 0
      writeCodec(0x01, 0x01); // soft reset
      writeCodec(0x04, 0x03); // pll clock in
      writeCodec(0x05, 0x91); // pll power up
      writeCodec(0x06, 0x08); // j = 8
      writeCodecDual(0x07, 0x0, 0x0); // D = 0000
      writeCodec(0x1B, 0x0); //  i2s, wordlength 16
      writeCodec(0x0B, 0x84); // NDAC is powered and set to 4
      writeCodec(0x0C, 0x84); // MDAC is powered and set to 4
      writeCodecDual(0x0D, 0x0, 0x80); // DOSR = 128, DOSR(9:8) = 0, DOSR(7:0) = 128
    
      writeCodec(0x74, 0x0); //  DAC -> volume control thru pin disable
      writeCodec(0x44, 0x0); // DAC -> DRC disable
      writeCodec(0x41, 0xD4); // DAC -> -22dB gain left
      writeCodec(0x42, 0xD4); // DAC -> -22dB gain right
    
      writeCodec(0x0, 0x01); // Select page 1
      writeCodec(0x21, 0x4E); // De-pop, power on = 800 ms, step time = 4ms
      writeCodec(0x1F, 0xC2); // HPL and HPR powered up
      writeCodec(0x23, 0x44); // LDAC routed to HPL, RDAC routed to HPR
      writeCodec(0x28, 0x06); // HPL unmute annd gain = 0dB
      writeCodec(0x29, 0x06); // HPR unmute annd gain = 0dB
      writeCodec(0x2A, 0x1C); // unmute class D left
      writeCodec(0x2B, 0x1C); // unmute class D right
      writeCodec(0x20, 0xC6); // power up class D drivers
      writeCodec(0x24, 0x92); // enables HPL output analog volume, set = -9 dB
      writeCodec(0x25, 0x92); // enables HPR output analog volume, set = -9 dB
      writeCodec(0x26, 0x92); // enables HPL output analog volume, set = -9 dB
      writeCodec(0x27, 0x92); // enables HPR output analog volume, set = -9 dB
    
      writeCodec(0x0, 0x0); // select page 0
      // select DAC DSP Processing Block PRB_P11
      writeCodec(0x3C, 0x0B); //
      writeCodec(0x00, 0x08); //
      writeCodec(0x01, 0x04); //
      writeCodec(0x00, 0x00); //
      writeCodec(0x3F, 0xD6); // power up DAC left and right channels (soft step disable)
      writeCodec(0x40, 0x0); // unmute DAC left and right channels
      Wire.end();
    
    }
    
    void writeCodec(uint8_t registerVal, uint8_t dataVal)
    {
      Wire.beginTransmission(codecAddress);
      Wire.write(registerVal); // set the address to write to
      Wire.write(dataVal); // set the data to write
      Wire.endTransmission(); // end
    }
    
    void writeCodecDual(uint8_t registerVal, uint8_t data0Val, uint8_t data1Val)
    {
      Wire.beginTransmission(codecAddress);
      Wire.write(registerVal); // set the address to write to
      Wire.write(data0Val); // set the data to write
      Wire.write(data1Val); // set the data to write
      Wire.endTransmission(); // end
    }
    I will try and play some music from the SD card next.

  2. #2
    Junior Member
    Join Date
    Dec 2020
    Posts
    13
    Oh great! Playing from SD card works. Grooving to SDTEST2.WAV as I type

  3. #3
    Junior Member
    Join Date
    Dec 2020
    Posts
    13
    I made some more progress, thanks to the contributors who have already written Audio library code for the TLV320AIC3206. Many of the register names and sequences appear to be the same or have similarities with the TLV320AIC3110. I only adapted the DAC side of things but after #including control_tlv320aic3110.h in audio.h, I am able to use the following without any of my in-sketch code from above:

    Code:
    AudioControlTLV320AIC3110  TLV320AIC3110;
    ...
    
    void setup() {
      Serial.begin(9600);
      AudioMemory(8);
      TLV320AIC3110.enable();
      TLV320AIC3110.volume(0.5);
      ...
    And WAV playback from SD works fine! Not tested volume controls but it's great how quickly new hardware can be integrated with this library. WIP header and c++ files hopefully attached for anyone interested. Once ADC is incorporated and it's all a bit better tested I can fork and PR, if the code gets tidy enough and that would be desirable to others.
    control_tlv320aic3110.cpp
    control_tlv320aic3110.h

  4. #4
    Senior Member
    Join Date
    Jun 2018
    Location
    USA
    Posts
    165
    Pretty sure the TLV320AIC3206 driver (and board) uses pin 22 for reset. I noticed that on your schematic when you posted earlier. I meant to check to see if the reset pin was required, so I could warn you, and I forgot! Sorry! Glad you figured it out.

  5. #5
    Junior Member
    Join Date
    Dec 2020
    Posts
    13
    JayShoe, thanks! I just picked a free gpio near where I could route my greenwire to. For ease of routing I will use a pin on the other side of the I2C pins when I revise the board. I think the TLV320AIC3206 uses 21, which is a possibility.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •