control for DAC AD5384 for the SOLID SM1 Slow Control
Diff: AD5384.cpp
- Revision:
- 4:bc9ab300ab26
- Parent:
- 3:7ca85ed310e0
- Child:
- 5:477603ce54a0
--- a/AD5384.cpp Wed Oct 08 10:43:18 2014 +0000 +++ b/AD5384.cpp Thu Oct 23 17:14:58 2014 +0000 @@ -21,10 +21,12 @@ * v1.12 * v1.13 corrected channel mask from 0x1F to 0x3F * v1.20 added hw_rst , added hwrst to init1 not in init2 - * + * v1.24 added update shadow registers + * v1.26 corrected mask for reading register value + * v1.30 added get voltage */ -#define AD5384_SRC_VERSION "1.23" +#define AD5384_SRC_VERSION "1.26" #define M_DATA_R 0x3 #define M_OFFS_R 0x2 @@ -71,23 +73,49 @@ spi=spiinterface; cs=chipselect; rst=reset; - for ( int nc=0 ; nc < nrch; nc++){ - gain[nc]=0x3FFE; + for ( int nc=0 ; nc < nrch; nc++){ + gain[nc]=0x3FFE; //power up values offset[nc]=0x2000; + dacr[nc]=0x0000; } }; - u16 AD5384::calculate_dac_setting(u8 nr, float vout ) { + +void AD5384::update_gain_shadow(u8 ch ) { + if( ch) gain[ch-1] = get_gain(ch-1); + else + for (u8 chc=0;chc < 40;chc++) { + gain[chc] = get_gain(chc); + } + +} +void AD5384::update_offset_shadow(u8 ch ) { + if( ch) offset[ch-1] = get_offset(ch-1); + else + for (u8 chc=0;chc < 40;chc++) { + offset[chc] = get_offset(chc); + } + } + + void AD5384::update_dac_shadow(u8 ch ) { + if( ch) dacr[ch-1] = get_dac(ch-1); + else + for (u8 chc=0;chc < 40;chc++) { + dacr[chc] = get_dac(chc); + } + } + + +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); + // x1 is the 14 bit DAC wordt written to the DAC input register + float x2= vout * (float)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); + u16 x1 = (float)p2_14/((float)gain[nr]+1) *( x2- offset[nr]+p2_13); x1= 0x3FFF & x1; - dac[nr]=x1 ; + dacr[nr]=x1 ; return x1; }; @@ -123,15 +151,38 @@ cs->write(CS_ACTIVE); spi->write(data); cs->write(CS_DEACTIVE); + dacr[ch]=dacin; return dacin; } + +float AD5384::get_volt(u8 nr, bool readallreg ) { + u16 lgain; + u16 loffset; + u16 ldac=get_ch_out_reg(nr); + dacr[nr]=ldac; + if( readallreg) { + lgain= get_gain(nr); gain[nr]=lgain; + loffset=get_offset(nr); offset[nr]=loffset; + } + else { lgain=gain[nr]; loffset=offset[nr];} + //Vout = 2 * Vref * x2 / 2^n x2= [x1*(m+2)]/2^n ]+ (c-2^(n-1)) + float x2= ((float)(lgain+2)/(float)p2_14)*(float) ldac + loffset- p2_13; + float vout = 2 *vref * x2 / p2_14; + return vout; +} + + + void AD5384::init1(){ u16 ctrlreg=0; hw_rst(); ctrlreg = (INT_REF_2500 | REF_SRC_INT ) & TOGGLE_DISABLE; set_reg(M_SPEC_R,CTRL_REG_ADDR,ctrlreg); - + wait_us(100); + // update_dac_shadow(0); + // update_gain_shadow(0); + // update_offset_shadow(0); } void AD5384::init2(){ @@ -158,19 +209,22 @@ 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_gain(u8 ch, u16 gainin ){ + set_reg(M_GAIN_R,ch,gainin); + gain[ch]=gainin; + return gainin; } -u16 AD5384::set_offset(u8 ch, u16 gain ){ - set_reg(M_OFFS_R,ch,gain); - return gain; +u16 AD5384::set_offset(u8 ch, u16 gainin ){ + set_reg(M_OFFS_R,ch,gainin); + offset[ch]=gainin; + return gainin; } u16 AD5384::set_dac(u8 ch, u16 dac ){ set_reg(M_DATA_R,ch,dac); + dacr[ch]=dac; return dac; } @@ -198,7 +252,7 @@ cs->write(CS_ACTIVE); data=spi->write(NOP_INST); cs->write(CS_DEACTIVE); - return (u16) data; + return (u16) data &0x3FFF; } u16 AD5384::get_gain(u8 ch ){ @@ -236,7 +290,7 @@ cs->write(CS_ACTIVE); data=spi->write(NOP_INST); cs->write(CS_DEACTIVE); - return (u16) data; + return (u16) data & 0x3FFF; }