TI LDC1000 library.
Diff: ldc1000.cpp
- Revision:
- 0:b9daf55d7586
diff -r 000000000000 -r b9daf55d7586 ldc1000.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ldc1000.cpp Wed Apr 05 20:34:42 2017 +0000 @@ -0,0 +1,483 @@ +/** + * @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; + +} +