ESS DAC chips register readout - how?

Hi folks,

today I built and tested a MCP2221A USB->I2C interface and a I2C isolator with optocouplers. To actually test the function I used one of iancanada's ES9038Q2M boards which was lying around.

We're currently in the process of developing a DAC board with this chip and the corresponding PC controller software... Will finally become a multi channel solution.

So right before I had to stop my experiments today because of time constraints (we have to be home by 10 pm right now in germany) I got the register write working. Had to wrap my head around the I2C adressing and needed an oscilloscope to find out that i had to rightshift the address 0x90 by 1 bit to actually make the DAC chip send the ACK on the I2C data line. Weird conventions but hey, who cares if it works :)

What I could not determine from the datasheet is how register read access works. Do I need to send one byte with the register number and then read one byte to get the register contents back?

I would greatly appreciate info on this topic, be it in text form or any kind of working/tested code, don't care which programming language.
 
The last bit following the 7bit address is the i2c way of saying read vs write. The library usually takes care of this, and you use the 7 bit chip address.
You have to send the register number you want and then request 1 byte.
You are probably using Python? In c++ the wire linrary code I use is this, there is undoubtedly similar Python code/i2c library:

byte readRegister(byte regAddr) { // returns one byte, 0 if no data
Wire.beginTransmission(ES9038_ADDR); // Hard coded the Sabre address
Wire.write(regAddr); // Queues the address of the register
Wire.endTransmission(); // Sends the address of the register
Wire.requestFrom(ES9038_ADDR, 1); // Hard coded to Sabre, request one byte from address
if (Wire.available()) // Wire.available indicates if data is available
return Wire.read(); // Wire.read() reads the data on the wire
else
return 0; // In no data in the wire, then return 0 to indicate error
}
 
There is an an I2C library for Arduino at: GitHub - felias-fogg/SoftI2CMaster: Software I2C Arduino library
The .md text file explains reading and writing registers pretty well.
The reason for 0x90 is that I2C addresses can be viewed as being either 7-bits or 8-bits. The LSB is a read/write bit, so in the 8-bit way of thinking about addresses, the read address will be the write address plus 1. To read, first write the register number you want to read, then do an I2C 'restart' operation to read the register data from read address.

EDIT: The library also comes with a nice little set of example programs including an I2C bus scanner.
 
Last edited: