Library to communicate with LDC1101

Dependents:   Inductive_Sensor Inductive_Sensor_Jasper Inductive_Sensor_3

Fork of LDC1000 by First Last

LDC1101.cpp

Committer:
bobgiesberts
Date:
2015-12-18
Revision:
20:8e1b1efdbb49
Parent:
19:e205ab9142d8
Child:
21:7c9e04e7d34f

File content as of revision 20:8e1b1efdbb49:

/**
* @file LDC1101.cpp
* @brief this C++ file contains all required
* functions to interface with Texas
* Instruments' LDC1101.
*
* @author Victor Sluiter & Bob Giesberts
*
* @date 2015-12-09
*/

#include "LDC1101.h"

 
LDC1101::LDC1101(PinName mosi, PinName miso, PinName sck, PinName cs, float capacitor, float f_CLKIN, PinName clock_out) : _spiport(mosi,miso,sck, NC), _cs_pin(cs)//, _clock(clock_out,1)
{
    // settings
    _cap = capacitor;
    _spiport.format(8,3);
    _spiport.frequency(1E6);
    setFrequency(f_CLKIN);
    
    _cs_pin.write(1);
    wait_us(100);
    
    init();
}

void LDC1101::func_mode(LDC_MODE mode) { writeSPI((uint8_t *)(&mode), 0x0B); wait(0.1); }
void LDC1101::sleep(void) { /* stop toggling the CLKIN pin input and drive the CLKIN pin Low */ func_mode(LDC_MODE_SHUTDOWN); }
void LDC1101::wakeup(void) { /* start toggling the clock input on the CLKIN pin */ init(); }


void LDC1101::init()
{
    /********* SETTINGS *****************
    ** C_sensor     = 120 pF
    ** L_sensor     =   5 uH
    ** Rs           = ??? Ohm
    ** Rp_min       = ??? Ohm
    **
    ** RCount       = 65535
    ** Samplerate   =    15.3 Hz
    ** t_conv       =    65.5 ms
    **
    ** f_sensor_min =   6.4 MHz (d = inf)
    ** f_sensor_max =  10   MHz (d = 0)
    ** divider      = (4*f_sensor_max)/f_CLKIN = 4*10/16 = 2,5 --> 2
    ************************************/
    
    
    // Set LDC1101 in configuration modus
    func_mode( LDC_MODE_STANDBY );     // STANDBY = 0x01 naar 0x0B  

    // - initialise LHR mode & enable SHUTDOWN mode
    setLHRmode();

    // - set ResponseTime to 6144
    setResponseTime( LDC_RESPONSE_6144 );
    
    // - set Reference Count to highest resolution
    setReferenceCount( 0xffff );
    
    // - set calibrated value for f_sensor_min (d = inf, no target)
    setf_sensorMin( 6.4 ); // 6.4 MHz
    
    // - disable RP_MAX
    // - set RP_MIN to 3 kOhm
    setRPsettings( 1, RPMIN_12 );

    //  - set Divider to 2
    setDivider( DIVIDER_2 );  

    // Done configuring settings, set LDC1101 in measuring modus
    func_mode( LDC_MODE_ACTIVE );
}

void LDC1101::setLHRmode( void ){
    writeSPIregister( 0x05, 0x03 ); // ALT_CONFIG:  0000 0011 --> LHR modus + Shutdown enabled
    writeSPIregister( 0x0C, 0x01 ); // D_CONFIG:    Enables LHR modus, disables RP 
}

void LDC1101::setRPsettings(bool RP_MAX_DIS, RPMIN rpmin)
{
    float rpmins[] = {96, 48, 24, 12, 6, 3, 1.5, 0.75};
    _RPmin = rpmins[rpmin];
    writeSPIregister(0x01, ((RP_MAX_DIS & 0x80) << 7 | rpmin));
}

void LDC1101::setDivider(DIVIDER div)
{
    uint8_t divs[] = {1, 2, 4, 8};
    _divider = divs[div];    
    writeSPIregister(0x34, div);
} 

void LDC1101::setResponseTime(LDC_RESPONSE responsetime)
{
    uint16_t resps[] = {0, 0, 192, 384, 768, 1536, 3072, 6144};
    _responsetime = resps[responsetime];
    uint8_t buffer[1];    
    readSPI(buffer, 0x04, 1);
    writeSPIregister(0x04, (buffer[0] & 0xF8) + responsetime);
}

void LDC1101::setReferenceCount(uint16_t rcount)
{
    _Rcount = rcount;
    uint8_t LHR_RCOUNT_LSB = (rcount & 0x00ff);
    uint8_t LHR_RCOUNT_MSB = ((rcount & 0xff00) >> 8);
    writeSPIregister(0x30, LHR_RCOUNT_LSB);   //LSB
    writeSPIregister(0x31, LHR_RCOUNT_MSB);   //MSB
}

void LDC1101::setSampleRate(float samplerate){ setReferenceCount( ((_fCLKIN/samplerate)-55)/16 ); }


void LDC1101::setf_sensorMin(float f_sensor_min)
{
    uint8_t buffer[1];    
    readSPI(buffer, 0x04, 1);
    uint8_t MIN_FREQ = 16 - (8 / f_sensor_min);
    writeSPIregister(0x04, ((buffer[0] & 0x0F) + (MIN_FREQ << 4)));
}



  


float LDC1101::get_Q(void){ return _RPmin * sqrt(_cap/_inductance*1000000); }  


float LDC1101::get_fsensor(void)
{
    _L_data = get_LHR_Data();
    _fsensor = _fCLKIN * _divider * _L_data/16777216;       // (p.26)
    return _fsensor;
}   


float LDC1101::get_Inductance(void)
{  
    _fsensor = get_fsensor();
    //               1
    // L = ---------------------        --> p. 34
    //     C * (2*PI*f_sensor)^2
    _inductance = 1./(_cap * 4*PI*PI*_fsensor*_fsensor); // (p.34)
    return _inductance;
}


uint32_t LDC1101::get_LHR_Data(void)
{
    uint8_t LHR_DATA[3];
    readSPI(LHR_DATA, 0x38, 3);     // 0x38 + 0x39 + 0x3A
    return (LHR_DATA[2]<<16) | (LHR_DATA[1]<<8) | LHR_DATA[0];
}

void LDC1101::readSPI(uint8_t *data, uint8_t address, uint8_t num_bytes)
{
    // CSB down
    _cs_pin.write(0);
    _spiport.write(address | 0x80); //read flag 
    for(int i=0; i < num_bytes ; i++)
    {
        data[i] = _spiport.write(0xFF);
    }
    // CSB up
    _cs_pin.write(1);
}

void LDC1101::writeSPI(uint8_t *data, uint8_t address, uint8_t num_bytes)
{
    // CSB down
    _cs_pin.write(0);
    
    _spiport.write(address); 
    for(int i=0; i < num_bytes ; i++)
    {
        _spiport.write(data[i]);
    }
    // CSB up
    _cs_pin.write(1);
}


// EXTRA test: Get&print values of all variables to verify (to calculate the induction)
// The data will be printed on the screen using RealTerm: baud 9600.
// Begin ***********************************************************
    float LDC1101::get_fCLKIN()             {return _fCLKIN;};    
    uint8_t LDC1101::get_divider()          {return _divider;};
    float LDC1101::get_RPmin()              {return _RPmin;};
    float LDC1101::get_cap()                {return _cap;};
// END ***********************************************************