Library to communicate with LDC1614
Dependents: Inductive_Sensor_3
Fork of LDC1101 by
Diff: LDC1614.cpp
- Revision:
- 29:41815fd13822
- Parent:
- 28:76a2fc42f888
- Child:
- 30:95c53d244f91
diff -r 76a2fc42f888 -r 41815fd13822 LDC1614.cpp --- a/LDC1614.cpp Tue Aug 23 08:25:40 2016 +0000 +++ b/LDC1614.cpp Wed Aug 24 07:42:49 2016 +0000 @@ -21,9 +21,9 @@ */ #include "LDC1614.h" - +#include "mbed_debug.h" -LDC1614::LDC1614(PinName sda, PinName scl, PinName sd, float f_CLKIN, int channels, float capacitor) : _i2c(sda, scl), _shutdown_pin(sd) +LDC1614::LDC1614(PinName sda, PinName scl, PinName sd, PinName os, float f_CLKIN, int channels, float capacitor) : _i2c(sda, scl), _shutdown_pin(sd), _oscillator(os) { // settings _channels = channels; // number of sensors @@ -35,12 +35,10 @@ _SettleCount = 50; // CHx_SETTLECOUNT = t_settle * f_REFx/16 = 50 (p.12) _DriveCurrent = 31; // max??? + // start communication _i2c.frequency(400000); // 400 kHz (p.6) - // Turn the LDC1614 on (exit shutdown) - _shutdown_pin.write(0); - wait_us(100); - + // Initilialize the LDC1614 init(); } @@ -68,6 +66,9 @@ ** CHx_FREF_DIVIDER = 1 (16.0 MHz) ************************************/ + // Configuring setup, set LDC in configuration modus + sleep(); + for(int i = 0; i < _channels; i++) { // set Reference Count to highest resolution @@ -91,7 +92,7 @@ // mux_config set( MUX_CONFIG, AUTOSCAN_EN, _channels > 1 ); - set( MUX_CONFIG, RR_SEQUENCE, max(0, _channels - 2) ); + 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 @@ -113,17 +114,26 @@ { case LDC_MODE_ACTIVE: case LDC_MODE_SLEEP: + + // turn on oscillator + _oscillator.write( 1 ); + wait_ms(3); // datasheet oscillator says 3 ms max + + // turn on LDC _shutdown_pin.write( 0 ); - set( CONFIG, SLEEP_MODE_EN, LDC_MODE_ACTIVE ); + set( CONFIG, SLEEP_MODE_EN, mode ); + wait_us(400); // Wait 16384 f_INT clock cycles (0.377 ms) (p.16) break; case LDC_MODE_SHUTDOWN: _shutdown_pin.write( 1 ); + _oscillator.write( 0 ); break; } } -void LDC1614::sleep( void ) { func_mode( LDC_MODE_SLEEP ); } -void LDC1614::wakeup( void ) { func_mode( LDC_MODE_ACTIVE ); } +void LDC1614::sleep( void ) { func_mode( LDC_MODE_SLEEP ); } +void LDC1614::wakeup( void ) { func_mode( LDC_MODE_ACTIVE ); } +void LDC1614::shutdown( void ) { func_mode( LDC_MODE_SHUTDOWN ); } void LDC1614::setReferenceCount( uint8_t channel, uint16_t rcount ) { @@ -145,14 +155,15 @@ void LDC1614::setDivider( uint8_t channel, uint8_t divIN, uint8_t divREF ) { // make sure the values fit - _dividerIN = min(max(divIN, 1), 15); // 4 bit - _dividerREF = min(max(divREF, 1), 255); // 8 bit + _dividerIN = (( divIN < 15) ? (( divIN > 1) ? divIN : 1) : 15 ); // 4 bit + _dividerIN = ((divREF < 255) ? ((divREF > 1) ? divREF : 1) : 255 ); // 8 bit writeI2Cregister( CLOCK_DIVIDERS_CH0 + channel, uint16_t ((_dividerIN << 12) + _dividerREF) ); } void LDC1614::setDriveCurrent( uint8_t channel, uint8_t idrive ) { - _DriveCurrent = min( idrive, 31 ); // 5-bit (b1 1111) + _DriveCurrent = ((idrive < 31) ? idrive : 31 ); // 5-bit (b1 1111) + // todo: read initial idrive [10:6] writeI2Cregister(DRIVE_CURRENT_CH0 + channel, uint16_t (_DriveCurrent<<10) ); @@ -172,6 +183,22 @@ regchange( addr, setting, value, mask ); } +uint8_t LDC1614::get( ADDR addr, SETTING setting, uint8_t mask ) +{ + if ( addr == MUX_CONFIG ) + { + switch (setting){ + case AUTOSCAN_EN: mask = 1; break; // 1 + case RR_SEQUENCE: mask = 3; break; // 11 + case DEGLITCH: mask = 7; break; // 111 + } + } + + uint16_t data[1]; + readI2C( data, addr ); + return ( data[0]>>setting ) & mask; +} + @@ -185,7 +212,16 @@ readI2C( status, STATUS ); return status[0]; } -bool LDC1614::is_ready( void ) { return ( get_status() & 0x0080 ); } +bool LDC1614::is_ready( uint8_t status ) +{ + if( status == 17 ) { status = get_status(); } + return ( status>>DRDY ) & 1; +} +bool LDC1614::is_error( uint8_t status ) +{ + if( status == 17 ) { status = get_status(); } + return ((( status>>ERR_ZC) & 6) == 0); +} uint16_t LDC1614::get_Rcount( uint8_t channel ) @@ -199,11 +235,18 @@ { 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" ); } + return ( (data[0] & 0x0fff)<<16) | data[1]; // MSB + LSB } +/* REGISTER FUNCTIONS (READ / WRITE) */ void LDC1614::readI2C( uint16_t *data, uint8_t address, uint8_t length ) @@ -247,7 +290,6 @@ float LDC1614::get_fsensor( uint32_t LData ) { _fsensor = _dividerIN * (_fCLKIN/_dividerREF) * ((LData / 268435456) + (_Offset / 65536)); // (p.14) - return _fsensor; }