TI LDC1000 library.

ldc1000.cpp

Committer:
jonebuckman
Date:
2017-04-05
Revision:
0:b9daf55d7586

File content as of revision 0:b9daf55d7586:

/**
 * @file ldc1000.cpp
 *
 * @author Jon Buckman
 * 
 * @section LICENSE
 *
 * Copyright (c) 2014 Jon Buckman
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * @section DESCRIPTION
 *
 * LDC1000 Inductance to Digital Converter from Texas Instruments.
 *
 * Datasheet:
 *
 * http://www.ti.com/lit/ds/symlink/ldc1000.pdf
 */
 
/**
 * Includes
 */
#include "ldc1000.h"

/**
 * Defines
 *
 * (Note that all defines here start with an underscore, e.g. '_LDC1000_MODE_UNKNOWN',
 *  and are local to this library.  The defines in the ldc1000.h file do not start
 *  with the underscore, and can be used by code to access this library.)
 */

typedef enum {
    _LDC1000_MODE_UNKNOWN,
    _LDC1000_MODE_POWER_DOWN,
    _LDC1000_MODE_STANDBY,
} LDC1000_Mode_Type;

/**
 * Registers
 */
#define _LDC1000_DEVICE_ID 0x00
#define _LDC1000_RP_MAX 0x01
#define _LDC1000_RP_MIN 0x02
#define _LDC1000_SENSOR_FREQ 0x03
#define _LDC1000_LDC_CONFIG 0x04
#define _LDC1000_CLK_CONFIG 0x05
#define _LDC1000_CMP_THLD_HI_LSB 0x06
#define _LDC1000_CMP_THLD_HI_MSB 0x07
#define _LDC1000_CMP_THLD_LO_LSB 0x08
#define _LDC1000_CMP_THLD_LO_MSB 0x09
#define _LDC1000_INTB_PIN_CONFIG 0x0A
#define _LDC1000_PWR_CONFIG 0x0B
#define _LDC1000_STATUS 0x20
#define _LDC1000_PRX_DATA_LSB 0x21
#define _LDC1000_PRX_DATA_MSB 0x22
#define _LDC1000_FREQ_CNT_DATA_LSB 0x23
#define _LDC1000_FREQ_CNT_DATA_MIDB 0x24
#define _LDC1000_FREQ_CNT_DATA_MSB 0x25

/**
 * LDC Configuration Masks
 */
#define _LDC1000_LDC_CONFIG_MASK_AMP (0x03<<3)
#define _LDC1000_LDC_CONFIG_MASK_RESP (0x07<<0)
#define _LDC1000_CLK_CONFIG_MASK_SEL (0x01<<1)
#define _LDC1000_CLK_CONFIG_MASK_PD (0x01<<0)
#define _LDC1000_INTB_PIN_CONFIG_MASK_MODE (0x07<<0)
#define _LDC1000_STATUS_MASK (0x08<<4)
#define _LDC1000_PWR_CONFIG_MASK (0x01<<0)

/**
 * LDC SPI
 */
#define _LDC1000_SPI_CMD_RD_REG 0x80
#define _LDC1000_SPI_CMD_WR_REG 0x00
#define _LDC1000_REG_ADDRESS_MASK 0x7f
#define _LDC1000_SPI_CMD_NOP 0xff
#define _LDC1000_SPI_MAX_DATA_RATE     10000000

/**
 * LDC Timing
 */
#define _LDC1000_TIMING_Tundef2pd_us     100000   // 100mS
#define _LDC1000_TIMING_Tstby2a_us          130   // 130uS
#define _LDC1000_TIMING_Thce_us              10   //  10uS
#define _LDC1000_TIMING_Tpd2stby_us        4500   // 4.5mS worst case
#define _LDC1000_TIMING_Tpece2csn_us          4   //   4uS

/**
 * Methods
 */
LDC1000::LDC1000(PinName mosi, 
                     PinName miso, 
                     PinName sck, 
                     PinName csn,
                     PinName irq) : spi_(mosi, miso, sck), nCS_(csn), nIRQ_(irq) {

    mode = _LDC1000_MODE_UNKNOWN;

    nCS_ = 1;

    spi_.frequency(_LDC1000_SPI_MAX_DATA_RATE/5);     // 2Mbit, 1/5th the maximum transfer rate for the SPI bus
    spi_.format(8,0);                                   // 8-bit, ClockPhase = 0, ClockPolarity = 0

    wait_us(_LDC1000_TIMING_Tundef2pd_us);    // Wait for Power-on reset

    setRegister(_LDC1000_PWR_CONFIG, 0); // Power Down

    //
    // Setup default configuration
    //
    setSensorFrequency(179);

    mode = _LDC1000_MODE_POWER_DOWN;

}


int LDC1000::getDeviceID(void) {

    int value = getRegister(_LDC1000_DEVICE_ID);

    return (value);

}

void LDC1000::setSensorFrequency(int frequency) {

    if ( ( frequency < LDC1000_MIN_SENSOR_FREQUENCY ) || ( frequency > LDC1000_MAX_SENSOR_FREQUENCY ) ) {

        error( "LDC1000: Invalid Sensor Frequency setting %d\r\n", frequency );
        return;

    }

    setRegister(_LDC1000_SENSOR_FREQ, frequency);

}


int LDC1000::getSensorFrequency(void) {

    int value = getRegister(_LDC1000_SENSOR_FREQ);

    return (value);

}


void LDC1000::setRpMaximum(int rp) {

    if ( ( rp < 0 ) || ( rp > 0x1f ) ) {

        error( "LDC1000: Invalid Rp maximum setting %d\r\n", rp );
        return;

    }

    setRegister(_LDC1000_RP_MAX, rp);

}


int LDC1000::getRpMaximum(void) {

    int value = getRegister(_LDC1000_RP_MAX);

    return (value);

}


void LDC1000::setRpMinimum(int rp) {

    if ( ( rp < 0x20 ) || ( rp > 0x3f ) ) {

        error( "LDC1000: Invalid Rp minimum setting %d\r\n", rp );
        return;

    }

    setRegister(_LDC1000_RP_MIN, rp);

}


int LDC1000::getRpMinimum(void) {

    int value = getRegister(_LDC1000_RP_MIN);

    return (value);

}


void LDC1000::setOscAmplitude(int oscamp) {

    if ( ( oscamp < 0 ) || ( oscamp > 2 ) ) {

        error( "LDC1000: Invalid oscillation amplitude setting %d\r\n", oscamp );
        return;

    }

    int value = getRegister(_LDC1000_LDC_CONFIG) & ~_LDC1000_LDC_CONFIG_MASK_AMP;

    value |= oscamp;

    setRegister(_LDC1000_LDC_CONFIG, value);

}


int LDC1000::getOscAmplitude(void) {

    int value = getRegister(_LDC1000_LDC_CONFIG) & ~_LDC1000_LDC_CONFIG_MASK_AMP;

    return (value);

}


void LDC1000::setResponseTime(int resp) {

    if ( ( resp < 2 ) || ( resp > 7 ) ) {

        error( "LDC1000: Invalid response time setting %d\r\n", resp );
        return;

    }

    int value = getRegister(_LDC1000_LDC_CONFIG) & ~_LDC1000_LDC_CONFIG_MASK_RESP;

    value |= resp;

    setRegister(_LDC1000_LDC_CONFIG, value);

}


int LDC1000::getResponseTime(void) {

    int value = getRegister(_LDC1000_LDC_CONFIG) & ~_LDC1000_LDC_CONFIG_MASK_RESP;

    return (value);

}


void LDC1000::setClockSelect(int sel) {

    int value = getRegister(_LDC1000_CLK_CONFIG) & ~_LDC1000_CLK_CONFIG_MASK_SEL;

    value |= sel;

    setRegister(_LDC1000_CLK_CONFIG, value);

}


int LDC1000::getClockSelect(void) {

    int value = getRegister(_LDC1000_CLK_CONFIG) & ~_LDC1000_CLK_CONFIG_MASK_SEL;

    return (value);

}


void LDC1000::setClockTimeBase(int pd) {

    int value = getRegister(_LDC1000_CLK_CONFIG) & ~_LDC1000_CLK_CONFIG_MASK_PD;

    value |= pd;

    setRegister(_LDC1000_CLK_CONFIG, value);

}


int LDC1000::getClockTimeBase(void) {

    int value = getRegister(_LDC1000_CLK_CONFIG) & ~_LDC1000_CLK_CONFIG_MASK_PD;

    return (value);

}


void LDC1000::setComparatorThresholdHighLSB(int data) {

    setRegister(_LDC1000_CMP_THLD_HI_LSB, data);

}


int LDC1000::getComparatorThresholdHighLSB(void) {

    int value = getRegister(_LDC1000_CMP_THLD_HI_LSB);

    return (value);

}


void LDC1000::setComparatorThresholdHighMSB(int data) {

    setRegister(_LDC1000_CMP_THLD_HI_MSB, data);

}


int LDC1000::getComparatorThresholdHighMSB(void) {

    int value = getRegister(_LDC1000_CMP_THLD_HI_MSB);

    return (value);

}


void LDC1000::setComparatorThresholdLowLSB(int data) {

    setRegister(_LDC1000_CMP_THLD_LO_LSB, data);

}


int LDC1000::getComparatorThresholdLowLSB(void) {

    int value = getRegister(_LDC1000_CMP_THLD_LO_LSB);

    return (value);

}


void LDC1000::setINTBPin(int mode) {

    if ( ( mode < 0 ) || ( mode > 4 ) || ( mode == 3 ) ) {

        error( "LDC1000: Invalid INTB pin setting %d\r\n", mode );
        return;

    }

    int value = getRegister(_LDC1000_INTB_PIN_CONFIG) & ~_LDC1000_INTB_PIN_CONFIG_MASK_MODE;

    value |= mode;

    setRegister(_LDC1000_INTB_PIN_CONFIG, value);

}


int LDC1000::getINTBPin(void) {

    int value = getRegister(_LDC1000_INTB_PIN_CONFIG) & ~_LDC1000_INTB_PIN_CONFIG_MASK_MODE;

    return (value);

}


void LDC1000::setPower(int data) {

    setRegister(_LDC1000_PWR_CONFIG, data & ~_LDC1000_PWR_CONFIG_MASK);

}


int LDC1000::getPower(void) {

    int value = getRegister(_LDC1000_PWR_CONFIG) & ~_LDC1000_PWR_CONFIG_MASK;

    return (value);

}


int LDC1000::getStatus(void) {

    int value = getRegister(_LDC1000_STATUS) & ~_LDC1000_STATUS_MASK;

    return (value);

}


int LDC1000::getProximityDataLSB(void) {

    int value = getRegister(_LDC1000_PRX_DATA_LSB);

    return (value);

}


int LDC1000::getProximityDataMSB(void) {

    int value = getRegister(_LDC1000_PRX_DATA_MSB);

    return (value);

}


int LDC1000::getFrequencyCounterLSB(void) {

    int value = getRegister(_LDC1000_FREQ_CNT_DATA_LSB);

    return (value);

}


int LDC1000::getFrequencyCounterMIDSB(void) {

    int value = getRegister(_LDC1000_FREQ_CNT_DATA_MIDB);

    return (value);

}


int LDC1000::getFrequencyCounterMSB(void) {

    int value = getRegister(_LDC1000_FREQ_CNT_DATA_MSB);

    return (value);

}


void LDC1000::setRegister(int regAddress, int regData) {

    int cn = (_LDC1000_SPI_CMD_WR_REG | (regAddress & _LDC1000_REG_ADDRESS_MASK));

    nCS_ = 0;

    int status = spi_.write(cn);

    spi_.write(regData & 0xFF);

    nCS_ = 1;

    wait_us( _LDC1000_TIMING_Tpece2csn_us );

}


int LDC1000::getRegister(int regAddress) {

    int cn = (_LDC1000_SPI_CMD_RD_REG | (regAddress & _LDC1000_REG_ADDRESS_MASK));

    nCS_ = 0;

    int status = spi_.write(cn);

    int dn = spi_.write(_LDC1000_SPI_CMD_NOP);

    nCS_ = 1;

    return dn;

}