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
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.
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).
Scope Images Show:
- MCLK
- BCLK
- FSYNC
- TDM DATA stream with visible transitions on slot 0 and 1



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/