AD5384 DAC.

Fork of AD5384 by wimbeaumont Project

Committer:
wbeaumont
Date:
Mon Oct 06 22:25:16 2014 +0000
Revision:
2:fc250e37a028
Parent:
1:d2d6341d3e97
bug correction in channel mask

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