AD5666 SPI DAC HELP

01 Apr 2011

Hello Everyone

I am trying to setup and use an AD5666 SPI quad DAC chip. The datasheet is here http://www.analog.com/static/imported-files/data_sheets/AD5666.pdf

I have tried the program below and I get nothing out on any of the DAC channels. I dont see what I am doing wrong?? I tried changing the SPI mode to 0-3 with no change in results. Please take a look and offer any thoughts as I'm stumped for now.

#include "mbed.h"

/*
			   ________AD5666_______
		     GND--| !LDAC  	     SCLK|-- MBED PIN7
            MBED PIN29--| !SYNC	     DIN |-- MBED PIN5
		    3.3V--|VDD		      GND|-- GND
		     NC --|DACA	     DACB|--NC
		     NC --|DACC	     DACD|--NC
		     GND--|POR	            !CLR|--3.3V
		    3.3V--|_Vref__________SDO_|--MBED PIN6
		
*/

SPI DAC(p5,p6,p7);              //mosi PIN13 on chip, miso PIN8 on chip, sck PIN14 on DAC chip
DigitalOut cs(p29);             // chip select of DAC pin2
Serial pc(USBTX, USBRX);


int main() {
    pc.baud(115200);



    cs=1;                       // deselect everything
    wait(0.1);
    DAC.format(16,1);           //16bit word X2, mode 1 SPI??
    DAC.frequency(1000000);


    cs=0;
    wait(0.1);                   //cs low.
                                //     31                                     0
    DAC.write(0x04FF);          //write 0000 0100 1111 1111 1111 1100 1111 1111 to power on all DACs?
    DAC.write(0xFCFF);
    cs=1;                       //cs high. end of data collection
    wait(0.2);

    while (1) {

        cs=0;                   //cs low.
        wait(0.1);              //     31                                     0
        DAC.write(0x010F);      //write 0000 0001 0000 1111 1111 1111 1111 0000 to output full DAC chA??
        DAC.write(0xFFF0);
        cs=1;                   //cs high. end of data collection

        wait(1);

    }

01 Apr 2011

Not 100% sure, but SPI Will only send 8 bits, not 16. If it does, then try swapping MSB & LAB ? Enjoy Ceri

01 Apr 2011

     /* Function: format 
56      *  Configure the data transmission format 
57      * 
58      * Variables: 
59      *  bits - Number of bits per SPI frame (4 - 16) 
60      *  mode - Clock polarity and phase mode (0 - 3) 

The API says it will do 16 bit and the compiler doesnt complain. I will try swapping words and then inverting MSB-LSB and report back.

Thanks Matt

01 Apr 2011

hear is my code for: LTC1660 Eight Channel and LTC2630 Single channel.

<>Code

  1. include "mbed.h"

DigitalOut myled1(LED1); DigitalOut myled2(LED2); DigitalOut myled3(LED3); DigitalOut myled4(LED4);

SPI spi (p5, p6, p7); mosi, miso, sclk

DigitalOut LTC_1660_CS (p22); DigitalOut LTC_1660_CLR (p21); DigitalOut LTC_2630_CS (p23);

Serial pc(USBTX, USBRX);

AnalogIn Therm1(p15);

void LTC1660_Set_DAC_Value (char Channel, int Value); void LTC2630_Set_DAC_Value (int Value); void GetTemperatyre (void);

int main() { int Pattern = 22;

pc.baud(921600); pc.format(8,Serial::None,1);

pc.printf ("\r\nIt Lives ..."); Serial pc(USBTX, USBRX);

set up LTC 1660 .. Vout = 0 ... force LTC1660 ADC's Low .. LTC_2630_CS = 1;

LTC_1660_CS = 1; LTC_1660_CLR = 1; wait_ms (50); LTC_1660_CLR = 0; wait_ms (50); LTC_1660_CLR = 1; wait_ms (50);

LTC1660_Set_DAC_Value (2, 0); LTC2630_Set_DAC_Value (0);

wait (0.5);

myled1 = 1;

while(1) {

while (++Pattern < 1000) 40% of 3.3V = 1.32V, R sens = 1.65 Ohms (3R3 || 3R3) { LTC1660_Set_DAC_Value (2, Pattern); LTC2630_Set_DAC_Value (Pattern); wait_ms (5.0);

myled1 = 1; myled4 = 0; }

myled1 = 0; myled2 = 1;

wait (2.50); GetTemperatyre();

while (Pattern > 1) { LTC1660_Set_DAC_Value (2, Pattern); LTC2630_Set_DAC_Value (Pattern); wait_ms (5.0);

myled2 = 0; myled3 = 1; }

GetTemperatyre();

myled3 = 0; myled4 = 1;

LTC1660_Set_DAC_Value (2, 0);

LTC2630_Set_DAC_Value (0);

LTC1660_Set_DAC_Value (2, 0);

LTC2630_Set_DAC_Value (0);

wait (1.50);

myled4 = 0;

wait (5.50);

myled2 = 0; myled3 = 0; myled4 = 0;

GetTemperatyre();

} }

======================================================

void LTC1660_Set_DAC_Value (char Channel, int Value) { int OUT = 0; check ranges .. Channel &= 0x07; Channel ++;

if (Value > 0x03ff) Value = 0x03ff ;

joine together .. OUT = Channel; OUT = OUT << 10; OUT |= Value; OUT = OUT << 2;

set all channels .. OUT |= 0xf000;

send (as 2 bytes) LTC_1660_CS = 0; spi.write (OUT >> 0x08); spi.write (OUT & 0xff); LTC_1660_CS = 1;

}

=============================================================

void LTC2630_Set_DAC_Value (int Value) { int OUT = 0;

check ranges ..

if (Value > 0x03ff) Value = 0x03ff ;

joine together .. OUT = Value;

OUT = OUT << 6;

send (as 2 bytes) LTC_2630_CS = 0; spi.write (0x30);

spi.write (OUT >> 0x08); spi.write (OUT & 0xff); LTC_2630_CS = 1;

}

============================================================= void GetTemperatyre (void) { float T_ADC = Therm1.read(); float C, C3;

11.239x2 - 61.705x + 94.628

T_ADC = T_ADC * 3.3;

C = ((11.239 * (T_ADC*T_ADC)) - (61.705 * T_ADC)) + 94.628;

C3 =(-12.727*(T_ADC*T_ADC*T_ADC))+(69.111*(T_ADC*T_ADC))-(140.49*T_ADC)+123.77;

printf ("Temp ADC Value = %3.6f - %3.6f Deg C - Third Order .. %3.6f Deg C\r\n",T_ADC, C, C3); }

<>

sorry cannot remember how to mark up code snippets

01 Apr 2011

<<code>>
<</code>>

01 Apr 2011

Matt -

Are you sure that the the initialization is OK?

    DAC.write(0x04FF);          //write 0000 0100 1111 1111 1111 1100 1111 1111 to power on all DACs?
    DAC.write(0xFCFF);

From the data sheet, it looks like command 4 will put the part in power-down mode the first time it is issued. (See "Power Down Modes", on page 23).

Reset is command 7, so you might try

    DAC.write(0x07FF);          //write 0000 0111 1111 1111 1111 1100 1111 1111 to power on all DACs?
    DAC.write(0xFCFF);

and see if that makes a difference.

01 Apr 2011

Hey Hexley

I originally didnt try the power down stuff but then I read the following paragraph which made me think they needed powered up before use?

Any combination of DACs can be powered up by setting PD1 and PD0 to 0 (normal operation). The output powers up to the value in the input register (LDAC Low) or to the value in the DAC register before powering down (LDAC high).

I will try replacing it with the reset 7FFFCFF as you pointed out and report back.

Can anyone confirm that the data in the write function gets sent out MSB first like the datasheet shows or do I need to flip the bit order on the write?

The datasheet does seem to have a mistake in reference to the PD1/PD0 bits being called Bit19 and Bit18 when table 11 shows them correctly as Bit9 and Bit8. That caught me off at first.

Thanks guys for the help I will test your ideas and report back shortly.

01 Apr 2011

I verified all the wiring matched what I drew in the code. I tried the reset Hexley suggested instead of the Power down. I also tried swapping words sent. I have not tried swapping bit order MSB<->LSB yet. Nothing is being output. I want to check that the !CLR should be to 3.3V under normal operation. I am also going to try swapping the MISO, MOSI pins on the slave device in case my interpretation of their pinout is swapped.

Thanks and keep the ideas coming.

Ceri-Your code looks like it confirms the spi MSB to LSB output order but I need to check your datasheet one more time first.

01 Apr 2011

Matt Clement wrote:

Any combination of DACs can be powered up by setting PD1 and PD0 to 0 (normal operation). The output powers up to the value in the input register (LDAC Low) or to the value in the DAC register before powering down (LDAC high).

I see your point. It looks like your original code should have worked...

OK, could it be a problem with the SPI format? The data sheet says that bits are clocked in on the falling edge of SCLK. So the mbed SPI should set up data on the rising edge.

If I read the spec right, you probably want mode 1 (CPOL = 0, CPHA = 1). That should let the clock idle low, then have the data asserted on the rising edge of the clock so the DAC can sample it on the falling edge.

Could be worth a try.

02 Apr 2011

Hexley

Yes I tried modes 0-3 just in case I didnt set it right. My original posted code is actually mode 1 which I thought most likely the proper setting.

DAC.format(16,1);           //16bit word X2, mode 1 SPI??

I might try bit banging the SPI port tomorrow to make sure the chip works.

Hopefully its something stupid on my end and someone will catch it on here soon.

Thanks

04 Apr 2011

so I decided to re-read the datasheet in case I missed something and there in front of me was the answer. the code I was writing was to update the register but not output to the dacs. I changed the code to as shown below and it works fine now.

Thanks everyone for your assistance and hopefully this helps someone else out there.....

        cs=0;                   //cs low.
        wait(0.1);              //     31                                     0
        DAC.write(0x03FF);      //write 0000 0011 0000 1111 1111 1111 1111 0000 to output full DAC chA??
        DAC.write(0xFFF0);
        cs=1;                   //cs high. end of data collection