ES9039Q2M S/PDIF DAC design

A bit of success, the amanero arrived from italy and I got the DAC working with I2S in software mode 🙂
It seems I have to send the registers for every start of the DAC, otherwise I get no output.

I changed these registers:

C++:
 // Register 1: SYS MODE CONFIG (default 0b10110001 = hex B1)
  // Enable SPDIF decode (bit 3 = 1), keep other defaults
  // New value for spdif: 0x89 (0b10001001)
  //for i2s: default, hex B1
  writeRegister(0x01, 0xB1);

  // Register 57: INPUT SELECTION (default 0b01000000 = hex 40)
  // SPDIF:        0b01000110 = 0x46 (INPUT_SEL = 3 = SPDIF, AUTO_INPUT_SEL = 0)
  // I2S (Amanero):0b01000001 = 0x41 (INPUT_SEL = 0 = PCM, AUTO_INPUT_SEL = 1)

  writeRegister(0x39, 0x41);

Its working with both crystals, sound quality is not mindblowing atm, there is a bit of a crackle/noise (maybe coming from the +-15V SMPS, I will investigate).
 
Working on the similar project, testing I2C configuring ES9039Q2M and now stuck with no analog output with SPDIF input.
Is it enough to startup with SPDIF enabled ?
Code:
#include <Wire.h>
#define DAC_ADDR 0x48;
void writeDACRegister(uint8_t reg, uint8_t val);
void applyStartupConfig() {
  writeDACRegister(0x09, 0x01);        // SPDIF input select
  writeDACRegister(0x39, 0b00000100);  // SPDIF, auto detect off
  writeDACRegister(0x89, 0b01000000);  // SPDIF_SEL = GPIO4
  writeDACRegister(0x88, 0b00010000);  // Enable GPIO4 as SPDIF input
  writeDACRegister(0x01, 0b00000010);// Enable DAC analog output
  writeDACRegister(0x02, 0x00);// Unmute
  uint8_t reg3; // Set ASRC mode
  readDACRegister(0x03, &reg3);
  reg3 &= ~0x80;  // Clear SYNC bit (bit7 = 0 -> Async)
  writeDACRegister(0x03, reg3);
  writeDACRegister(123, 0x00);  // Disable automute
}
and to call once during boot applyStartupConfig() or it is it is absolutely necessary to do hardware reset CHIP_EN for SPDIF even if we boot with such settings, not switch from I2S to SPDIF during work or I miss something ?
 
Ok. Leave that SPDIF and go with I2S, is it enough to play analog out with 3 wire I2S in and onboard XO, need help with debug what is the reason of silence (in HW mode it works well) ? Is it enough to set this registers to play sound with ASRC and I2S input ?
Code:
#include <Wire.h>
#define I2C_ADDRESS 0x48
void setup() {
Wire.begin();
writeRegister(0x00, 0x02);
writeRegister(0x01, 0xB1);
writeRegister(0x39, 0x41);
writeRegister(0x56, 0x00);
writeRegister(0x7B, 0x00);
void loop() {
}
bool writeRegister(uint8_t reg, uint8_t value) {
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(reg);
  Wire.write(value);
  return Wire.endTransmission() == 0;
}
 
Arduino IDE with Arduino Nano, <Wire.h>, all is well with I2C bus, writing and reading registers. I can read them after writing and check, but something is missing to get sound from DAC (or it is hardware problem at board). Pin29 (mode) at GND, pin19 and 20 are at GND to configure I2C address 0x48.
 
IMHO, its too much trouble to sort through your code and the datasheet. Why don't you annotate you register programming lines with the settings you intend them to make? Then we can read what you are trying to do in something closer to English.

You should also be reading out status bits such as Lock status, and tell us what status information you are getting back.
 
Solved, it was AI mistake in other part of сode to set some registers which should not have been touched at all with errors. Only these register settings are enough to play 3 wire I2S with onboard clock:
Code:
writeRegister(0x00, 0x80); // Register 0 Bit 7 to 1 Reset digital core (all settings are set to default)  - on the off-chance
writeRegister(0x00, 0x02); // Register 0 Bit 1=1 Set DAC_MODE to enable DAC analog output

Is it necessary to do some kind of restart procedure or something else for the changes to take effect immediately for ex with changing digital filters?
 
Last edited:
If you would ever need a premade i2s card to measure against, this is made according to the eval. I have used it in hw mode and it measures extremly well with non perfect surrounding components.
1750861340061.png
 
What is strugling me in the docs from ESS is they put in // two Rf resistor in the fedbackloop. I don't see why, the noise figure should be the same than one resistor with half the value and it adds parasitic capacitance exposure and longer path !

Btw layout wise, should the resistors not be the nearest from the op amp and VS the capacitor ?

What am I missing ? Thanks.

1750863196703.png
 
If you would ever need a premade i2s card to measure against, this is made according to the eval. I have used it in hw mode and it measures extremly well with non perfect surrounding components.
I have exactly the same board, it works fine in HW mode, but I want to have UI and almost done it with Arduino (even with chosing SPDIF/I2S input). Now solved to run SPDIF in SW mode. It is enough to set just these register settings to play SPDIF with ES9039Q2M:
Code:
writeRegister(0x00, 0x80); // Register 0 Bit 7 to 1 Reset digital core (all settings are set to default) - on the off-chance
writeRegister(0x39, 0x01); // INPUT SELECTION [0] 1'b1: Automatically determine the input data format
writeRegister(0x59, 0x64); // Select GPIO4 as SPDIF IN
writeRegister(0x2A, 0x08); // GPIO4_SDB Enables GPIO4 input
uint8_t val = readRegister(0x01); // SYS MODE CONFIG > ENABLE_SPDIF_DECODE set only bit 3 to 1
val |= 0x08;
writeRegister(0x01, val);
writeRegister(0x00, 0x02);// SYSTEM CONFIG Register 0 Bit 1=1 Set DAC_MODE to enable DAC analog output

@diyiggy it was here about it
 
Last edited:
Found easy way to switch between sources. I2S input works fine even with connected active SPDIF signal and with other needed SPDIF settings, just with disabling GPIO4_SDB, so this will be universal code for both inputs, just set register 0x2A to 0x00 anytime to swtich to I2S input without reboot/restart and without CHIP_EN touching.
Code:
writeRegister(0x00, 0x80); // Register 0 Bit 7 to 1 Reset digital core (all settings are set to default) - on the off-chance
writeRegister(0x39, 0x01); // INPUT SELECTION [0] 1'b1: Automatically determine the input data format
writeRegister(0x59, 0x64); // Select GPIO4 as SPDIF IN
writeRegister(0x2A, 0x08); // GPIO4_SDB Enables GPIO4 input (SPDIF IN ACTIVE) or writeRegister(0x2A, 0x00); // I2S IN ACTIVE
uint8_t val = readRegister(0x01); // SYS MODE CONFIG > ENABLE_SPDIF_DECODE set only bit 3 to 1
val |= 0x08;
writeRegister(0x01, val);
writeRegister(0x00, 0x02); // SYSTEM CONFIG Register 0 Bit 1=1 Set DAC_MODE to enable DAC analog output

Next question is how to autoplay DSD via I2S. If USB processor has DSDon output, is it just trigger with high/low logic level ? And we need to put it on some ESS GPIO port and watch high level to setup right DSD settings ?
 
Last edited:
IIRC, ESS dac chips can deduce when DSD is being playing by looking at the LRCK signal. Something more or less like that. Again IIRC, it worked okay in auto detect mode without needing to be programmed to switch to DSD mode.