drive the analog devices AD57XX series of DACs using SPI

Revision:
0:cbb2d9111355
Child:
1:59ce04153689
diff -r 000000000000 -r cbb2d9111355 dac57xx.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dac57xx.h	Tue Oct 25 00:02:56 2011 +0000
@@ -0,0 +1,206 @@
+#pragma once
+#include <stdint.h>
+
+
+/**
+ *   a library for driving the Analog Devices Dac 57xx series.
+ *
+ *
+ */
+
+class DacAD57XX : public SPI {
+public:
+  /**
+   *   
+   */
+  DacAD57XX(PinName mosi, PinName miso, PinName sclk, PinName cs) : 
+      SPI(mosi, miso, sclk), 
+      mCS(cs)
+  {
+    frequency(1000000);
+    // 8 bits a frame
+    // mode 2: ClockPolarity 1 ClockPhase 1
+    format(8, 2); 
+    disableChipSelect();
+  };
+  
+  enum registers {
+    RW   = 128,
+    REG2 = 32,
+    REG1 = 16,
+    REG0 = 8,
+    A2   = 4,
+    A1   = 2,
+    A0   = 1,
+    
+    PUA = 1,
+    PUB = 2,
+    PUC = 4,
+    PUD = 8
+  };
+  
+  enum control {
+    OUTPUT_RANGE_SELECT = REG0,
+    CONTROL = REG0 | REG1,
+    CONTROL_SET = CONTROL | A0,
+    POWER_CONTROL = REG1
+  };
+  
+  // enum resolution {AD5724R, AD5734R, AD5754R};
+  enum outputRanges {
+    UNIPOLAR_5V =  0, 
+    UNIPOLAR_10V = 1, 
+    BIPOLAR_5V =   3, 
+    BIPOLAR_10V =  4
+  };
+  enum channels {
+    ADDRESS_A = 0,
+    ADDRESS_B = A0,
+    ADDRESS_C = A1,
+    ADDRESS_D = A0+A1,
+    ADDRESS_ALL = A2
+  };
+  
+  /**
+   *   start communicating with the dac
+   */  
+  inline void enableChipSelect() 
+  {
+    mCS = 0; // zero to select
+  }
+  /**
+   *   End communicating with the dac
+   */
+  inline void disableChipSelect() 
+  {
+    mCS = 1;
+  }
+  
+  /**
+   *   Send 3 bytes to the dac. Discard returned values.
+   */
+  inline void send(uint8_t a, uint8_t b, uint8_t c)
+  {
+    enableChipSelect();
+     write(a);
+     write(b);
+     write(c);
+     disableChipSelect();
+   }
+   
+  /**
+   *   Send 3 bytes, Receive 3 bytes. To receive from the previous command 
+   *   use transferNop()
+   *   @return: a 32bit unsigned int with the received 3 bytes.
+   */
+  // do range check your input. 
+  inline uint32_t transfer(uint8_t a, uint8_t b, uint8_t c)
+  {
+     enableChipSelect();
+     
+     // TODO(dps): refactor to shorter code.
+     uint8_t aa = (uint8_t)write(a);
+     uint8_t ab = (uint8_t)write(b);
+     uint8_t ac = (uint8_t)write(c);
+  
+     uint32_t result = (uint32_t)aa;
+     result << 8;
+     result |= (uint32_t)ab;
+     result << 8;
+     result |= ac;
+
+     disableChipSelect();
+  
+     return result;
+/*     
+     uint32_t r = ((uint8_t)(write(a))) << 16;
+     r |= ((uint8_t)(write(b))) << 8;
+     r |= (uint8_t)(write(c));
+     disableChipSelect();
+     return r;
+*/
+   }
+
+  /**
+   *   Send a NOP to receive the output of the previous command.
+   *   @return: a 32bit unsigned int with the received 3 bytes.
+   */   
+   inline uint32_t transferNop() {
+     return transfer( 0x18, 0, 0 );
+   }
+  
+   
+   void setup() 
+   {  
+   }
+   
+   uint32_t getPowerControl()
+   {
+     send( RW | POWER_CONTROL, 0, 0 );
+     return transferNop();
+   }
+   uint32_t getControl()
+   {
+     send( RW | CONTROL_SET, 0, 0 );
+     return transferNop();
+   }
+   
+   /**
+    *   Set the output range for the addresses.
+    *   example : setOutputRange( ADDRESS_ALL, BIPOLAR_5V );
+    *
+    */
+  
+   void setOutputRange(int address, int range)
+   {
+    uint8_t a = OUTPUT_RANGE_SELECT | address;
+    uint8_t b = 0;
+    uint8_t c = range; // range & 0x7;
+    send(a,b,c);
+   }
+  
+   /**
+    *   Query the output range of the given address.
+    *   The address is stored in the lower bytes.
+    *   (result & 0x3) == BIPOLAR_5V
+    */
+   
+   uint32_t getOutputRange(int address) 
+   {
+      uint8_t a = RW | OUTPUT_RANGE_SELECT | address;
+      send(a,0,0);
+      return transferNop();
+   }
+   
+   void setPowerControl(int channels)
+   {
+   /* AD5722R http://www.analog.com/static/imported-files/data_sheets/AD5722R_5732R_5752R.pdf
+     |R/W |Zero|Reg2|Reg1|Reg0 | A2| A1| A0| | DB15-DB11|10 |  9|  8| |  7|  6|  5|    4|  3|  2|  1|  0|
+     |0   |0   |0   |1   |0    |0  |0  |0  | | ---------|X  |OCb|X  | |OCa|0  |TSD|PUref|X  |PUb|X  |PUa|
+   */
+   uint8_t a = POWER_CONTROL;
+   uint8_t b = 0;
+   uint8_t c = channels & 15;
+   send(a,b,c);
+   }
+   void setControl()
+   {
+    uint8_t a = CONTROL_SET;
+    uint8_t b = 0;
+    uint8_t c = 8+4;  // TSD termal shutdown + clamp enable
+    send(a,b,c);
+   }
+  
+   /**
+    *   Send a value to the dac.
+    */
+  
+   void setValue(int address, uint16_t value) 
+   {
+       send(address,(uint8_t)(value >> 8) & 0xFF,(uint8_t)(value) & 0xFF);
+   }
+   
+   private:
+     DigitalOut mCS;
+   
+};
\ No newline at end of file