drive the analog devices AD57XX series of DACs using SPI
Diff: dac57xx.h
- 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