drive the analog devices AD57XX series of DACs using SPI

Files at this revision

API Documentation at this revision

Comitter:
daan
Date:
Wed Oct 26 06:42:45 2011 +0000
Parent:
0:cbb2d9111355
Commit message:
added some documentation.

Changed in this revision

dac57xx.h Show annotated file Show diff for this revision Revisions of this file
--- a/dac57xx.h	Tue Oct 25 00:02:56 2011 +0000
+++ b/dac57xx.h	Wed Oct 26 06:42:45 2011 +0000
@@ -1,206 +1,226 @@
-#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;
-   
+#pragma once
+#include <stdint.h>
+
+/**
+ *   a library for driving the Analog Devices Dac 57X4 series and more.
+ *   Tested on the AD5724 and AD5754. The AD5734 should also work.
+ *   http://www.analog.com/en/digital-to-analog-converters/da-converters/ad5724/products/product.html 
+ *   the AD5722 AFD5732 and AD5752 should also work with minimal effort.
+ *
+ *   note: this is the first commit. not all functionalities have been tested with the mbed.
+ */
+
+class DacAD57XX : public SPI {
+public:
+  /**
+   *   
+   */
+  DacAD57XX(PinName mosi, PinName miso, PinName sclk, PinName cs) : 
+      SPI(mosi, miso, sclk), 
+      mCS(cs)
+  {
+    // TODO(dps): make the frequency in an argument? 
+    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 = result << 8;
+     result |= (uint32_t)ab;
+     result = 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 );
+   }
+  
+   /**
+    *   Nothing to be done here yet. TODO(dps): move some items from the constructor?
+    */
+   void setup() 
+   {  
+   }
+   
+   /**
+    *  returns the power control register.
+    */
+   
+   uint32_t getPowerControl()
+   {
+     send( RW | POWER_CONTROL, 0, 0 );
+     return transferNop();
+   }
+   /** 
+    *  returns the control register. 
+    */
+   
+   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();
+   }
+   
+   
+   /** 
+    *
+    *   Set power control.
+    *       
+    */
+   
+   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