First Commit as a new library

Dependents:   Host_Software_MAX32664GWEB_HR_wrist Host_Software_MAX32664GWEC_SpO2_HR Host_Software_MAX32664GWEB_HR_EXTENDED Host_Software_MAX32664GWEC_SpO2_HR-_EXTE ... more

Files at this revision

API Documentation at this revision

Comitter:
seyhmuscacina
Date:
Wed Dec 19 14:54:05 2018 +0300
Parent:
20:a521606048bb
Commit message:
adds interrupt support to the BMI160 library

Changed in this revision

bmi160.cpp Show annotated file Show diff for this revision Revisions of this file
bmi160.h Show annotated file Show diff for this revision Revisions of this file
bmi160_i2c.cpp Show annotated file Show diff for this revision Revisions of this file
bmi160_spi.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r a521606048bb -r f7216b5dc6c0 bmi160.cpp
--- a/bmi160.cpp	Fri May 04 13:35:59 2018 +0300
+++ b/bmi160.cpp	Wed Dec 19 14:54:05 2018 +0300
@@ -34,54 +34,40 @@
 #include "bmi160.h"
 
 
-const struct BMI160::AccConfig BMI160::DEFAULT_ACC_CONFIG = {SENS_2G, 
-                                                             ACC_US_OFF, 
-                                                             ACC_BWP_2, 
+const struct BMI160::AccConfig BMI160::DEFAULT_ACC_CONFIG = {SENS_2G,
+                                                             ACC_US_OFF,
+                                                             ACC_BWP_2,
                                                              ACC_ODR_8};
-                                                             
-const struct BMI160::GyroConfig BMI160::DEFAULT_GYRO_CONFIG = {DPS_2000, 
-                                                               GYRO_BWP_2, 
+
+const struct BMI160::GyroConfig BMI160::DEFAULT_GYRO_CONFIG = {DPS_2000,
+                                                               GYRO_BWP_2,
                                                                GYRO_ODR_8};
 
-///Period of internal counter
-static const float SENSOR_TIME_LSB = 39e-6;
-
-static const float SENS_2G_LSB_PER_G = 16384.0F;
-static const float SENS_4G_LSB_PER_G = 8192.0F;
-static const float SENS_8G_LSB_PER_G = 4096.0F;
-static const float SENS_16G_LSB_PER_G = 2048.0F;
-
-static const float SENS_2000_DPS_LSB_PER_DPS = 16.4F;
-static const float SENS_1000_DPS_LSB_PER_DPS = 32.8F;
-static const float SENS_500_DPS_LSB_PER_DPS = 65.6F;
-static const float SENS_250_DPS_LSB_PER_DPS = 131.2F;
-static const float SENS_125_DPS_LSB_PER_DPS = 262.4F;
-    
 
 //*****************************************************************************
 int32_t BMI160::setSensorPowerMode(Sensors sensor, PowerModes pwrMode)
 {
     int32_t rtnVal = -1;
-    
+
     switch(sensor)
     {
         case MAG:
             rtnVal = writeRegister(CMD, (MAG_SET_PMU_MODE | pwrMode));
         break;
-        
+
         case GYRO:
             rtnVal = writeRegister(CMD, (GYR_SET_PMU_MODE | pwrMode));
         break;
-        
+
         case ACC:
             rtnVal = writeRegister(CMD, (ACC_SET_PMU_MODE | pwrMode));
         break;
-        
+
         default:
             rtnVal = -1;
         break;
     }
-    
+
     return rtnVal;
 }
 
@@ -90,11 +76,11 @@
 int32_t BMI160::setSensorConfig(const AccConfig &config)
 {
     uint8_t data[2];
-    
-    data[0] = ((config.us << ACC_US_POS) | (config.bwp << ACC_BWP_POS) | 
+
+    data[0] = ((config.us << ACC_US_POS) | (config.bwp << ACC_BWP_POS) |
                (config.odr << ACC_ODR_POS));
     data[1] = config.range;
-    
+
     return writeBlock(ACC_CONF, ACC_RANGE, data);
 }
 
@@ -103,10 +89,10 @@
 int32_t BMI160::setSensorConfig(const GyroConfig &config)
 {
     uint8_t data[2];
-    
+
     data[0] = ((config.bwp << GYRO_BWP_POS) | (config.odr << GYRO_ODR_POS));
     data[1] = config.range;
-    
+
     return writeBlock(GYR_CONF, GYR_RANGE, data);
 }
 
@@ -116,7 +102,7 @@
 {
     uint8_t data[2];
     int32_t rtnVal = readBlock(ACC_CONF, ACC_RANGE, data);
-    
+
     if(rtnVal == RTN_NO_ERROR)
     {
         config.range = static_cast<BMI160::AccRange>(
@@ -128,7 +114,7 @@
         config.odr = static_cast<BMI160::AccOutputDataRate>(
         ((data[0] & ACC_ODR_MASK) >> ACC_ODR_POS));
     }
-    
+
     return rtnVal;
 }
 
@@ -138,7 +124,7 @@
 {
     uint8_t data[2];
     int32_t rtnVal = readBlock(GYR_CONF, GYR_RANGE, data);
-    
+
     if(rtnVal == RTN_NO_ERROR)
     {
         config.range = static_cast<BMI160::GyroRange>(
@@ -148,7 +134,7 @@
         config.odr = static_cast<BMI160::GyroOutputDataRate>(
         ((data[0] & GYRO_ODR_MASK) >> GYRO_ODR_POS));
     }
-    
+
     return rtnVal;
 }
 
@@ -158,26 +144,26 @@
 {
     uint8_t localData[2];
     int32_t rtnVal;
-    
+
     switch(axis)
     {
         case X_AXIS:
             rtnVal = readBlock(DATA_14, DATA_15, localData);
         break;
-        
+
         case Y_AXIS:
             rtnVal = readBlock(DATA_16, DATA_17, localData);
         break;
-        
+
         case Z_AXIS:
             rtnVal = readBlock(DATA_18, DATA_19, localData);
         break;
-        
+
         default:
             rtnVal = -1;
         break;
     }
-    
+
     if(rtnVal == RTN_NO_ERROR)
     {
         data.raw = ((localData[1] << 8) | localData[0]);
@@ -186,21 +172,21 @@
             case SENS_2G:
                 data.scaled = (data.raw/SENS_2G_LSB_PER_G);
             break;
-            
+
             case SENS_4G:
                 data.scaled = (data.raw/SENS_4G_LSB_PER_G);
             break;
-            
+
             case SENS_8G:
                 data.scaled = (data.raw/SENS_8G_LSB_PER_G);
             break;
-            
+
             case SENS_16G:
                 data.scaled = (data.raw/SENS_16G_LSB_PER_G);
             break;
         }
     }
-    
+
     return rtnVal;
 }
 
@@ -210,26 +196,26 @@
 {
     uint8_t localData[2];
     int32_t rtnVal;
-    
+
     switch(axis)
     {
         case X_AXIS:
             rtnVal = readBlock(DATA_8, DATA_9, localData);
         break;
-        
+
         case Y_AXIS:
             rtnVal = readBlock(DATA_10, DATA_11, localData);
         break;
-        
+
         case Z_AXIS:
             rtnVal = readBlock(DATA_12, DATA_13, localData);
         break;
-        
+
         default:
             rtnVal = -1;
         break;
     }
-    
+
     if(rtnVal == RTN_NO_ERROR)
     {
         data.raw = ((localData[1] << 8) | localData[0]);
@@ -238,41 +224,45 @@
             case DPS_2000:
                 data.scaled = (data.raw/SENS_2000_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_1000:
                 data.scaled = (data.raw/SENS_1000_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_500:
                 data.scaled = (data.raw/SENS_500_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_250:
                 data.scaled = (data.raw/SENS_250_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_125:
                 data.scaled = (data.raw/SENS_125_DPS_LSB_PER_DPS);
             break;
         }
     }
-    
+
     return rtnVal;
 }
-    
+
 
-//*****************************************************************************    
+//*****************************************************************************
 int32_t BMI160::getSensorXYZ(SensorData &data, AccRange range)
 {
     uint8_t localData[6];
     int32_t rtnVal = readBlock(DATA_14, DATA_19, localData);
-    
+
+	if (m_use_irq == true && bmi160_irq_asserted == false)
+		return -1;
+
+	bmi160_irq_asserted = false;
     if(rtnVal == RTN_NO_ERROR)
     {
         data.xAxis.raw = ((localData[1] << 8) | localData[0]);
         data.yAxis.raw = ((localData[3] << 8) | localData[2]);
         data.zAxis.raw = ((localData[5] << 8) | localData[4]);
-        
+
         switch(range)
         {
             case SENS_2G:
@@ -280,19 +270,19 @@
                 data.yAxis.scaled = (data.yAxis.raw/SENS_2G_LSB_PER_G);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_2G_LSB_PER_G);
             break;
-            
+
             case SENS_4G:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_4G_LSB_PER_G);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_4G_LSB_PER_G);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_4G_LSB_PER_G);
             break;
-            
+
             case SENS_8G:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_8G_LSB_PER_G);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_8G_LSB_PER_G);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_8G_LSB_PER_G);
             break;
-            
+
             case SENS_16G:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_16G_LSB_PER_G);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_16G_LSB_PER_G);
@@ -300,23 +290,23 @@
             break;
         }
     }
-    
+
     return rtnVal;
 }
 
 
-//*****************************************************************************    
+//*****************************************************************************
 int32_t BMI160::getSensorXYZ(SensorData &data, GyroRange range)
 {
     uint8_t localData[6];
     int32_t rtnVal = readBlock(DATA_8, DATA_13, localData);
-    
+
     if(rtnVal == RTN_NO_ERROR)
     {
         data.xAxis.raw = ((localData[1] << 8) | localData[0]);
         data.yAxis.raw = ((localData[3] << 8) | localData[2]);
         data.zAxis.raw = ((localData[5] << 8) | localData[4]);
-        
+
         switch(range)
         {
             case DPS_2000:
@@ -324,25 +314,25 @@
                 data.yAxis.scaled = (data.yAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_1000:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_500:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_500_DPS_LSB_PER_DPS);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_500_DPS_LSB_PER_DPS);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_500_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_250:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_250_DPS_LSB_PER_DPS);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_250_DPS_LSB_PER_DPS);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_250_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_125:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_125_DPS_LSB_PER_DPS);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_125_DPS_LSB_PER_DPS);
@@ -350,14 +340,14 @@
             break;
         }
     }
-    
+
     return rtnVal;
 }
 
 
-//***************************************************************************** 
-int32_t BMI160::getSensorXYZandSensorTime(SensorData &data, 
-                                          SensorTime &sensorTime, 
+//*****************************************************************************
+int32_t BMI160::getSensorXYZandSensorTime(SensorData &data,
+                                          SensorTime &sensorTime,
                                           AccRange range)
 {
     uint8_t localData[9];
@@ -367,7 +357,7 @@
         data.xAxis.raw = ((localData[1] << 8) | localData[0]);
         data.yAxis.raw = ((localData[3] << 8) | localData[2]);
         data.zAxis.raw = ((localData[5] << 8) | localData[4]);
-        
+
         switch(range)
         {
             case SENS_2G:
@@ -375,38 +365,38 @@
                 data.yAxis.scaled = (data.yAxis.raw/SENS_2G_LSB_PER_G);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_2G_LSB_PER_G);
             break;
-            
+
             case SENS_4G:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_4G_LSB_PER_G);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_4G_LSB_PER_G);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_4G_LSB_PER_G);
             break;
-            
+
             case SENS_8G:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_8G_LSB_PER_G);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_8G_LSB_PER_G);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_8G_LSB_PER_G);
             break;
-            
+
             case SENS_16G:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_16G_LSB_PER_G);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_16G_LSB_PER_G);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_16G_LSB_PER_G);
             break;
         }
-        
-        sensorTime.raw = ((localData[8] << 16) | (localData[7] << 8) | 
+
+        sensorTime.raw = ((localData[8] << 16) | (localData[7] << 8) |
                            localData[6]);
         sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
     }
-    
+
     return rtnVal;
 }
 
 
-//***************************************************************************** 
-int32_t BMI160::getSensorXYZandSensorTime(SensorData &data, 
-                                          SensorTime &sensorTime, 
+//*****************************************************************************
+int32_t BMI160::getSensorXYZandSensorTime(SensorData &data,
+                                          SensorTime &sensorTime,
                                           GyroRange range)
 {
     uint8_t localData[16];
@@ -416,7 +406,7 @@
         data.xAxis.raw = ((localData[1] << 8) | localData[0]);
         data.yAxis.raw = ((localData[3] << 8) | localData[2]);
         data.zAxis.raw = ((localData[5] << 8) | localData[4]);
-        
+
         switch(range)
         {
             case DPS_2000:
@@ -424,46 +414,46 @@
                 data.yAxis.scaled = (data.yAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_1000:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_500:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_500_DPS_LSB_PER_DPS);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_500_DPS_LSB_PER_DPS);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_500_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_250:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_250_DPS_LSB_PER_DPS);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_250_DPS_LSB_PER_DPS);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_250_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_125:
                 data.xAxis.scaled = (data.xAxis.raw/SENS_125_DPS_LSB_PER_DPS);
                 data.yAxis.scaled = (data.yAxis.raw/SENS_125_DPS_LSB_PER_DPS);
                 data.zAxis.scaled = (data.zAxis.raw/SENS_125_DPS_LSB_PER_DPS);
             break;
         }
-        
-        sensorTime.raw = ((localData[14] << 16) | (localData[13] << 8) | 
+
+        sensorTime.raw = ((localData[14] << 16) | (localData[13] << 8) |
                            localData[12]);
         sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
     }
-    
+
     return rtnVal;
 }
 
 
-//***************************************************************************** 
-int32_t BMI160::getGyroAccXYZandSensorTime(SensorData &accData, 
-                                           SensorData &gyroData, 
-                                           SensorTime &sensorTime, 
-                                           AccRange accRange, 
+//*****************************************************************************
+int32_t BMI160::getGyroAccXYZandSensorTime(SensorData &accData,
+                                           SensorData &gyroData,
+                                           SensorTime &sensorTime,
+                                           AccRange accRange,
                                            GyroRange gyroRange)
 {
     uint8_t localData[16];
@@ -473,11 +463,11 @@
         gyroData.xAxis.raw = ((localData[1] << 8) | localData[0]);
         gyroData.yAxis.raw = ((localData[3] << 8) | localData[2]);
         gyroData.zAxis.raw = ((localData[5] << 8) | localData[4]);
-        
+
         accData.xAxis.raw = ((localData[7] << 8) | localData[6]);
         accData.yAxis.raw = ((localData[9] << 8) | localData[8]);
         accData.zAxis.raw = ((localData[11] << 8) | localData[10]);
-        
+
         switch(gyroRange)
         {
             case DPS_2000:
@@ -485,32 +475,32 @@
                 gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
                 gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_1000:
                 gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
                 gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
                 gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_500:
                 gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_500_DPS_LSB_PER_DPS);
                 gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_500_DPS_LSB_PER_DPS);
                 gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_500_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_250:
                 gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_250_DPS_LSB_PER_DPS);
                 gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_250_DPS_LSB_PER_DPS);
                 gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_250_DPS_LSB_PER_DPS);
             break;
-            
+
             case DPS_125:
                 gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_125_DPS_LSB_PER_DPS);
                 gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_125_DPS_LSB_PER_DPS);
                 gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_125_DPS_LSB_PER_DPS);
             break;
         }
-        
+
         switch(accRange)
         {
             case SENS_2G:
@@ -518,48 +508,82 @@
                 accData.yAxis.scaled = (accData.yAxis.raw/SENS_2G_LSB_PER_G);
                 accData.zAxis.scaled = (accData.zAxis.raw/SENS_2G_LSB_PER_G);
             break;
-            
+
             case SENS_4G:
                 accData.xAxis.scaled = (accData.xAxis.raw/SENS_4G_LSB_PER_G);
                 accData.yAxis.scaled = (accData.yAxis.raw/SENS_4G_LSB_PER_G);
                 accData.zAxis.scaled = (accData.zAxis.raw/SENS_4G_LSB_PER_G);
             break;
-            
+
             case SENS_8G:
                 accData.xAxis.scaled = (accData.xAxis.raw/SENS_8G_LSB_PER_G);
                 accData.yAxis.scaled = (accData.yAxis.raw/SENS_8G_LSB_PER_G);
                 accData.zAxis.scaled = (accData.zAxis.raw/SENS_8G_LSB_PER_G);
             break;
-            
+
             case SENS_16G:
                 accData.xAxis.scaled = (accData.xAxis.raw/SENS_16G_LSB_PER_G);
                 accData.yAxis.scaled = (accData.yAxis.raw/SENS_16G_LSB_PER_G);
                 accData.zAxis.scaled = (accData.zAxis.raw/SENS_16G_LSB_PER_G);
             break;
         }
-        
-        sensorTime.raw = ((localData[14] << 16) | (localData[13] << 8) | 
+
+        sensorTime.raw = ((localData[14] << 16) | (localData[13] << 8) |
                            localData[12]);
         sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
     }
-    
+
     return rtnVal;
 }
 
+int32_t BMI160::setSampleRate(int sample_rate)
+{
+	int sr_reg_val = -1;
+	int i;
+	const uint16_t odr_table[][2] = {
+	    {25, GYRO_ODR_6}, ///<25Hz
+        {50, GYRO_ODR_7}, ///<50Hz
+        {100, GYRO_ODR_8}, ///<100Hz
+        {200, GYRO_ODR_9}, ///<200Hz
+        {400, GYRO_ODR_10}, ///<400Hz
+        {800, GYRO_ODR_11}, ///<800Hz
+        {1600, GYRO_ODR_12}, ///<1600Hz
+        {3200, GYRO_ODR_13}, ///<3200Hz
+	};
 
-//***************************************************************************** 
+	int num_sr = sizeof(odr_table)/sizeof(odr_table[0]);
+	for (i = 0; i < num_sr; i++) {
+		if (sample_rate == odr_table[i][0]) {
+			sr_reg_val = odr_table[i][1];
+			break;
+		}
+	}
+
+	if (sr_reg_val == -1)
+		return -2;
+
+	AccConfig accConfigRead;
+	if (getSensorConfig(accConfigRead) == BMI160::RTN_NO_ERROR) {
+	accConfigRead.odr = (AccOutputDataRate)sr_reg_val;
+		return setSensorConfig(accConfigRead) == BMI160::RTN_NO_ERROR ? 0 : -1;
+	} else
+		return -1;
+}
+
+
+//*****************************************************************************
 int32_t BMI160::getSensorTime(SensorTime &sensorTime)
 {
     uint8_t localData[3];
     int32_t rtnVal = readBlock(SENSORTIME_0, SENSORTIME_2, localData);
-    
+
     if(rtnVal == RTN_NO_ERROR)
     {
-        sensorTime.raw = ((localData[2] << 16) | (localData[1] << 8) | 
+        sensorTime.raw = ((localData[2] << 16) | (localData[1] << 8) |
                            localData[0]);
         sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
     }
-    
+
     return rtnVal;
 }
 
@@ -569,7 +593,7 @@
 {
     uint8_t data[2];
     uint16_t rawTemp;
-    
+
     int32_t rtnVal = readBlock(TEMPERATURE_0, TEMPERATURE_1, data);
     if(rtnVal == RTN_NO_ERROR)
     {
@@ -583,6 +607,117 @@
             *temp = ((rawTemp/512.0F) + 23.0F);
         }
     }
-    
+
     return rtnVal;
 }
+
+//***********************************************************************************
+int32_t BMI160::BMI160_DefaultInitalize(){
+
+		//soft reset the accelerometer
+		writeRegister(CMD ,SOFT_RESET);
+		wait(0.1);
+
+	    //Power up sensors in normal mode
+	    if(setSensorPowerMode(BMI160::GYRO, BMI160::SUSPEND) != BMI160::RTN_NO_ERROR){
+	        printf("Failed to set gyroscope power mode\n");
+	    }
+
+	    wait(0.1);
+
+	    if(setSensorPowerMode(BMI160::ACC, BMI160::NORMAL) != BMI160::RTN_NO_ERROR){
+	        printf("Failed to set accelerometer power mode\n");
+	    }
+	    wait(0.1);
+
+	    BMI160::AccConfig accConfig;
+	    BMI160::AccConfig accConfigRead;
+	    accConfig.range = BMI160::SENS_2G;
+	    accConfig.us = BMI160::ACC_US_OFF;
+	    accConfig.bwp = BMI160::ACC_BWP_2;
+	    accConfig.odr = BMI160::ACC_ODR_6;
+	    if(setSensorConfig(accConfig) == BMI160::RTN_NO_ERROR)
+	    {
+	        if(getSensorConfig(accConfigRead) == BMI160::RTN_NO_ERROR)
+	        {
+	            if((accConfig.range != accConfigRead.range) ||
+	                    (accConfig.us != accConfigRead.us) ||
+	                    (accConfig.bwp != accConfigRead.bwp) ||
+	                    (accConfig.odr != accConfigRead.odr))
+	            {
+	                printf("ACC read data desn't equal set data\n\n");
+	                printf("ACC Set Range = %d\n", accConfig.range);
+	                printf("ACC Set UnderSampling = %d\n", accConfig.us);
+	                printf("ACC Set BandWidthParam = %d\n", accConfig.bwp);
+	                printf("ACC Set OutputDataRate = %d\n\n", accConfig.odr);
+	                printf("ACC Read Range = %d\n", accConfigRead.range);
+	                printf("ACC Read UnderSampling = %d\n", accConfigRead.us);
+	                printf("ACC Read BandWidthParam = %d\n", accConfigRead.bwp);
+	                printf("ACC Read OutputDataRate = %d\n\n", accConfigRead.odr);
+	            }
+
+	        }
+	        else
+	        {
+	             printf("Failed to read back accelerometer configuration\n");
+	        }
+	    }
+	    else
+	    {
+	        printf("Failed to set accelerometer configuration\n");
+	    }
+	    return 0;
+}
+
+//***********************************************************************************
+int32_t BMI160::enable_data_ready_interrupt() {
+	uint8_t data = 0;
+	uint8_t temp = 0;
+	int32_t result;
+
+	result = readRegister(INT_EN_1, &data);
+	temp = data & ~0x10;
+	data = temp | ((1 << 4) & 0x10);
+	/* Writing data to INT ENABLE 1 Address */
+	result |= writeRegister(INT_EN_1, data);
+
+	// configure in_out ctrl
+	//bmi160_get_regs(BMI160_INT_OUT_CTRL_ADDR, &data, 1, dev);
+	result |= readRegister(INT_OUT_CTRL, &data);
+	data = 0x09;
+	result |= writeRegister(INT_OUT_CTRL,data);
+
+	//config int latch
+	//bmi160_get_regs(BMI160_INT_LATCH_ADDR, &data, 1, dev);
+	result |= readRegister(INT_LATCH, &data);
+	data = 0x0F;
+	result |= writeRegister(INT_LATCH, data);
+
+	//bmi160_get_regs(BMI160_INT_MAP_1_ADDR, &data, 1, dev);
+	result |= readRegister(INT_MAP_1, &data);
+	data = 0x80;
+	result |= writeRegister(INT_MAP_1, data);
+
+	if(result != 0){
+		printf("BMI160::%s failed.\r\n", __func__);
+		return -1;
+	}
+
+	m_bmi160_irq->disable_irq();
+	m_bmi160_irq->mode(PullUp);
+	m_bmi160_irq->fall(this, &BMI160::irq_handler);
+	m_bmi160_irq->enable_irq();
+	return 0;
+}
+
+void BMI160::irq_handler() {
+	bmi160_irq_asserted = true;
+}
+
+int32_t BMI160::reset() {
+	if (m_use_irq)
+		m_bmi160_irq->disable_irq();
+	bmi160_irq_asserted = false;
+	writeRegister(CMD, SOFT_RESET);
+	return 0;
+}
diff -r a521606048bb -r f7216b5dc6c0 bmi160.h
--- a/bmi160.h	Fri May 04 13:35:59 2018 +0300
+++ b/bmi160.h	Wed Dec 19 14:54:05 2018 +0300
@@ -46,7 +46,7 @@
 battery driven devices. It is available in a compact 14-pin 2.5 x 3.0 x 0.8 mm³
 LGA package."
 
-This class is an abstract base class and can not be instaniated, use BMI160_I2C 
+This class is an abstract base class and can not be instaniated, use BMI160_I2C
 or BMI160_SPI.
 */
 class BMI160
@@ -55,7 +55,7 @@
 
     ///Return value on success.
     static const uint8_t RTN_NO_ERROR = 0;
-    
+
     ///Sensor types
     enum Sensors
     {
@@ -63,7 +63,7 @@
         GYRO,    ///<Angular rate sensor
         ACC      ///<g sensor
     };
-    
+
     ///Sensor Axis
     enum SensorAxis
     {
@@ -71,21 +71,24 @@
         Y_AXIS,
         Z_AXIS
     };
-    
+
     ///Structure for axis data
     struct AxisData
     {
         int16_t raw;  ///<Axis raw data
-        float scaled; ///<Axis scaled data 
+        float scaled; ///<Axis scaled data
     };
-    
+
     ///Structure for sensor time data
     struct SensorTime
     {
         uint32_t raw;  ///<raw SensorTime
         float seconds; ///<SensorTime as seconds
     };
-    
+
+    ///Period of internal counter
+    static const float SENSOR_TIME_LSB = 39e-6;
+
     ///Structure for holding sensor data
     struct SensorData
     {
@@ -93,12 +96,12 @@
         AxisData yAxis; ///<Sensor Y axis data
         AxisData zAxis; ///<Sensor Z axis data
     };
-    
-    
+
+
     ///BMI160 registers
     enum Registers
     {
-        CHIP_ID = 0x00,  ///<Chip Identification. 
+        CHIP_ID = 0x00,  ///<Chip Identification.
         ERR_REG = 0x02,  ///<Reports sensor error flags.  Flags reset when read.
         PMU_STATUS,      ///<Reports current power mode for sensors.
         DATA_0,          ///<MAG_X axis bits7:0
@@ -139,10 +142,10 @@
         GYR_CONF,        ///<Set ODR, bandwidth, and read mode of gyroscope
         GYR_RANGE,       ///<Sets gyroscope angular rate measurement range
         MAG_CONF,        ///<Sets ODR of magnetometer interface
-        FIFO_DOWNS,      ///<Sets down sampling ratios of accel and gyro data 
+        FIFO_DOWNS,      ///<Sets down sampling ratios of accel and gyro data
                          ///<for FIFO
         FIFO_CONFIG_0,   ///<Sets FIFO Watermark
-        FIFO_CONFIG_1,   ///<Sets which sensor data is available in FIFO, 
+        FIFO_CONFIG_1,   ///<Sets which sensor data is available in FIFO,
                          ///<Header/Headerless mode, Ext Int tagging, Sensortime
         MAG_IF_0 = 0x4B, ///<Magnetometer 7-bit I2C address, bits7:1
         MAG_IF_1,        ///<Magnetometer interface configuration
@@ -153,40 +156,40 @@
         INT_EN_1,        ///<Interrupt enable bits
         INT_EN_2,        ///<Interrupt enable bits
         INT_OUT_CTRL,    ///<Contains the behavioral configuration of INT pins
-        INT_LATCH,       ///<Contains the interrupt rest bit and the interrupt 
+        INT_LATCH,       ///<Contains the interrupt rest bit and the interrupt
                          ///<mode selection
-        INT_MAP_0,       ///<Controls which interrupt signals are mapped to the 
+        INT_MAP_0,       ///<Controls which interrupt signals are mapped to the
                          ///<INT1 and INT2 pins
-        INT_MAP_1,       ///<Controls which interrupt signals are mapped to the 
+        INT_MAP_1,       ///<Controls which interrupt signals are mapped to the
                          ///<INT1 and INT2 pins
-        INT_MAP_2,       ///<Controls which interrupt signals are mapped to the 
+        INT_MAP_2,       ///<Controls which interrupt signals are mapped to the
                          ///<INT1 and INT2 pins
-        INT_DATA_0,      ///<Contains the data source definition for the two 
+        INT_DATA_0,      ///<Contains the data source definition for the two
                          ///<interrupt groups
-        INT_DATA_1,      ///<Contains the data source definition for the two 
+        INT_DATA_1,      ///<Contains the data source definition for the two
                          ///<interrupt groups
         INT_LOWHIGH_0,   ///<Contains the configuration for the low g interrupt
         INT_LOWHIGH_1,   ///<Contains the configuration for the low g interrupt
         INT_LOWHIGH_2,   ///<Contains the configuration for the low g interrupt
         INT_LOWHIGH_3,   ///<Contains the configuration for the low g interrupt
         INT_LOWHIGH_4,   ///<Contains the configuration for the low g interrupt
-        INT_MOTION_0,    ///<Contains the configuration for the any motion and 
+        INT_MOTION_0,    ///<Contains the configuration for the any motion and
                          ///<no motion interrupts
-        INT_MOTION_1,    ///<Contains the configuration for the any motion and 
+        INT_MOTION_1,    ///<Contains the configuration for the any motion and
                          ///<no motion interrupts
-        INT_MOTION_2,    ///<Contains the configuration for the any motion and 
+        INT_MOTION_2,    ///<Contains the configuration for the any motion and
                          ///<no motion interrupts
-        INT_MOTION_3,    ///<Contains the configuration for the any motion and 
+        INT_MOTION_3,    ///<Contains the configuration for the any motion and
                          ///<no motion interrupts
         INT_TAP_0,       ///<Contains the configuration for the tap interrupts
         INT_TAP_1,       ///<Contains the configuration for the tap interrupts
-        INT_ORIENT_0,    ///<Contains the configuration for the oeientation 
+        INT_ORIENT_0,    ///<Contains the configuration for the oeientation
                          ///<interrupt
-        INT_ORIENT_1,    ///<Contains the configuration for the oeientation 
+        INT_ORIENT_1,    ///<Contains the configuration for the oeientation
                          ///<interrupt
         INT_FLAT_0,      ///<Contains the configuration for the flat interrupt
         INT_FLAT_1,      ///<Contains the configuration for the flat interrupt
-        FOC_CONF,        ///<Contains configuration for the fast offset 
+        FOC_CONF,        ///<Contains configuration for the fast offset
                          ///<compensation for the accelerometer and gyroscope
         CONF,            ///<Configuration of sensor, nvm_prog_en bit
         IF_CONF,         ///<Contains settings for the digital interface
@@ -204,15 +207,15 @@
         STEP_CNT_1,      ///<Step counter bits 7:0
         STEP_CONF_0,     ///<Contains configuration of the step detector
         STEP_CONF_1,     ///<Contains configuration of the step detector
-        CMD = 0x7E       ///<Command register triggers operations like 
+        CMD = 0x7E       ///<Command register triggers operations like
                          ///<softreset, NVM programming, etc.
     };
-    
-    
+
+
     ///@name ERR_REG(0x02)
     ///Error register data
     ///@{
-        
+
     static const uint8_t FATAL_ERR_MASK = 0x01;
     static const uint8_t FATAL_ERR_POS = 0x00;
     static const uint8_t ERR_CODE_MASK = 0x1E;
@@ -223,26 +226,26 @@
     static const uint8_t DROP_CMD_ERR_POS = 0x06;
     static const uint8_t MAG_DRDY_ERR_MASK = 0x80;
     static const uint8_t MAG_DRDY_ERR_POS = 0x08;
-    
+
     ///Enumerated error codes
     enum ErrorCodes
     {
         NO_ERROR = 0,        ///<No Error
-        ERROR_1,             ///<Listed as error   
+        ERROR_1,             ///<Listed as error
         ERROR_2,             ///<Listed as error
-        LPM_INT_PFD,         ///<Low-power mode and interrupt uses pre-filtered 
+        LPM_INT_PFD,         ///<Low-power mode and interrupt uses pre-filtered
                              ///<data
-        ODR_MISMATCH = 0x06, ///<ODRs of enabled sensors in headerless mode do 
+        ODR_MISMATCH = 0x06, ///<ODRs of enabled sensors in headerless mode do
                              ///<not match
         PFD_USED_LPM         ///<Pre-filtered data are used in low power mode
     };
     ///@}
-    
-    
-    ///@name ACC_CONF(0x40) and ACC_RANGE(0x41) 
+
+
+    ///@name ACC_CONF(0x40) and ACC_RANGE(0x41)
     ///Data for configuring accelerometer
     ///@{
-        
+
     static const uint8_t ACC_ODR_MASK = 0x0F;
     static const uint8_t ACC_ODR_POS = 0x00;
     static const uint8_t ACC_BWP_MASK = 0x70;
@@ -251,7 +254,7 @@
     static const uint8_t ACC_US_POS = 0x07;
     static const uint8_t ACC_RANGE_MASK = 0x0F;
     static const uint8_t ACC_RANGE_POS = 0x00;
-    
+
     ///Accelerometer output data rates
     enum AccOutputDataRate
     {
@@ -268,7 +271,7 @@
         ACC_ODR_11,     ///< 800Hz
         ACC_ODR_12      ///< 1600Hz
     };
-    
+
     ///Accelerometer bandwidth parameters
     enum AccBandWidthParam
     {
@@ -281,14 +284,14 @@
         ACC_BWP_6,     ///< Average 64 cycles
         ACC_BWP_7      ///< Average 128 cycles
     };
-    
+
     ///Accelerometer undersampling
     enum AccUnderSampling
     {
         ACC_US_OFF = 0,
         ACC_US_ON
     };
-    
+
     ///Accelerometer ranges
     enum AccRange
     {
@@ -297,7 +300,12 @@
         SENS_8G = 0x08,  ///<Accelerometer range +-8G
         SENS_16G = 0x0C ///<Accelerometer range +-16G
     };
-    
+
+    static const float SENS_2G_LSB_PER_G = 16384.0F;
+    static const float SENS_4G_LSB_PER_G = 8192.0F;
+    static const float SENS_8G_LSB_PER_G = 4096.0F;
+    static const float SENS_16G_LSB_PER_G = 2048.0F;
+
     ///Accelerometer configuration data structure
     struct AccConfig
     {
@@ -306,27 +314,27 @@
         AccBandWidthParam bwp; ///<Accelerometer bandwidth param
         AccOutputDataRate odr; ///<Accelerometr output data rate
     };
-    
+
     ///Accelerometer default configuration
     static const AccConfig DEFAULT_ACC_CONFIG;
     ///@}
-    
-    
-    ///@name GYR_CONF(0x42) and GYR_RANGE(0x43) 
+
+
+    ///@name GYR_CONF(0x42) and GYR_RANGE(0x43)
     ///Data for configuring gyroscope
     ///@{
-    
+
     static const uint8_t GYRO_ODR_MASK = 0x0F;
     static const uint8_t GYRO_ODR_POS = 0x00;
     static const uint8_t GYRO_BWP_MASK = 0x30;
     static const uint8_t GYRO_BWP_POS = 0x04;
     static const uint8_t GYRO_RANGE_MASK = 0x07;
     static const uint8_t GYRO_RANGE_POS = 0x00;
-    
+
     ///Gyroscope output data rates
     enum GyroOutputDataRate
     {
-        GYRO_ODR_6 = 0x06,  ///<25Hz 
+        GYRO_ODR_6 = 0x06,  ///<25Hz
         GYRO_ODR_7 = 0x07,  ///<50Hz
         GYRO_ODR_8 = 0x08,  ///<100Hz
         GYRO_ODR_9 = 0x09,  ///<200Hz
@@ -335,7 +343,7 @@
         GYRO_ODR_12 = 0x0C, ///<1600Hz
         GYRO_ODR_13 = 0x0D  ///<3200Hz
     };
-    
+
     ///Gyroscope bandwidth paramaters
     enum GyroBandWidthParam
     {
@@ -343,7 +351,7 @@
         GYRO_BWP_1,     ///<OSR2 Over Sampling Rate of 2
         GYRO_BWP_2      ///<Normal Mode, Equidistant Sampling
     };
-    
+
     ///Gyroscope ranges
     enum GyroRange
     {
@@ -351,22 +359,28 @@
         DPS_1000,     ///<+-1000dps, 32.8LSB/dps
         DPS_500,      ///<+-500dps, 65.6LSB/dps
         DPS_250,      ///<+-250dps, 131.2LSB/dps
-        DPS_125       ///<+-125dps, 262.4LSB/dps, 
+        DPS_125       ///<+-125dps, 262.4LSB/dps,
     };
-    
-    ///Gyroscope configuration data structure    
+
+    static const float SENS_2000_DPS_LSB_PER_DPS = 16.4F;
+    static const float SENS_1000_DPS_LSB_PER_DPS = 32.8F;
+    static const float SENS_500_DPS_LSB_PER_DPS = 65.6F;
+    static const float SENS_250_DPS_LSB_PER_DPS = 131.2F;
+    static const float SENS_125_DPS_LSB_PER_DPS = 262.4F;
+
+    ///Gyroscope configuration data structure
     struct GyroConfig
     {
         GyroRange range;        ///<Gyroscope range
         GyroBandWidthParam bwp; ///<Gyroscope bandwidth param
         GyroOutputDataRate odr; ///<Gyroscope output data rate
     };
-    
+
     ///Gyroscope default configuration
     static const GyroConfig DEFAULT_GYRO_CONFIG;
     ///@}
-    
-    
+
+
     ///Enumerated power modes
     enum PowerModes
     {
@@ -375,36 +389,36 @@
         LOW_POWER,    ///<Acc duty-cycling between suspend and normal
         FAST_START_UP ///<Gyro start up delay time to normal mode <= 10 ms
     };
-    
-    
+
+
     ///Enumerated commands used with CMD register
     enum Commands
     {
-        START_FOC = 0x03,        ///<Starts Fast Offset Calibrartion 
+        START_FOC = 0x03,        ///<Starts Fast Offset Calibrartion
         ACC_SET_PMU_MODE = 0x10, ///<Sets acc power mode
         GYR_SET_PMU_MODE = 0x14, ///<Sets gyro power mode
         MAG_SET_PMU_MODE = 0x18, ///<Sets mag power mode
         PROG_NVM = 0xA0,         ///<Writes NVM backed registers into NVM
         FIFO_FLUSH = 0xB0,       ///<Clears FIFO
-        INT_RESET,               ///<Clears interrupt engine, INT_STATUS, and 
+        INT_RESET,               ///<Clears interrupt engine, INT_STATUS, and
                                  ///<the interrupt pin
         STEP_CNT_CLR,            ///<Triggers reset of the step counter
         SOFT_RESET = 0xB6        ///<Triggers a reset including a reboot.
     };
-    
-    
+
+
     ///@brief BMI160 Destructor.\n
     ///
     ///On Entry:
-    ///@param[in] none 
+    ///@param[in] none
     ///
     ///On Exit:
     ///@param[out] none
     ///
     ///@returns none
     virtual ~BMI160(){ }
-    
-    
+
+
     ///@brief Reads a single register.\n
     ///
     ///On Entry:
@@ -415,8 +429,8 @@
     ///
     ///@returns 0 on success, non 0 on failure
     virtual int32_t readRegister(Registers reg, uint8_t *data) = 0;
-    
-    
+
+
     ///@brief Writes a single register.\n
     ///
     ///On Entry:
@@ -427,11 +441,11 @@
     ///
     ///@returns 0 on success, non 0 on failure
     virtual int32_t writeRegister(Registers reg, const uint8_t data) = 0;
-    
-    
+
+
     ///@brief Reads a block of registers.\n
-    ///@detail User must ensure that all registers between 'startReg' and 
-    ///'stopReg' exist and are readable.  Function reads up to, including, 
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are readable.  Function reads up to, including,
     ///'stopReg'.\n
     ///
     ///On Entry:
@@ -443,17 +457,17 @@
     ///@param[out] data - holds contents of read registers on success
     ///
     ///@returns 0 on success, non 0 on failure
-    virtual int32_t readBlock(Registers startReg, Registers stopReg, 
+    virtual int32_t readBlock(Registers startReg, Registers stopReg,
     uint8_t *data) = 0;
-    
-    
+
+
     ///@brief Writes a block of registers.\n
-    ///@detail User must ensure that all registers between 'startReg' and 
-    ///'stopReg' exist and are writeable.  Function writes up to, including, 
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are writeable.  Function writes up to, including,
     ///'stopReg'.\n
     ///
     ///On Entry:
-    ///@param[in] startReg - register to start writing at 
+    ///@param[in] startReg - register to start writing at
     ///@param[in] stopReg - register to stop writing at
     ///@param[in] data - pointer to data to write to registers
     ///
@@ -461,24 +475,24 @@
     ///@param[out] none
     ///
     ///@returns 0 on success, non 0 on failure
-    virtual int32_t writeBlock(Registers startReg, Registers stopReg, 
+    virtual int32_t writeBlock(Registers startReg, Registers stopReg,
     const uint8_t *data) = 0;
-    
-    
+
+
     ///@brief Sets sensors power mode through CMD register.\n
-    ///@details Observe command execution times given in datasheet.\n 
+    ///@details Observe command execution times given in datasheet.\n
     ///
     ///On Entry:
     ///@param[in] sensor - Sensor which power mode we are setting
     ///@param[in] pwrMode - Desired powermode of the sensor
     ///
     ///On Exit:
-    ///@param[out] 
+    ///@param[out]
     ///
     ///@returns 0 on success, non 0 on failure
     int32_t setSensorPowerMode(Sensors sensor, PowerModes pwrMode);
-    
-    
+
+
     ///@brief Configure sensor.\n
     ///
     ///On Entry:
@@ -490,22 +504,22 @@
     ///@returns 0 on success, non 0 on failure
     int32_t setSensorConfig(const AccConfig &config);
     int32_t setSensorConfig(const GyroConfig &config);
-    
-    
+
+
     ///@brief Get sensor configuration.\n
     ///
     ///On Entry:
     ///@param[in] config - Sensor configuration data structure
     ///
     ///On Exit:
-    ///@param[out] config - on success, holds sensor's current 
+    ///@param[out] config - on success, holds sensor's current
     ///configuration
     ///
     ///@returns 0 on success, non 0 on failure
     int32_t getSensorConfig(AccConfig &config);
     int32_t getSensorConfig(GyroConfig &config);
-    
-    
+
+
     ///@brief Get sensor axis.\n
     ///
     ///On Entry:
@@ -519,8 +533,8 @@
     ///@returns 0 on success, non 0 on failure
     int32_t getSensorAxis(SensorAxis axis, AxisData &data, AccRange range);
     int32_t getSensorAxis(SensorAxis axis, AxisData &data, GyroRange range);
-    
-    
+
+
     ///@brief Get sensor xyz axis.\n
     ///
     ///On Entry:
@@ -533,8 +547,8 @@
     ///@returns 0 on success, non 0 on failure
     int32_t getSensorXYZ(SensorData &data, AccRange range);
     int32_t getSensorXYZ(SensorData &data, GyroRange range);
-    
-    
+
+
     ///@brief Get sensor xyz axis and sensor time.\n
     ///
     ///On Entry:
@@ -547,12 +561,12 @@
     ///@param[out] sensorTime - Holds sensor time on success
     ///
     ///@returns 0 on success, non 0 on failure
-    int32_t getSensorXYZandSensorTime(SensorData &data, SensorTime &sensorTime, 
+    int32_t getSensorXYZandSensorTime(SensorData &data, SensorTime &sensorTime,
                                       AccRange range);
-    int32_t getSensorXYZandSensorTime(SensorData &data, SensorTime &sensorTime, 
+    int32_t getSensorXYZandSensorTime(SensorData &data, SensorTime &sensorTime,
                                       GyroRange range);
-    
-    
+
+
     ///@brief Get Gyroscope/Accelerometer data and sensor time.\n
     ///
     ///On Entry:
@@ -568,12 +582,12 @@
     ///@param[out] sensorTime - Synchronized sensor time
     ///
     ///@returns 0 on success, non 0 on failure
-    int32_t getGyroAccXYZandSensorTime(SensorData &accData, 
-                                       SensorData &gyroData, 
-                                       SensorTime &sensorTime, 
+    int32_t getGyroAccXYZandSensorTime(SensorData &accData,
+                                       SensorData &gyroData,
+                                       SensorTime &sensorTime,
                                        AccRange accRange, GyroRange gyroRange);
-    
-    
+
+
     ///@brief Get sensor time.\n
     ///
     ///On Entry:
@@ -584,18 +598,48 @@
     ///
     ///@returns returns 0 on success, non 0 on failure
     int32_t getSensorTime(SensorTime &sensorTime);
-    
-    
+
+
     ///@brief Get die temperature.\n
     ///
     ///On Entry:
-    ///@param[in] temp - pointer to float for temperature 
+    ///@param[in] temp - pointer to float for temperature
     ///
     ///On Exit:
     ///@param[out] temp - on success, holds the die temperature
     ///
     ///@returns 0 on success, non 0 on failure
     int32_t getTemperature(float *temp);
+
+    // Initialize BMI160 with default parameters:
+    // set GYRO: Suspended, Acc Normal Mode, ODR:25 Hz
+    int32_t BMI160_DefaultInitalize();
+
+    //
+    //
+    int32_t enable_data_ready_interrupt();
+
+	//
+	// Set sample rate
+	// This function can be alled after BMI160_DefaultInitalize
+	int32_t setSampleRate(int sample_rate);
+
+	/// @brief Soft reset
+	///
+	int32_t reset();
+
+private:
+	bool m_use_irq;
+	bool bmi160_irq_asserted;
+	InterruptIn *m_bmi160_irq;
+	void irq_handler();
+
+protected:
+	BMI160(InterruptIn *int_pin): m_bmi160_irq(int_pin), m_use_irq(true) {
+		bmi160_irq_asserted = false;
+	}
+
+	BMI160(): m_use_irq(false) { }
 };
 
 
@@ -610,7 +654,7 @@
     static const uint8_t I2C_ADRS_SDO_LO = 0x68;
     ///BMI160 optional I2C address.
     static const uint8_t I2C_ADRS_SDO_HI = 0x69;
-    
+
 
     ///@brief BMI160_I2C Constructor.\n
     ///
@@ -622,9 +666,21 @@
     ///@param[out] none
     ///
     ///@returns none
-    BMI160_I2C(I2C &i2cBus, uint8_t i2cAdrs);
-    
-    
+    BMI160_I2C(I2C *i2cBus, uint8_t i2cAdrs);
+
+    ///@brief BMI160_I2C Constructor.\n
+    ///
+    ///On Entry:
+    ///@param[in] i2cBus - reference to I2C bus for this device
+    ///@param[in] i2cAdrs - 7-bit I2C address
+    ///@param[in] int_pin - Interrupt pin
+    ///
+    ///On Exit:
+    ///@param[out] none
+    ///
+    ///@returns none
+	BMI160_I2C(I2C *i2cBus, uint8_t i2cAdrs, InterruptIn *int_pin);
+
     ///@brief Reads a single register.\n
     ///
     ///On Entry:
@@ -635,8 +691,8 @@
     ///
     ///@returns 0 on success, non 0 on failure
     virtual int32_t readRegister(Registers reg, uint8_t *data);
-    
-    
+
+
     ///@brief Writes a single register.\n
     ///
     ///On Entry:
@@ -647,11 +703,11 @@
     ///
     ///@returns 0 on success, non 0 on failure
     virtual int32_t writeRegister(Registers reg, const uint8_t data);
-    
-    
+
+
     ///@brief Reads a block of registers.\n
-    ///@detail User must ensure that all registers between 'startReg' and 
-    ///'stopReg' exist and are readable.  Function reads up to, including, 
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are readable.  Function reads up to, including,
     ///'stopReg'.\n
     ///
     ///On Entry:
@@ -663,17 +719,17 @@
     ///@param[out] data - holds contents of read registers on success
     ///
     ///@returns 0 on success, non 0 on failure
-    virtual int32_t readBlock(Registers startReg, Registers stopReg, 
+    virtual int32_t readBlock(Registers startReg, Registers stopReg,
     uint8_t *data);
-    
-    
+
+
     ///@brief Writes a block of registers.\n
-    ///@detail User must ensure that all registers between 'startReg' and 
-    ///'stopReg' exist and are writeable.  Function writes up to, including, 
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are writeable.  Function writes up to, including,
     ///'stopReg'.\n
     ///
     ///On Entry:
-    ///@param[in] startReg - register to start writing at 
+    ///@param[in] startReg - register to start writing at
     ///@param[in] stopReg - register to stop writing at
     ///@param[in] data - pointer to data to write to registers
     ///
@@ -681,12 +737,11 @@
     ///@param[out] none
     ///
     ///@returns 0 on success, non 0 on failure
-    virtual int32_t writeBlock(Registers startReg, Registers stopReg, 
+    virtual int32_t writeBlock(Registers startReg, Registers stopReg,
     const uint8_t *data);
-    
+
 private:
-
-    I2C &m_i2cBus;
+    I2C *m_i2cBus;
     uint8_t m_Wadrs, m_Radrs;
 };
 
@@ -708,9 +763,9 @@
     ///@param[out] none
     ///
     ///@returns none
-    BMI160_SPI(SPI &spiBus, DigitalOut &cs);
-    
-    
+    BMI160_SPI(SPI *spiBus, DigitalOut &cs);
+
+
     ///@brief Reads a single register.\n
     ///
     ///On Entry:
@@ -721,8 +776,8 @@
     ///
     ///@returns 0 on success, non 0 on failure
     virtual int32_t readRegister(Registers reg, uint8_t *data);
-    
-    
+
+
     ///@brief Writes a single register.\n
     ///
     ///On Entry:
@@ -733,11 +788,11 @@
     ///
     ///@returns 0 on success, non 0 on failure
     virtual int32_t writeRegister(Registers reg, const uint8_t data);
-    
-    
+
+
     ///@brief Reads a block of registers.\n
-    ///@detail User must ensure that all registers between 'startReg' and 
-    ///'stopReg' exist and are readable.  Function reads up to, including, 
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are readable.  Function reads up to, including,
     ///'stopReg'.\n
     ///
     ///On Entry:
@@ -749,17 +804,17 @@
     ///@param[out] data - holds contents of read registers on success
     ///
     ///@returns 0 on success, non 0 on failure
-    virtual int32_t readBlock(Registers startReg, Registers stopReg, 
+    virtual int32_t readBlock(Registers startReg, Registers stopReg,
     uint8_t *data);
-    
-    
+
+
     ///@brief Writes a block of registers.\n
-    ///@detail User must ensure that all registers between 'startReg' and 
-    ///'stopReg' exist and are writeable.  Function writes up to, including, 
+    ///@detail User must ensure that all registers between 'startReg' and
+    ///'stopReg' exist and are writeable.  Function writes up to, including,
     ///'stopReg'.\n
     ///
     ///On Entry:
-    ///@param[in] startReg - register to start writing at 
+    ///@param[in] startReg - register to start writing at
     ///@param[in] stopReg - register to stop writing at
     ///@param[in] data - pointer to data to write to registers
     ///
@@ -767,12 +822,12 @@
     ///@param[out] none
     ///
     ///@returns 0 on success, non 0 on failure
-    virtual int32_t writeBlock(Registers startReg, Registers stopReg, 
+    virtual int32_t writeBlock(Registers startReg, Registers stopReg,
     const uint8_t *data);
-    
+
 private:
 
-    SPI &m_spiBus;
+    SPI *m_spiBus;
     DigitalOut m_cs;
 };
 
@@ -782,7 +837,7 @@
 ///@brief fx documentation template.\n
 ///
 ///On Entry:
-///@param[in] none 
+///@param[in] none
 ///
 ///On Exit:
 ///@param[out] none
diff -r a521606048bb -r f7216b5dc6c0 bmi160_i2c.cpp
--- a/bmi160_i2c.cpp	Fri May 04 13:35:59 2018 +0300
+++ b/bmi160_i2c.cpp	Wed Dec 19 14:54:05 2018 +0300
@@ -35,24 +35,29 @@
 
 
 //*****************************************************************************
-BMI160_I2C::BMI160_I2C(I2C &i2cBus, uint8_t i2cAdrs)
+BMI160_I2C::BMI160_I2C(I2C *i2cBus, uint8_t i2cAdrs)
 :m_i2cBus(i2cBus), m_Wadrs(i2cAdrs << 1), m_Radrs((i2cAdrs << 1) | 1)
 {
-    
+
 }
 
+BMI160_I2C::BMI160_I2C(I2C *i2cBus, uint8_t i2cAdrs, InterruptIn *int_pin)
+:m_i2cBus(i2cBus), m_Wadrs(i2cAdrs << 1), m_Radrs((i2cAdrs << 1) | 1), BMI160(int_pin)
+{
 
-//*****************************************************************************   
+}
+
+//*****************************************************************************
 int32_t BMI160_I2C::readRegister(Registers reg, uint8_t *data)
 {
     int32_t rtnVal = -1;
     char packet[] = {static_cast<char>(reg)};
-    
-    if(m_i2cBus.write(m_Wadrs, packet, 1) == 0)
+
+    if(m_i2cBus->write(m_Wadrs, packet, 1) == 0)
     {
-        rtnVal = m_i2cBus.read(m_Radrs, reinterpret_cast<char *>(data), 1);
+        rtnVal = m_i2cBus->read(m_Radrs, reinterpret_cast<char *>(data), 1);
     }
-    
+
     return rtnVal;
 }
 
@@ -61,38 +66,38 @@
 int32_t BMI160_I2C::writeRegister(Registers reg, const uint8_t data)
 {
     char packet[] = {static_cast<char>(reg), static_cast<char>(data)};
-    
-    return m_i2cBus.write(m_Wadrs, packet, sizeof(packet));
+
+    return m_i2cBus->write(m_Wadrs, packet, sizeof(packet));
 }
 
 
 //*****************************************************************************
-int32_t BMI160_I2C::readBlock(Registers startReg, Registers stopReg, 
+int32_t BMI160_I2C::readBlock(Registers startReg, Registers stopReg,
 uint8_t *data)
 {
     int32_t rtnVal = -1;
     int32_t numBytes = ((stopReg - startReg) + 1);
     char packet[] = {static_cast<char>(startReg)};
-    
-    if(m_i2cBus.write(m_Wadrs, packet, 1) == 0)
+
+    if(m_i2cBus->write(m_Wadrs, packet, 1) == 0)
     {
-        rtnVal = m_i2cBus.read(m_Radrs, reinterpret_cast<char *>(data), numBytes);
+        rtnVal = m_i2cBus->read(m_Radrs, reinterpret_cast<char *>(data), numBytes);
     }
-    
+
     return rtnVal;
 }
 
 
 //*****************************************************************************
-int32_t BMI160_I2C::writeBlock(Registers startReg, Registers stopReg, 
+int32_t BMI160_I2C::writeBlock(Registers startReg, Registers stopReg,
 const uint8_t *data)
 {
     int32_t numBytes = ((stopReg - startReg) + 1);
-    char packet[32];
-    
+    char packet[numBytes + 1];
+
     packet[0] = static_cast<char>(startReg);
-    
+
     memcpy(packet + 1, data, numBytes);
-    
-    return m_i2cBus.write(m_Wadrs, packet, (numBytes+1) * sizeof(char));
+
+    return m_i2cBus->write(m_Wadrs, packet, sizeof(packet));
 }
diff -r a521606048bb -r f7216b5dc6c0 bmi160_spi.cpp
--- a/bmi160_spi.cpp	Fri May 04 13:35:59 2018 +0300
+++ b/bmi160_spi.cpp	Wed Dec 19 14:54:05 2018 +0300
@@ -35,18 +35,18 @@
 
 
 //*****************************************************************************
-BMI160_SPI::BMI160_SPI(SPI &spiBus, DigitalOut &cs)
+BMI160_SPI::BMI160_SPI(SPI *spiBus, DigitalOut &cs)
 :m_spiBus(spiBus), m_cs(cs)
 {
-    
+
 }
 
 
-//*****************************************************************************   
+//*****************************************************************************
 int32_t BMI160_SPI::readRegister(Registers reg, uint8_t *data)
 {
     int32_t rtnVal = -1;
-    
+
     return rtnVal;
 }
 
@@ -55,26 +55,26 @@
 int32_t BMI160_SPI::writeRegister(Registers reg, const uint8_t data)
 {
     int32_t rtnVal = -1;
-    
+
     return rtnVal;
 }
 
 
 //*****************************************************************************
-int32_t BMI160_SPI::readBlock(Registers startReg, Registers stopReg, 
+int32_t BMI160_SPI::readBlock(Registers startReg, Registers stopReg,
 uint8_t *data)
 {
     int32_t rtnVal = -1;
-    
+
     return rtnVal;
 }
 
 
 //*****************************************************************************
-int32_t BMI160_SPI::writeBlock(Registers startReg, Registers stopReg, 
+int32_t BMI160_SPI::writeBlock(Registers startReg, Registers stopReg,
 const uint8_t *data)
 {
     int32_t rtnVal = -1;
-    
+
     return rtnVal;
 }