AD5384 DAC.
Fork of AD5384 by
AD5384.cpp@3:0d930c475e72, 2014-10-07 (annotated)
- Committer:
- NickRyder
- Date:
- Tue Oct 07 21:17:50 2014 +0000
- Revision:
- 3:0d930c475e72
- Parent:
- 1:d2d6341d3e97
Tidying up.
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 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 | 1:d2d6341d3e97 | 18 | */ |
wbeaumont | 1:d2d6341d3e97 | 19 | |
wbeaumont | 1:d2d6341d3e97 | 20 | #define AD5384_SRC_VERSION "1.12" |
wbeaumont | 0:33bb5081488a | 21 | |
wbeaumont | 0:33bb5081488a | 22 | #define M_DATA_R 0x3 |
wbeaumont | 0:33bb5081488a | 23 | #define M_OFFS_R 0x2 |
wbeaumont | 0:33bb5081488a | 24 | #define M_GAIN_R 0x1 |
wbeaumont | 0:33bb5081488a | 25 | #define M_SPEC_R 0x0 |
wbeaumont | 0:33bb5081488a | 26 | |
wbeaumont | 0:33bb5081488a | 27 | #define NOP_INST 0x0 |
wbeaumont | 0:33bb5081488a | 28 | |
wbeaumont | 1:d2d6341d3e97 | 29 | |
wbeaumont | 1:d2d6341d3e97 | 30 | // control register bits |
wbeaumont | 1:d2d6341d3e97 | 31 | #define CTRL_REG_ADDR 0x0C |
wbeaumont | 1:d2d6341d3e97 | 32 | #define OUT_PWD_STAT_HIMP 0x2000 |
wbeaumont | 1:d2d6341d3e97 | 33 | //0b10 0000 0000 0000 |
wbeaumont | 1:d2d6341d3e97 | 34 | #define OUT_PWD_STAT_100K 0x1FFF |
wbeaumont | 1:d2d6341d3e97 | 35 | //0b01 1111 1111 1111 |
wbeaumont | 1:d2d6341d3e97 | 36 | #define INT_REF_2500 0X1000 |
wbeaumont | 1:d2d6341d3e97 | 37 | //0b01000000000000 |
wbeaumont | 1:d2d6341d3e97 | 38 | #define INT_REF_1250 0x2FFF |
wbeaumont | 1:d2d6341d3e97 | 39 | //0b10111111111111 |
wbeaumont | 1:d2d6341d3e97 | 40 | #define I_BOOST_ON 0x0800 |
wbeaumont | 1:d2d6341d3e97 | 41 | //0b00100000000000 |
wbeaumont | 1:d2d6341d3e97 | 42 | #define I_BOOST_OFF 0x37FF |
wbeaumont | 1:d2d6341d3e97 | 43 | //0b11011111111111 |
wbeaumont | 1:d2d6341d3e97 | 44 | #define REF_SRC_INT 0x0400 |
wbeaumont | 1:d2d6341d3e97 | 45 | //0b00010000000000 |
wbeaumont | 1:d2d6341d3e97 | 46 | #define REF_SRC_EXT 0x3BFF |
wbeaumont | 1:d2d6341d3e97 | 47 | //0b11 1011 1111 1111 |
wbeaumont | 1:d2d6341d3e97 | 48 | #define MONITOR_MODE_EN 0x0200 |
wbeaumont | 1:d2d6341d3e97 | 49 | //0b00001000000000 |
wbeaumont | 1:d2d6341d3e97 | 50 | #define MONITOR_MODE_DIS 0x3DFF |
wbeaumont | 1:d2d6341d3e97 | 51 | //0b11 1101 1111 1111 |
wbeaumont | 1:d2d6341d3e97 | 52 | #define TEMP_MONITOR_EN 0x0100 |
wbeaumont | 1:d2d6341d3e97 | 53 | //0b00000100000000 |
wbeaumont | 1:d2d6341d3e97 | 54 | #define TEMP_MONITOR_DIS 0x3EFF |
wbeaumont | 1:d2d6341d3e97 | 55 | //0b11 1110 1111 1111 |
wbeaumont | 1:d2d6341d3e97 | 56 | #define TOGGLE_DISABLE 0x3F83 |
wbeaumont | 1:d2d6341d3e97 | 57 | //0b11 1111 1000 0011 |
wbeaumont | 1:d2d6341d3e97 | 58 | |
wbeaumont | 1:d2d6341d3e97 | 59 | |
wbeaumont | 1:d2d6341d3e97 | 60 | |
wbeaumont | 1:d2d6341d3e97 | 61 | |
NickRyder | 3:0d930c475e72 | 62 | AD5384::AD5384(SWSPI * spiinterface, DigitalOut * chipselect): |
NickRyder | 3:0d930c475e72 | 63 | getVersion(VERSION_AD5384_HDR, AD5384_SRC_VERSION, __TIME__, __DATE__) |
NickRyder | 3:0d930c475e72 | 64 | { |
NickRyder | 3:0d930c475e72 | 65 | vref = 2.5; |
NickRyder | 3:0d930c475e72 | 66 | spi = spiinterface; |
NickRyder | 3:0d930c475e72 | 67 | cs = chipselect; |
NickRyder | 3:0d930c475e72 | 68 | for (int nc = 0; nc < nrch; nc++) { |
NickRyder | 3:0d930c475e72 | 69 | gain[nc] = 0x3FFE; |
NickRyder | 3:0d930c475e72 | 70 | offset[nc] = 0x2000; |
NickRyder | 3:0d930c475e72 | 71 | } |
NickRyder | 3:0d930c475e72 | 72 | }; |
wbeaumont | 0:33bb5081488a | 73 | |
NickRyder | 3:0d930c475e72 | 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 |
NickRyder | 3:0d930c475e72 | 78 | if (nr > 39) return 0; |
NickRyder | 3:0d930c475e72 | 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 ] |
NickRyder | 3:0d930c475e72 | 82 | u16 x1 = p2_14 / (gain[nr] + 1) * (x2 - offset[nr] + p2_13); |
NickRyder | 3:0d930c475e72 | 83 | x1 = 0x3FFF & x1; |
NickRyder | 3:0d930c475e72 | 84 | dac[nr] = x1; |
NickRyder | 3:0d930c475e72 | 85 | return x1; |
NickRyder | 3:0d930c475e72 | 86 | }; |
wbeaumont | 0:33bb5081488a | 87 | |
NickRyder | 3:0d930c475e72 | 88 | u32 AD5384::format_word(u8 mode, u8 ch, u8 rw, u16 data) { |
NickRyder | 3:0d930c475e72 | 89 | // not clear what is the MSB bit ,set it to zero |
NickRyder | 3:0d930c475e72 | 90 | u32 shift = (u32) rw & 1; |
NickRyder | 3:0d930c475e72 | 91 | u32 word = shift << 22; |
NickRyder | 3:0d930c475e72 | 92 | shift = (u32) (ch & 0x1F); |
NickRyder | 3:0d930c475e72 | 93 | shift = shift << 16; |
NickRyder | 3:0d930c475e72 | 94 | word = word | shift; |
NickRyder | 3:0d930c475e72 | 95 | shift = (u32) (mode & 0x3); |
NickRyder | 3:0d930c475e72 | 96 | shift = shift << 14; |
NickRyder | 3:0d930c475e72 | 97 | word = word | shift; |
NickRyder | 3:0d930c475e72 | 98 | word = word | (data & 0x3FFF); |
NickRyder | 3:0d930c475e72 | 99 | return word; |
wbeaumont | 0:33bb5081488a | 100 | } |
NickRyder | 3:0d930c475e72 | 101 | |
NickRyder | 3:0d930c475e72 | 102 | void AD5384::set_spi_mode() { |
NickRyder | 3:0d930c475e72 | 103 | spi->format(24, 1); |
wbeaumont | 0:33bb5081488a | 104 | spi->frequency(10000000); |
wbeaumont | 0:33bb5081488a | 105 | } |
wbeaumont | 0:33bb5081488a | 106 | |
NickRyder | 3:0d930c475e72 | 107 | u16 AD5384::set_volt(u8 ch, float vout) { |
NickRyder | 3:0d930c475e72 | 108 | volt[ch] = vout; |
NickRyder | 3:0d930c475e72 | 109 | u16 dacin = calculate_dac_setting(ch, vout); |
wbeaumont | 0:33bb5081488a | 110 | set_spi_mode(); |
NickRyder | 3:0d930c475e72 | 111 | u32 data = format_word(M_DATA_R, ch, 0, dacin); |
wbeaumont | 0:33bb5081488a | 112 | cs->write(C_ACTIVE); |
wbeaumont | 0:33bb5081488a | 113 | spi->write(data); |
wbeaumont | 0:33bb5081488a | 114 | cs->write(C_DEACTIVE); |
wbeaumont | 0:33bb5081488a | 115 | return dacin; |
wbeaumont | 0:33bb5081488a | 116 | } |
wbeaumont | 0:33bb5081488a | 117 | |
NickRyder | 3:0d930c475e72 | 118 | void AD5384::init1() { |
NickRyder | 3:0d930c475e72 | 119 | u16 ctrlreg = 0; |
NickRyder | 3:0d930c475e72 | 120 | ctrlreg = (INT_REF_2500 | REF_SRC_INT ) & TOGGLE_DISABLE; |
NickRyder | 3:0d930c475e72 | 121 | set_reg(M_SPEC_R, CTRL_REG_ADDR, ctrlreg); |
wbeaumont | 1:d2d6341d3e97 | 122 | } |
wbeaumont | 1:d2d6341d3e97 | 123 | |
NickRyder | 3:0d930c475e72 | 124 | void AD5384::init2() { |
NickRyder | 3:0d930c475e72 | 125 | u16 ctrlreg = 0; |
NickRyder | 3:0d930c475e72 | 126 | // implecite INT_REF_1250 |
NickRyder | 3:0d930c475e72 | 127 | ctrlreg = REF_SRC_INT & TOGGLE_DISABLE; |
NickRyder | 3:0d930c475e72 | 128 | set_reg(M_SPEC_R, CTRL_REG_ADDR, ctrlreg); |
wbeaumont | 1:d2d6341d3e97 | 129 | } |
wbeaumont | 1:d2d6341d3e97 | 130 | |
NickRyder | 3:0d930c475e72 | 131 | u32 AD5384::soft_clr() { |
NickRyder | 3:0d930c475e72 | 132 | return set_reg(M_SPEC_R, 0x02, 0x2000); |
wbeaumont | 0:33bb5081488a | 133 | } |
wbeaumont | 0:33bb5081488a | 134 | |
NickRyder | 3:0d930c475e72 | 135 | u32 AD5384::soft_rst() { |
NickRyder | 3:0d930c475e72 | 136 | return set_reg(M_SPEC_R, 0x0F, 0x211F); |
wbeaumont | 0:33bb5081488a | 137 | } |
wbeaumont | 0:33bb5081488a | 138 | |
NickRyder | 3:0d930c475e72 | 139 | u32 AD5384::clear_code() { |
NickRyder | 3:0d930c475e72 | 140 | return set_reg(M_SPEC_R, 0x01, 0x2000); |
NickRyder | 3:0d930c475e72 | 141 | } |
wbeaumont | 0:33bb5081488a | 142 | |
NickRyder | 3:0d930c475e72 | 143 | u16 AD5384::set_gain(u8 ch, u16 gain) { |
NickRyder | 3:0d930c475e72 | 144 | set_reg(M_GAIN_R, ch, gain); |
NickRyder | 3:0d930c475e72 | 145 | return gain; |
wbeaumont | 0:33bb5081488a | 146 | } |
wbeaumont | 0:33bb5081488a | 147 | |
NickRyder | 3:0d930c475e72 | 148 | u16 AD5384::set_offset(u8 ch, u16 gain){ |
NickRyder | 3:0d930c475e72 | 149 | set_reg(M_OFFS_R, ch, gain); |
NickRyder | 3:0d930c475e72 | 150 | return gain; |
wbeaumont | 0:33bb5081488a | 151 | } |
wbeaumont | 0:33bb5081488a | 152 | |
wbeaumont | 1:d2d6341d3e97 | 153 | |
NickRyder | 3:0d930c475e72 | 154 | u16 AD5384::set_dac(u8 ch, u16 dac){ |
NickRyder | 3:0d930c475e72 | 155 | set_reg(M_DATA_R, ch, dac); |
NickRyder | 3:0d930c475e72 | 156 | return dac; |
NickRyder | 3:0d930c475e72 | 157 | } |
wbeaumont | 1:d2d6341d3e97 | 158 | |
NickRyder | 3:0d930c475e72 | 159 | u32 AD5384::set_reg(u8 mode, u8 ch, u16 value){ |
NickRyder | 3:0d930c475e72 | 160 | set_spi_mode(); |
NickRyder | 3:0d930c475e72 | 161 | value = value & 0x3FFF; |
NickRyder | 3:0d930c475e72 | 162 | u32 data = format_word(mode, ch, 0, value); |
NickRyder | 3:0d930c475e72 | 163 | cs->write(C_ACTIVE); |
NickRyder | 3:0d930c475e72 | 164 | spi->write(data); |
NickRyder | 3:0d930c475e72 | 165 | cs->write(C_DEACTIVE); |
NickRyder | 3:0d930c475e72 | 166 | return data; |
NickRyder | 3:0d930c475e72 | 167 | } |
wbeaumont | 0:33bb5081488a | 168 | |
NickRyder | 3:0d930c475e72 | 169 | u16 AD5384::get_reg(u8 mode, u8 ch ){ |
NickRyder | 3:0d930c475e72 | 170 | set_spi_mode(); |
NickRyder | 3:0d930c475e72 | 171 | u32 data = format_word(mode, ch, 1, 0); |
NickRyder | 3:0d930c475e72 | 172 | cs->write(C_ACTIVE); |
NickRyder | 3:0d930c475e72 | 173 | spi->write(data); |
NickRyder | 3:0d930c475e72 | 174 | cs->write(C_DEACTIVE); |
NickRyder | 3:0d930c475e72 | 175 | wait(0.00001); |
NickRyder | 3:0d930c475e72 | 176 | cs->write(C_ACTIVE); |
NickRyder | 3:0d930c475e72 | 177 | data=spi->write(NOP_INST); |
NickRyder | 3:0d930c475e72 | 178 | cs->write(C_DEACTIVE); |
NickRyder | 3:0d930c475e72 | 179 | return (u16) data; |
wbeaumont | 0:33bb5081488a | 180 | } |
wbeaumont | 0:33bb5081488a | 181 | |
NickRyder | 3:0d930c475e72 | 182 | u16 AD5384::get_gain(u8 ch) { |
NickRyder | 3:0d930c475e72 | 183 | return get_reg(M_GAIN_R, ch); |
wbeaumont | 0:33bb5081488a | 184 | } |
wbeaumont | 0:33bb5081488a | 185 | |
NickRyder | 3:0d930c475e72 | 186 | u16 AD5384::get_dac(u8 ch) { |
NickRyder | 3:0d930c475e72 | 187 | return get_reg(M_DATA_R, ch); |
wbeaumont | 0:33bb5081488a | 188 | } |
NickRyder | 3:0d930c475e72 | 189 | |
NickRyder | 3:0d930c475e72 | 190 | u16 AD5384::get_offset(u8 ch) { |
NickRyder | 3:0d930c475e72 | 191 | return get_reg(M_OFFS_R, ch); |
wbeaumont | 0:33bb5081488a | 192 | } |
wbeaumont | 0:33bb5081488a | 193 | |
wbeaumont | 0:33bb5081488a | 194 | u32 AD5384::get_ctrl(){ |
wbeaumont | 0:33bb5081488a | 195 | return get_reg(M_SPEC_R, 0x0C); |
wbeaumont | 0:33bb5081488a | 196 | } |
wbeaumont | 0:33bb5081488a | 197 | |
wbeaumont | 0:33bb5081488a | 198 | u16 AD5384::get_ch_out_reg(u8 ch) { |
NickRyder | 3:0d930c475e72 | 199 | u32 data=format_word(M_DATA_R,ch,1,0); |
NickRyder | 3:0d930c475e72 | 200 | cs->write(C_ACTIVE); |
NickRyder | 3:0d930c475e72 | 201 | spi->write(data); |
NickRyder | 3:0d930c475e72 | 202 | cs->write(C_DEACTIVE); |
NickRyder | 3:0d930c475e72 | 203 | wait(0.00001); |
NickRyder | 3:0d930c475e72 | 204 | cs->write(C_ACTIVE); |
NickRyder | 3:0d930c475e72 | 205 | data = spi->write(NOP_INST); |
NickRyder | 3:0d930c475e72 | 206 | cs->write(C_DEACTIVE); |
NickRyder | 3:0d930c475e72 | 207 | return (u16) data; |
wbeaumont | 1:d2d6341d3e97 | 208 | } |
wbeaumont | 1:d2d6341d3e97 | 209 | |
NickRyder | 3:0d930c475e72 | 210 | #include "sscm_comm.h" // Weird place for an include |
wbeaumont | 1:d2d6341d3e97 | 211 | /* |
wbeaumont | 1:d2d6341d3e97 | 212 | |
wbeaumont | 1:d2d6341d3e97 | 213 | u16 AD5384::get_src_version_nr(){ |
wbeaumont | 1:d2d6341d3e97 | 214 | return sscm_comm::get_hex_version_nr(VERSION_AD5384_SRC); |
wbeaumont | 1:d2d6341d3e97 | 215 | } |
wbeaumont | 1:d2d6341d3e97 | 216 | |
wbeaumont | 1:d2d6341d3e97 | 217 | // returns the version number of hdr of this module |
wbeaumont | 1:d2d6341d3e97 | 218 | u16 AD5384::get_hdr_version_nr(){ |
wbeaumont | 1:d2d6341d3e97 | 219 | return sscm_comm::get_hex_version_nr(VERSION_AD5384_HDR); |
wbeaumont | 1:d2d6341d3e97 | 220 | |
wbeaumont | 1:d2d6341d3e97 | 221 | } |
wbeaumont | 1:d2d6341d3e97 | 222 | |
wbeaumont | 1:d2d6341d3e97 | 223 | */ |