The AD8556 is a zero-drift, sensor signal amplifier with digitally programmable gain and output offset.

Dependents:   AD8556_HelloWolrd

AD8556.cpp

Committer:
fblanc
Date:
2013-09-11
Revision:
0:05eaa16f3327

File content as of revision 0:05eaa16f3327:

/**
 * @brief AD8556:  Digitally Programmable Sensor Signal Amplifier with EMI Filters
 * http://www.analog.com/en/specialty-amplifiers/instrumentation-amplifiers/ad8556/products/product.html
 * @date 05/09/2013
 * @author F.BLANC LAAS-CNRS
 * http://homepages.laas.fr/fblanc/
 */

#include "AD8556.h"

/**
 * @brief Constructor.
 *
 * @param dig

 */
AD8556::AD8556(PinName dig) : _dig(dig)
{
}

/**
 * @brief Destructor.
 */
AD8556::~AD8556()
{
}





/**
   * @brief init
   * @param mode
   * @param First_Stage_Gain_Code
   * @param Second_Stage_Gain_Code
   * @param Vdac_Code
   */
int AD8556::init(unsigned char mode,unsigned char First_Stage_Gain_Code, unsigned char Second_Stage_Gain_Code,unsigned char Vdac_Code)
{
    trame(ADC_Second_Stage_Gain_Code,mode,Second_Stage_Gain_Code);
    trame(ADC_First_Stage_Gain_Code,mode,First_Stage_Gain_Code);
    trame(ADC_Output_Offset_Code,mode,Vdac_Code);
    return 0;
}

/**
   * @brief trame
   * @param parameter
   * @param mode
   * @param data
   */
void AD8556::trame(unsigned char parameter,unsigned char mode,unsigned char data)
{
    //12-Bit Start of Packet 1000 0000 0001
    write_bit(1);
    for(unsigned char i=0; i<10; ++i)
        write_bit(0);
    write_bit(1);
    //2-Bit Function
    switch (mode) {
        case  ADC_MODE_SENSE_CURENT :
            write_bit(0);
            write_bit(0);
            break;
        case  ADC_MODE_SIMULATION :
            write_bit(0);
            write_bit(1);
            break;
        case  ADC_MODE_FUSE :
            write_bit(1);
            write_bit(0);
            break;
        case  ADC_MODE_READ :
            write_bit(1);
            write_bit(1);
            break;
    }
    //2-Bit Parameter
    switch (parameter) {
        case  ADC_Second_Stage_Gain_Code :
            write_bit(0);
            write_bit(0);
            break;
        case  ADC_First_Stage_Gain_Code :
            write_bit(0);
            write_bit(1);
            break;
        case  ADC_Output_Offset_Code :
            write_bit(1);
            write_bit(0);
            break;
        case  ADC_Other_Functions :
            write_bit(1);
            write_bit(1);
            break;
    }


    //2-Bit Dummy 10
    write_bit(1);
    write_bit(0);
    //8-Bit Value
    for(char i=0; i<8; ++i) {
        write_bit( data & (0x80>>i) );
    }
    //12-Bit End of Packet 1000 0000 0001
    write_bit(0);
    for(unsigned char i=0; i<10; ++i)
        write_bit(1);
    write_bit(0);
}

/**
 * @brief write_bit
 *
 * @param bit 1 or 0
 */
void AD8556::write_bit(unsigned char bit)
{
    _dig = 0;
    _dig.output();
    wait_us(10);
    _dig = 1;
    if ( bit )
        wait_us(50); //1
    wait_us(5);
    _dig = 0;
    wait_us(10);
}

/**
   * @brief vdac
   * @param vdac consigne (volt)
   * @param vdd positive voltage supply (volt)
   * @param vss nagative voltage supply (volt)
   * @param mode
   */
void AD8556::prog_vdac(float vdac,float vdd,float vss, unsigned char mode)
{
    unsigned char Vdac_Code;
    Vdac_Code=256*(vdac-vss)/(vdd-vss)-0.5;
    trame(ADC_Output_Offset_Code,mode,Vdac_Code);

}
/**
  * @brief prog_gain
  * @param gain 70 to 1280
  * @param mode
  */
void AD8556::prog_gain(float gain, unsigned char mode)
{
float Second_Stage_Gain;
int First_Stage_Gain_Code;
    if (gain<70) {
        trame(ADC_Second_Stage_Gain_Code,mode,0);
        trame(ADC_First_Stage_Gain_Code,mode,0);
    } else if (gain<100) {
        trame(ADC_Second_Stage_Gain_Code,mode,0);
        Second_Stage_Gain=17.5;
        First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
        trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
    } else if (gain<140) {
        trame(ADC_Second_Stage_Gain_Code,mode,1);
        int First_Stage_Gain_Code=(int)gain/25;
        Second_Stage_Gain=25;
        First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
        trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
    } else if (gain<200) {
        trame(ADC_Second_Stage_Gain_Code,mode,2);
        Second_Stage_Gain=35;
        First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
        trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
    } else if (gain<280) {
        trame(ADC_Second_Stage_Gain_Code,mode,3);
        Second_Stage_Gain=50;
        First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
        trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
    } else if (gain<400) {
        trame(ADC_Second_Stage_Gain_Code,mode,4);
        Second_Stage_Gain=70;
        First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
        trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
    } else if (gain<560) {
        trame(ADC_Second_Stage_Gain_Code,mode,5);
        Second_Stage_Gain=100;
        First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
        trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
    } else if (gain<800) {
        trame(ADC_Second_Stage_Gain_Code,mode,6);
        Second_Stage_Gain=140;
        First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
        trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
    } else if (gain<1280) {
        trame(ADC_Second_Stage_Gain_Code,mode,7);
        Second_Stage_Gain=200;
        First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
        trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
    } else if (gain>=1280) {
        trame(ADC_Second_Stage_Gain_Code,mode,7);
        trame(ADC_First_Stage_Gain_Code, mode, 127);
    }
   
}