AD5384 DAC.
Fork of AD5384 by
AD5384.cpp
- Committer:
- NickRyder
- Date:
- 2014-10-07
- Revision:
- 3:0d930c475e72
- Parent:
- 1:d2d6341d3e97
File content as of revision 3:0d930c475e72:
#include "AD5384.h" #include "mbed.h" #define nrch 40 // nr channels #define p2_14 16384 #define p2_13 8192 #define C_ACTIVE 1 #define C_DEACTIVE 0 // spi mode has to be set for each transmission as spi bus can be shared /***** * version history * v1.10 initial release version * v1.11 added init 1 and init 2 function an ctrlreg defs * v1.12 */ #define AD5384_SRC_VERSION "1.12" #define M_DATA_R 0x3 #define M_OFFS_R 0x2 #define M_GAIN_R 0x1 #define M_SPEC_R 0x0 #define NOP_INST 0x0 // control register bits #define CTRL_REG_ADDR 0x0C #define OUT_PWD_STAT_HIMP 0x2000 //0b10 0000 0000 0000 #define OUT_PWD_STAT_100K 0x1FFF //0b01 1111 1111 1111 #define INT_REF_2500 0X1000 //0b01000000000000 #define INT_REF_1250 0x2FFF //0b10111111111111 #define I_BOOST_ON 0x0800 //0b00100000000000 #define I_BOOST_OFF 0x37FF //0b11011111111111 #define REF_SRC_INT 0x0400 //0b00010000000000 #define REF_SRC_EXT 0x3BFF //0b11 1011 1111 1111 #define MONITOR_MODE_EN 0x0200 //0b00001000000000 #define MONITOR_MODE_DIS 0x3DFF //0b11 1101 1111 1111 #define TEMP_MONITOR_EN 0x0100 //0b00000100000000 #define TEMP_MONITOR_DIS 0x3EFF //0b11 1110 1111 1111 #define TOGGLE_DISABLE 0x3F83 //0b11 1111 1000 0011 AD5384::AD5384(SWSPI * spiinterface, DigitalOut * chipselect): getVersion(VERSION_AD5384_HDR, AD5384_SRC_VERSION, __TIME__, __DATE__) { vref = 2.5; spi = spiinterface; cs = chipselect; for (int nc = 0; nc < nrch; nc++) { gain[nc] = 0x3FFE; offset[nc] = 0x2000; } }; u16 AD5384::calculate_dac_setting(u8 nr, float vout) { //Vout = 2 * Vref * x2 / 2^n => x2 = Vout * 2^14 /(2 * Vref) // x2 is loaded to the DAC string // x1 is the 14 bit DAC wordt written to the DAC input register if (nr > 39) return 0; float x2 = vout * p2_14 / (2 * vref); // x2 = [(gain+2)/2^n * x1] + offset-2^13 // x1 = 2^14/(gain+2) * [ x2 - offset+2^13 ] u16 x1 = p2_14 / (gain[nr] + 1) * (x2 - offset[nr] + p2_13); x1 = 0x3FFF & x1; dac[nr] = x1; return x1; }; u32 AD5384::format_word(u8 mode, u8 ch, u8 rw, u16 data) { // not clear what is the MSB bit ,set it to zero u32 shift = (u32) rw & 1; u32 word = shift << 22; shift = (u32) (ch & 0x1F); shift = shift << 16; word = word | shift; shift = (u32) (mode & 0x3); shift = shift << 14; word = word | shift; word = word | (data & 0x3FFF); return word; } void AD5384::set_spi_mode() { spi->format(24, 1); spi->frequency(10000000); } u16 AD5384::set_volt(u8 ch, float vout) { volt[ch] = vout; u16 dacin = calculate_dac_setting(ch, vout); set_spi_mode(); u32 data = format_word(M_DATA_R, ch, 0, dacin); cs->write(C_ACTIVE); spi->write(data); cs->write(C_DEACTIVE); return dacin; } void AD5384::init1() { u16 ctrlreg = 0; ctrlreg = (INT_REF_2500 | REF_SRC_INT ) & TOGGLE_DISABLE; set_reg(M_SPEC_R, CTRL_REG_ADDR, ctrlreg); } void AD5384::init2() { u16 ctrlreg = 0; // implecite INT_REF_1250 ctrlreg = REF_SRC_INT & TOGGLE_DISABLE; set_reg(M_SPEC_R, CTRL_REG_ADDR, ctrlreg); } u32 AD5384::soft_clr() { return set_reg(M_SPEC_R, 0x02, 0x2000); } u32 AD5384::soft_rst() { return set_reg(M_SPEC_R, 0x0F, 0x211F); } u32 AD5384::clear_code() { return set_reg(M_SPEC_R, 0x01, 0x2000); } u16 AD5384::set_gain(u8 ch, u16 gain) { set_reg(M_GAIN_R, ch, gain); return gain; } u16 AD5384::set_offset(u8 ch, u16 gain){ set_reg(M_OFFS_R, ch, gain); return gain; } u16 AD5384::set_dac(u8 ch, u16 dac){ set_reg(M_DATA_R, ch, dac); return dac; } u32 AD5384::set_reg(u8 mode, u8 ch, u16 value){ set_spi_mode(); value = value & 0x3FFF; u32 data = format_word(mode, ch, 0, value); cs->write(C_ACTIVE); spi->write(data); cs->write(C_DEACTIVE); return data; } u16 AD5384::get_reg(u8 mode, u8 ch ){ set_spi_mode(); u32 data = format_word(mode, ch, 1, 0); cs->write(C_ACTIVE); spi->write(data); cs->write(C_DEACTIVE); wait(0.00001); cs->write(C_ACTIVE); data=spi->write(NOP_INST); cs->write(C_DEACTIVE); return (u16) data; } u16 AD5384::get_gain(u8 ch) { return get_reg(M_GAIN_R, ch); } u16 AD5384::get_dac(u8 ch) { return get_reg(M_DATA_R, ch); } u16 AD5384::get_offset(u8 ch) { return get_reg(M_OFFS_R, ch); } u32 AD5384::get_ctrl(){ return get_reg(M_SPEC_R, 0x0C); } u16 AD5384::get_ch_out_reg(u8 ch) { u32 data=format_word(M_DATA_R,ch,1,0); cs->write(C_ACTIVE); spi->write(data); cs->write(C_DEACTIVE); wait(0.00001); cs->write(C_ACTIVE); data = spi->write(NOP_INST); cs->write(C_DEACTIVE); return (u16) data; } #include "sscm_comm.h" // Weird place for an include /* u16 AD5384::get_src_version_nr(){ return sscm_comm::get_hex_version_nr(VERSION_AD5384_SRC); } // returns the version number of hdr of this module u16 AD5384::get_hdr_version_nr(){ return sscm_comm::get_hex_version_nr(VERSION_AD5384_HDR); } */