Problem Description
I'm trying to get an I2SCodecStream working with an SGTL5000 CODEC, and all I2C comms are failing without getting ACKs.
Probing SDA, SCL, and MCLK with my scope, I'm seeing that the very first I2C transaction is not getting ACK'd, and it all goes down hill from there. MCLK is idle, not clocking.
Page 11 of the SGTL5000 datasheet https://www.nxp.com.cn/docs/en/data-sheet/SGTL5000.pdf shows that MCLK needs to be clocking before the chip will respond:

Is there a way to get AudioDriver/AudioTools to turn on MCLK early in the process, before trying to configure the CODEC over I2C?
Device Description
It's a custom board. It's an RP2040 and an SGTL5000.
Relevant bits of the schematic:
Sketch
Relevant bits:
// Pin assignments, if it matters. Not sure it does, but here ya are.
const static uint8_t PIN_I2C_SDA = 12;
const static uint8_t PIN_I2C_SCL = 13;
const static uint8_t PIN_I2S_DIN = 17;
const static uint8_t PIN_I2S_DOUT = 18;
const static uint8_t PIN_I2S_BCLK = 19;
const static uint8_t PIN_I2S_LRCLK = 20;
const static uint8_t PIN_I2S_MCLK = 21;
AudioInfo info(44100, 2, 16);
// Destination: I2S
DriverDeviceInfo pins_sgtl5000;
AudioDriverSGTL5000Class sgtl5000;
AudioBoard board(sgtl5000, pins_sgtl5000);
I2SCodecStream out(board);
bool started;
void setup() {
Serial.begin(115200);
started = false;
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
Wire.setSDA(PIN_I2C_SDA);
Wire.setSCL(PIN_I2C_SCL);
Wire.begin();
}
void beginAudio() {
pins_sgtl5000.addI2C(PinFunction::CODEC, PIN_I2C_SCL, PIN_I2C_SDA);
pins_sgtl5000.addI2S(PinFunction::CODEC, PIN_I2S_MCLK, PIN_I2S_BCLK, PIN_I2S_LRCLK, PIN_I2S_DOUT, PIN_I2S_DIN);
pins_sgtl5000.begin();
board.begin();
auto i2s_config = out.defaultConfig();
i2s_config.copyFrom(info);
out.begin(i2s_config);
}
uint16_t readReg(SGTL5000::Reg reg) {
Wire.beginTransmission(SGTL5000_ADDR);
Wire.write((uint16_t)reg >> 8);
Wire.write((uint16_t)reg & 0xFF);
Wire.endTransmission(false);
Wire.requestFrom(SGTL5000_ADDR, 2);
uint16_t ret_val = (Wire.read() & 0xFF) << 8;
ret_val |= (Wire.read() & 0xFF);
return ret_val;
}
void loop() {
// This waits for the serial port to connect and my terminal to be ready before it starts doing stuff.
if (!started && Serial.available()) {
beginAudio();
started = true;
}
if (started) {
Serial.println(readReg(SGTL5000::Reg::ChipId), 16);
}
delay(1000);
}
platformio.ini:
[env:pico]
; platform = raspberrypi
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
board = pico
framework = arduino
board_build.core = earlephilhower
monitor_port = /dev/ttyACM*
build_flags =
-DAUDIO_TOOLS_LOG_LEVEL="Debug"
lib_deps =
git@github.com:pschatzmann/arduino-audio-tools.git
git@github.com:pschatzmann/arduino-audio-driver.git
These are the relevant bits. I removed a bunch of debugging output so the functional code is easier to read.
I THINK I'm following the procedure of a Stand Alone board:
https://github.com/pschatzmann/arduino-audio-driver/wiki/Stand%E2%80%90Alone:-Custom-Boards
One thing that is different between my code and the documentation is that I had to instantiate an `AudioDriverSGTL5000Class` object and pass that to the `board()` instantiator, where as all your documentation and shows passing the CLASS to the instantiator. When I try to pass the class instead of an object, it tries to interpret the `DriverDeviceInfo` object (second parameter) as an `<error_type>` instead. I can't even find where that instantiator is defined! Passing the object matches with the instantiators that I CAN find, so I'm assuming your docs are a touch out of date on that one.
Other Steps to Reproduce
Running this code returns FFFF when reading the ChipID. The other debug output shows that endTransmission() is returning with error code 4, which says it's not getting an ACK.
I have I2C SDA and SCL, and I2S MCLK going into my o-scope. I can verify that there is no ACK after the address/write packet, or the immediately following address/read packet (since my code isn't error checking on the register address write.)
All the while, MCLK remains inactive, no clocking. And the SGTL5000 documentation says that MCLK needs to be live before trying to talk to it on I2C.
What is your development environment (with Arduino Core Version information)
- Linux: Ubuntu 24.04, up to date, literally updated this morning.
- VScode: 1.126.0 (Part of that update this morning. :-)
- PlatformIO: Core 6.1.19, Home 3.4.4
- Audio Tools hash: b90c162140a1674aabddca091c635bf8f9273d96
- Audio Driver hash: adf7d79
I have checked existing issues, discussions and online documentation
Problem Description
I'm trying to get an I2SCodecStream working with an SGTL5000 CODEC, and all I2C comms are failing without getting ACKs.
Probing SDA, SCL, and MCLK with my scope, I'm seeing that the very first I2C transaction is not getting ACK'd, and it all goes down hill from there. MCLK is idle, not clocking.
Page 11 of the SGTL5000 datasheet https://www.nxp.com.cn/docs/en/data-sheet/SGTL5000.pdf shows that MCLK needs to be clocking before the chip will respond:

Is there a way to get AudioDriver/AudioTools to turn on MCLK early in the process, before trying to configure the CODEC over I2C?
Device Description
It's a custom board. It's an RP2040 and an SGTL5000.
Relevant bits of the schematic:
Sketch
Other Steps to Reproduce
Running this code returns
FFFFwhen reading the ChipID. The other debug output shows thatendTransmission()is returning with error code 4, which says it's not getting an ACK.I have I2C SDA and SCL, and I2S MCLK going into my o-scope. I can verify that there is no ACK after the address/write packet, or the immediately following address/read packet (since my code isn't error checking on the register address write.)
All the while, MCLK remains inactive, no clocking. And the SGTL5000 documentation says that MCLK needs to be live before trying to talk to it on I2C.
What is your development environment (with Arduino Core Version information)
I have checked existing issues, discussions and online documentation