MAX5825 full scale on 8 bits

86 views Asked by At

I am using a MAX5825 as an external DAC for RPi.
According to the datasheet, the resolution of this component is 12 bits.
As I read, I'm supposed to write the value I want to set in the CODEn (0x8n) register, n being the DAC channel I want to set, and then write anything in the LOADn (0x9n) register, or use the CODEn_LOADn (0xBn) register to do it in one step. See here the datasheet extract.
I'm using pigpio daemon library to interface I²C communication

void AnalogOutput::updateValue(int value) { 
    i2c_write_word_data(my_pi_device, my_handler, 0xB0, value << 4);
} 

This is supposed to set my CODE0 register to the value parameter.
However, I had a strange behavior so I tried to read the data from CODEn (0x80) register to watch if my set attempt was correct.

i2c_read_word_data(my_pi_device, my_handler, 0x80);

I'm not sure I can read a value from a command register tho, but when my value exceed 0xFF, the return I get from I²C reading looks like value & 0xFF. (i.e. when I set the register to 0xFF I read 0xFF in the register, when I set the register to 0x100 I read 0x00)
Also, the output voltage of my DAC0 channel is at its maximum scale when CODEn register is set to 0xFF. I used 4.0V internal reference and when I set value to 0xFF, the output voltage is 4.0V-ish.
I don't understand why is 0xFF the maximum scale on a 12-bits resolution DAC ? Am I missing a way to configure the resolution or anything like that ?
What I've tried so far :

  • Remove the << 4 shifting on the set value : no change on the behavior
  • Invert the LSByte and MSByte written to the CODEn register (I've seen on pigpiod API SMBus standard was supposed to send LSByte then MSByte in a word writing procedure) : the reading of CODEn register was jumping over 0x0FFF value. MAX5825 is supposed to be compatible with SMBus standard tho.
  • Use i2c_write_block_data instead of i2c_write_word_data function of pigpiod lib : no change on the behavior.

Thanks for your time !

References :
MAX5825 datasheet : https://datasheets.maximintegrated.com/en/ds/MAX5823-MAX5825.pdf
pigpio API : https://abyz.me.uk/rpi/pigpio/pdif2.html

1

There are 1 answers

0
buloz On

Ok I got it fixed using i2cget & i2cset, my supposition about LSByte & MSByte was right.
CODEn registers are filled with 12 MSB. That means a set value of 0x0ABC needs to be stored in CODEn register by : 0xABC0. pigpio following SMBus standard send I²C word message with LSByte first and then MSByte, so if I send 0x0ABC message through I²C it will actually send 0xBC0A. When I tried to invert LSByte and MSByte, I was sending through I²C the message 0xBC0A so what was stored inside MAX5825 was 0x0AB.
One functionnal workaround would be :

void AnalogOutput::updateValue(int value) {
    int codeRegisterData = (value >> 4) + ((value & 0xF)<<12);
    i2c_write_word_data(my_pi_device, my_handler, 0xB0, codeRegisterData);
}

If value = 0x0ABC, codeRegisterData would be = 0xC0AB so pigpio will write over the I²C bus into the CODEn register the message 0xABC0.