control for DAC AD5384 for the SOLID SM1 Slow Control

Dependents:   SPItest sscm

Committer:
wbeaumont
Date:
Wed Oct 08 10:43:18 2014 +0000
Revision:
3:7ca85ed310e0
Parent:
2:fc250e37a028
Child:
4:bc9ab300ab26
added hw reset

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wbeaumont 0:33bb5081488a 1 #include "AD5384.h"
wbeaumont 0:33bb5081488a 2 #include "mbed.h"
wbeaumont 0:33bb5081488a 3
wbeaumont 0:33bb5081488a 4 #define nrch 40 // nr channels
wbeaumont 0:33bb5081488a 5 #define p2_14 16384
wbeaumont 0:33bb5081488a 6 #define p2_13 8192
wbeaumont 0:33bb5081488a 7
wbeaumont 3:7ca85ed310e0 8 #define CS_ACTIVE 1
wbeaumont 3:7ca85ed310e0 9 #define CS_DEACTIVE 0
wbeaumont 3:7ca85ed310e0 10
wbeaumont 3:7ca85ed310e0 11 #define RST_ACTIVE 1
wbeaumont 3:7ca85ed310e0 12 #define RST_DEACTIVE 0
wbeaumont 3:7ca85ed310e0 13
wbeaumont 0:33bb5081488a 14
wbeaumont 0:33bb5081488a 15 // spi mode has to be set for each transmission as spi bus can be shared
wbeaumont 0:33bb5081488a 16
wbeaumont 1:d2d6341d3e97 17 /*****
wbeaumont 1:d2d6341d3e97 18 * version history
wbeaumont 1:d2d6341d3e97 19 * v1.10 initial release version
wbeaumont 1:d2d6341d3e97 20 * v1.11 added init 1 and init 2 function an ctrlreg defs
wbeaumont 1:d2d6341d3e97 21 * v1.12
wbeaumont 2:fc250e37a028 22 * v1.13 corrected channel mask from 0x1F to 0x3F
wbeaumont 3:7ca85ed310e0 23 * v1.20 added hw_rst , added hwrst to init1 not in init2
wbeaumont 2:fc250e37a028 24 *
wbeaumont 1:d2d6341d3e97 25 */
wbeaumont 1:d2d6341d3e97 26
wbeaumont 3:7ca85ed310e0 27 #define AD5384_SRC_VERSION "1.23"
wbeaumont 0:33bb5081488a 28
wbeaumont 0:33bb5081488a 29 #define M_DATA_R 0x3
wbeaumont 0:33bb5081488a 30 #define M_OFFS_R 0x2
wbeaumont 0:33bb5081488a 31 #define M_GAIN_R 0x1
wbeaumont 0:33bb5081488a 32 #define M_SPEC_R 0x0
wbeaumont 0:33bb5081488a 33
wbeaumont 0:33bb5081488a 34 #define NOP_INST 0x0
wbeaumont 0:33bb5081488a 35
wbeaumont 1:d2d6341d3e97 36
wbeaumont 1:d2d6341d3e97 37 // control register bits
wbeaumont 1:d2d6341d3e97 38 #define CTRL_REG_ADDR 0x0C
wbeaumont 1:d2d6341d3e97 39 #define OUT_PWD_STAT_HIMP 0x2000
wbeaumont 1:d2d6341d3e97 40 //0b10 0000 0000 0000
wbeaumont 1:d2d6341d3e97 41 #define OUT_PWD_STAT_100K 0x1FFF
wbeaumont 1:d2d6341d3e97 42 //0b01 1111 1111 1111
wbeaumont 1:d2d6341d3e97 43 #define INT_REF_2500 0X1000
wbeaumont 1:d2d6341d3e97 44 //0b01000000000000
wbeaumont 1:d2d6341d3e97 45 #define INT_REF_1250 0x2FFF
wbeaumont 1:d2d6341d3e97 46 //0b10111111111111
wbeaumont 1:d2d6341d3e97 47 #define I_BOOST_ON 0x0800
wbeaumont 1:d2d6341d3e97 48 //0b00100000000000
wbeaumont 1:d2d6341d3e97 49 #define I_BOOST_OFF 0x37FF
wbeaumont 1:d2d6341d3e97 50 //0b11011111111111
wbeaumont 1:d2d6341d3e97 51 #define REF_SRC_INT 0x0400
wbeaumont 1:d2d6341d3e97 52 //0b00010000000000
wbeaumont 1:d2d6341d3e97 53 #define REF_SRC_EXT 0x3BFF
wbeaumont 1:d2d6341d3e97 54 //0b11 1011 1111 1111
wbeaumont 1:d2d6341d3e97 55 #define MONITOR_MODE_EN 0x0200
wbeaumont 1:d2d6341d3e97 56 //0b00001000000000
wbeaumont 1:d2d6341d3e97 57 #define MONITOR_MODE_DIS 0x3DFF
wbeaumont 1:d2d6341d3e97 58 //0b11 1101 1111 1111
wbeaumont 1:d2d6341d3e97 59 #define TEMP_MONITOR_EN 0x0100
wbeaumont 1:d2d6341d3e97 60 //0b00000100000000
wbeaumont 1:d2d6341d3e97 61 #define TEMP_MONITOR_DIS 0x3EFF
wbeaumont 1:d2d6341d3e97 62 //0b11 1110 1111 1111
wbeaumont 1:d2d6341d3e97 63 #define TOGGLE_DISABLE 0x3F83
wbeaumont 1:d2d6341d3e97 64 //0b11 1111 1000 0011
wbeaumont 1:d2d6341d3e97 65
wbeaumont 1:d2d6341d3e97 66
wbeaumont 1:d2d6341d3e97 67
wbeaumont 1:d2d6341d3e97 68
wbeaumont 3:7ca85ed310e0 69 AD5384::AD5384(SWSPI *spiinterface ,DigitalOut* chipselect, DigitalOut* reset):getVersion( VERSION_AD5384_HDR,AD5384_SRC_VERSION, __TIME__, __DATE__) {
wbeaumont 0:33bb5081488a 70 vref=2.5;
wbeaumont 0:33bb5081488a 71 spi=spiinterface;
wbeaumont 0:33bb5081488a 72 cs=chipselect;
wbeaumont 3:7ca85ed310e0 73 rst=reset;
wbeaumont 0:33bb5081488a 74 for ( int nc=0 ; nc < nrch; nc++){
wbeaumont 0:33bb5081488a 75 gain[nc]=0x3FFE;
wbeaumont 0:33bb5081488a 76 offset[nc]=0x2000;
wbeaumont 0:33bb5081488a 77 }
wbeaumont 0:33bb5081488a 78 };
wbeaumont 0:33bb5081488a 79
wbeaumont 0:33bb5081488a 80 u16 AD5384::calculate_dac_setting(u8 nr, float vout ) {
wbeaumont 0:33bb5081488a 81 //Vout = 2 * Vref * x2 / 2^n => x2 = Vout * 2^14 /(2 * Vref)
wbeaumont 0:33bb5081488a 82 // x2 is loaded to the DAC string
wbeaumont 0:33bb5081488a 83 // x1 is the 14 bit DAC wordt written to the DAC input register
wbeaumont 0:33bb5081488a 84 if( nr >39 ) return 0;
wbeaumont 0:33bb5081488a 85 float x2= vout * p2_14 /(2 *vref);
wbeaumont 0:33bb5081488a 86 // x2 = [(gain+2)/2^n * x1] + offset-2^13
wbeaumont 0:33bb5081488a 87 // x1 = 2^14/(gain+2) * [ x2 - offset+2^13 ]
wbeaumont 0:33bb5081488a 88 u16 x1 = p2_14/(gain[nr]+1) *( x2- offset[nr]+p2_13);
wbeaumont 1:d2d6341d3e97 89 x1= 0x3FFF & x1;
wbeaumont 0:33bb5081488a 90 dac[nr]=x1 ;
wbeaumont 0:33bb5081488a 91 return x1;
wbeaumont 0:33bb5081488a 92 };
wbeaumont 0:33bb5081488a 93
wbeaumont 0:33bb5081488a 94
wbeaumont 0:33bb5081488a 95 u32 AD5384::format_word(u8 mode,u8 ch,u8 rw,u16 data) {
wbeaumont 2:fc250e37a028 96 // MSB set to 0 , toggle mode not supported
wbeaumont 0:33bb5081488a 97 u32 shift = (u32) rw&1;
wbeaumont 0:33bb5081488a 98 u32 word= shift << 22;
wbeaumont 0:33bb5081488a 99
wbeaumont 2:fc250e37a028 100 shift= (u32)(ch &0x3F);
wbeaumont 0:33bb5081488a 101 shift = shift << 16;
wbeaumont 0:33bb5081488a 102 word = word | shift;
wbeaumont 0:33bb5081488a 103
wbeaumont 0:33bb5081488a 104 shift= (u32)(mode & 0x3);
wbeaumont 0:33bb5081488a 105 shift = shift << 14;
wbeaumont 0:33bb5081488a 106 word = word | shift;
wbeaumont 0:33bb5081488a 107
wbeaumont 0:33bb5081488a 108 word = word | (data & 0x3FFF);
wbeaumont 0:33bb5081488a 109
wbeaumont 0:33bb5081488a 110 return word;
wbeaumont 0:33bb5081488a 111 }
wbeaumont 0:33bb5081488a 112
wbeaumont 0:33bb5081488a 113 void AD5384::set_spi_mode(){
wbeaumont 0:33bb5081488a 114 spi->format(24,1);
wbeaumont 0:33bb5081488a 115 spi->frequency(10000000);
wbeaumont 0:33bb5081488a 116 }
wbeaumont 0:33bb5081488a 117
wbeaumont 0:33bb5081488a 118 u16 AD5384::set_volt(u8 ch, float vout ){
wbeaumont 0:33bb5081488a 119 volt[ch]=vout;
wbeaumont 0:33bb5081488a 120 u16 dacin=calculate_dac_setting(ch, vout );
wbeaumont 0:33bb5081488a 121 set_spi_mode();
wbeaumont 0:33bb5081488a 122 u32 data=format_word(M_DATA_R,ch,0,dacin);
wbeaumont 3:7ca85ed310e0 123 cs->write(CS_ACTIVE);
wbeaumont 0:33bb5081488a 124 spi->write(data);
wbeaumont 3:7ca85ed310e0 125 cs->write(CS_DEACTIVE);
wbeaumont 0:33bb5081488a 126 return dacin;
wbeaumont 0:33bb5081488a 127 }
wbeaumont 0:33bb5081488a 128
wbeaumont 1:d2d6341d3e97 129 void AD5384::init1(){
wbeaumont 1:d2d6341d3e97 130 u16 ctrlreg=0;
wbeaumont 3:7ca85ed310e0 131 hw_rst();
wbeaumont 1:d2d6341d3e97 132 ctrlreg = (INT_REF_2500 | REF_SRC_INT ) & TOGGLE_DISABLE;
wbeaumont 1:d2d6341d3e97 133 set_reg(M_SPEC_R,CTRL_REG_ADDR,ctrlreg);
wbeaumont 1:d2d6341d3e97 134
wbeaumont 1:d2d6341d3e97 135 }
wbeaumont 1:d2d6341d3e97 136
wbeaumont 1:d2d6341d3e97 137 void AD5384::init2(){
wbeaumont 1:d2d6341d3e97 138 u16 ctrlreg=0;
wbeaumont 1:d2d6341d3e97 139 // implecite INT_REF_1250
wbeaumont 1:d2d6341d3e97 140 ctrlreg = REF_SRC_INT & TOGGLE_DISABLE;
wbeaumont 1:d2d6341d3e97 141 set_reg(M_SPEC_R,CTRL_REG_ADDR,ctrlreg);
wbeaumont 1:d2d6341d3e97 142
wbeaumont 1:d2d6341d3e97 143 }
wbeaumont 1:d2d6341d3e97 144
wbeaumont 0:33bb5081488a 145
wbeaumont 0:33bb5081488a 146
wbeaumont 0:33bb5081488a 147 u32 AD5384::soft_clr(){
wbeaumont 0:33bb5081488a 148 return set_reg(M_SPEC_R,0x02,0x2000);
wbeaumont 0:33bb5081488a 149 }
wbeaumont 0:33bb5081488a 150
wbeaumont 0:33bb5081488a 151
wbeaumont 0:33bb5081488a 152 u32 AD5384::soft_rst(){
wbeaumont 0:33bb5081488a 153 return set_reg(M_SPEC_R,0x0F,0x211F);
wbeaumont 0:33bb5081488a 154 }
wbeaumont 0:33bb5081488a 155
wbeaumont 0:33bb5081488a 156
wbeaumont 0:33bb5081488a 157 u32 AD5384::clear_code(){
wbeaumont 0:33bb5081488a 158 return set_reg(M_SPEC_R,0x01,0x2000);
wbeaumont 0:33bb5081488a 159 }
wbeaumont 0:33bb5081488a 160
wbeaumont 0:33bb5081488a 161 u16 AD5384::set_gain(u8 ch, u16 gain ){
wbeaumont 0:33bb5081488a 162 set_reg(M_GAIN_R,ch,gain);
wbeaumont 0:33bb5081488a 163 return gain;
wbeaumont 0:33bb5081488a 164 }
wbeaumont 0:33bb5081488a 165
wbeaumont 0:33bb5081488a 166 u16 AD5384::set_offset(u8 ch, u16 gain ){
wbeaumont 0:33bb5081488a 167 set_reg(M_OFFS_R,ch,gain);
wbeaumont 0:33bb5081488a 168 return gain;
wbeaumont 0:33bb5081488a 169 }
wbeaumont 0:33bb5081488a 170
wbeaumont 0:33bb5081488a 171
wbeaumont 0:33bb5081488a 172 u16 AD5384::set_dac(u8 ch, u16 dac ){
wbeaumont 0:33bb5081488a 173 set_reg(M_DATA_R,ch,dac);
wbeaumont 0:33bb5081488a 174 return dac;
wbeaumont 0:33bb5081488a 175 }
wbeaumont 0:33bb5081488a 176
wbeaumont 1:d2d6341d3e97 177
wbeaumont 1:d2d6341d3e97 178
wbeaumont 1:d2d6341d3e97 179
wbeaumont 0:33bb5081488a 180
wbeaumont 0:33bb5081488a 181 u32 AD5384::set_reg(u8 mode,u8 ch, u16 value ){
wbeaumont 0:33bb5081488a 182 set_spi_mode();
wbeaumont 0:33bb5081488a 183 value=value & 0x3FFF;
wbeaumont 0:33bb5081488a 184 u32 data=format_word(mode,ch,0,value);
wbeaumont 3:7ca85ed310e0 185 cs->write(CS_ACTIVE);
wbeaumont 0:33bb5081488a 186 spi->write(data);
wbeaumont 3:7ca85ed310e0 187 cs->write(CS_DEACTIVE);
wbeaumont 0:33bb5081488a 188 return data;
wbeaumont 0:33bb5081488a 189 }
wbeaumont 0:33bb5081488a 190
wbeaumont 0:33bb5081488a 191 u16 AD5384::get_reg(u8 mode, u8 ch ){
wbeaumont 0:33bb5081488a 192 set_spi_mode();
wbeaumont 0:33bb5081488a 193 u32 data=format_word(mode,ch,1,0);
wbeaumont 3:7ca85ed310e0 194 cs->write(CS_ACTIVE);
wbeaumont 0:33bb5081488a 195 spi->write(data);
wbeaumont 3:7ca85ed310e0 196 cs->write(CS_DEACTIVE);
wbeaumont 0:33bb5081488a 197 wait( .00001);
wbeaumont 3:7ca85ed310e0 198 cs->write(CS_ACTIVE);
wbeaumont 0:33bb5081488a 199 data=spi->write(NOP_INST);
wbeaumont 3:7ca85ed310e0 200 cs->write(CS_DEACTIVE);
wbeaumont 0:33bb5081488a 201 return (u16) data;
wbeaumont 0:33bb5081488a 202 }
wbeaumont 0:33bb5081488a 203
wbeaumont 0:33bb5081488a 204 u16 AD5384::get_gain(u8 ch ){
wbeaumont 0:33bb5081488a 205 return get_reg(M_GAIN_R,ch);
wbeaumont 0:33bb5081488a 206
wbeaumont 0:33bb5081488a 207 }
wbeaumont 0:33bb5081488a 208
wbeaumont 0:33bb5081488a 209 u16 AD5384::get_dac(u8 ch){
wbeaumont 0:33bb5081488a 210 return get_reg(M_DATA_R,ch);
wbeaumont 0:33bb5081488a 211
wbeaumont 0:33bb5081488a 212 }
wbeaumont 0:33bb5081488a 213
wbeaumont 0:33bb5081488a 214
wbeaumont 0:33bb5081488a 215
wbeaumont 0:33bb5081488a 216
wbeaumont 0:33bb5081488a 217 u16 AD5384::get_offset(u8 ch ){
wbeaumont 0:33bb5081488a 218 return get_reg(M_OFFS_R,ch);
wbeaumont 0:33bb5081488a 219
wbeaumont 0:33bb5081488a 220 }
wbeaumont 0:33bb5081488a 221
wbeaumont 0:33bb5081488a 222 u32 AD5384::get_ctrl(){
wbeaumont 1:d2d6341d3e97 223
wbeaumont 0:33bb5081488a 224 return get_reg(M_SPEC_R, 0x0C);
wbeaumont 0:33bb5081488a 225 }
wbeaumont 0:33bb5081488a 226
wbeaumont 0:33bb5081488a 227
wbeaumont 0:33bb5081488a 228
wbeaumont 0:33bb5081488a 229
wbeaumont 0:33bb5081488a 230 u16 AD5384::get_ch_out_reg(u8 ch) {
wbeaumont 0:33bb5081488a 231 u32 data=format_word(M_DATA_R,ch,1,0);
wbeaumont 3:7ca85ed310e0 232 cs->write(CS_ACTIVE);
wbeaumont 0:33bb5081488a 233 spi->write(data);
wbeaumont 3:7ca85ed310e0 234 cs->write(CS_DEACTIVE);
wbeaumont 0:33bb5081488a 235 wait( .00001);
wbeaumont 3:7ca85ed310e0 236 cs->write(CS_ACTIVE);
wbeaumont 0:33bb5081488a 237 data=spi->write(NOP_INST);
wbeaumont 3:7ca85ed310e0 238 cs->write(CS_DEACTIVE);
wbeaumont 0:33bb5081488a 239 return (u16) data;
wbeaumont 1:d2d6341d3e97 240 }
wbeaumont 1:d2d6341d3e97 241
wbeaumont 3:7ca85ed310e0 242
wbeaumont 3:7ca85ed310e0 243 void AD5384::hw_rst(){
wbeaumont 3:7ca85ed310e0 244 rst->write( RST_ACTIVE); // edge sensitive
wbeaumont 3:7ca85ed310e0 245 wait_us(30);
wbeaumont 3:7ca85ed310e0 246 rst->write( RST_DEACTIVE);
wbeaumont 3:7ca85ed310e0 247 wait_us(300); // 270 us according data sheet
wbeaumont 3:7ca85ed310e0 248
wbeaumont 3:7ca85ed310e0 249 }
wbeaumont 3:7ca85ed310e0 250