daniel saakes / dac57xx
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers dac57xx.h Source File

dac57xx.h

00001 #pragma once
00002 #include <stdint.h>
00003 
00004 /**
00005  *   a library for driving the Analog Devices Dac 57X4 series and more.
00006  *   Tested on the AD5724 and AD5754. The AD5734 should also work.
00007  *   http://www.analog.com/en/digital-to-analog-converters/da-converters/ad5724/products/product.html 
00008  *   the AD5722 AFD5732 and AD5752 should also work with minimal effort.
00009  *
00010  *   note: this is the first commit. not all functionalities have been tested with the mbed.
00011  */
00012 
00013 class DacAD57XX : public SPI {
00014 public:
00015   /**
00016    *   
00017    */
00018   DacAD57XX(PinName mosi, PinName miso, PinName sclk, PinName cs) : 
00019       SPI(mosi, miso, sclk), 
00020       mCS(cs)
00021   {
00022     // TODO(dps): make the frequency in an argument? 
00023     frequency(1000000);
00024     // 8 bits a frame
00025     // mode 2: ClockPolarity 1 ClockPhase 1
00026     format(8, 2); 
00027     disableChipSelect();
00028   };
00029   
00030   enum registers {
00031     RW   = 128,
00032     REG2 = 32,
00033     REG1 = 16,
00034     REG0 = 8,
00035     A2   = 4,
00036     A1   = 2,
00037     A0   = 1,
00038     
00039     PUA = 1,
00040     PUB = 2,
00041     PUC = 4,
00042     PUD = 8
00043   };
00044   
00045   enum control {
00046     OUTPUT_RANGE_SELECT = REG0,
00047     CONTROL = REG0 | REG1,
00048     CONTROL_SET = CONTROL | A0,
00049     POWER_CONTROL = REG1
00050   };
00051   
00052   // enum resolution {AD5724R, AD5734R, AD5754R};
00053   enum outputRanges {
00054     UNIPOLAR_5V =  0, 
00055     UNIPOLAR_10V = 1, 
00056     BIPOLAR_5V =   3, 
00057     BIPOLAR_10V =  4
00058   };
00059   enum channels {
00060     ADDRESS_A = 0,
00061     ADDRESS_B = A0,
00062     ADDRESS_C = A1,
00063     ADDRESS_D = A0+A1,
00064     ADDRESS_ALL = A2
00065   };
00066   
00067   /**
00068    *   start communicating with the dac
00069    */  
00070   inline void enableChipSelect() 
00071   {
00072     mCS = 0; // zero to select
00073   }
00074   /**
00075    *   End communicating with the dac
00076    */
00077   inline void disableChipSelect() 
00078   {
00079     mCS = 1;
00080   }
00081   
00082   /**
00083    *   Send 3 bytes to the dac. Discard returned values.
00084    */
00085   inline void send(uint8_t a, uint8_t b, uint8_t c)
00086   {
00087     enableChipSelect();
00088      write(a);
00089      write(b);
00090      write(c);
00091      disableChipSelect();
00092    }
00093    
00094   /**
00095    *   Send 3 bytes, Receive 3 bytes. To receive from the previous command 
00096    *   use transferNop()
00097    *   @return: a 32bit unsigned int with the received 3 bytes.
00098    */
00099   // do range check your input. 
00100   inline uint32_t transfer(uint8_t a, uint8_t b, uint8_t c)
00101   {
00102      enableChipSelect();
00103      
00104      // TODO(dps): refactor to shorter code.
00105      uint8_t aa = (uint8_t)write(a);
00106      uint8_t ab = (uint8_t)write(b);
00107      uint8_t ac = (uint8_t)write(c);
00108   
00109      uint32_t result = (uint32_t)aa;
00110      result = result << 8;
00111      result |= (uint32_t)ab;
00112      result = result << 8;
00113      result |= ac;
00114 
00115      disableChipSelect();
00116   
00117      return result;
00118 /*     
00119      uint32_t r = ((uint8_t)(write(a))) << 16;
00120      r |= ((uint8_t)(write(b))) << 8;
00121      r |= (uint8_t)(write(c));
00122      disableChipSelect();
00123      return r;
00124 */
00125    }
00126 
00127   /**
00128    *   Send a NOP to receive the output of the previous command.
00129    *   @return: a 32bit unsigned int with the received 3 bytes.
00130    */   
00131    inline uint32_t transferNop() {
00132      return transfer( 0x18, 0, 0 );
00133    }
00134   
00135    /**
00136     *   Nothing to be done here yet. TODO(dps): move some items from the constructor?
00137     */
00138    void setup() 
00139    {  
00140    }
00141    
00142    /**
00143     *  returns the power control register.
00144     */
00145    
00146    uint32_t getPowerControl()
00147    {
00148      send( RW | POWER_CONTROL, 0, 0 );
00149      return transferNop();
00150    }
00151    /** 
00152     *  returns the control register. 
00153     */
00154    
00155    uint32_t getControl()
00156    {
00157      send( RW | CONTROL_SET, 0, 0 );
00158      return transferNop();
00159    }
00160    
00161    /**
00162     *   Set the output range for the addresses.
00163     *   example : setOutputRange( ADDRESS_ALL, BIPOLAR_5V );
00164     *
00165     */
00166   
00167    void setOutputRange(int address, int range)
00168    {
00169     uint8_t a = OUTPUT_RANGE_SELECT | address;
00170     uint8_t b = 0;
00171     uint8_t c = range; // range & 0x7;
00172     send(a,b,c);
00173    }
00174   
00175    /**
00176     *   Query the output range of the given address.
00177     *   The address is stored in the lower bytes.
00178     *   (result & 0x3) == BIPOLAR_5V
00179     */
00180    
00181    uint32_t getOutputRange(int address) 
00182    {
00183       uint8_t a = RW | OUTPUT_RANGE_SELECT | address;
00184       send(a,0,0);
00185       return transferNop();
00186    }
00187    
00188    
00189    /** 
00190     *
00191     *   Set power control.
00192     *       
00193     */
00194    
00195    void setPowerControl(int channels)
00196    {
00197    /* AD5722R http://www.analog.com/static/imported-files/data_sheets/AD5722R_5732R_5752R.pdf
00198      |R/W |Zero|Reg2|Reg1|Reg0 | A2| A1| A0| | DB15-DB11|10 |  9|  8| |  7|  6|  5|    4|  3|  2|  1|  0|
00199      |0   |0   |0   |1   |0    |0  |0  |0  | | ---------|X  |OCb|X  | |OCa|0  |TSD|PUref|X  |PUb|X  |PUa|
00200    */
00201    uint8_t a = POWER_CONTROL;
00202    uint8_t b = 0;
00203    uint8_t c = channels & 15;
00204    send(a,b,c);
00205    }
00206    void setControl()
00207    {
00208     uint8_t a = CONTROL_SET;
00209     uint8_t b = 0;
00210     uint8_t c = 8+4;  // TSD termal shutdown + clamp enable
00211     send(a,b,c);
00212    }
00213   
00214    /**
00215     *   Send a value to the dac.
00216     */
00217   
00218    void setValue(int address, uint16_t value) 
00219    {
00220        send(address,(uint8_t)(value >> 8) & 0xFF,(uint8_t)(value) & 0xFF);
00221    }
00222    
00223    private:
00224      DigitalOut mCS;
00225    
00226 };