This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DAC7678: LDAC does not seem to function

Part Number: DAC7678

Tool/software:

I have a design that has 5 DAC7678SPW DACs on two separate I2C buses.  In this application, I want to write to all but 5 of the 40 DAC channels then toggle the LDAC pin low then high to transfer the data to the DACs all at the same time.  However, this does not seem to work. 

Some example code is below that does not work:

HAL_StatusTypeDef dacsUpdate35(uint16_t daca[35])
{
	static const uint8_t udacadr[] = {DAC0ADR, DAC1ADR, DAC2ADR, DAC3ADR, DAC4ADR};
	HAL_StatusTypeDef ret;
	uint8_t dacch;
	uint8_t i2cadr;

	// write the wavelength data for all wavelengths (update the outputs later)
	for (dacch=0; dacch<QTY_WAVELEN; dacch++)
	{
		// determine the the DAC I2C address
		i2cadr = udacadr[dacch>>3];

		// build the data to send to the DAC
		uint8_t dat[3] =
		{
			// 0x30|(dacch&7),	/* command to write the DAC channel and update its output */
			(dacch&7),			/* command to write the DAC channel but don't update the output yet */
			daca[dacch]>>4,		/* top 8 bits of the dac setting, left justified */
			daca[dacch]<<4		/* bottom 4 bits of the dac setting, left justified */
		};

		// write the dac
		if ( dacch < 24 )
			ret = HAL_I2C_Master_Transmit(&hi2c4, i2cadr, dat, 3, HAL_MAX_DELAY);
		else
			ret = HAL_I2C_Master_Transmit(&hi2c3, i2cadr, dat, 3, HAL_MAX_DELAY);

		if (ret != HAL_OK)
			goto ERRXIT;
	}

	// all wavelength DAC data has now been written to the DAC registers but the
	// outputs have not been updated yet.

ERRXIT:

	// toggle the DAC_LDAC line to transfer all DAC registers to their outputs
	LL_GPIO_ResetOutputPin(nDAC_LDAC_GPIO_Port, nDAC_LDAC_Pin);
	delay_us(50);
	LL_GPIO_SetOutputPin(nDAC_LDAC_GPIO_Port, nDAC_LDAC_Pin);

	return ret;
}

If I change just one line of code that sets the command to write to the DAC input resister from (0x00|dacch) to (0x30|dacch) to update the DAC channel after each write (doesn't wait for LDAC), all of the DAC channels are correctly updated.

I have checked that the LDAC pin is going low 50us with a scope, but the DACs are not updated.

Any help or example code would be greatly appreciated.

Thank you,

David

  • Hi David,

    We unfortunately don't have any example code you can use.

    I think this is what you're doing, but make sure you are sending 0x600000 to set the DACs to respond to the LDAC pin. How long after finishing SCLK does your LDAC trigger? There is a requirement for at least 20us after the falling edge of SCL.

    Thanks,
    Erin

  • Erin,

     I am sending 0x600000 to all DACs by sending to the broadcast address (maybe I’m not using the broadcast address correctly).

    If I send 0x600000 to the broadcast address of 0x8e, will that properly configure all DAC7678s on that I2C bus?

    I have experimented with several delays.  The MCU that I am using is very fast (ARM Cortex-M4F).  I have the I2C bus running in FAST MODE (400kHz) and have added the following delays:

    1. delay of 5us after each STOP condition before allowing another START condition.

    2. I am now delaying 50us after programming all input registers of all DACs before I toggle the LDAC line low for 50us.  When I toggle the LDAC line low, the I2C bus is idle with both SCL and SDA lines high.

    I have done quite a bit of experimenting with adding delays here and there but have not yet solved the problem.

    NOTE that my code to update all DAC channels works properly if I do a "write and update" (C3:C2:C1:C0 = 3) for each DAC channel of all of the DACs.  But doing a "write input register" (C3:C2:C1:C0 = 0) for each DAC channel for all of the DACs then delaying 50us and toggling the LDAC pin low for 50us, does not work.

    I have verified that the LDAC pin is pulsing low as expected.

    Do you have any suggestions for something else I should try?

  • Erin,

    With more experimenting, I must not understand how the input register gets transferred to the DAC output register.  I have written a test function to write a value to a single DAC channel input register then try various ways to update the DAC output while reading the registers after each attempt.

    Toggling the LDAC line does not work, nor does setting the "select to update DAC register" command.

    The only way I seem to be able to get the DAC output to get updated is if I write the desired DAC value using the "write to input register then update the DAC" command (C3:C2:C1:C0 = 3)

    When reading the datasheet, it seems straight forward.  Can you think of another reason that I am unable to transfer the input registers to their associated DAC outputs?

    Thank you,

    David

  • Hi David,

    There's nothing that says broadcast mode shouldn't work for what you're trying to do. 

    When testing the standalone Software LDAC, what code did you have in the LDAC register? To use the C3:C2:C1:C0 = 1 registers, I believe you must have the DAC ignore the LDAC pin through the LDAC register.

    I'm going to see if I can find an EVM to test this on. Looking through past e2e questions, it looks like there's been some discrepancy with updating the DACs vs what the datasheet says, though no one has explicitly mentioned using the LDAC.

    Thanks,
    Erin

  • Hi Erin,

    I found the problem.  The datasheet is incorrect concerning the LDAC register.  It turns out that the bits must be 1 for the corresponding DAC channel to respond to the LDAC input pin.

    This also means that before you can use the LDAC input pin following a reset, you must change the LDAC register to have 1s for all DAC channels that are to respond to the LDAC input pin instead of the default 0s..

    There might be more to the story concerning manually updating the DAC outputs by issuing the C3:C2:C1:C0 = 1 command, but it's midnight here and I have a resolution as long as I use the LDAC pin so I won't work on this any more.

    Thank you,

    David

  • Hi David,

    That's a big datasheet bug, thanks for finding it. I'll put in a request to fix the datasheet.

    Thanks,
    Erin

  • Erin,

    I expect that the C3:C2:C1:C0 = 1 command may not be working as documented as well.  I wasn't able to get that working when the LDAC register was all zeros, but I didn't do much experimenting because that wasn't going to be an ideal solution for my application.

    Regards,

    David