Library to communicate with LDC1614

Dependencies:   SHTx

Dependents:   Inductive_Sensor_3

Fork of LDC1101 by Bob Giesberts

Revision:
32:9712c9bdaf44
Parent:
31:ab4354a71996
Child:
33:2f4c791f37b2
--- a/LDC1614.cpp	Wed Sep 07 09:58:32 2016 +0000
+++ b/LDC1614.cpp	Sat Sep 10 12:46:36 2016 +0000
@@ -24,6 +24,8 @@
 #include "LDC1614.h"
 #include "mbed_debug.h"
 
+#include "i2c.hpp"
+
 
 LDC1614::LDC1614(PinName sda, PinName scl, PinName sd, float f_CLKIN, int channels, float capacitor) : _i2c(sda, scl), _shutdown_pin(sd)
 {
@@ -32,13 +34,13 @@
     _cap      = capacitor;
     _fCLKIN  = f_CLKIN;
 
-    _Offset = 0;            // no offset needed
+    _Offset = 0;            // highest 16-bit of 32-bit number (so e.g. 100E6 / 65536 = 1525) 
     _Rcount = 0xffff;       // maximum for greatest precision
-    _SettleCount = 50;      // CHx_SETTLECOUNT = t_settle * f_REFx/16 = 50 (p.12)
-    _DriveCurrent = 31;     // max???
+    _SettleCount = 500;     // CHx_SETTLECOUNT = t_settle * f_REFx/16 = 50 (p.12)
+    _DriveCurrent = 20;     // max = 31, automatically settles at 20
        
     // start communication
-    _i2c.frequency(400000); // 400 kHz (p.6)
+    _i2c.setFrequency( 400000 ); // 400 kHz (p.6)
     
     // Initilialize the LDC1614
     init();
@@ -90,14 +92,20 @@
         setOffset( i, _Offset );
     }
 
-    // error_config (all  is standard)
+    // error_config
+    set( ERROR_CONFIG, UR_ERR2OUT,    1 );
+    set( ERROR_CONFIG, OR_ERR2OUT,    1 );
+    set( ERROR_CONFIG, WD_ERR2OUT,    1 );
+    // set( ERROR_CONFIG, AH_ERR2OUT,    1 );
+    // set( ERROR_CONFIG, AL_ERR2OUT,    1 );    
     
     // mux_config    
-    set( MUX_CONFIG, AUTOSCAN_EN,    _channels > 1 );
-    set( MUX_CONFIG, RR_SEQUENCE,    ( ( _channels - 2 > 0 ) ? _channels - 2 : 0 ) );
-    set( MUX_CONFIG, DEGLITCH,       DEGLITCH_10M );
+    set( MUX_CONFIG, AUTOSCAN_EN,     _channels > 1 );
+    set( MUX_CONFIG, RR_SEQUENCE,     ( ( _channels - 2 > 0 ) ? _channels - 2 : 0 ) );
+    set( MUX_CONFIG, DEGLITCH,        DEGLITCH_10M );
     
     // override Rp and use own Drive Current to reduce power consumption
+    set( CONFIG, ACTIVE_CHAN,         0 ); // CH0. Will be overruled when _channels > 1
     set( CONFIG, RP_OVERRIDE_EN,      1 );
     set( CONFIG, SENSOR_ACTIVATE_SEL, 1 );
     set( CONFIG, AUTO_AMP_DIS,        1 );
@@ -119,8 +127,10 @@
 
             // turn on LDC
             _shutdown_pin.write( 0 );
+            wait_us(10);
             set( CONFIG, SLEEP_MODE_EN, mode );
-            wait_us(400); // Wait 16384 f_INT clock cycles (0.377 ms) (p.16)
+            wait_us(377); // Wait 16384 f_INT clock cycles (0.377 ms) (p.16)
+            wait_ms(1);
             break;
         
         case LDC_MODE_SHUTDOWN:
@@ -137,10 +147,10 @@
     writeI2Cregister( RCOUNT_CH0 + channel, rcount );
 }
 
-void LDC1614::setOffset( uint8_t channel, uint32_t offset )
+void LDC1614::setOffset( uint8_t channel, uint16_t offset )
 {
     _Offset = offset;
-    writeI2Cregister( OFFSET_CH0 + channel, uint16_t (offset >> 16) );
+    writeI2Cregister( OFFSET_CH0 + channel, offset );
 }
 
 void LDC1614::setSettlecount( uint8_t channel, uint16_t settlecount )
@@ -196,9 +206,19 @@
     return ( data[0]>>setting ) & mask;    
 }
 
-
+uint16_t LDC1614::get_config()
+{
+    uint16_t data[1];
+    readI2C( data, CONFIG );
+    return data[0];
+}
 
-
+uint16_t LDC1614::get_error_config()
+{
+    uint16_t data[1];
+    readI2C( data, ERROR_CONFIG );
+    return data[0];
+}
 
 
 /* GETTING DATA FROM SENSOR */
@@ -209,17 +229,32 @@
     readI2C( status, STATUS );  
     return status[0];
 }
-bool LDC1614::is_ready( uint8_t status )
+bool LDC1614::is_ready( uint8_t channel )
 {
-    if( status == 17 ) { status = get_status(); }
-    return ( status>>DRDY ) & 1;
+    uint8_t status = get_status();
+    if( channel < 4 )
+    {
+        return ( status>>(3-channel)) & 1; // this specific channel is ready
+    }else{
+        return ( status>>DRDY ) & 1;       // all channels are ready
+    }
 }
 bool LDC1614::is_error( uint8_t status )
 {
     if( status == 17 ) { status = get_status(); }
-    return ((( status>>ERR_ZC ) & 6) == 0);
+    return ((( status>>ERR_ZC ) & 7) != 0);
 }
-
+uint8_t LDC1614::what_error( uint8_t channel )
+{
+    uint8_t status = get_status();
+    if ( ( ( status>>ERR_CHAN ) & 2 ) == channel )
+    {
+        if ((( status>>ERR_AHE ) & 1) != 0) return 1; // Amplitude High Error
+        if ((( status>>ERR_ALE ) & 1) != 0) return 2; // Amplitide Low Error
+        if ((( status>>ERR_ZC  ) & 1) != 0) return 3; // Zero Count Error
+    }
+    return 0;                                     // no error?
+}
 
 uint16_t LDC1614::get_Rcount( uint8_t channel )
 {
@@ -233,41 +268,98 @@
     uint16_t data[2];
     readI2C( data, DATA_MSB_CH0 + channel, 2 );
     
-    if( ((data[0]>>CHx_ERR_UR) & 1) == 1 ) { debug( "Under-range Error" ); }
-    if( ((data[0]>>CHx_ERR_OR) & 1) == 1 ) { debug( "Over-range Error" ); }
-    if( ((data[0]>>CHx_ERR_WD) & 1) == 1 ) { debug( "Watchdog Timeout Error" ); }
-    if( ((data[0]>>CHx_ERR_AE) & 1) == 1 ) { debug( "Amplitude Error" ); }
+    if( ((data[0]>>CHx_ERR_UR) & 1) == 1 ) { debug( "Sensor %d: Under-range Error\r\n", channel ); }
+    if( ((data[0]>>CHx_ERR_OR) & 1) == 1 ) { debug( "Sensor %d: Over-range Error\r\n", channel ); }
+    if( ((data[0]>>CHx_ERR_WD) & 1) == 1 ) { debug( "Sensor %d: Watchdog Timeout Error\r\n", channel ); }
+    if( ((data[0]>>CHx_ERR_AE) & 1) == 1 ) { debug( "Sensor %d: Amplitude Error\r\n", channel ); }
     
     return ( (data[0] & 0x0fff)<<16 ) | data[1]; // MSB + LSB
 }
 
+uint16_t LDC1614::get_ID( void )
+{
+    uint16_t ID[1]; 
+    readI2C( ID, DEVICE_ID, 1 );
+    return ID[0];
+
+}
+
+uint16_t LDC1614::get_manufacturer_ID( void )
+{
+    // uint16_t ID[1]; 
+    // readI2C( ID, MANUFACTURER_ID, 1 );
+    // return ID[0];
+
+    _i2c.start();
+    
+    // Write address + 0 (write)
+    if( _i2c.write( 0x2A << 1 ) == true ){ // NACK = true
+        _i2c.stop();
+        return 1;
+    }
+    
+    // Write register address
+    if ( _i2c.write( 0x7E ) == true ) { // NACK = true
+        _i2c.stop();
+        return 2;
+    }
+
+    _i2c.start();
+
+    // Write address + 1 (read)
+    if ( _i2c.write( (0x2A << 1) | 0x01 ) == true ) { // NACK = true
+        _i2c.stop();
+        return 3;
+    }
+        
+    uint16_t data;
+    data = _i2c.read(1) << 8;   // ACK
+    data |= _i2c.read(0);       // NACK
+    _i2c.stop();
+    return data;
+    
+    //return _i2c.read(1) << 8;    // MSB
+    //return data[i] |= _i2c.read(0);        // LSB
+    //_i2c.stop();
 
 
-
+}
 
 
 /* REGISTER FUNCTIONS (READ / WRITE)  */
 
 void LDC1614::readI2C( uint16_t *data, uint8_t address, uint8_t length )
 {
-    // I2C reads per 8-bits, char is 8-bit, combine 8-bit in 16-bit sets
-    char temp[length*2];
-    _i2c.read( address, temp, length*2 );
-    
-    for ( int i = 0; i < length; i++ ) 
-        data[i] = (uint16_t) (temp[2*i+1]<<8) | temp[2*i];
+    for( int i = 0; i < length; i++ )
+    {
+        _i2c.start();
+        _i2c.write( ( 0x2A << 1 ) | 0 ); // 7 bit 0x2A + 0 (write) = 0x55
+        _i2c.write( address );
+
+        _i2c.start();
+        _i2c.write( ( 0x2A << 1 ) | 1 ); // 7 bit 0x2A + 1 (read) = 0x55
+
+        data[i] = _i2c.read(1) << 8;    // MSB
+        data[i] |= _i2c.read(0);        // LSB
+        _i2c.stop();
+    }        
 }
 
 void LDC1614::writeI2C( uint16_t *data, uint8_t address, uint8_t length )
 {
-    // I2C reads per 8-bits, char is 8-bit, split 16-bit data up in sets of 8-bit
-    char temp[length*2];
+   
     for ( int i = 0; i < length; i++ )
     {
-        temp[2*i]   = (data[i] & 0x00ff) >> 0; // 0, 2, 4 ...
-        temp[2*i+1] = (data[i] & 0xff00) >> 8; // 1, 3, 5 ...
+        _i2c.start();
+        _i2c.write( ( 0x2A << 1 ) | 0 );   // 7 bit 0x2A + 0 (write) = 0x54
+        _i2c.write( address + i );
+        
+        _i2c.write( ( data[i] & 0xff00 ) >> 8 ); // MSB
+        _i2c.write( ( data[i] & 0x00ff ) >> 0 ); // LSB
+        _i2c.stop();
     }
-    _i2c.write( address, temp, length*2 );
+    
+    
 }
 
 void LDC1614::writeI2Cregister(uint8_t reg, uint16_t value)
@@ -279,7 +371,7 @@
 {
     uint16_t config[1];
     readI2C( config, addr );
-    writeI2Cregister( addr, uint16_t ( (config[0] & !(mask<<setting)) | (value<<setting)) ); // replace bits with number SETTING
+    writeI2Cregister( addr, uint16_t ( (config[0] & ~(mask<<setting)) | (value<<setting)) ); // replace bits with number SETTING
 }
 
 
@@ -288,7 +380,7 @@
 
 float LDC1614::get_fsensor( uint32_t LData )
 {    
-    _fsensor = _dividerIN * (_fCLKIN/_dividerREF) * ((LData / 268435456) + (_Offset / 65536)); // (p.14)
+    _fsensor = _dividerIN * (_fCLKIN/_dividerREF) * ((LData / 268435456) + _Offset); // (p.14)
     return _fsensor;
 }   
 
@@ -307,6 +399,6 @@
     float LDC1614::get_fCLKIN()             {return _fCLKIN;}    
     uint8_t LDC1614::get_dividerIN()        {return _dividerIN;}
     uint8_t LDC1614::get_dividerREF()       {return _dividerREF;}
-    uint32_t LDC1614::get_Offset()          {return _Offset;}
+    uint16_t LDC1614::get_Offset()          {return _Offset;}
     float LDC1614::get_cap()                {return _cap;}
-// END ***********************************************************
\ No newline at end of file
+// END ***********************************************************