control for DAC AD5384 for the SOLID SM1 Slow Control
Diff: AD5384.cpp
- Revision:
- 0:33bb5081488a
- Child:
- 1:d2d6341d3e97
diff -r 000000000000 -r 33bb5081488a AD5384.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AD5384.cpp Thu Oct 02 06:30:46 2014 +0000 @@ -0,0 +1,175 @@ +#include "AD5384.h" +#include "mbed.h" + +#define VERSION_AD5384_SRC "1.01" + +#define nrch 40 // nr channels +#define p2_14 16384 +#define p2_13 8192 + +#define C_ACTIVE 1 +#define C_DEACTIVE 0 + + +// spi mode has to be set for each transmission as spi bus can be shared + +#define AD5384_SRC_VERSION "1.01" + +#define M_DATA_R 0x3 +#define M_OFFS_R 0x2 +#define M_GAIN_R 0x1 +#define M_SPEC_R 0x0 + +#define NOP_INST 0x0 + +AD5384::AD5384(SWSPI *spiinterface ,DigitalOut* chipselect) { + vref=2.5; + spi=spiinterface; + cs=chipselect; + for ( int nc=0 ; nc < nrch; nc++){ + gain[nc]=0x3FFE; + offset[nc]=0x2000; + } + }; + + u16 AD5384::calculate_dac_setting(u8 nr, float vout ) { + //Vout = 2 * Vref * x2 / 2^n => x2 = Vout * 2^14 /(2 * Vref) + // x2 is loaded to the DAC string + // x1 is the 14 bit DAC wordt written to the DAC input register + if( nr >39 ) return 0; + float x2= vout * p2_14 /(2 *vref); + // x2 = [(gain+2)/2^n * x1] + offset-2^13 + // x1 = 2^14/(gain+2) * [ x2 - offset+2^13 ] + u16 x1 = p2_14/(gain[nr]+1) *( x2- offset[nr]+p2_13); + x1= 0x3FF & x1; + dac[nr]=x1 ; + return x1; + }; + + +u32 AD5384::format_word(u8 mode,u8 ch,u8 rw,u16 data) { + // not clear what is the MSB bit ,set it to zero + u32 shift = (u32) rw&1; + u32 word= shift << 22; + + shift= (u32)(ch &0x1F); + shift = shift << 16; + word = word | shift; + + shift= (u32)(mode & 0x3); + shift = shift << 14; + word = word | shift; + + word = word | (data & 0x3FFF); + + return word; +} + +void AD5384::set_spi_mode(){ + spi->format(24,1); + spi->frequency(10000000); +} + + u16 AD5384::set_volt(u8 ch, float vout ){ + volt[ch]=vout; + u16 dacin=calculate_dac_setting(ch, vout ); + set_spi_mode(); + u32 data=format_word(M_DATA_R,ch,0,dacin); + cs->write(C_ACTIVE); + spi->write(data); + cs->write(C_DEACTIVE); + return dacin; +} + + + +u32 AD5384::soft_clr(){ + return set_reg(M_SPEC_R,0x02,0x2000); +} + + +u32 AD5384::soft_rst(){ + return set_reg(M_SPEC_R,0x0F,0x211F); +} + + +u32 AD5384::clear_code(){ + return set_reg(M_SPEC_R,0x01,0x2000); + } + +u16 AD5384::set_gain(u8 ch, u16 gain ){ + set_reg(M_GAIN_R,ch,gain); + return gain; +} + +u16 AD5384::set_offset(u8 ch, u16 gain ){ + set_reg(M_OFFS_R,ch,gain); + return gain; +} + + +u16 AD5384::set_dac(u8 ch, u16 dac ){ + set_reg(M_DATA_R,ch,dac); + return dac; +} + + + u32 AD5384::set_reg(u8 mode,u8 ch, u16 value ){ + set_spi_mode(); + value=value & 0x3FFF; + u32 data=format_word(mode,ch,0,value); + cs->write(C_ACTIVE); + spi->write(data); + cs->write(C_DEACTIVE); + return data; + } + + u16 AD5384::get_reg(u8 mode, u8 ch ){ + set_spi_mode(); + u32 data=format_word(mode,ch,1,0); + cs->write(C_ACTIVE); + spi->write(data); + cs->write(C_DEACTIVE); + wait( .00001); + cs->write(C_ACTIVE); + data=spi->write(NOP_INST); + cs->write(C_DEACTIVE); + return (u16) data; +} + + u16 AD5384::get_gain(u8 ch ){ + return get_reg(M_GAIN_R,ch); + +} + +u16 AD5384::get_dac(u8 ch){ + return get_reg(M_DATA_R,ch); + +} + + + + + u16 AD5384::get_offset(u8 ch ){ + return get_reg(M_OFFS_R,ch); + +} + +u32 AD5384::get_ctrl(){ + return get_reg(M_SPEC_R, 0x0C); +} + + + + +u16 AD5384::get_ch_out_reg(u8 ch) { + u32 data=format_word(M_DATA_R,ch,1,0); + cs->write(C_ACTIVE); + spi->write(data); + cs->write(C_DEACTIVE); + wait( .00001); + cs->write(C_ACTIVE); + data=spi->write(NOP_INST); + cs->write(C_DEACTIVE); + return (u16) data; +} \ No newline at end of file