drive the analog devices AD57XX series of DACs using SPI
dac57xx.h@0:cbb2d9111355, 2011-10-25 (annotated)
- 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?
User | Revision | Line number | New 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 | }; |