drive the analog devices AD57XX series of DACs using SPI

Committer:
daan
Date:
Tue Oct 25 00:02:56 2011 +0000
Revision:
0:cbb2d9111355
Child:
1:59ce04153689
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daan 0:cbb2d9111355 1 #pragma once
daan 0:cbb2d9111355 2 #include <stdint.h>
daan 0:cbb2d9111355 3
daan 0:cbb2d9111355 4
daan 0:cbb2d9111355 5 /**
daan 0:cbb2d9111355 6 * a library for driving the Analog Devices Dac 57xx series.
daan 0:cbb2d9111355 7 *
daan 0:cbb2d9111355 8 *
daan 0:cbb2d9111355 9 */
daan 0:cbb2d9111355 10
daan 0:cbb2d9111355 11 class DacAD57XX : public SPI {
daan 0:cbb2d9111355 12 public:
daan 0:cbb2d9111355 13 /**
daan 0:cbb2d9111355 14 *
daan 0:cbb2d9111355 15 */
daan 0:cbb2d9111355 16 DacAD57XX(PinName mosi, PinName miso, PinName sclk, PinName cs) :
daan 0:cbb2d9111355 17 SPI(mosi, miso, sclk),
daan 0:cbb2d9111355 18 mCS(cs)
daan 0:cbb2d9111355 19 {
daan 0:cbb2d9111355 20 frequency(1000000);
daan 0:cbb2d9111355 21 // 8 bits a frame
daan 0:cbb2d9111355 22 // mode 2: ClockPolarity 1 ClockPhase 1
daan 0:cbb2d9111355 23 format(8, 2);
daan 0:cbb2d9111355 24 disableChipSelect();
daan 0:cbb2d9111355 25 };
daan 0:cbb2d9111355 26
daan 0:cbb2d9111355 27 enum registers {
daan 0:cbb2d9111355 28 RW = 128,
daan 0:cbb2d9111355 29 REG2 = 32,
daan 0:cbb2d9111355 30 REG1 = 16,
daan 0:cbb2d9111355 31 REG0 = 8,
daan 0:cbb2d9111355 32 A2 = 4,
daan 0:cbb2d9111355 33 A1 = 2,
daan 0:cbb2d9111355 34 A0 = 1,
daan 0:cbb2d9111355 35
daan 0:cbb2d9111355 36 PUA = 1,
daan 0:cbb2d9111355 37 PUB = 2,
daan 0:cbb2d9111355 38 PUC = 4,
daan 0:cbb2d9111355 39 PUD = 8
daan 0:cbb2d9111355 40 };
daan 0:cbb2d9111355 41
daan 0:cbb2d9111355 42 enum control {
daan 0:cbb2d9111355 43 OUTPUT_RANGE_SELECT = REG0,
daan 0:cbb2d9111355 44 CONTROL = REG0 | REG1,
daan 0:cbb2d9111355 45 CONTROL_SET = CONTROL | A0,
daan 0:cbb2d9111355 46 POWER_CONTROL = REG1
daan 0:cbb2d9111355 47 };
daan 0:cbb2d9111355 48
daan 0:cbb2d9111355 49 // enum resolution {AD5724R, AD5734R, AD5754R};
daan 0:cbb2d9111355 50 enum outputRanges {
daan 0:cbb2d9111355 51 UNIPOLAR_5V = 0,
daan 0:cbb2d9111355 52 UNIPOLAR_10V = 1,
daan 0:cbb2d9111355 53 BIPOLAR_5V = 3,
daan 0:cbb2d9111355 54 BIPOLAR_10V = 4
daan 0:cbb2d9111355 55 };
daan 0:cbb2d9111355 56 enum channels {
daan 0:cbb2d9111355 57 ADDRESS_A = 0,
daan 0:cbb2d9111355 58 ADDRESS_B = A0,
daan 0:cbb2d9111355 59 ADDRESS_C = A1,
daan 0:cbb2d9111355 60 ADDRESS_D = A0+A1,
daan 0:cbb2d9111355 61 ADDRESS_ALL = A2
daan 0:cbb2d9111355 62 };
daan 0:cbb2d9111355 63
daan 0:cbb2d9111355 64 /**
daan 0:cbb2d9111355 65 * start communicating with the dac
daan 0:cbb2d9111355 66 */
daan 0:cbb2d9111355 67 inline void enableChipSelect()
daan 0:cbb2d9111355 68 {
daan 0:cbb2d9111355 69 mCS = 0; // zero to select
daan 0:cbb2d9111355 70 }
daan 0:cbb2d9111355 71 /**
daan 0:cbb2d9111355 72 * End communicating with the dac
daan 0:cbb2d9111355 73 */
daan 0:cbb2d9111355 74 inline void disableChipSelect()
daan 0:cbb2d9111355 75 {
daan 0:cbb2d9111355 76 mCS = 1;
daan 0:cbb2d9111355 77 }
daan 0:cbb2d9111355 78
daan 0:cbb2d9111355 79 /**
daan 0:cbb2d9111355 80 * Send 3 bytes to the dac. Discard returned values.
daan 0:cbb2d9111355 81 */
daan 0:cbb2d9111355 82 inline void send(uint8_t a, uint8_t b, uint8_t c)
daan 0:cbb2d9111355 83 {
daan 0:cbb2d9111355 84 enableChipSelect();
daan 0:cbb2d9111355 85 write(a);
daan 0:cbb2d9111355 86 write(b);
daan 0:cbb2d9111355 87 write(c);
daan 0:cbb2d9111355 88 disableChipSelect();
daan 0:cbb2d9111355 89 }
daan 0:cbb2d9111355 90
daan 0:cbb2d9111355 91 /**
daan 0:cbb2d9111355 92 * Send 3 bytes, Receive 3 bytes. To receive from the previous command
daan 0:cbb2d9111355 93 * use transferNop()
daan 0:cbb2d9111355 94 * @return: a 32bit unsigned int with the received 3 bytes.
daan 0:cbb2d9111355 95 */
daan 0:cbb2d9111355 96 // do range check your input.
daan 0:cbb2d9111355 97 inline uint32_t transfer(uint8_t a, uint8_t b, uint8_t c)
daan 0:cbb2d9111355 98 {
daan 0:cbb2d9111355 99 enableChipSelect();
daan 0:cbb2d9111355 100
daan 0:cbb2d9111355 101 // TODO(dps): refactor to shorter code.
daan 0:cbb2d9111355 102 uint8_t aa = (uint8_t)write(a);
daan 0:cbb2d9111355 103 uint8_t ab = (uint8_t)write(b);
daan 0:cbb2d9111355 104 uint8_t ac = (uint8_t)write(c);
daan 0:cbb2d9111355 105
daan 0:cbb2d9111355 106 uint32_t result = (uint32_t)aa;
daan 0:cbb2d9111355 107 result << 8;
daan 0:cbb2d9111355 108 result |= (uint32_t)ab;
daan 0:cbb2d9111355 109 result << 8;
daan 0:cbb2d9111355 110 result |= ac;
daan 0:cbb2d9111355 111
daan 0:cbb2d9111355 112 disableChipSelect();
daan 0:cbb2d9111355 113
daan 0:cbb2d9111355 114 return result;
daan 0:cbb2d9111355 115 /*
daan 0:cbb2d9111355 116 uint32_t r = ((uint8_t)(write(a))) << 16;
daan 0:cbb2d9111355 117 r |= ((uint8_t)(write(b))) << 8;
daan 0:cbb2d9111355 118 r |= (uint8_t)(write(c));
daan 0:cbb2d9111355 119 disableChipSelect();
daan 0:cbb2d9111355 120 return r;
daan 0:cbb2d9111355 121 */
daan 0:cbb2d9111355 122 }
daan 0:cbb2d9111355 123
daan 0:cbb2d9111355 124 /**
daan 0:cbb2d9111355 125 * Send a NOP to receive the output of the previous command.
daan 0:cbb2d9111355 126 * @return: a 32bit unsigned int with the received 3 bytes.
daan 0:cbb2d9111355 127 */
daan 0:cbb2d9111355 128 inline uint32_t transferNop() {
daan 0:cbb2d9111355 129 return transfer( 0x18, 0, 0 );
daan 0:cbb2d9111355 130 }
daan 0:cbb2d9111355 131
daan 0:cbb2d9111355 132
daan 0:cbb2d9111355 133 void setup()
daan 0:cbb2d9111355 134 {
daan 0:cbb2d9111355 135 }
daan 0:cbb2d9111355 136
daan 0:cbb2d9111355 137 uint32_t getPowerControl()
daan 0:cbb2d9111355 138 {
daan 0:cbb2d9111355 139 send( RW | POWER_CONTROL, 0, 0 );
daan 0:cbb2d9111355 140 return transferNop();
daan 0:cbb2d9111355 141 }
daan 0:cbb2d9111355 142 uint32_t getControl()
daan 0:cbb2d9111355 143 {
daan 0:cbb2d9111355 144 send( RW | CONTROL_SET, 0, 0 );
daan 0:cbb2d9111355 145 return transferNop();
daan 0:cbb2d9111355 146 }
daan 0:cbb2d9111355 147
daan 0:cbb2d9111355 148 /**
daan 0:cbb2d9111355 149 * Set the output range for the addresses.
daan 0:cbb2d9111355 150 * example : setOutputRange( ADDRESS_ALL, BIPOLAR_5V );
daan 0:cbb2d9111355 151 *
daan 0:cbb2d9111355 152 */
daan 0:cbb2d9111355 153
daan 0:cbb2d9111355 154 void setOutputRange(int address, int range)
daan 0:cbb2d9111355 155 {
daan 0:cbb2d9111355 156 uint8_t a = OUTPUT_RANGE_SELECT | address;
daan 0:cbb2d9111355 157 uint8_t b = 0;
daan 0:cbb2d9111355 158 uint8_t c = range; // range & 0x7;
daan 0:cbb2d9111355 159 send(a,b,c);
daan 0:cbb2d9111355 160 }
daan 0:cbb2d9111355 161
daan 0:cbb2d9111355 162 /**
daan 0:cbb2d9111355 163 * Query the output range of the given address.
daan 0:cbb2d9111355 164 * The address is stored in the lower bytes.
daan 0:cbb2d9111355 165 * (result & 0x3) == BIPOLAR_5V
daan 0:cbb2d9111355 166 */
daan 0:cbb2d9111355 167
daan 0:cbb2d9111355 168 uint32_t getOutputRange(int address)
daan 0:cbb2d9111355 169 {
daan 0:cbb2d9111355 170 uint8_t a = RW | OUTPUT_RANGE_SELECT | address;
daan 0:cbb2d9111355 171 send(a,0,0);
daan 0:cbb2d9111355 172 return transferNop();
daan 0:cbb2d9111355 173 }
daan 0:cbb2d9111355 174
daan 0:cbb2d9111355 175 void setPowerControl(int channels)
daan 0:cbb2d9111355 176 {
daan 0:cbb2d9111355 177 /* AD5722R http://www.analog.com/static/imported-files/data_sheets/AD5722R_5732R_5752R.pdf
daan 0:cbb2d9111355 178 |R/W |Zero|Reg2|Reg1|Reg0 | A2| A1| A0| | DB15-DB11|10 | 9| 8| | 7| 6| 5| 4| 3| 2| 1| 0|
daan 0:cbb2d9111355 179 |0 |0 |0 |1 |0 |0 |0 |0 | | ---------|X |OCb|X | |OCa|0 |TSD|PUref|X |PUb|X |PUa|
daan 0:cbb2d9111355 180 */
daan 0:cbb2d9111355 181 uint8_t a = POWER_CONTROL;
daan 0:cbb2d9111355 182 uint8_t b = 0;
daan 0:cbb2d9111355 183 uint8_t c = channels & 15;
daan 0:cbb2d9111355 184 send(a,b,c);
daan 0:cbb2d9111355 185 }
daan 0:cbb2d9111355 186 void setControl()
daan 0:cbb2d9111355 187 {
daan 0:cbb2d9111355 188 uint8_t a = CONTROL_SET;
daan 0:cbb2d9111355 189 uint8_t b = 0;
daan 0:cbb2d9111355 190 uint8_t c = 8+4; // TSD termal shutdown + clamp enable
daan 0:cbb2d9111355 191 send(a,b,c);
daan 0:cbb2d9111355 192 }
daan 0:cbb2d9111355 193
daan 0:cbb2d9111355 194 /**
daan 0:cbb2d9111355 195 * Send a value to the dac.
daan 0:cbb2d9111355 196 */
daan 0:cbb2d9111355 197
daan 0:cbb2d9111355 198 void setValue(int address, uint16_t value)
daan 0:cbb2d9111355 199 {
daan 0:cbb2d9111355 200 send(address,(uint8_t)(value >> 8) & 0xFF,(uint8_t)(value) & 0xFF);
daan 0:cbb2d9111355 201 }
daan 0:cbb2d9111355 202
daan 0:cbb2d9111355 203 private:
daan 0:cbb2d9111355 204 DigitalOut mCS;
daan 0:cbb2d9111355 205
daan 0:cbb2d9111355 206 };