control for DAC AD5384 for the SOLID SM1 Slow Control
AD5384.cpp@0:33bb5081488a, 2014-10-02 (annotated)
- 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?
User | Revision | Line number | New 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 | } |