This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TAC5212: Help Configuring TAC5212 for TDM Mode with External Clocks from Teensy 4.1

Part Number: TAC5212

Tool/software:

Subject: Help Configuring TAC5212 for TDM Mode with External Clocks from Teensy 4.1

Hi TI Team,

I'm working on a audio project using the TAC5212 codec in TDM slave mode, driven by a Teensy 4.1 microcontroller (NXP i.MX RT1062 @ 600 MHz). I’ve read the datasheet and clocking app notes, but I’m still unable to get a clean output or valid clock lock.

Setup Summary:
- Codec: TAC5212
- MCU: Teensy 4.1 (TDM Master)
- MCLK: 11.2896 MHz (from Teensy)
- BCLK: 12.288 MHz (32-bit × 16 slots × 24 kHz)
- FSYNC: 24 kHz, active high
- DATA: TDM stream, slots 0 and 1 used for stereo

Headphones Behavior:
- Audio is present but scratchy or misaligned.
- Clock Status Register (0x13) always reads 0x00 — never locks.
- Adjusting PASI_RX_OFFSET improves quality slightly, but never clean.
- Enabling PLL results in no audio.

Tools Minimal Configuration Code:
Here is the Teensy sketch I'm currently using to configure the codec and send test audio:

#include <Arduino.h>
#include <Wire.h>
#include <Audio.h>

#define TAC5212_ADDR 0x50

AudioSynthWaveform waveform1;
AudioSynthWaveform waveform2;
AudioOutputI2S i2sOut;
AudioConnection patchCord1(waveform1, 0, i2sOut, 0);
AudioConnection patchCord2(waveform2, 0, i2sOut, 1);
AudioControlSGTL5000 dummyControl;

void writeReg(uint8_t reg, uint8_t val) {
Wire.beginTransmission(TAC5212_ADDR);
Wire.write(reg);
Wire.write(val);
Wire.endTransmission();
}

void setupCodec() {
writeReg(0x01, 0x01); delay(100); // Reset
writeReg(0x02, 0x09); delay(100); // Wakeup

uint8_t PASI_FORMAT = 0b00 << 6; // [7:6] PASI_FORMAT: 00 = TDM
uint8_t PASI_WLEN = 0b11 << 4; // [5:4] PASI_WLEN: 11 = 32-bit
uint8_t PASI_FSYNC_POL = 0 << 3; // [3] FSYNC_POL: 0 = Active Low, 1 = Active High
uint8_t PASI_BCLK_POL = 0 << 2; // [2] BCLK_POL: 0 = Normal (rising edge)
uint8_t PASI_BUS_ERR = 0 << 1; // [1] BUS_ERR: 0 = Disable error detection
uint8_t PASI_BUS_ERR_RCOV = 0 << 0; // [0] BUS_ERR_RCOV: 0 = Disable recovery
uint8_t pasi_cfg0 = PASI_FORMAT | PASI_WLEN | PASI_FSYNC_POL | PASI_BCLK_POL | PASI_BUS_ERR | PASI_BUS_ERR_RCOV;
writeReg(0x1A, pasi_cfg0);

uint8_t PASI_RX_EDGE = 0 << 7; // [7] Half-cycle delay
uint8_t PASI_RX_USE_INT_FSYNC = 0 << 6; // [6] Use external FSYNC
uint8_t PASI_RX_USE_INT_BCLK = 0 << 5; // [5] Use external BCLK
uint8_t PASI_RX_OFFSET = 2; // [4:0] Shift input by 2 BCLKs
uint8_t pasi_rx_cfg0 = PASI_RX_EDGE | PASI_RX_USE_INT_FSYNC | PASI_RX_USE_INT_BCLK | PASI_RX_OFFSET;
writeReg(0x26, pasi_rx_cfg0);

writeReg(0x2A, 0b00100000); // DAC L2 ← Slot 0
writeReg(0x2B, 0b00100001); // DAC R2 ← Slot 1
writeReg(0x6E, 80); // L2 Volume
writeReg(0x70, 80); // R2 Volume
writeReg(0x76, 0x0C); // Enable L2 + R2
writeReg(0x78, 0x40); // Power up
}

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
Wire.begin();
AudioMemory(12);

waveform1.begin(WAVEFORM_SQUARE);
waveform1.frequency(440);
waveform1.amplitude(0.25);

waveform2.begin(WAVEFORM_SQUARE);
waveform2.frequency(660);
waveform2.amplitude(0.25);

delay(1000);
setupCodec();
}

void loop() {}

MCLK is connected to GPI1 (as per docs).

Camera with flash Scope Images Show:
- MCLK
- BCLK
- FSYNC
- TDM DATA stream with visible transitions on slot 0 and 1

Pray Request:
Could you please help confirm:
1. Correct settings for PASI_CFG0 (0x1A) and PASI_RX_CFG0 (0x26) for this mode
2. Whether the PLL is required even when external clocks are stable
3. Whether there's an undocumented setting or alignment needed for slot/delay timing

Any advice is hugely appreciated — I’ve been stuck on this for weeks.

Best regards,
Jay Shoemaker
https://t-dsp.com/

  • Hi Jay,

    Since you're running the device in target mode, no external MCLK is required and the device can be operate off of the 24kHz FSYNC and 12.288MHz BCLK. 

    If audio is present but sounds scratchy, this is likely an ASI formatting issue. Is the host flexible enough to provide clocks without a 2-Bclk delay?

    Additionally, you can force the IC to anticipate a 24kHz sampling by setting (0x32, 64)

    I can look at your script a little more in depth tomorrow and amend this comment

  • Hello Daveon, 

    If you want I'll send you a Teensy to try it with. :-)

    So I attempted to provide clocks without a 2-BCLK delay as suggested on the Teensy forum here:

    https://forum.pjrc.com/index.php?threads/introducing-the-t-dsp-tac5212-pro-audio-module-%E2%80%93-help-needed-getting-clock-sync-on-teensy-4-1.76784/#post-357106

    The result was a horrible high pitched sound. I don't know if that's the right setting or not. I tried a bunch of different combinations. 

    I believe the correct offset is 1 bit because if you look at the clocks, FSYNC and BCLK come down together at the same time when SD starts up for Slot 0. But no luck still on getting the clocks locked, or the audio sounding any good. 

    If you know anywhere else to look, I'm all ears. 

    Jay

  • Hi, 

    Apologies for the delay, I will update thread within a day

  • Hi,

    Please try the two following scripts to validate the record and playback separately on your EVM.

    ##### Record AC-Couple Differential IN1-IN2 path ######
    # Target Mode, TDM, 32-bit
    # Primary ASI only, multiple of 48KHz Sampling
    #
    w a0 00 00	# Set page 0
    w a0 01 01	# Software Reset
    w a0 02 09	# Wake up with AVDD > 2v and all VDDIO level
    w a0 10 50 	# Configure DOUT as Primary ASI (PASI) DOUT
    w a0 19 00	# 1 data input and 1 data output for PASI
    w a0 1a 30	# PASI TDM, 32 bit format
    w a0 1c 02	# Data output offset by 2 BCLKs
    w a0 1e 20	# PASI Ch1 on slot 0
    w a0 1f 21	# PASI Ch2 on slot 1
    w a0 50 00	# ADC Ch1 diff input, 5KOhm, 2Vrms ac-coupled, audio band
    w a0 55 00	# ADC Ch2 diff input, 5KOhm, 2Vrms ac-coupled, audio band
    w a0 76 c0	# Enable Input Ch1 and Ch2, disable output channels
    w a0 78 a0	# Power up ADC and MICBIAS

    ##### Playback Differential LINEOUT Path ######
    # Target Mode, TDM, 32-bit
    # Primary ASI only, multiple of 48KHz Sampling
    #
    w a0 00 00	# Set page 0
    w a0 01 01	# Software Reset
    w a0 02 09	# Wake up with AVDD > 2v and all VDDIO level
    w a0 11 80 	# Enable PASI DIN
    w a0 19 00	# 1 data inputs and 1 data outputs for PASI
    w a0 1a 30	# PASI TDM, 32 bit format
    w a0 26 02	# Offset Data input by 2 BCLKs
    w a0 28 20	# PASI DIN Ch1 on TDM slot 0
    w a0 29 21	# PASI DIN Ch2 on TDM slot 1
    w a0 64 20	# Configure OUT1P/M as differential from DAC1
    w a0 65 20	# Configure OUT1P LINEOUT 0dB audio band
    w a0 66 20	# Configure OUT1M LINEOUT 0dB 2Vrms Differential 
    w a0 6b 20	# Configure OUT2P/M as differential from DAC2
    w a0 6c 20	# Configure OUT2P LINEOUT 0dB audio band
    w a0 6d 20	# Configure OUT2M LINEOUT 0dB 2Vrms Differential 
    w a0 76 0c	# Disable all input channels and enable output channel 1 and 2
    w a0 78 40	# Power up all DAC channel