TI LDC1000 library.
Revision 0:b9daf55d7586, committed 2017-04-05
- Comitter:
- jonebuckman
- Date:
- Wed Apr 05 20:34:42 2017 +0000
- Commit message:
- First release.
Changed in this revision
ldc1000.cpp | Show annotated file Show diff for this revision Revisions of this file |
ldc1000.h | Show annotated file Show diff for this revision Revisions of this file |
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; + +} +
diff -r 000000000000 -r b9daf55d7586 ldc1000.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ldc1000.h Wed Apr 05 20:34:42 2017 +0000 @@ -0,0 +1,348 @@ +/** + * @file ldc1000.h + * + * @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 + * + * Example: + * @code + * #include "mbed.h" + * #include "ldc1000.h" + * + * Serial pc(USBTX, USBRX); // tx, rx + * + * LDC1000 ldc(D11, D12, D13, D10, D9); // mosi, miso, sck, cs, irq + * + * int main() { + * while(1) { + * pc.printf("The device revision ID is %d\n", ldc.getDeviceID()); + * wait(1); + * } + * } + * @endcode + */ + +#ifndef __LDC1000_H__ +#define __LDC1000_H__ + +/** + * Includes + */ +#include "mbed.h" + +/** + * Defines + */ +#define LDC1000_MIN_SENSOR_FREQUENCY 27 +#define LDC1000_MAX_SENSOR_FREQUENCY 234 +#define LDC1000_AMP_1V 0x00 +#define LDC1000_AMP_2V 0x08 +#define LDC1000_AMP_4V 0x10 +#define LDC1000_RESP_192 0x02 +#define LDC1000_RESP_384 0x03 +#define LDC1000_RESP_768 0x04 +#define LDC1000_RESP_1536 0x05 +#define LDC1000_RESP_3072 0x06 +#define LDC1000_RESP_6144 0x07 +#define LDC1000_CLK_SEL 0x02 +#define LDC1000_CLK_PD 0x01 +#define LDC1000_INTB_MODE_DRDYB_ENBL 0x04 +#define LDC1000_INTB_MODE_CMP_STAT 0x03 +#define LDC1000_INTB_MODE_WAKE_ENBL 0x01 +#define LDC1000_INTB_MODE_DSBL 0x00 +#define LDC1000_PWR_MODE_ACT 0x01 +#define LDC1000_PWR_MODE_STDBY 0x00 +#define LDC1000_STAT_OSC 0x80 +#define LDC1000_STAT_DRDY 0x40 +#define LDC1000_STAT_WAKE 0x20 +#define LDC1000_STAT_CMP 0x10 + +/** + * LDC1000 Inductance to Digital Converter from Texas Instruments. + */ +class LDC1000 { + +public: + + /** + * Constructor. + * + * @param mosi mbed pin to use for MOSI line of SPI interface. + * @param miso mbed pin to use for MISO line of SPI interface. + * @param sck mbed pin to use for SCK line of SPI interface. + * @param csn mbed pin to use for not chip select line of SPI interface. + * @param irq mbed pin to use for the interrupt request line. + */ + LDC1000(PinName mosi, PinName miso, PinName sck, PinName csn, PinName irq = NC); + + /** + * Get the device ID. + * + * @return The device ID (8). + */ + int getDeviceID(void); + + /** + * Set the Rp maximum. + * + * @param rp Rp maximum (0x00 - 0x1f). + */ + void setRpMaximum(int rp); + + /** + * Get the Rp maximum. + * + * @return The device ID (0x00 - 0x1f). + */ + int getRpMaximum(void); + + /** + * Set the Rp minimum. + * + * @param rp Rp maximum (0x20 - 0x3f). + */ + void setRpMinimum(int rp); + + /** + * Get the Rp minimum. + * + * @return The device ID (0x20 - 0x3f). + */ + int getRpMinimum(void); + + /** + * Set the sensor frequency. + * + * @param frequency sensor frequency (N = 68.94 * log10(F/2000)). + */ + void setSensorFrequency(int frequency); + + /** + * Get the sensor frequency. + * + * @return The sensor frequency (0 - 255). + */ + int getSensorFrequency(void); + + /** + * Set the oscillator amplitude. + * + * @param oscamp oscillator amplitude (0x00 - 1V, 0x01 - 2V, 0x10 - 4V). + */ + void setOscAmplitude(int oscamp); + + /** + * Get the oscillator amplitude. + * + * @return The oscillator amplitude (0x00 - 1V, 0x01 - 2V, 0x02 - 4V). + */ + int getOscAmplitude(void); + + /** + * Set the response time. + * + * @param resp response time (0x02 - 192, 0x03 - 384, 0x04 - 768, 0x05 - 1536, 0x06 - 3072, 0x07 - 6144). + */ + void setResponseTime(int resp); + + /** + * Get the response time. + * + * @return The response time (0x02 - 192, 0x03 - 384, 0x04 - 768, 0x05 - 1536, 0x06 - 3072, 0x07 - 6144). + */ + int getResponseTime(void); + + /** + * Set the clock select. + * + * @param sel clock select (0 - external time base, 1 - external crystal). + */ + void setClockSelect(int sel); + + /** + * Get the clock select. + * + * @return The clock select (0 - external time base, 1 - external crystal). + */ + int getClockSelect(void); + + /** + * Set the disable external time base clock. + * + * @param pd clock select (0 - enable external time base clock, 1 - disable external time base clock). + */ + void setClockTimeBase(int pd); + + /** + * Get the disable external time base clock. + * + * @return The clock select (0 - enable external time base clock, 1 - disable external time base clock). + */ + int getClockTimeBase(void); + + /** + * Set the least significant byte of comparator threshold high register. + * + * @param data data (0 - 255). + */ + void setComparatorThresholdHighLSB(int data); + + /** + * Get the least significant byte of comparator threshold high register. + * + * @return The register (0 - 255). + */ + int getComparatorThresholdHighLSB(void); + + /** + * Set the most significant byte of comparator threshold high register. + * + * @param data data (0 - 255). + */ + void setComparatorThresholdHighMSB(int data); + + /** + * Get the most significant byte of comparator threshold high register. + * + * @return The register (0 - 255). + */ + int getComparatorThresholdHighMSB(void); + + /** + * Set the least significant byte of comparator threshold low register. + * + * @param data data (0 - 255). + */ + void setComparatorThresholdLowLSB(int data); + + /** + * Get the least significant byte of comparator threshold low register. + * + * @return The register (0 - 255). + */ + int getComparatorThresholdLowLSB(void); + + /** + * Set the mode of the INTB pin. + * + * @param mode mode (0x00 - all modes disabled, 0x01 - wake up enable on INTB pin, 0x02 - INTB pin indicates status of comparator, 0x04 - DRDYB enable on INTB pin ). + */ + void setINTBPin(int mode); + + /** + * Get the mode of the INTB pin. + * + * @return The mode register (0x00 - all modes disabled, 0x01 - wake up enable on INTB pin, 0x02 - INTB pin indicates status of comparator, 0x04 - DRDYB enable on INTB pin ). + */ + int getINTBPin(void); + + /** + * Set the power mode configuraton. + * + * @param data power mode (0 - standby, 1 - active). + */ + void setPower(int data); + + /** + * Get the power mode configuration. + * + * @return The power mode (0 - standby, 1 - active). + */ + int getPower(void); + + /** + * Get the status. + * + * @return The status (0x10 - comparator, 0x20 - wake up, 0x40 - data ready, 0x80 - OSC status). + */ + int getStatus(void); + + /** + * Get the least significant byte of promiity data. + * + * @return The proximity data (0 - 255). + */ + int getProximityDataLSB(void); + + /** + * Get the most significant byte of promiity data. + * + * @return The proximity data (0 - 255). + */ + int getProximityDataMSB(void); + + /** + * Get the least significant byte of frequency counter data. + * + * @return The frequency counter data (0 - 255). + */ + int getFrequencyCounterLSB(void); + + /** + * Get the mid significant byte of frequency counter data. + * + * @return The frequency counter data (0 - 255). + */ + int getFrequencyCounterMIDSB(void); + + /** + * Get the most significant byte of frequency counter data. + * + * @return The frequency counter data (0 - 255). + */ + int getFrequencyCounterMSB(void); + +private: + + /** + * Set the contents of an addressable register. + * + * @param regAddress address of the register + * @param regData data to write to the register + */ + void setRegister(int regAddress, int regData); + + /** + * Get the contents of an addressable register. + * + * @param regAddress address of the register + * @return The contents of the register + */ + int getRegister(int regAddress); + + SPI spi_; + DigitalOut nCS_; + InterruptIn nIRQ_; + + int mode; + +}; + +#endif /* __LDC1000_H__ */ \ No newline at end of file