AD5384 DAC.

Fork of AD5384 by wimbeaumont Project

Committer:
wbeaumont
Date:
Thu Oct 02 06:30:46 2014 +0000
Revision:
0:33bb5081488a
Child:
1:d2d6341d3e97
inital version,  not checked for output,   problems with read back value

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 VERSION_AD5384_SRC "1.01"
wbeaumont 0:33bb5081488a 5
wbeaumont 0:33bb5081488a 6 #define nrch 40 // nr channels
wbeaumont 0:33bb5081488a 7 #define p2_14 16384
wbeaumont 0:33bb5081488a 8 #define p2_13 8192
wbeaumont 0:33bb5081488a 9
wbeaumont 0:33bb5081488a 10 #define C_ACTIVE 1
wbeaumont 0:33bb5081488a 11 #define C_DEACTIVE 0
wbeaumont 0:33bb5081488a 12
wbeaumont 0:33bb5081488a 13
wbeaumont 0:33bb5081488a 14 // spi mode has to be set for each transmission as spi bus can be shared
wbeaumont 0:33bb5081488a 15
wbeaumont 0:33bb5081488a 16 #define AD5384_SRC_VERSION "1.01"
wbeaumont 0:33bb5081488a 17
wbeaumont 0:33bb5081488a 18 #define M_DATA_R 0x3
wbeaumont 0:33bb5081488a 19 #define M_OFFS_R 0x2
wbeaumont 0:33bb5081488a 20 #define M_GAIN_R 0x1
wbeaumont 0:33bb5081488a 21 #define M_SPEC_R 0x0
wbeaumont 0:33bb5081488a 22
wbeaumont 0:33bb5081488a 23 #define NOP_INST 0x0
wbeaumont 0:33bb5081488a 24
wbeaumont 0:33bb5081488a 25 AD5384::AD5384(SWSPI *spiinterface ,DigitalOut* chipselect) {
wbeaumont 0:33bb5081488a 26 vref=2.5;
wbeaumont 0:33bb5081488a 27 spi=spiinterface;
wbeaumont 0:33bb5081488a 28 cs=chipselect;
wbeaumont 0:33bb5081488a 29 for ( int nc=0 ; nc < nrch; nc++){
wbeaumont 0:33bb5081488a 30 gain[nc]=0x3FFE;
wbeaumont 0:33bb5081488a 31 offset[nc]=0x2000;
wbeaumont 0:33bb5081488a 32 }
wbeaumont 0:33bb5081488a 33 };
wbeaumont 0:33bb5081488a 34
wbeaumont 0:33bb5081488a 35 u16 AD5384::calculate_dac_setting(u8 nr, float vout ) {
wbeaumont 0:33bb5081488a 36 //Vout = 2 * Vref * x2 / 2^n => x2 = Vout * 2^14 /(2 * Vref)
wbeaumont 0:33bb5081488a 37 // x2 is loaded to the DAC string
wbeaumont 0:33bb5081488a 38 // x1 is the 14 bit DAC wordt written to the DAC input register
wbeaumont 0:33bb5081488a 39 if( nr >39 ) return 0;
wbeaumont 0:33bb5081488a 40 float x2= vout * p2_14 /(2 *vref);
wbeaumont 0:33bb5081488a 41 // x2 = [(gain+2)/2^n * x1] + offset-2^13
wbeaumont 0:33bb5081488a 42 // x1 = 2^14/(gain+2) * [ x2 - offset+2^13 ]
wbeaumont 0:33bb5081488a 43 u16 x1 = p2_14/(gain[nr]+1) *( x2- offset[nr]+p2_13);
wbeaumont 0:33bb5081488a 44 x1= 0x3FF & x1;
wbeaumont 0:33bb5081488a 45 dac[nr]=x1 ;
wbeaumont 0:33bb5081488a 46 return x1;
wbeaumont 0:33bb5081488a 47 };
wbeaumont 0:33bb5081488a 48
wbeaumont 0:33bb5081488a 49
wbeaumont 0:33bb5081488a 50 u32 AD5384::format_word(u8 mode,u8 ch,u8 rw,u16 data) {
wbeaumont 0:33bb5081488a 51 // not clear what is the MSB bit ,set it to zero
wbeaumont 0:33bb5081488a 52 u32 shift = (u32) rw&1;
wbeaumont 0:33bb5081488a 53 u32 word= shift << 22;
wbeaumont 0:33bb5081488a 54
wbeaumont 0:33bb5081488a 55 shift= (u32)(ch &0x1F);
wbeaumont 0:33bb5081488a 56 shift = shift << 16;
wbeaumont 0:33bb5081488a 57 word = word | shift;
wbeaumont 0:33bb5081488a 58
wbeaumont 0:33bb5081488a 59 shift= (u32)(mode & 0x3);
wbeaumont 0:33bb5081488a 60 shift = shift << 14;
wbeaumont 0:33bb5081488a 61 word = word | shift;
wbeaumont 0:33bb5081488a 62
wbeaumont 0:33bb5081488a 63 word = word | (data & 0x3FFF);
wbeaumont 0:33bb5081488a 64
wbeaumont 0:33bb5081488a 65 return word;
wbeaumont 0:33bb5081488a 66 }
wbeaumont 0:33bb5081488a 67
wbeaumont 0:33bb5081488a 68 void AD5384::set_spi_mode(){
wbeaumont 0:33bb5081488a 69 spi->format(24,1);
wbeaumont 0:33bb5081488a 70 spi->frequency(10000000);
wbeaumont 0:33bb5081488a 71 }
wbeaumont 0:33bb5081488a 72
wbeaumont 0:33bb5081488a 73 u16 AD5384::set_volt(u8 ch, float vout ){
wbeaumont 0:33bb5081488a 74 volt[ch]=vout;
wbeaumont 0:33bb5081488a 75 u16 dacin=calculate_dac_setting(ch, vout );
wbeaumont 0:33bb5081488a 76 set_spi_mode();
wbeaumont 0:33bb5081488a 77 u32 data=format_word(M_DATA_R,ch,0,dacin);
wbeaumont 0:33bb5081488a 78 cs->write(C_ACTIVE);
wbeaumont 0:33bb5081488a 79 spi->write(data);
wbeaumont 0:33bb5081488a 80 cs->write(C_DEACTIVE);
wbeaumont 0:33bb5081488a 81 return dacin;
wbeaumont 0:33bb5081488a 82 }
wbeaumont 0:33bb5081488a 83
wbeaumont 0:33bb5081488a 84
wbeaumont 0:33bb5081488a 85
wbeaumont 0:33bb5081488a 86 u32 AD5384::soft_clr(){
wbeaumont 0:33bb5081488a 87 return set_reg(M_SPEC_R,0x02,0x2000);
wbeaumont 0:33bb5081488a 88 }
wbeaumont 0:33bb5081488a 89
wbeaumont 0:33bb5081488a 90
wbeaumont 0:33bb5081488a 91 u32 AD5384::soft_rst(){
wbeaumont 0:33bb5081488a 92 return set_reg(M_SPEC_R,0x0F,0x211F);
wbeaumont 0:33bb5081488a 93 }
wbeaumont 0:33bb5081488a 94
wbeaumont 0:33bb5081488a 95
wbeaumont 0:33bb5081488a 96 u32 AD5384::clear_code(){
wbeaumont 0:33bb5081488a 97 return set_reg(M_SPEC_R,0x01,0x2000);
wbeaumont 0:33bb5081488a 98 }
wbeaumont 0:33bb5081488a 99
wbeaumont 0:33bb5081488a 100 u16 AD5384::set_gain(u8 ch, u16 gain ){
wbeaumont 0:33bb5081488a 101 set_reg(M_GAIN_R,ch,gain);
wbeaumont 0:33bb5081488a 102 return gain;
wbeaumont 0:33bb5081488a 103 }
wbeaumont 0:33bb5081488a 104
wbeaumont 0:33bb5081488a 105 u16 AD5384::set_offset(u8 ch, u16 gain ){
wbeaumont 0:33bb5081488a 106 set_reg(M_OFFS_R,ch,gain);
wbeaumont 0:33bb5081488a 107 return gain;
wbeaumont 0:33bb5081488a 108 }
wbeaumont 0:33bb5081488a 109
wbeaumont 0:33bb5081488a 110
wbeaumont 0:33bb5081488a 111 u16 AD5384::set_dac(u8 ch, u16 dac ){
wbeaumont 0:33bb5081488a 112 set_reg(M_DATA_R,ch,dac);
wbeaumont 0:33bb5081488a 113 return dac;
wbeaumont 0:33bb5081488a 114 }
wbeaumont 0:33bb5081488a 115
wbeaumont 0:33bb5081488a 116
wbeaumont 0:33bb5081488a 117 u32 AD5384::set_reg(u8 mode,u8 ch, u16 value ){
wbeaumont 0:33bb5081488a 118 set_spi_mode();
wbeaumont 0:33bb5081488a 119 value=value & 0x3FFF;
wbeaumont 0:33bb5081488a 120 u32 data=format_word(mode,ch,0,value);
wbeaumont 0:33bb5081488a 121 cs->write(C_ACTIVE);
wbeaumont 0:33bb5081488a 122 spi->write(data);
wbeaumont 0:33bb5081488a 123 cs->write(C_DEACTIVE);
wbeaumont 0:33bb5081488a 124 return data;
wbeaumont 0:33bb5081488a 125 }
wbeaumont 0:33bb5081488a 126
wbeaumont 0:33bb5081488a 127 u16 AD5384::get_reg(u8 mode, u8 ch ){
wbeaumont 0:33bb5081488a 128 set_spi_mode();
wbeaumont 0:33bb5081488a 129 u32 data=format_word(mode,ch,1,0);
wbeaumont 0:33bb5081488a 130 cs->write(C_ACTIVE);
wbeaumont 0:33bb5081488a 131 spi->write(data);
wbeaumont 0:33bb5081488a 132 cs->write(C_DEACTIVE);
wbeaumont 0:33bb5081488a 133 wait( .00001);
wbeaumont 0:33bb5081488a 134 cs->write(C_ACTIVE);
wbeaumont 0:33bb5081488a 135 data=spi->write(NOP_INST);
wbeaumont 0:33bb5081488a 136 cs->write(C_DEACTIVE);
wbeaumont 0:33bb5081488a 137 return (u16) data;
wbeaumont 0:33bb5081488a 138 }
wbeaumont 0:33bb5081488a 139
wbeaumont 0:33bb5081488a 140 u16 AD5384::get_gain(u8 ch ){
wbeaumont 0:33bb5081488a 141 return get_reg(M_GAIN_R,ch);
wbeaumont 0:33bb5081488a 142
wbeaumont 0:33bb5081488a 143 }
wbeaumont 0:33bb5081488a 144
wbeaumont 0:33bb5081488a 145 u16 AD5384::get_dac(u8 ch){
wbeaumont 0:33bb5081488a 146 return get_reg(M_DATA_R,ch);
wbeaumont 0:33bb5081488a 147
wbeaumont 0:33bb5081488a 148 }
wbeaumont 0:33bb5081488a 149
wbeaumont 0:33bb5081488a 150
wbeaumont 0:33bb5081488a 151
wbeaumont 0:33bb5081488a 152
wbeaumont 0:33bb5081488a 153 u16 AD5384::get_offset(u8 ch ){
wbeaumont 0:33bb5081488a 154 return get_reg(M_OFFS_R,ch);
wbeaumont 0:33bb5081488a 155
wbeaumont 0:33bb5081488a 156 }
wbeaumont 0:33bb5081488a 157
wbeaumont 0:33bb5081488a 158 u32 AD5384::get_ctrl(){
wbeaumont 0:33bb5081488a 159 return get_reg(M_SPEC_R, 0x0C);
wbeaumont 0:33bb5081488a 160 }
wbeaumont 0:33bb5081488a 161
wbeaumont 0:33bb5081488a 162
wbeaumont 0:33bb5081488a 163
wbeaumont 0:33bb5081488a 164
wbeaumont 0:33bb5081488a 165 u16 AD5384::get_ch_out_reg(u8 ch) {
wbeaumont 0:33bb5081488a 166 u32 data=format_word(M_DATA_R,ch,1,0);
wbeaumont 0:33bb5081488a 167 cs->write(C_ACTIVE);
wbeaumont 0:33bb5081488a 168 spi->write(data);
wbeaumont 0:33bb5081488a 169 cs->write(C_DEACTIVE);
wbeaumont 0:33bb5081488a 170 wait( .00001);
wbeaumont 0:33bb5081488a 171 cs->write(C_ACTIVE);
wbeaumont 0:33bb5081488a 172 data=spi->write(NOP_INST);
wbeaumont 0:33bb5081488a 173 cs->write(C_DEACTIVE);
wbeaumont 0:33bb5081488a 174 return (u16) data;
wbeaumont 0:33bb5081488a 175 }