Arduino SPI/DAC Problems

Hello Friends,
I’m having trouble interfacing my Duemilanove with TI’s TLC5628 DAC.
I’d love to get some more eyes on it if I could!

Here’s my code:

#include <Spi.h>
/***********************
#define SCK_PIN   13  //Clock
#define MISO_PIN  12  //not going to use
#define MOSI_PIN  11  //DATA
#define SS_PIN    10  //LOAD pin
***********************/

//SPI message format
//filler at beginning: 0000
//channel A: 000
//gain = 1: 0
//value = xxxx xxxx
//so: 0000 0000 xxxx xxxx

byte header = 0x00000000;  //channel A, gain 1
byte dac_off = 0x00000000; //output = 0V
byte dac_on = 0x11111111;  //output = Vref

void setup()
{
  Serial.begin(9600);
  
/*
SPCR
| 7    | 6    | 5    | 4    | 3    | 2    | 1    | 0    |
| SPIE | SPE  | DORD | MSTR | CPOL | CPHA | SPR1 | SPR0 |

SPIE - Enables the SPI interrupt when 1: 0
SPE - Enables the SPI when 1: 1
DORD - Sends data least Significant Bit First when 1, most Significant Bit first when 0: 0
MSTR - Sets the Arduino in master mode when 1, slave mode when 0: 1
CPOL - Sets the data clock to be idle when high if set to 1, idle when low if set to 0: 0
CPHA - Samples data on the falling edge of the data clock when 1, rising edge when 0: 1
SPR1 and SPR0 - Sets the SPI speed, 00 is fastest (4MHz) 11 is slowest (250KHz): 00
*/
  
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR);
  delay(10);

  pinMode(MOSI_PIN, OUTPUT);
  pinMode(MISO_PIN, INPUT);
  pinMode(SCK_PIN,OUTPUT);
  pinMode(SS_PIN,OUTPUT);

  digitalWrite(SS_PIN,HIGH); //keep this line high...
}

/***************SPI TRANSFER**************************/
byte spi_transfer(volatile byte data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}
/******************************************************/


void loop()
{
  delay(10);
  spi_transfer((header));     //send header (filler + gain + address)
  spi_transfer((dac_off));    //send desired DAC Value (in this case, 0V)
  //now toggle the LOAD line
  digitalWrite(SS_PIN,LOW);
  delay(10);
  digitalWrite(SS_PIN,HIGH);
  
  
  delay(3000);  //wait 3 sec...
  
  
  spi_transfer((header));    //send header (filler + gain + address)
  spi_transfer((dac_on));    //send LSByte address (in this case VREF)
  
  //now toggle the LOAD line
  digitalWrite(SS_PIN,LOW);
  delay(10);
  digitalWrite(SS_PIN,HIGH);
  
  delay(3000);  //wait 3 sec...
}

When I run this code, I see my DAC output toggle between 0 and ~1.5V. So the good news is it kinda works. But the bad news is I was expecting it to toggle between 0 and VREF (which is 5V in my case).

So my questions are:

  1. Am I correct in assuming I can use SPI to talk to this IC, or do i have to bitbang it?

  2. Am I handling the 2 byte message to the DAC correctly?

  3. Do i have my SPI set up correctly? (From the datasheet, it looks like i should set (1<<CPHA), but when i do that, it really doesn’t work…)

  4. What am i missing? I feel like I might be going about this the wrong way…

Any help is greatly appreciated!
Thanks

Here's a link to the DAC's page btw:

I have some SPI code and examples for the TLC5618 and TLC5620 at

http://wiblocks.luciani.org/docs/app-notes/nb1a-nco.html
http://wiblocks.luciani.org/docs/app-notes/nb1a-dac.html

(* jcl *)


www: http://www.wiblocks.com
twitter: http://twitter.com/wiblocks
blog: http://luciani.org