AD5384 DAC.

Fork of AD5384 by wimbeaumont Project

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);

}

*/