Library to communicate with LDC1614

Dependencies:   SHTx

Dependents:   Inductive_Sensor_3

Fork of LDC1101 by Bob Giesberts

LDC1614.h

Committer:
bobgiesberts
Date:
2016-09-21
Revision:
34:b03d7bb9010c
Parent:
32:9712c9bdaf44
Child:
35:00c9c01f0c0f

File content as of revision 34:b03d7bb9010c:

#ifndef _LDC1614_H_
#define _LDC1614_H_

#include "mbed.h"
#include "mbed_debug.h"
#include "register_values.h"
#include "i2c.hpp"

#ifndef PI
#define PI 3.14
#endif


/*
int min(int a, int b)       { return (a<b) ? a : b; }
float min(float a, float b) { return (a<b) ? a : b; }
int max(int a, int b)       { return (a>b) ? a : b; }
float max(float a, float b) { return (a>b) ? a : b; }
*/


/** Class for the LDC1614.
 *  @author     Bob Giesberts
 *  @date       2016-08-09
 *  @file       LDC1614.h
 *  @brief      this header file will contain all required
 *              definitions for the functions to interface with Texas
 *              Instruments' LDC1614.
 */
class LDC1614 {
    public:
        /** Create a new LDC1614 class
        * @brief            Create a new Class to interface to an LDC1614
        * @param sda        I2C SDA pin connected to LDC1614
        * @param scl        I2C SCL pin connected to LDC1614
        * @param sd         Shutdown pin connected to LDC1614
        * @param f_CLKIN    f_CLKIN (MHz)
        * @param sensors    number of sensors
        * @param capacitor  Used capacitor (pF) on all connected sensors
        **/
        LDC1614(PinName sda, PinName scl, PinName sd, uint8_t f_CLKIN, int sensors, uint8_t capacitor);
        ~LDC1614();
        
        /**
        * @brief            Set power mode.
        *                   The constructor sets the LDC1614 in Active mode.
        * @param mode       choose from:
        *                    - LDC_MODE_ACTIVE
        *                    - LDC_MODE_SLEEP
        *                    - LDC_MODE_SHUTDOWN
        **/
        void func_mode(LDC_MODE mode);
        
        /// @brief Put the LDC in configuration modus
        void sleep(void);
        /// @brief Get LDC1614 to work for you again
        void wakeup(void);
        /// @brief Put the LDC in its lowest power modus
        void shutdown(void);
        /// @brief initial configurations
        void init(void);
        
        
        /** 
        * @brief            Set the Reference Count parameter.
        * @param channel    the channel (CH0, CH1, CH2, CH3)
        * @param RCOUNT     For LHR mode, the conversion time is set by the reference count CHx_RCOUNT
        *                   The conversion time represents the number of clock cycles used to measure the sensor frequency.
        *                   Higher values for CHx_RCOUNT have a higher effective measurement resolution but a lower sample rate.
        *                   The maximum setting (0xffff) is required for full resolution
        *                       t_conv = (CHx_RCOUNT x 16) / f_REFx
        *                       CHx_RCount = (f_CLKIN/sample rate - 55)/16
        **/
        void setReferenceCount( uint8_t channel, uint16_t rcount );
        
        /**
        * @brief            Sensor offset (p.13) 
        *                   The sensor might reach a value > 2^28. To prevent this, set an offset.
        * @param channel    the channel (CH0, CH1, CH2, CH3)
        * @param offset     16 bit value that should be substracted from the current sensor value
        *                   f_offsetx = (CHx_OFFSET / 2^16)*f_REFx
        **/
        void setOffset( uint8_t channel, uint16_t offset );       
        
        /**
        * @brief            sensor settling time
        *                   CHx_SETTLECOUNT >= Q * f_REFx / (16 * f_SENSORx)
        *                   t_settle = (CHx_SETTLECOUNT x 16) / f_REFx
        * @param channel    the channel (CH0, CH1, CH2, CH3)
        * @param settlecount CHx_SETTLECOUNT (0 - 65 535)
        **/
        void setSettlecount( uint8_t channel, uint16_t settlecount);      
        
        /**
        * @brief            clock divider
        *                   Sensor divider (p.14)
        *                   f_REF = f_CLKIN  / CHx_REF_DIVIDER
        *                   f_IN  = f_SENSOR / CHx_FIN_DIVIDER
        *                   f_REF > 4*f_IN
        *                   if f_SENSOR >= 8.75 MHz, then CHx_FIN_DIVIDER >= 2 (p.10)
        * @param channel    the channel (CH0, CH1, CH2, CH3)
        * @param divIN      CHx_FIN_DIVIDER (4bit: 1 - 15)
        * @param divREF     CHx_FREF_DIVIDER (8 bit: 1 - 255)
        **/
        void setDivider( uint8_t channel, uint8_t divIN, uint8_t divREF );
        
           
        /**
        * @brief            Configuration of the LDC1614
        *                   This function can be used to set all settings (p.31)
        * @param addr       address of the setting catgory
        *                    - ERROR_CONFIG
        *                    - CONFIG
        *                    - MUX_CONFIG
        * @param setting    for ERROR_CONFIG
        *                    - UR_ERR2OUT
        *                    - OR_ERR2OUT
        *                    - WD_ERR2OUT
        *                    - AH_ERR2OUT
        *                    - AL_ERR2OUT
        *                    - UR_ERR2INT
        *                    - OR_ERR2INT
        *                    - WD_ERR2INT
        *                    - AH_ERR2INT
        *                    - AL_ERR2INT
        *                    - ZC_ERR2INT
        *                    - DRDY_2INT
        *                   for CONFIG (0x1A)
        *                    - ACTIVE_CHAN         : 0 (CH0)          | 1 (CH1)               | 10, 11 (CHx)
        *                    - SLEEP_MODE_EN       : 0 (ACTIVE)       | 1 (SLEEP)
        *                    - RP_OVERRIDE_EN      : 0 (OFF)          | 1 (Rp override on)
        *                    - SENSOR_ACTIVATE_SEL : 0 (full current) | 1 (low power)
        *                    - AUTO_AMP_DIS        : 0 (enabled)      | 1 (disabled)
        *                    - REF_CLK_SRC         : 0 (internal)     | 1 (external)
        *                    - INTB_DIS            : 0 (enabled)      | 1 (disabled)
        *                    - HIGH_CURRENT_DRV    : 0 (1.5 mA)       | 1 (> 1.5 mA)
        *                   for MUX_CONFIG (0x1B)
        *                    - AUTOSCAN_EN         : 0 (1 channel)    | 1 (multichannel)
        *                    - RR_SEQUENCE         : 00 (CH0, CH1)    | 01 (CH0, CH1, CH2)    | 10 (CH0, CH1, CH2, CH3)
        *                    - DEGLITCH            : 001 (1.0 MHz)    | 100 (3.3 MHz)         | 101 (10 MHz)            | 111 (33 MHz)
        * @param value      0 | 1 | ...
        *                   for MUX_CONFIG.DEGLITCH
        *                       f_deglitch > f_sensor_max (p. 16)
        *                       DEGLITCH_1M -  1.0 MHz
        *                       DEGLITCH_3M -  3.3 MHz
        *                       DEGLITCH_10M - 10.0 MHz
        *                       DEGLITCH_33M - 33.0 MHz
        **/
        void set( ADDR addr, SETTING setting, uint8_t value );
        

        uint8_t get( ADDR addr, SETTING setting, uint8_t mask = 1 );

        uint16_t get_config();
        uint16_t get_error_config();


        /** !!!!!!
        * @brief            Set the drive current
        *                   Exact functioning still unknown (p.14)
        * @param idrive     5-bit value
        *                   b00000 ( 0) -   16 uA
        *                   b11111 (31) - 1563 uA
        **/
        void setDriveCurrent( uint8_t channel, uint8_t idrive );

        
        /**
        * @brief Set the value of the external capacitor
        * This is needed for the calculation of the inductance.
        **/
        void setCapacitor(float c){_cap = c;};
        /**
        * @brief set the value of the external clock
        **/
        void setFrequency(float frequency){_fCLKIN = frequency;};





        /**
        * @brief            Read Data, the raw 28-bit inductance value.
        *                   This is needed for the calculation of the inductance.
        * @param channel    the channel (CH0, CH1, CH2, CH3)
        **/
        uint32_t get_Data( uint8_t channel );
        /**
        * @brief            get the calculated value for f_sensor (Hz)
        * @param Ldata      the obtained Data, if omitted, get_Data(0) will be used
        **/        
        float get_fsensor( uint32_t Ldata = 0 );
        /**
        * @brief            get the calculated inductance value
        * @param Ldata      the obtained Data, if omitted, get_Data(0) will be used
        **/
        float get_Inductance( uint32_t Ldata = 0 );
        
        
                
        /// @brief get the reference frequency (f_CLKIN)
        float get_fCLKIN(void);
        /// @brief get the reference count
        uint16_t get_ReferenceCount( uint8_t channel );
        /// @brief get the reference count
        uint8_t get_DriveCurrent( uint8_t channel );
        /// @brief get the divider
        uint8_t get_dividerIN(void);
        /// @brief get the divider
        uint8_t get_dividerREF(void);
        /// @brief get _Offset
        uint16_t get_Offset(void);
        /// @brief get the capacitance
        float get_cap(void);
        
        /// @brief get the status of the sensors (p.28)
        uint16_t get_status(void);
        
        /** 
        * @brief            is data ready?
        *                   returns true when data is ready for all sensors
        *                   returns false if not
        * @param status     the obtained value from get_status()
        *                   if omitted, get_status() will be used to get a value
        **/
        bool is_ready( uint8_t channel );
        
        /**
        * @brief            is there an error?
        *                   returns true when there is an error
        *                   returns false if not
        * @param status     the obtained value from get_status()
        *                   if omitted, get_status() will be used to get a value
        **/
        bool is_error( uint8_t status = 17 );
        uint8_t what_error( uint8_t channel );
        uint8_t get_error( uint8_t channel );

        uint16_t get_device_ID( void );
        uint16_t get_manufacturer_ID( void );
        
    private:
        void readI2C( uint16_t *data, uint8_t address, uint8_t length = 1);
        void writeI2C( uint16_t *data, uint8_t address, uint8_t length = 1);
        void writeI2Cregister( uint8_t reg, uint16_t value);
        void regchange( uint8_t addr, uint8_t setting, uint8_t value, uint8_t mask = 1 );
        
        void suicide(void *obj) {delete obj;};
        
        uint8_t _channels;      // number of sensors
        uint8_t _dividerIN;     // CHx_FIN_DIVIDER
        uint8_t _dividerREF;    // CHx_FREF_DIVIDER
        uint16_t _Offset;       // LHR_OFFSET
       
        uint16_t _Rcount;       // CHx_RCOUNT
        uint16_t _SettleCount;  // CHx_SETTLECOUNT
        uint8_t _DriveCurrent;  // CHx_IDRIVE
        
        float _fsensor;         // f_sensor (Hz): the calculated frequency of the sensor
        uint8_t _fCLKIN;        // f_CLKIN (MHz): frequency of external clock: 40MHz
        
        float _inductance;      // the calculated inductance        
        uint8_t _cap;           // capacitor (pF): 120 pF

        uint8_t error[];
        
        SHTx::I2C _i2c;
        DigitalOut _shutdown_pin;
};

#endif