0
votes

I'm trying to drive the LTC1664 DAC from an Arduino (Mega 2560). The SPI data and clock coming out of the Arduino is always synched (rise and falls) for all 4 modes when the DAC data sheet indicates phasing

I've tried all modes, the SS line on the chip is being brought low during the writes (as it should) and I've tried different speeds and shiftOut(), setClockDivider(), setDataMode(), beginTransaction() and endTransaction().

Is this a bug in Arduino SPI, something specific to the Mega 2560, should I try an Uno or Due? Help please! Code below o-scope traces.

BTW: The 16 bit word I'm trying to transmit is, 0x3600 (o-scope trace truncated).

"MODE1" "MODE0"

/*
  Test DAC Control

  created 18 Mar 2020 (Covid-19, oppsies)
  by Danny Holstein

*/


// inslude the SPI library:
#include <SPI.h>

void DAC(unsigned short value, unsigned char channel, int SS_Pin, int model);
enum models{LTC1664};
enum models model;

// set pin 10 as the slave select for the digital pot:
const int DAC_SS_Pin = 22;

void setup() {
  // set the DAC_SS_Pin as an output:
  // initialize SPI:
  Serial.begin(115200);
  SPI.begin();
  Serial.println("SPI.begin");
  pinMode(DAC_SS_Pin, OUTPUT);

}

void loop() {
  // go through the six channels of the digital pot:
    for (int channel = 1; channel < 6; channel++) {
        delay(500);
        DAC(128*channel, channel, DAC_SS_Pin, LTC1664);
    }
    delay(1000);
 Serial.println("new loop");
}

/*
  DAC Control

  This function controls an LTC1664 Micropower Quad 10-Bit DAC.

 The LTC1664 is SPI-controlled,and to command it, you send one 16 bit word,
  A3 A2 A1 A0 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 X1 X0
  |  ADDR   |         INPUT CODE           | DON'T CARE

 The circuit:
  * CS - to digital pin 22  (SS pin)
  * SDI - to digital pin 51 (MOSI pin)
  * SDO - to digital pin 50 (MISO pin, not used in this function)
  * CLK - to digital pin 52 (SCK pin)

 created 18 Mar 2020 (Covid-19, oppsies)
 by Danny Holstein

*/

void DAC(unsigned short value, unsigned char channel, int SS_Pin, int model) {
  // take the SS pin low to select the chip:
    digitalWrite(SS_Pin, LOW); delay(100);
    unsigned short buf, b16;
    unsigned char *c, b; c = (unsigned char *) &buf;
    switch (model)
    {
        case LTC1664:
            if (channel > 4) channel = 0xF;
            buf = (channel << 12) | ((value & 0x3FF) << 2);
            SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
            b16 = SPI.transfer16(buf);
            Serial.print("0x" + String(buf, HEX)); Serial.println("\t0x" + String(b16, HEX) + "\t");
            SPI.endTransaction();
            break;
        default:
            break;
    }   
    delay(100);
  // take the SS pin high to de-select the chip:
    digitalWrite(SS_Pin, HIGH);
    // printf("value = 0x%04x", buf);
}
1
If I read the datasheet correctly, the figure 2 on the datasheet shows that it should be MSBFIRST, not LSBFIRST in your code. SPI_MODE0 is correct.hcheung
I see you try to set the spi clock speed to 1MHz, you should do that with adding spi.setClockDivider(SPI_CLOCK_DIV16) in your setup(), and use SPISettings(16000000, MSBFIRST, SPI_MODE0) with 16000000 that matching the MCU speed (16MHz) for Arduino Mega.hcheung
Thanks for the comments. You're right on the MSBFIRST, I had had that in my code but the last bit of code included the what-if-I'm-reading-this-wrong desperation move (corrected and still not working). The SPI settings comment is useful but doesn't fix the phasing issue.Danny Holstein

1 Answers

0
votes

Turns out it wasn't related to the Arduino SPI function or phasing issues, the LTC1664 has a CLR pin that I had attached to a GPIO but had failed to command HIGH, it had been floating and inhibiting the chip, command HIGH and everything is good now.