Library to communicate with LDC1614

Dependencies:   SHTx

Dependents:   Inductive_Sensor_3

Fork of LDC1101 by Bob Giesberts

Committer:
bobgiesberts
Date:
Wed Oct 05 08:19:35 2016 +0000
Revision:
36:6a4e28dadae6
Parent:
35:00c9c01f0c0f
new function to automatic determine DriveCurrent

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bobgiesberts 30:95c53d244f91 1 /** LDC1614 library
bobgiesberts 28:76a2fc42f888 2 * @file LDC1614.cpp
bobgiesberts 16:07d0e43c2d12 3 * @brief this C++ file contains all required
bobgiesberts 16:07d0e43c2d12 4 * functions to interface with Texas
bobgiesberts 28:76a2fc42f888 5 * Instruments' LDC1614.
bobgiesberts 28:76a2fc42f888 6 *
bobgiesberts 28:76a2fc42f888 7 * @author Bob Giesberts
bobgiesberts 28:76a2fc42f888 8 *
bobgiesberts 28:76a2fc42f888 9 * @date 2016-08-09
bobgiesberts 16:07d0e43c2d12 10 *
bobgiesberts 30:95c53d244f91 11 * @code
bobgiesberts 28:76a2fc42f888 12 * Serial pc(USBTX, USBRX);
bobgiesberts 31:ab4354a71996 13 * LDC1614 ldc(PTC5, PTC4, PTC6, 16E6, 2, 120E-12);
bobgiesberts 28:76a2fc42f888 14 * int main(){
bobgiesberts 28:76a2fc42f888 15 * while(1) {
bobgiesberts 28:76a2fc42f888 16 * while( !ldc.is_ready() ) {}
bobgiesberts 28:76a2fc42f888 17 *
bobgiesberts 28:76a2fc42f888 18 * pc.printf("sensor 1: %d | sensor 2: %d\r\n", ldc.get_Data(0), ldc.get_Data(1) );
bobgiesberts 28:76a2fc42f888 19 * }
bobgiesberts 28:76a2fc42f888 20 * }
bobgiesberts 30:95c53d244f91 21 * @endcode
bobgiesberts 16:07d0e43c2d12 22 */
bobgiesberts 16:07d0e43c2d12 23
bobgiesberts 28:76a2fc42f888 24 #include "LDC1614.h"
bobgiesberts 28:76a2fc42f888 25
bobgiesberts 34:b03d7bb9010c 26 LDC1614::LDC1614(PinName sda, PinName scl, PinName sd, uint8_t f_CLKIN, int channels, uint8_t capacitor) : _i2c(sda, scl), _shutdown_pin(sd)
bobgiesberts 16:07d0e43c2d12 27 {
bobgiesberts 18:fc9bb81a631f 28 // settings
bobgiesberts 34:b03d7bb9010c 29 _channels = channels; // number of sensors
bobgiesberts 28:76a2fc42f888 30 _cap = capacitor;
bobgiesberts 34:b03d7bb9010c 31 _fCLKIN = f_CLKIN;
bobgiesberts 28:76a2fc42f888 32
bobgiesberts 34:b03d7bb9010c 33 _Offset = 0; // highest 16-bit of 32-bit number (so e.g. 100E6 / 65536 = 1525)
bobgiesberts 34:b03d7bb9010c 34 _Rcount = 0xffff; // maximum for greatest precision (0xffff)
bobgiesberts 34:b03d7bb9010c 35 _SettleCount = 50; // CHx_SETTLECOUNT = t_settle * f_REFx/16 = 50 (p.12)
bobgiesberts 35:00c9c01f0c0f 36 _DriveCurrent = 23; // max = 31, automatically settles at 22
bobgiesberts 34:b03d7bb9010c 37 _dividerREF = 2; // 2 (f_REF = f_CLKIN/2 = 40/2 = 20 < 35) (p.10)
bobgiesberts 34:b03d7bb9010c 38 _dividerIN = 2; // 2 (f_IN = f_SENSOR/2 = 6.5/2 = 3.4 < 5 = 20/4 = f_REF/4
bobgiesberts 34:b03d7bb9010c 39
bobgiesberts 34:b03d7bb9010c 40 for(int i = 0; i < channels; i++)
bobgiesberts 34:b03d7bb9010c 41 error[i] = 0;
bobgiesberts 22:8da965ce5af3 42
bobgiesberts 29:41815fd13822 43 // start communication
bobgiesberts 34:b03d7bb9010c 44 _i2c.setFrequency( 400000 ); // max 400 kHz (p.6)
bobgiesberts 16:07d0e43c2d12 45
bobgiesberts 29:41815fd13822 46 // Initilialize the LDC1614
bobgiesberts 16:07d0e43c2d12 47 init();
bobgiesberts 16:07d0e43c2d12 48 }
bobgiesberts 16:07d0e43c2d12 49
bobgiesberts 28:76a2fc42f888 50 LDC1614::~LDC1614()
bobgiesberts 26:1ef9172cd355 51 {
bobgiesberts 28:76a2fc42f888 52
bobgiesberts 26:1ef9172cd355 53 }
bobgiesberts 26:1ef9172cd355 54
bobgiesberts 28:76a2fc42f888 55 void LDC1614::init()
bobgiesberts 16:07d0e43c2d12 56 {
bobgiesberts 20:8e1b1efdbb49 57 /********* SETTINGS *****************
bobgiesberts 25:ae111662ee03 58 ** C_sensor = 120 pF
bobgiesberts 25:ae111662ee03 59 ** L_sensor = 5 uH
bobgiesberts 25:ae111662ee03 60 ** Rp_min = 1500 Ohm
bobgiesberts 20:8e1b1efdbb49 61 **
bobgiesberts 25:ae111662ee03 62 ** f_sensor_min = 6.4 MHz (d = inf)
bobgiesberts 25:ae111662ee03 63 ** f_sensor_max = 10 MHz (d = 0)
bobgiesberts 28:76a2fc42f888 64 **
bobgiesberts 20:8e1b1efdbb49 65 ************************************/
bobgiesberts 20:8e1b1efdbb49 66
bobgiesberts 29:41815fd13822 67 // Configuring setup, set LDC in configuration modus
bobgiesberts 29:41815fd13822 68 sleep();
bobgiesberts 29:41815fd13822 69
bobgiesberts 28:76a2fc42f888 70 for(int i = 0; i < _channels; i++)
bobgiesberts 28:76a2fc42f888 71 {
bobgiesberts 28:76a2fc42f888 72 // set Reference Count to highest resolution
bobgiesberts 28:76a2fc42f888 73 setReferenceCount( i, _Rcount );
bobgiesberts 18:fc9bb81a631f 74
bobgiesberts 28:76a2fc42f888 75 // set the settling time
bobgiesberts 28:76a2fc42f888 76 // t_settle = (settlecount * 16) /f_REF
bobgiesberts 34:b03d7bb9010c 77 // settlecount > Q * f_REF / (16 * f_SENSOR)
bobgiesberts 28:76a2fc42f888 78 setSettlecount( i, _SettleCount );
bobgiesberts 28:76a2fc42f888 79
bobgiesberts 28:76a2fc42f888 80 // set Divider to 1 (for large range / ENOB / resolution)
bobgiesberts 34:b03d7bb9010c 81 setDivider( i, _dividerIN, _dividerREF );
bobgiesberts 28:76a2fc42f888 82
bobgiesberts 28:76a2fc42f888 83 // set the drive current during sampling
bobgiesberts 28:76a2fc42f888 84 setDriveCurrent( i, _DriveCurrent ); // (p. 15 | Figure 14)
bobgiesberts 28:76a2fc42f888 85
bobgiesberts 28:76a2fc42f888 86 // shift the signal down a bit
bobgiesberts 28:76a2fc42f888 87 setOffset( i, _Offset );
bobgiesberts 28:76a2fc42f888 88 }
bobgiesberts 16:07d0e43c2d12 89
bobgiesberts 34:b03d7bb9010c 90 // error_config (does not work?)
bobgiesberts 32:9712c9bdaf44 91 set( ERROR_CONFIG, UR_ERR2OUT, 1 );
bobgiesberts 32:9712c9bdaf44 92 set( ERROR_CONFIG, OR_ERR2OUT, 1 );
bobgiesberts 32:9712c9bdaf44 93 set( ERROR_CONFIG, WD_ERR2OUT, 1 );
bobgiesberts 34:b03d7bb9010c 94 set( ERROR_CONFIG, AH_ERR2OUT, 1 );
bobgiesberts 34:b03d7bb9010c 95 set( ERROR_CONFIG, AL_ERR2OUT, 1 );
bobgiesberts 20:8e1b1efdbb49 96
bobgiesberts 28:76a2fc42f888 97 // mux_config
bobgiesberts 32:9712c9bdaf44 98 set( MUX_CONFIG, AUTOSCAN_EN, _channels > 1 );
bobgiesberts 32:9712c9bdaf44 99 set( MUX_CONFIG, RR_SEQUENCE, ( ( _channels - 2 > 0 ) ? _channels - 2 : 0 ) );
bobgiesberts 32:9712c9bdaf44 100 set( MUX_CONFIG, DEGLITCH, DEGLITCH_10M );
bobgiesberts 18:fc9bb81a631f 101
bobgiesberts 28:76a2fc42f888 102 // override Rp and use own Drive Current to reduce power consumption
bobgiesberts 32:9712c9bdaf44 103 set( CONFIG, ACTIVE_CHAN, 0 ); // CH0. Will be overruled when _channels > 1
bobgiesberts 28:76a2fc42f888 104 set( CONFIG, RP_OVERRIDE_EN, 1 );
bobgiesberts 28:76a2fc42f888 105 set( CONFIG, SENSOR_ACTIVATE_SEL, 1 );
bobgiesberts 28:76a2fc42f888 106 set( CONFIG, AUTO_AMP_DIS, 1 );
bobgiesberts 28:76a2fc42f888 107 set( CONFIG, REF_CLK_SRC, 1 ); // external f_CLKIN
bobgiesberts 28:76a2fc42f888 108 set( CONFIG, INTB_DIS, 1 );
bobgiesberts 28:76a2fc42f888 109 set( CONFIG, HIGH_CURRENT_DRV, 0 );
bobgiesberts 28:76a2fc42f888 110
bobgiesberts 28:76a2fc42f888 111 // Done configuring settings, set LDC1614 in measuring modus
bobgiesberts 28:76a2fc42f888 112 wakeup();
bobgiesberts 16:07d0e43c2d12 113 }
bobgiesberts 16:07d0e43c2d12 114
bobgiesberts 28:76a2fc42f888 115
bobgiesberts 34:b03d7bb9010c 116 void LDC1614::func_mode( LDC_MODE mode )
bobgiesberts 28:76a2fc42f888 117 {
bobgiesberts 28:76a2fc42f888 118 switch (mode)
bobgiesberts 28:76a2fc42f888 119 {
bobgiesberts 28:76a2fc42f888 120 case LDC_MODE_ACTIVE:
bobgiesberts 28:76a2fc42f888 121 case LDC_MODE_SLEEP:
bobgiesberts 31:ab4354a71996 122
bobgiesberts 29:41815fd13822 123 // turn on LDC
bobgiesberts 28:76a2fc42f888 124 _shutdown_pin.write( 0 );
bobgiesberts 32:9712c9bdaf44 125 wait_us(10);
bobgiesberts 29:41815fd13822 126 set( CONFIG, SLEEP_MODE_EN, mode );
bobgiesberts 32:9712c9bdaf44 127 wait_us(377); // Wait 16384 f_INT clock cycles (0.377 ms) (p.16)
bobgiesberts 32:9712c9bdaf44 128 wait_ms(1);
bobgiesberts 28:76a2fc42f888 129 break;
bobgiesberts 28:76a2fc42f888 130
bobgiesberts 28:76a2fc42f888 131 case LDC_MODE_SHUTDOWN:
bobgiesberts 28:76a2fc42f888 132 _shutdown_pin.write( 1 );
bobgiesberts 28:76a2fc42f888 133 break;
bobgiesberts 28:76a2fc42f888 134 }
bobgiesberts 19:e205ab9142d8 135 }
bobgiesberts 29:41815fd13822 136 void LDC1614::sleep( void ) { func_mode( LDC_MODE_SLEEP ); }
bobgiesberts 29:41815fd13822 137 void LDC1614::wakeup( void ) { func_mode( LDC_MODE_ACTIVE ); }
bobgiesberts 29:41815fd13822 138 void LDC1614::shutdown( void ) { func_mode( LDC_MODE_SHUTDOWN ); }
bobgiesberts 19:e205ab9142d8 139
bobgiesberts 28:76a2fc42f888 140 void LDC1614::setReferenceCount( uint8_t channel, uint16_t rcount )
bobgiesberts 28:76a2fc42f888 141 {
bobgiesberts 28:76a2fc42f888 142 writeI2Cregister( RCOUNT_CH0 + channel, rcount );
bobgiesberts 34:b03d7bb9010c 143 // debug("[ReferenceCount channel %d: 0x%02x]\r\n", channel, get_ReferenceCount( channel ) );
bobgiesberts 25:ae111662ee03 144 }
bobgiesberts 25:ae111662ee03 145
bobgiesberts 32:9712c9bdaf44 146 void LDC1614::setOffset( uint8_t channel, uint16_t offset )
bobgiesberts 19:e205ab9142d8 147 {
bobgiesberts 28:76a2fc42f888 148 _Offset = offset;
bobgiesberts 32:9712c9bdaf44 149 writeI2Cregister( OFFSET_CH0 + channel, offset );
bobgiesberts 19:e205ab9142d8 150 }
bobgiesberts 19:e205ab9142d8 151
bobgiesberts 28:76a2fc42f888 152 void LDC1614::setSettlecount( uint8_t channel, uint16_t settlecount )
bobgiesberts 17:a5cf2b4bec13 153 {
bobgiesberts 28:76a2fc42f888 154 writeI2Cregister( SETTLECOUNT_CH0 + channel, settlecount );
bobgiesberts 28:76a2fc42f888 155 }
bobgiesberts 28:76a2fc42f888 156
bobgiesberts 28:76a2fc42f888 157 void LDC1614::setDivider( uint8_t channel, uint8_t divIN, uint8_t divREF )
bobgiesberts 28:76a2fc42f888 158 {
bobgiesberts 28:76a2fc42f888 159 // make sure the values fit
bobgiesberts 29:41815fd13822 160 _dividerIN = (( divIN < 15) ? (( divIN > 1) ? divIN : 1) : 15 ); // 4 bit
bobgiesberts 34:b03d7bb9010c 161 _dividerREF = ((divREF < 255) ? ((divREF > 1) ? divREF : 1) : 255 ); // 8 bit
bobgiesberts 34:b03d7bb9010c 162 writeI2Cregister( CLOCK_DIVIDERS_CH0 + channel, uint16_t ((_dividerIN << CHx_FIN_DIVIDER) | (_dividerREF << CHx_FREF_DIVIDER)) );
bobgiesberts 20:8e1b1efdbb49 163 }
bobgiesberts 20:8e1b1efdbb49 164
bobgiesberts 28:76a2fc42f888 165 void LDC1614::setDriveCurrent( uint8_t channel, uint8_t idrive )
bobgiesberts 28:76a2fc42f888 166 {
bobgiesberts 29:41815fd13822 167 _DriveCurrent = ((idrive < 31) ? idrive : 31 ); // 5-bit (b1 1111)
bobgiesberts 34:b03d7bb9010c 168 regchange( DRIVE_CURRENT_CH0 + channel, CHx_IDRIVE, _DriveCurrent, 31 );
bobgiesberts 34:b03d7bb9010c 169 // debug("[DriveCurrent channel %d: 0x%02x]\r\n", channel, get_DriveCurrent( channel ) );
bobgiesberts 25:ae111662ee03 170 }
bobgiesberts 25:ae111662ee03 171
bobgiesberts 35:00c9c01f0c0f 172 uint8_t LDC1614::autoDriveCurrent( uint8_t channel )
bobgiesberts 35:00c9c01f0c0f 173 {
bobgiesberts 35:00c9c01f0c0f 174 // set automatic calculation mode
bobgiesberts 35:00c9c01f0c0f 175 sleep();
bobgiesberts 35:00c9c01f0c0f 176 set( CONFIG, AUTO_AMP_DIS, 0);
bobgiesberts 35:00c9c01f0c0f 177 wakeup();
bobgiesberts 35:00c9c01f0c0f 178
bobgiesberts 35:00c9c01f0c0f 179 // find the right register based on the channel
bobgiesberts 35:00c9c01f0c0f 180 uint8_t tempDriveCurrent = 0;
bobgiesberts 35:00c9c01f0c0f 181 ADDR addr;
bobgiesberts 35:00c9c01f0c0f 182 switch ( channel ){
bobgiesberts 35:00c9c01f0c0f 183 case 1: addr = DRIVE_CURRENT_CH1; break;
bobgiesberts 35:00c9c01f0c0f 184 case 2: addr = DRIVE_CURRENT_CH2; break;
bobgiesberts 35:00c9c01f0c0f 185 case 3: addr = DRIVE_CURRENT_CH3; break;
bobgiesberts 35:00c9c01f0c0f 186 default: addr = DRIVE_CURRENT_CH0; break;
bobgiesberts 35:00c9c01f0c0f 187 }
bobgiesberts 35:00c9c01f0c0f 188
bobgiesberts 35:00c9c01f0c0f 189 // read data until DriveCurrent settles
bobgiesberts 35:00c9c01f0c0f 190 for(int i = 0; i < 10; i++)
bobgiesberts 35:00c9c01f0c0f 191 {
bobgiesberts 35:00c9c01f0c0f 192 while( !is_ready( channel ) ) { }
bobgiesberts 35:00c9c01f0c0f 193 get_Data( channel );
bobgiesberts 35:00c9c01f0c0f 194 tempDriveCurrent = get( addr, CHx_INIT_IDRIVE, 31 );
bobgiesberts 35:00c9c01f0c0f 195
bobgiesberts 35:00c9c01f0c0f 196 debug( "[poging %d] new: %d, old: %d\r\n", i, tempDriveCurrent, _DriveCurrent );
bobgiesberts 35:00c9c01f0c0f 197 /*
bobgiesberts 35:00c9c01f0c0f 198 if ( _DriveCurrent == tempDriveCurrent )
bobgiesberts 35:00c9c01f0c0f 199 {
bobgiesberts 35:00c9c01f0c0f 200 break;
bobgiesberts 35:00c9c01f0c0f 201 }else{
bobgiesberts 35:00c9c01f0c0f 202 _DriveCurrent = tempDriveCurrent;
bobgiesberts 35:00c9c01f0c0f 203 }
bobgiesberts 35:00c9c01f0c0f 204 */
bobgiesberts 35:00c9c01f0c0f 205 }
bobgiesberts 35:00c9c01f0c0f 206
bobgiesberts 35:00c9c01f0c0f 207 _DriveCurrent = tempDriveCurrent;
bobgiesberts 35:00c9c01f0c0f 208
bobgiesberts 35:00c9c01f0c0f 209 // set back to manual configuration
bobgiesberts 35:00c9c01f0c0f 210 sleep();
bobgiesberts 35:00c9c01f0c0f 211 setDriveCurrent( channel, _DriveCurrent );
bobgiesberts 35:00c9c01f0c0f 212 set( CONFIG, AUTO_AMP_DIS, 1);
bobgiesberts 35:00c9c01f0c0f 213 wakeup();
bobgiesberts 35:00c9c01f0c0f 214
bobgiesberts 35:00c9c01f0c0f 215 return _DriveCurrent;
bobgiesberts 35:00c9c01f0c0f 216 }
bobgiesberts 35:00c9c01f0c0f 217
bobgiesberts 28:76a2fc42f888 218 void LDC1614::set( ADDR addr, SETTING setting, uint8_t value )
bobgiesberts 20:8e1b1efdbb49 219 {
bobgiesberts 28:76a2fc42f888 220 uint8_t mask = 1;
bobgiesberts 28:76a2fc42f888 221 if ( addr == MUX_CONFIG )
bobgiesberts 28:76a2fc42f888 222 {
bobgiesberts 28:76a2fc42f888 223 switch (setting){
bobgiesberts 28:76a2fc42f888 224 case AUTOSCAN_EN: mask = 1; break; // 1
bobgiesberts 28:76a2fc42f888 225 case RR_SEQUENCE: mask = 3; break; // 11
bobgiesberts 28:76a2fc42f888 226 case DEGLITCH: mask = 7; break; // 111
bobgiesberts 28:76a2fc42f888 227 }
bobgiesberts 28:76a2fc42f888 228 }
bobgiesberts 28:76a2fc42f888 229 regchange( addr, setting, value, mask );
bobgiesberts 20:8e1b1efdbb49 230 }
bobgiesberts 20:8e1b1efdbb49 231
bobgiesberts 34:b03d7bb9010c 232
bobgiesberts 34:b03d7bb9010c 233
bobgiesberts 34:b03d7bb9010c 234
bobgiesberts 34:b03d7bb9010c 235
bobgiesberts 34:b03d7bb9010c 236 /* GETTING DATA FROM SENSOR */
bobgiesberts 34:b03d7bb9010c 237
bobgiesberts 29:41815fd13822 238 uint8_t LDC1614::get( ADDR addr, SETTING setting, uint8_t mask )
bobgiesberts 29:41815fd13822 239 {
bobgiesberts 29:41815fd13822 240 if ( addr == MUX_CONFIG )
bobgiesberts 29:41815fd13822 241 {
bobgiesberts 29:41815fd13822 242 switch (setting){
bobgiesberts 29:41815fd13822 243 case AUTOSCAN_EN: mask = 1; break; // 1
bobgiesberts 29:41815fd13822 244 case RR_SEQUENCE: mask = 3; break; // 11
bobgiesberts 29:41815fd13822 245 case DEGLITCH: mask = 7; break; // 111
bobgiesberts 29:41815fd13822 246 }
bobgiesberts 29:41815fd13822 247 }
bobgiesberts 29:41815fd13822 248
bobgiesberts 29:41815fd13822 249 uint16_t data[1];
bobgiesberts 29:41815fd13822 250 readI2C( data, addr );
bobgiesberts 29:41815fd13822 251 return ( data[0]>>setting ) & mask;
bobgiesberts 29:41815fd13822 252 }
bobgiesberts 29:41815fd13822 253
bobgiesberts 32:9712c9bdaf44 254 uint16_t LDC1614::get_config()
bobgiesberts 32:9712c9bdaf44 255 {
bobgiesberts 32:9712c9bdaf44 256 uint16_t data[1];
bobgiesberts 32:9712c9bdaf44 257 readI2C( data, CONFIG );
bobgiesberts 32:9712c9bdaf44 258 return data[0];
bobgiesberts 32:9712c9bdaf44 259 }
bobgiesberts 28:76a2fc42f888 260
bobgiesberts 32:9712c9bdaf44 261 uint16_t LDC1614::get_error_config()
bobgiesberts 32:9712c9bdaf44 262 {
bobgiesberts 32:9712c9bdaf44 263 uint16_t data[1];
bobgiesberts 32:9712c9bdaf44 264 readI2C( data, ERROR_CONFIG );
bobgiesberts 32:9712c9bdaf44 265 return data[0];
bobgiesberts 32:9712c9bdaf44 266 }
bobgiesberts 28:76a2fc42f888 267
bobgiesberts 28:76a2fc42f888 268 uint16_t LDC1614::get_status( void )
bobgiesberts 20:8e1b1efdbb49 269 {
bobgiesberts 34:b03d7bb9010c 270 uint16_t data[1];
bobgiesberts 34:b03d7bb9010c 271 readI2C( data, STATUS );
bobgiesberts 34:b03d7bb9010c 272 return data[0];
bobgiesberts 20:8e1b1efdbb49 273 }
bobgiesberts 32:9712c9bdaf44 274 bool LDC1614::is_ready( uint8_t channel )
bobgiesberts 29:41815fd13822 275 {
bobgiesberts 32:9712c9bdaf44 276 uint8_t status = get_status();
bobgiesberts 32:9712c9bdaf44 277 if( channel < 4 )
bobgiesberts 32:9712c9bdaf44 278 {
bobgiesberts 32:9712c9bdaf44 279 return ( status>>(3-channel)) & 1; // this specific channel is ready
bobgiesberts 32:9712c9bdaf44 280 }else{
bobgiesberts 32:9712c9bdaf44 281 return ( status>>DRDY ) & 1; // all channels are ready
bobgiesberts 32:9712c9bdaf44 282 }
bobgiesberts 29:41815fd13822 283 }
bobgiesberts 29:41815fd13822 284 bool LDC1614::is_error( uint8_t status )
bobgiesberts 29:41815fd13822 285 {
bobgiesberts 34:b03d7bb9010c 286 // DOES NOT WORK PROPERLY YET!!
bobgiesberts 34:b03d7bb9010c 287 // STATUS is reset after reading DATA_MSB_CHx
bobgiesberts 29:41815fd13822 288 if( status == 17 ) { status = get_status(); }
bobgiesberts 32:9712c9bdaf44 289 return ((( status>>ERR_ZC ) & 7) != 0);
bobgiesberts 29:41815fd13822 290 }
bobgiesberts 32:9712c9bdaf44 291 uint8_t LDC1614::what_error( uint8_t channel )
bobgiesberts 32:9712c9bdaf44 292 {
bobgiesberts 34:b03d7bb9010c 293 // DOES NOT WORK PROPERLY YET!!
bobgiesberts 34:b03d7bb9010c 294 // STATUS is reset after reading DATA_MSB_CHx
bobgiesberts 32:9712c9bdaf44 295 uint8_t status = get_status();
bobgiesberts 32:9712c9bdaf44 296 if ( ( ( status>>ERR_CHAN ) & 2 ) == channel )
bobgiesberts 32:9712c9bdaf44 297 {
bobgiesberts 32:9712c9bdaf44 298 if ((( status>>ERR_AHE ) & 1) != 0) return 1; // Amplitude High Error
bobgiesberts 32:9712c9bdaf44 299 if ((( status>>ERR_ALE ) & 1) != 0) return 2; // Amplitide Low Error
bobgiesberts 32:9712c9bdaf44 300 if ((( status>>ERR_ZC ) & 1) != 0) return 3; // Zero Count Error
bobgiesberts 32:9712c9bdaf44 301 }
bobgiesberts 34:b03d7bb9010c 302 return 0;
bobgiesberts 34:b03d7bb9010c 303 }
bobgiesberts 34:b03d7bb9010c 304 uint8_t LDC1614::get_error( uint8_t channel )
bobgiesberts 34:b03d7bb9010c 305 {
bobgiesberts 34:b03d7bb9010c 306 if( ( (error[channel]>>(CHx_ERR_UR - CHx_ERR_AE)) & 1) == 1 ) { debug( "Sensor %d: Under-range Error\r\n", channel ); }
bobgiesberts 34:b03d7bb9010c 307 if( ( (error[channel]>>(CHx_ERR_OR - CHx_ERR_AE)) & 1) == 1 ) { debug( "Sensor %d: Over-range Error\r\n", channel ); }
bobgiesberts 34:b03d7bb9010c 308 if( ( (error[channel]>>(CHx_ERR_WD - CHx_ERR_AE)) & 1) == 1 ) { debug( "Sensor %d: Watchdog Timeout Error\r\n", channel ); }
bobgiesberts 34:b03d7bb9010c 309 if( ( (error[channel]>>(CHx_ERR_AE - CHx_ERR_AE)) & 1) == 1 ) { debug( "Sensor %d: Amplitude Error\r\n", channel ); }
bobgiesberts 34:b03d7bb9010c 310 return error[channel];
bobgiesberts 32:9712c9bdaf44 311 }
bobgiesberts 17:a5cf2b4bec13 312
bobgiesberts 34:b03d7bb9010c 313
bobgiesberts 34:b03d7bb9010c 314 uint16_t LDC1614::get_ReferenceCount( uint8_t channel )
bobgiesberts 16:07d0e43c2d12 315 {
bobgiesberts 28:76a2fc42f888 316 uint16_t rcount[1];
bobgiesberts 28:76a2fc42f888 317 readI2C( rcount, RCOUNT_CH0 + channel );
bobgiesberts 28:76a2fc42f888 318 return rcount[0];
bobgiesberts 20:8e1b1efdbb49 319 }
bobgiesberts 20:8e1b1efdbb49 320
bobgiesberts 34:b03d7bb9010c 321 uint8_t LDC1614::get_DriveCurrent( uint8_t channel )
bobgiesberts 34:b03d7bb9010c 322 {
bobgiesberts 34:b03d7bb9010c 323 ADDR addr;
bobgiesberts 34:b03d7bb9010c 324 switch ( channel ){
bobgiesberts 34:b03d7bb9010c 325 case 1: addr = DRIVE_CURRENT_CH1; break;
bobgiesberts 34:b03d7bb9010c 326 case 2: addr = DRIVE_CURRENT_CH2; break;
bobgiesberts 34:b03d7bb9010c 327 case 3: addr = DRIVE_CURRENT_CH3; break;
bobgiesberts 34:b03d7bb9010c 328 default: addr = DRIVE_CURRENT_CH0; break;
bobgiesberts 34:b03d7bb9010c 329 }
bobgiesberts 34:b03d7bb9010c 330 return get( addr, CHx_IDRIVE, 31 );
bobgiesberts 34:b03d7bb9010c 331 }
bobgiesberts 34:b03d7bb9010c 332
bobgiesberts 28:76a2fc42f888 333 uint32_t LDC1614::get_Data( uint8_t channel )
bobgiesberts 22:8da965ce5af3 334 {
bobgiesberts 28:76a2fc42f888 335 uint16_t data[2];
bobgiesberts 34:b03d7bb9010c 336 readI2C( data, DATA_MSB_CH0 + 2*channel, 2 );
bobgiesberts 34:b03d7bb9010c 337 error[channel] = ((data[0]>>CHx_ERR_AE) & 0x0f);
bobgiesberts 34:b03d7bb9010c 338 // debug("[Error channel %d (0x%02X): 0x%01X] 0x%04X %04X\r\n", channel, DATA_MSB_CH0 + 2*channel, error[channel], data[0], data[1] );
bobgiesberts 30:95c53d244f91 339 return ( (data[0] & 0x0fff)<<16 ) | data[1]; // MSB + LSB
bobgiesberts 22:8da965ce5af3 340 }
bobgiesberts 20:8e1b1efdbb49 341
bobgiesberts 34:b03d7bb9010c 342 uint16_t LDC1614::get_device_ID( void )
bobgiesberts 32:9712c9bdaf44 343 {
bobgiesberts 32:9712c9bdaf44 344 uint16_t ID[1];
bobgiesberts 32:9712c9bdaf44 345 readI2C( ID, DEVICE_ID, 1 );
bobgiesberts 32:9712c9bdaf44 346 return ID[0];
bobgiesberts 32:9712c9bdaf44 347
bobgiesberts 32:9712c9bdaf44 348 }
bobgiesberts 32:9712c9bdaf44 349
bobgiesberts 32:9712c9bdaf44 350 uint16_t LDC1614::get_manufacturer_ID( void )
bobgiesberts 32:9712c9bdaf44 351 {
bobgiesberts 34:b03d7bb9010c 352 uint16_t ID[1];
bobgiesberts 34:b03d7bb9010c 353 readI2C( ID, MANUFACTURER_ID, 1 );
bobgiesberts 34:b03d7bb9010c 354 return ID[0];
bobgiesberts 32:9712c9bdaf44 355 }
bobgiesberts 30:95c53d244f91 356
bobgiesberts 30:95c53d244f91 357
bobgiesberts 29:41815fd13822 358 /* REGISTER FUNCTIONS (READ / WRITE) */
bobgiesberts 28:76a2fc42f888 359
bobgiesberts 28:76a2fc42f888 360 void LDC1614::readI2C( uint16_t *data, uint8_t address, uint8_t length )
bobgiesberts 22:8da965ce5af3 361 {
bobgiesberts 32:9712c9bdaf44 362 for( int i = 0; i < length; i++ )
bobgiesberts 32:9712c9bdaf44 363 {
bobgiesberts 34:b03d7bb9010c 364 // start sequence (Device ID + Register Address + write)
bobgiesberts 32:9712c9bdaf44 365 _i2c.start();
bobgiesberts 34:b03d7bb9010c 366 _i2c.write( ( 0x2A << 1 ) | 0 );
bobgiesberts 33:2f4c791f37b2 367 _i2c.write( address + i );
bobgiesberts 34:b03d7bb9010c 368
bobgiesberts 34:b03d7bb9010c 369 // start sequence (Register Address + read)
bobgiesberts 34:b03d7bb9010c 370 _i2c.start();
bobgiesberts 34:b03d7bb9010c 371 _i2c.write( ( 0x2A << 1 ) | 1 );
bobgiesberts 32:9712c9bdaf44 372
bobgiesberts 34:b03d7bb9010c 373 // Build up 16 bit result
bobgiesberts 32:9712c9bdaf44 374 data[i] = _i2c.read(1) << 8; // MSB
bobgiesberts 32:9712c9bdaf44 375 data[i] |= _i2c.read(0); // LSB
bobgiesberts 34:b03d7bb9010c 376 // debug("Read from 0x%02X : 0x%04X\r\n", address + i, data[i]);
bobgiesberts 34:b03d7bb9010c 377
bobgiesberts 34:b03d7bb9010c 378 // Stop command
bobgiesberts 32:9712c9bdaf44 379 _i2c.stop();
bobgiesberts 32:9712c9bdaf44 380 }
bobgiesberts 22:8da965ce5af3 381 }
bobgiesberts 20:8e1b1efdbb49 382
bobgiesberts 28:76a2fc42f888 383 void LDC1614::writeI2C( uint16_t *data, uint8_t address, uint8_t length )
bobgiesberts 22:8da965ce5af3 384 {
bobgiesberts 28:76a2fc42f888 385 for ( int i = 0; i < length; i++ )
bobgiesberts 28:76a2fc42f888 386 {
bobgiesberts 32:9712c9bdaf44 387 _i2c.start();
bobgiesberts 32:9712c9bdaf44 388 _i2c.write( ( 0x2A << 1 ) | 0 ); // 7 bit 0x2A + 0 (write) = 0x54
bobgiesberts 32:9712c9bdaf44 389 _i2c.write( address + i );
bobgiesberts 32:9712c9bdaf44 390
bobgiesberts 32:9712c9bdaf44 391 _i2c.write( ( data[i] & 0xff00 ) >> 8 ); // MSB
bobgiesberts 32:9712c9bdaf44 392 _i2c.write( ( data[i] & 0x00ff ) >> 0 ); // LSB
bobgiesberts 32:9712c9bdaf44 393 _i2c.stop();
bobgiesberts 28:76a2fc42f888 394 }
bobgiesberts 22:8da965ce5af3 395 }
bobgiesberts 20:8e1b1efdbb49 396
bobgiesberts 28:76a2fc42f888 397 void LDC1614::writeI2Cregister(uint8_t reg, uint16_t value)
bobgiesberts 28:76a2fc42f888 398 {
bobgiesberts 28:76a2fc42f888 399 writeI2C( &value, reg );
bobgiesberts 28:76a2fc42f888 400 }
bobgiesberts 28:76a2fc42f888 401
bobgiesberts 28:76a2fc42f888 402 void LDC1614::regchange( uint8_t addr, uint8_t setting, uint8_t value, uint8_t mask )
bobgiesberts 28:76a2fc42f888 403 {
bobgiesberts 28:76a2fc42f888 404 uint16_t config[1];
bobgiesberts 28:76a2fc42f888 405 readI2C( config, addr );
bobgiesberts 32:9712c9bdaf44 406 writeI2Cregister( addr, uint16_t ( (config[0] & ~(mask<<setting)) | (value<<setting)) ); // replace bits with number SETTING
bobgiesberts 28:76a2fc42f888 407 }
bobgiesberts 28:76a2fc42f888 408
bobgiesberts 28:76a2fc42f888 409
bobgiesberts 25:ae111662ee03 410
bobgiesberts 25:ae111662ee03 411 /* CALCULATE STUFF WITH SENSOR DATA */
bobgiesberts 25:ae111662ee03 412
bobgiesberts 28:76a2fc42f888 413 float LDC1614::get_fsensor( uint32_t LData )
bobgiesberts 28:76a2fc42f888 414 {
bobgiesberts 34:b03d7bb9010c 415 _fsensor = _dividerIN * ((_fCLKIN*1E6)/_dividerREF) * (LData / 268435456.0); // (p.14)
bobgiesberts 18:fc9bb81a631f 416 return _fsensor;
bobgiesberts 19:e205ab9142d8 417 }
bobgiesberts 18:fc9bb81a631f 418
bobgiesberts 28:76a2fc42f888 419 float LDC1614::get_Inductance( uint32_t Ldata )
bobgiesberts 18:fc9bb81a631f 420 {
bobgiesberts 25:ae111662ee03 421 float fsensor = get_fsensor( Ldata );
bobgiesberts 34:b03d7bb9010c 422 _inductance = 1.0 / ((_cap*1E-12) * 4 * PI*PI * fsensor*fsensor ); // ???
bobgiesberts 19:e205ab9142d8 423 return _inductance;
bobgiesberts 19:e205ab9142d8 424 }
bobgiesberts 16:07d0e43c2d12 425
bobgiesberts 16:07d0e43c2d12 426
bobgiesberts 16:07d0e43c2d12 427
bobgiesberts 16:07d0e43c2d12 428 // EXTRA test: Get&print values of all variables to verify (to calculate the induction)
bobgiesberts 16:07d0e43c2d12 429 // The data will be printed on the screen using RealTerm: baud 9600.
bobgiesberts 16:07d0e43c2d12 430 // Begin ***********************************************************
bobgiesberts 28:76a2fc42f888 431 float LDC1614::get_fCLKIN() {return _fCLKIN;}
bobgiesberts 28:76a2fc42f888 432 uint8_t LDC1614::get_dividerIN() {return _dividerIN;}
bobgiesberts 28:76a2fc42f888 433 uint8_t LDC1614::get_dividerREF() {return _dividerREF;}
bobgiesberts 32:9712c9bdaf44 434 uint16_t LDC1614::get_Offset() {return _Offset;}
bobgiesberts 28:76a2fc42f888 435 float LDC1614::get_cap() {return _cap;}
bobgiesberts 32:9712c9bdaf44 436 // END ***********************************************************