AD5791 Board Patches Revisited

photo(3)

Tried to tidy up the patches a bit and fix the gain issue previously noted appears to have been a config error (wasn’t configured correctly for the external unity gain opamp). Test code follows:

#include <SPI.h>

const int reset = A5;
const int clr   = A4;
const int ldac  = A3;
const int sync  = A2;

#define AD5791_NOP 0 // No operation (NOP).
#define AD5791_REG_DAC 1 // DAC register.
#define AD5791_REG_CTRL 2 // Control register.
#define AD5791_REG_CLR_CODE 3 // Clearcode register.
#define AD5791_CMD_WR_SOFT_CTRL 4 // Software control register(Write only).

typedef enum {
ID_AD5760,
ID_AD5780,
ID_AD5781,
ID_AD5790,
ID_AD5791,
} AD5791_type;

struct ad5791_chip_info {
unsigned int resolution;
};
static const struct ad5791_chip_info ad5791_chip_info[] = {
[ID_AD5760] = {
.resolution = 16,
},
[ID_AD5780] = {
.resolution = 18,
},
[ID_AD5781] = {
.resolution = 18,
},
[ID_AD5790] = {
.resolution = 20,
},
[ID_AD5791] = {
.resolution = 20,
}
};

AD5791_type act_device;

/* Maximum resolution */
#define MAX_RESOLUTION 20
/* Register Map */
#define AD5791_NOP 0 // No operation (NOP).
#define AD5791_REG_DAC 1 // DAC register.
#define AD5791_REG_CTRL 2 // Control register.
#define AD5791_REG_CLR_CODE 3 // Clearcode register.
#define AD5791_CMD_WR_SOFT_CTRL 4 // Software control register(Write only).
/* Input Shift Register bit definition. */
#define AD5791_READ (1ul << 23)
#define AD5791_WRITE (0ul << 23)
#define AD5791_ADDR_REG(x) (((unsigned long)(x) & 0x7) << 20)
/* Control Register bit Definition */
#define AD5791_CTRL_LINCOMP(x) (((x) & 0xF) << 6) // Linearity error compensation.
#define AD5791_CTRL_SDODIS (1 << 5) // SDO pin enable/disable control.
#define AD5791_CTRL_BIN2SC (1 << 4) // DAC register coding selection.
#define AD5791_CTRL_DACTRI (1 << 3) // DAC tristate control.
#define AD5791_CTRL_OPGND (1 << 2) // Output ground clamp control.
#define AD5791_CTRL_RBUF (1 << 1) // Output amplifier configuration control.
/* Software Control Register bit definition */
#define AD5791_SOFT_CTRL_RESET (1 << 2) // RESET function.
#define AD5791_SOFT_CTRL_CLR (1 << 1) // CLR function.
#define AD5791_SOFT_CTRL_LDAC (1 << 0) // LDAC function.
/* DAC OUTPUT STATES */
#define AD5791_OUT_NORMAL 0x0
#define AD5791_OUT_CLAMPED_6K 0x1
#define AD5791_OUT_TRISTATE 0x2

void setup() {
  Serial.begin(115200);

  SPI.begin();
 
  pinMode(11,OUTPUT);
  digitalWrite(11,LOW);

  pinMode(reset, OUTPUT);
  pinMode(clr  , OUTPUT);
  pinMode(ldac , OUTPUT);
  pinMode(sync , OUTPUT);  

  // setup
  digitalWrite(ldac,HIGH);
  digitalWrite(reset,HIGH);
  digitalWrite(clr,HIGH);
  digitalWrite(sync,HIGH);
  SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE1));
    
  long status = AD5791_GetRegisterValue(AD5791_REG_CTRL);
  
  status = AD5791_GetRegisterValue(AD5791_REG_CTRL);
  
  Serial.print(status,BIN);
  Serial.println();

  digitalWrite(ldac,LOW);
  status = AD5791_SetRegisterValue(AD5791_REG_DAC, 1);
  digitalWrite(ldac,HIGH);


  unsigned long oldCtrl = status;
  oldCtrl = oldCtrl & ~(AD5791_CTRL_LINCOMP(-1) | AD5791_CTRL_SDODIS | AD5791_CTRL_BIN2SC | AD5791_CTRL_OPGND);

  oldCtrl = oldCtrl | AD5791_CTRL_RBUF;
  status = AD5791_SetRegisterValue(AD5791_REG_CTRL, oldCtrl);
  
  status = AD5791_GetRegisterValue(AD5791_REG_CTRL);
  


  Serial.print(status,BIN);
  Serial.println();
  Serial.println("DAC");

  digitalWrite(ldac,LOW);
  status = AD5791_SetRegisterValue(AD5791_REG_DAC, 1);
  digitalWrite(ldac,HIGH);

}



long AD5791_SetRegisterValue(unsigned char registerAddress, unsigned long registerValue) {
  unsigned char writeCommand[3] = {0, 0, 0};
  unsigned long spiWord = 0;
  char status = 0;
  spiWord = AD5791_WRITE | AD5791_ADDR_REG(registerAddress) | (registerValue & 0xFFFFF);
  writeCommand[0] = (spiWord >> 16) & 0x0000FF;
  writeCommand[1] = (spiWord >> 8 ) & 0x0000FF;
  writeCommand[2] = (spiWord >> 0 ) & 0x0000FF;
  
  digitalWrite(sync,LOW);
  status = SPI.transfer(writeCommand[0]);
  status = SPI.transfer(writeCommand[1]);
  status = SPI.transfer(writeCommand[2]);
  digitalWrite(sync,HIGH);

  return 0;
}

long AD5791_GetRegisterValue(unsigned char registerAddress) {
  unsigned char registerWord[3] = {0, 0, 0};
  unsigned long dataRead = 0x0;
  char status = 0;
  registerWord[0] = (AD5791_READ | AD5791_ADDR_REG(registerAddress)) >> 16;

  digitalWrite(sync,LOW);

  status = SPI.transfer(registerWord[0]);
  status = SPI.transfer(registerWord[1]);
  status = SPI.transfer(registerWord[2]);
  digitalWrite(sync,HIGH);


  registerWord[0] = 0x00;
  registerWord[1] = 0x00;
  registerWord[2] = 0x00;
    digitalWrite(sync,LOW);
  registerWord[0] = SPI.transfer(0x00);
  registerWord[1] = SPI.transfer(0x00);
  registerWord[2] = SPI.transfer(0x00);
    digitalWrite(sync,HIGH);
  dataRead = ((long)registerWord[0] << 16) |
             ((long)registerWord[1] << 8) |
             ((long)registerWord[2] << 0);
  return dataRead;
}

long current_value=0;
long d=0;
void loop() {
   
    digitalWrite(ldac,LOW);
    int status = AD5791_SetRegisterValue(AD5791_REG_DAC, current_value);
    digitalWrite(ldac,HIGH);
   // Serial.print(current_value);
   // Serial.print("\r\n");
 
  current_value+=10000; 
if(current_value>524000) current_value=-524000;
}