Library to communicate with LDC1614
Dependents: Inductive_Sensor_3
Fork of LDC1101 by
Diff: LDC1614.cpp
- Revision:
- 32:9712c9bdaf44
- Parent:
- 31:ab4354a71996
- Child:
- 33:2f4c791f37b2
diff -r ab4354a71996 -r 9712c9bdaf44 LDC1614.cpp --- 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 ***********************************************************