24bit SPI word size for AD5686 Chip

Hi all,
I have a DAC , AD5686. It requires 8bit registry address and 16bit data send via SPI. (24 all together)

How can I do this, since default SPI size is 8 ?
Please help. Thanks in advance.
Gayan

How can I do this, since default SPI size is 8 ?

Send it 3 times using the SPI.transfer for each byte.

It requires 8bit registry address and 16bit data send via SPI. (24 all together)

address is easy since it is already just one byte
The 16 bit data you have to split it using an easy bitwise operations.

byte address = 0x11;//Dummy value
int data = 0xffff;//Your data with the 16 bit
byte highByte = data >>8; //high byte of data
byte lowByte = (data <<8) & 0xff;//low byte of data
//Now send it
SPI.transfer(address);
SPI.transfer(highByte);
SPI.transfer(lowByte);

Dear HugoPT,
I appreciate your help and thank you. :slight_smile:
However I don't think that solution may work. Here is the timing diagram provided in the data sheet.

In it, Sync line drops to low at the start of the data transmission and remains that way till all 24 bits are transmitted. If we transmit data as 3 separate words wont the that line becomes high three times ? The chip may think the signal is over only after the first 8bits.
(actually I tried transmitting data as 3 words one after another using buspirate.It too has a limit of 8bit word size. But didnt get any results. ) :frowning:
Is there any other suggestions ? Is there a configuration setting or something like that we can change ?
Thanks for the help HugoPT.

Gayan

timingdiagram.png

Read this:

Take a clooser look at first picture and look to the SS line.It stays low during 3 bytes transfer like you want.
The reason for that is in the code Nick provide above:

// Written by Nick Gammon
// January 2011

#include <SPI.h>
#include "pins_arduino.h"

void setup (void)
{
}


void loop (void)
{

  
  digitalWrite(SS, HIGH);  // ensure SS stays high

  // Put SCK, MOSI, SS pins into output mode
  // also put SCK, MOSI into LOW state, and SS into HIGH state.
  // Then put SPI hardware into Master mode and turn SPI on
  SPI.begin ();

  delay (5000);  // 5 seconds delay to start logic analyser.

  char c;
  
  // enable Slave Select
  digitalWrite(SS, LOW);    // SS is pin 10
  
  // send test string
  for (const char * p = "Fab" ; c = *p; p++)
    SPI.transfer (c);

 // disable Slave Select
 digitalWrite(SS, HIGH);

 // turn SPI hardware off
 SPI.end ();
 
 while (1);  //loop
}

Your answer and solution is just puting down the SS line using digitalWrite(SS,LOW),then transfer all 3 bytes using SPI.transfer() and then pull the SS line up using the digitalWrite(SS,HIGH).
This will insure your SS line will be low during the 3 bytes transmission to the DAC.
Post results

It 'd be nice to know what arduino board. Due has SSC, and things may be different

The Due has SPI support (SSC is not relevant here) but with a different interface since
the Due hardware insists on controlling the chip-select line itself.

There is a second version of SPI.transfer on the Due that allows for continuation bytes.

For standard AVR Arduinos just call SPI.transfer() as many times as you want.

Remember SPI doesn't require any specific timing, you can clock it at any speed within
the upper limit for the chip(s) involved, adding delays anywhere. So long as MISO and
MOSI are stable on the appropriate clock edge it will work.

gd_illeperuma:
Hi all,
I have a DAC , AD5686. It requires 8bit registry address and 16bit data send via SPI. (24 all together)

http://www.analog.com/en/digital-to-analog-converters/da-converters/ad5686/products/product.html

How can I do this, since default SPI size is 8 ?
Please help. Thanks in advance.
Gayan

Data is clocked on the falling edge of SCLK. So you need to set the SPI mode accordingly.

The SYNC pin on the device seems to be the device select (i.e. the SS pin).

The command to be sent and which DAC it goes to is determined by the first byte. So, to send data to the part, you would do this (pseudo-code):

    uint16_t dac_data = (whatever)
    uint8_t high_byte = dac_command << 4;
    uint8_t high_byte |= dac_address;
    uint8_t mid_byte = dac_data << 8;
    uint8_t low_byte = dac_data & 0xFF;
    digitalWrite (sync_pin, LOW); // begin transfer
    SPI.transfer (high_byte); // send command + DAC address
    SPI.transfer (mid_byte); // send DAC value hi byte
    SPI.transfer (low_byte); // send DAC value, lo byte
    digitalWrite (sync_pin, HIGH); // end transfer

Make sense?

gd_illeperuma:
Dear HugoPT,
I appreciate your help and thank you. :slight_smile:
However I don't think that solution may work. Here is the timing diagram provided in the data sheet.

That timing diagram is for reading and daisy-chaining devices. You want the diagram for WRITING.

Dear all,
Thank you very much for the help. This was the first time I posted to the arduino forum and it seems to be a great nice place with a vibrant community.
I will implement the solution and see what happens and will let you know. By the way the board is an Arduino Uno clone.
Thanks
Gayan