Library for Bosch Sensortech BMI160 IMU

Fork of BMI160 by Justin Jordan

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bmi160.cpp Source File

bmi160.cpp

00001 /**********************************************************************
00002 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
00003 *
00004 * Permission is hereby granted, free of charge, to any person obtaining a
00005 * copy of this software and associated documentation files (the "Software"),
00006 * to deal in the Software without restriction, including without limitation
00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 * and/or sell copies of the Software, and to permit persons to whom the
00009 * Software is furnished to do so, subject to the following conditions:
00010 *
00011 * The above copyright notice and this permission notice shall be included
00012 * in all copies or substantial portions of the Software.
00013 *
00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020 * OTHER DEALINGS IN THE SOFTWARE.
00021 *
00022 * Except as contained in this notice, the name of Maxim Integrated
00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024 * Products, Inc. Branding Policy.
00025 *
00026 * The mere transfer of this software does not imply any licenses
00027 * of trade secrets, proprietary technology, copyrights, patents,
00028 * trademarks, maskwork rights, or any other form of intellectual
00029 * property whatsoever. Maxim Integrated Products, Inc. retains all
00030 * ownership rights.
00031 **********************************************************************/
00032 
00033 
00034 #include "bmi160.h"
00035 
00036 
00037 const struct BMI160::AccConfig BMI160::DEFAULT_ACC_CONFIG = {SENS_2G, 
00038                                                              ACC_US_OFF, 
00039                                                              ACC_BWP_2, 
00040                                                              ACC_ODR_8};
00041                                                              
00042 const struct BMI160::GyroConfig BMI160::DEFAULT_GYRO_CONFIG = {DPS_2000, 
00043                                                                GYRO_BWP_2, 
00044                                                                GYRO_ODR_8};
00045     
00046 
00047 //*****************************************************************************
00048 int32_t BMI160::setSensorPowerMode(Sensors sensor, PowerModes pwrMode)
00049 {
00050     int32_t rtnVal = -1;
00051     
00052     switch(sensor)
00053     {
00054         case MAG:
00055             rtnVal = writeRegister(CMD, (MAG_SET_PMU_MODE | pwrMode));
00056         break;
00057         
00058         case GYRO:
00059             rtnVal = writeRegister(CMD, (GYR_SET_PMU_MODE | pwrMode));
00060         break;
00061         
00062         case ACC:
00063             rtnVal = writeRegister(CMD, (ACC_SET_PMU_MODE | pwrMode));
00064         break;
00065         
00066         default:
00067             rtnVal = -1;
00068         break;
00069     }
00070     
00071     return rtnVal;
00072 }
00073 
00074 
00075 //*****************************************************************************
00076 int32_t BMI160::setSensorConfig(const AccConfig &config)
00077 {
00078     uint8_t data[2];
00079     
00080     data[0] = ((config.us << ACC_US_POS) | (config.bwp << ACC_BWP_POS) | 
00081                (config.odr << ACC_ODR_POS));
00082     data[1] = config.range;
00083     
00084     return writeBlock(ACC_CONF, ACC_RANGE, data);
00085 }
00086 
00087 
00088 //*****************************************************************************
00089 int32_t BMI160::setSensorConfig(const GyroConfig &config)
00090 {
00091     uint8_t data[2];
00092     
00093     data[0] = ((config.bwp << GYRO_BWP_POS) | (config.odr << GYRO_ODR_POS));
00094     data[1] = config.range;
00095     
00096     return writeBlock(GYR_CONF, GYR_RANGE, data);
00097 }
00098 
00099 
00100 //*****************************************************************************
00101 int32_t BMI160::getSensorConfig(AccConfig &config)
00102 {
00103     uint8_t data[2];
00104     int32_t rtnVal = readBlock(ACC_CONF, ACC_RANGE, data);
00105     
00106     if(rtnVal == RTN_NO_ERROR)
00107     {
00108         config.range = static_cast<BMI160::AccRange>(
00109         (data[1] & ACC_RANGE_MASK));
00110         config.us = static_cast<BMI160::AccUnderSampling>(
00111         ((data[0] & ACC_US_MASK) >> ACC_US_POS));
00112         config.bwp = static_cast<BMI160::AccBandWidthParam>(
00113         ((data[0] & ACC_BWP_MASK) >> ACC_BWP_POS));
00114         config.odr = static_cast<BMI160::AccOutputDataRate>(
00115         ((data[0] & ACC_ODR_MASK) >> ACC_ODR_POS));
00116     }
00117     
00118     return rtnVal;
00119 }
00120 
00121 
00122 //*****************************************************************************
00123 int32_t BMI160::getSensorConfig(GyroConfig &config)
00124 {
00125     uint8_t data[2];
00126     int32_t rtnVal = readBlock(GYR_CONF, GYR_RANGE, data);
00127     
00128     if(rtnVal == RTN_NO_ERROR)
00129     {
00130         config.range = static_cast<BMI160::GyroRange>(
00131         (data[1] & GYRO_RANGE_MASK));
00132         config.bwp = static_cast<BMI160::GyroBandWidthParam>(
00133         ((data[0] & GYRO_BWP_MASK) >> GYRO_BWP_POS));
00134         config.odr = static_cast<BMI160::GyroOutputDataRate>(
00135         ((data[0] & GYRO_ODR_MASK) >> GYRO_ODR_POS));
00136     }
00137     
00138     return rtnVal;
00139 }
00140 
00141 
00142 //*****************************************************************************
00143 int32_t BMI160::getSensorAxis(SensorAxis axis, AxisData &data, AccRange range)
00144 {
00145     uint8_t localData[2];
00146     int32_t rtnVal;
00147     
00148     switch(axis)
00149     {
00150         case X_AXIS:
00151             rtnVal = readBlock(DATA_14, DATA_15, localData);
00152         break;
00153         
00154         case Y_AXIS:
00155             rtnVal = readBlock(DATA_16, DATA_17, localData);
00156         break;
00157         
00158         case Z_AXIS:
00159             rtnVal = readBlock(DATA_18, DATA_19, localData);
00160         break;
00161         
00162         default:
00163             rtnVal = -1;
00164         break;
00165     }
00166     
00167     if(rtnVal == RTN_NO_ERROR)
00168     {
00169         data.raw = ((localData[1] << 8) | localData[0]);
00170         switch(range)
00171         {
00172             case SENS_2G:
00173                 data.scaled = (data.raw/SENS_2G_LSB_PER_G);
00174             break;
00175             
00176             case SENS_4G:
00177                 data.scaled = (data.raw/SENS_4G_LSB_PER_G);
00178             break;
00179             
00180             case SENS_8G:
00181                 data.scaled = (data.raw/SENS_8G_LSB_PER_G);
00182             break;
00183             
00184             case SENS_16G:
00185                 data.scaled = (data.raw/SENS_16G_LSB_PER_G);
00186             break;
00187         }
00188     }
00189     
00190     return rtnVal;
00191 }
00192 
00193 
00194 //*****************************************************************************
00195 int32_t BMI160::getSensorAxis(SensorAxis axis, AxisData &data, GyroRange range)
00196 {
00197     uint8_t localData[2];
00198     int32_t rtnVal;
00199     
00200     switch(axis)
00201     {
00202         case X_AXIS:
00203             rtnVal = readBlock(DATA_8, DATA_9, localData);
00204         break;
00205         
00206         case Y_AXIS:
00207             rtnVal = readBlock(DATA_10, DATA_11, localData);
00208         break;
00209         
00210         case Z_AXIS:
00211             rtnVal = readBlock(DATA_12, DATA_13, localData);
00212         break;
00213         
00214         default:
00215             rtnVal = -1;
00216         break;
00217     }
00218     
00219     if(rtnVal == RTN_NO_ERROR)
00220     {
00221         data.raw = ((localData[1] << 8) | localData[0]);
00222         switch(range)
00223         {
00224             case DPS_2000:
00225                 data.scaled = (data.raw/SENS_2000_DPS_LSB_PER_DPS);
00226             break;
00227             
00228             case DPS_1000:
00229                 data.scaled = (data.raw/SENS_1000_DPS_LSB_PER_DPS);
00230             break;
00231             
00232             case DPS_500:
00233                 data.scaled = (data.raw/SENS_500_DPS_LSB_PER_DPS);
00234             break;
00235             
00236             case DPS_250:
00237                 data.scaled = (data.raw/SENS_250_DPS_LSB_PER_DPS);
00238             break;
00239             
00240             case DPS_125:
00241                 data.scaled = (data.raw/SENS_125_DPS_LSB_PER_DPS);
00242             break;
00243         }
00244     }
00245     
00246     return rtnVal;
00247 }
00248     
00249 
00250 //*****************************************************************************    
00251 int32_t BMI160::getSensorXYZ(SensorData &data, AccRange range)
00252 {
00253     uint8_t localData[6];
00254     int32_t rtnVal = readBlock(DATA_14, DATA_19, localData);
00255     
00256     if(rtnVal == RTN_NO_ERROR)
00257     {
00258         data.xAxis.raw = ((localData[1] << 8) | localData[0]);
00259         data.yAxis.raw = ((localData[3] << 8) | localData[2]);
00260         data.zAxis.raw = ((localData[5] << 8) | localData[4]);
00261         
00262         switch(range)
00263         {
00264             case SENS_2G:
00265                 data.xAxis.scaled = (data.xAxis.raw/SENS_2G_LSB_PER_G);
00266                 data.yAxis.scaled = (data.yAxis.raw/SENS_2G_LSB_PER_G);
00267                 data.zAxis.scaled = (data.zAxis.raw/SENS_2G_LSB_PER_G);
00268             break;
00269             
00270             case SENS_4G:
00271                 data.xAxis.scaled = (data.xAxis.raw/SENS_4G_LSB_PER_G);
00272                 data.yAxis.scaled = (data.yAxis.raw/SENS_4G_LSB_PER_G);
00273                 data.zAxis.scaled = (data.zAxis.raw/SENS_4G_LSB_PER_G);
00274             break;
00275             
00276             case SENS_8G:
00277                 data.xAxis.scaled = (data.xAxis.raw/SENS_8G_LSB_PER_G);
00278                 data.yAxis.scaled = (data.yAxis.raw/SENS_8G_LSB_PER_G);
00279                 data.zAxis.scaled = (data.zAxis.raw/SENS_8G_LSB_PER_G);
00280             break;
00281             
00282             case SENS_16G:
00283                 data.xAxis.scaled = (data.xAxis.raw/SENS_16G_LSB_PER_G);
00284                 data.yAxis.scaled = (data.yAxis.raw/SENS_16G_LSB_PER_G);
00285                 data.zAxis.scaled = (data.zAxis.raw/SENS_16G_LSB_PER_G);
00286             break;
00287         }
00288     }
00289     
00290     return rtnVal;
00291 }
00292 
00293 
00294 //*****************************************************************************    
00295 int32_t BMI160::getSensorXYZ(SensorData &data, GyroRange range)
00296 {
00297     uint8_t localData[6];
00298     int32_t rtnVal = readBlock(DATA_8, DATA_13, localData);
00299     
00300     if(rtnVal == RTN_NO_ERROR)
00301     {
00302         data.xAxis.raw = ((localData[1] << 8) | localData[0]);
00303         data.yAxis.raw = ((localData[3] << 8) | localData[2]);
00304         data.zAxis.raw = ((localData[5] << 8) | localData[4]);
00305         
00306         switch(range)
00307         {
00308             case DPS_2000:
00309                 data.xAxis.scaled = (data.xAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
00310                 data.yAxis.scaled = (data.yAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
00311                 data.zAxis.scaled = (data.zAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
00312             break;
00313             
00314             case DPS_1000:
00315                 data.xAxis.scaled = (data.xAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
00316                 data.yAxis.scaled = (data.yAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
00317                 data.zAxis.scaled = (data.zAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
00318             break;
00319             
00320             case DPS_500:
00321                 data.xAxis.scaled = (data.xAxis.raw/SENS_500_DPS_LSB_PER_DPS);
00322                 data.yAxis.scaled = (data.yAxis.raw/SENS_500_DPS_LSB_PER_DPS);
00323                 data.zAxis.scaled = (data.zAxis.raw/SENS_500_DPS_LSB_PER_DPS);
00324             break;
00325             
00326             case DPS_250:
00327                 data.xAxis.scaled = (data.xAxis.raw/SENS_250_DPS_LSB_PER_DPS);
00328                 data.yAxis.scaled = (data.yAxis.raw/SENS_250_DPS_LSB_PER_DPS);
00329                 data.zAxis.scaled = (data.zAxis.raw/SENS_250_DPS_LSB_PER_DPS);
00330             break;
00331             
00332             case DPS_125:
00333                 data.xAxis.scaled = (data.xAxis.raw/SENS_125_DPS_LSB_PER_DPS);
00334                 data.yAxis.scaled = (data.yAxis.raw/SENS_125_DPS_LSB_PER_DPS);
00335                 data.zAxis.scaled = (data.zAxis.raw/SENS_125_DPS_LSB_PER_DPS);
00336             break;
00337         }
00338     }
00339     
00340     return rtnVal;
00341 }
00342 
00343 
00344 //***************************************************************************** 
00345 int32_t BMI160::getSensorXYZandSensorTime(SensorData &data, 
00346                                           SensorTime &sensorTime, 
00347                                           AccRange range)
00348 {
00349     uint8_t localData[9];
00350     int32_t rtnVal = readBlock(DATA_14, SENSORTIME_2, localData);
00351     if(rtnVal == RTN_NO_ERROR)
00352     {
00353         data.xAxis.raw = ((localData[1] << 8) | localData[0]);
00354         data.yAxis.raw = ((localData[3] << 8) | localData[2]);
00355         data.zAxis.raw = ((localData[5] << 8) | localData[4]);
00356         
00357         switch(range)
00358         {
00359             case SENS_2G:
00360                 data.xAxis.scaled = (data.xAxis.raw/SENS_2G_LSB_PER_G);
00361                 data.yAxis.scaled = (data.yAxis.raw/SENS_2G_LSB_PER_G);
00362                 data.zAxis.scaled = (data.zAxis.raw/SENS_2G_LSB_PER_G);
00363             break;
00364             
00365             case SENS_4G:
00366                 data.xAxis.scaled = (data.xAxis.raw/SENS_4G_LSB_PER_G);
00367                 data.yAxis.scaled = (data.yAxis.raw/SENS_4G_LSB_PER_G);
00368                 data.zAxis.scaled = (data.zAxis.raw/SENS_4G_LSB_PER_G);
00369             break;
00370             
00371             case SENS_8G:
00372                 data.xAxis.scaled = (data.xAxis.raw/SENS_8G_LSB_PER_G);
00373                 data.yAxis.scaled = (data.yAxis.raw/SENS_8G_LSB_PER_G);
00374                 data.zAxis.scaled = (data.zAxis.raw/SENS_8G_LSB_PER_G);
00375             break;
00376             
00377             case SENS_16G:
00378                 data.xAxis.scaled = (data.xAxis.raw/SENS_16G_LSB_PER_G);
00379                 data.yAxis.scaled = (data.yAxis.raw/SENS_16G_LSB_PER_G);
00380                 data.zAxis.scaled = (data.zAxis.raw/SENS_16G_LSB_PER_G);
00381             break;
00382         }
00383         
00384         sensorTime.raw = ((localData[8] << 16) | (localData[7] << 8) | 
00385                            localData[6]);
00386         sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
00387     }
00388     
00389     return rtnVal;
00390 }
00391 
00392 
00393 //***************************************************************************** 
00394 int32_t BMI160::getSensorXYZandSensorTime(SensorData &data, 
00395                                           SensorTime &sensorTime, 
00396                                           GyroRange range)
00397 {
00398     uint8_t localData[16];
00399     int32_t rtnVal = readBlock(DATA_8, SENSORTIME_2, localData);
00400     if(rtnVal == RTN_NO_ERROR)
00401     {
00402         data.xAxis.raw = ((localData[1] << 8) | localData[0]);
00403         data.yAxis.raw = ((localData[3] << 8) | localData[2]);
00404         data.zAxis.raw = ((localData[5] << 8) | localData[4]);
00405         
00406         switch(range)
00407         {
00408             case DPS_2000:
00409                 data.xAxis.scaled = (data.xAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
00410                 data.yAxis.scaled = (data.yAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
00411                 data.zAxis.scaled = (data.zAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
00412             break;
00413             
00414             case DPS_1000:
00415                 data.xAxis.scaled = (data.xAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
00416                 data.yAxis.scaled = (data.yAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
00417                 data.zAxis.scaled = (data.zAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
00418             break;
00419             
00420             case DPS_500:
00421                 data.xAxis.scaled = (data.xAxis.raw/SENS_500_DPS_LSB_PER_DPS);
00422                 data.yAxis.scaled = (data.yAxis.raw/SENS_500_DPS_LSB_PER_DPS);
00423                 data.zAxis.scaled = (data.zAxis.raw/SENS_500_DPS_LSB_PER_DPS);
00424             break;
00425             
00426             case DPS_250:
00427                 data.xAxis.scaled = (data.xAxis.raw/SENS_250_DPS_LSB_PER_DPS);
00428                 data.yAxis.scaled = (data.yAxis.raw/SENS_250_DPS_LSB_PER_DPS);
00429                 data.zAxis.scaled = (data.zAxis.raw/SENS_250_DPS_LSB_PER_DPS);
00430             break;
00431             
00432             case DPS_125:
00433                 data.xAxis.scaled = (data.xAxis.raw/SENS_125_DPS_LSB_PER_DPS);
00434                 data.yAxis.scaled = (data.yAxis.raw/SENS_125_DPS_LSB_PER_DPS);
00435                 data.zAxis.scaled = (data.zAxis.raw/SENS_125_DPS_LSB_PER_DPS);
00436             break;
00437         }
00438         
00439         sensorTime.raw = ((localData[14] << 16) | (localData[13] << 8) | 
00440                            localData[12]);
00441         sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
00442     }
00443     
00444     return rtnVal;
00445 }
00446 
00447 
00448 //***************************************************************************** 
00449 int32_t BMI160::getGyroAccXYZandSensorTime(SensorData &accData, 
00450                                            SensorData &gyroData, 
00451                                            SensorTime &sensorTime, 
00452                                            AccRange accRange, 
00453                                            GyroRange gyroRange)
00454 {
00455     uint8_t localData[16];
00456     int32_t rtnVal = readBlock(DATA_8, SENSORTIME_2, localData);
00457     if(rtnVal == RTN_NO_ERROR)
00458     {
00459         gyroData.xAxis.raw = ((localData[1] << 8) | localData[0]);
00460         gyroData.yAxis.raw = ((localData[3] << 8) | localData[2]);
00461         gyroData.zAxis.raw = ((localData[5] << 8) | localData[4]);
00462         
00463         accData.xAxis.raw = ((localData[7] << 8) | localData[6]);
00464         accData.yAxis.raw = ((localData[9] << 8) | localData[8]);
00465         accData.zAxis.raw = ((localData[11] << 8) | localData[10]);
00466         
00467         switch(gyroRange)
00468         {
00469             case DPS_2000:
00470                 gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
00471                 gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
00472                 gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_2000_DPS_LSB_PER_DPS);
00473             break;
00474             
00475             case DPS_1000:
00476                 gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
00477                 gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
00478                 gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_1000_DPS_LSB_PER_DPS);
00479             break;
00480             
00481             case DPS_500:
00482                 gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_500_DPS_LSB_PER_DPS);
00483                 gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_500_DPS_LSB_PER_DPS);
00484                 gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_500_DPS_LSB_PER_DPS);
00485             break;
00486             
00487             case DPS_250:
00488                 gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_250_DPS_LSB_PER_DPS);
00489                 gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_250_DPS_LSB_PER_DPS);
00490                 gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_250_DPS_LSB_PER_DPS);
00491             break;
00492             
00493             case DPS_125:
00494                 gyroData.xAxis.scaled = (gyroData.xAxis.raw/SENS_125_DPS_LSB_PER_DPS);
00495                 gyroData.yAxis.scaled = (gyroData.yAxis.raw/SENS_125_DPS_LSB_PER_DPS);
00496                 gyroData.zAxis.scaled = (gyroData.zAxis.raw/SENS_125_DPS_LSB_PER_DPS);
00497             break;
00498         }
00499         
00500         switch(accRange)
00501         {
00502             case SENS_2G:
00503                 accData.xAxis.scaled = (accData.xAxis.raw/SENS_2G_LSB_PER_G);
00504                 accData.yAxis.scaled = (accData.yAxis.raw/SENS_2G_LSB_PER_G);
00505                 accData.zAxis.scaled = (accData.zAxis.raw/SENS_2G_LSB_PER_G);
00506             break;
00507             
00508             case SENS_4G:
00509                 accData.xAxis.scaled = (accData.xAxis.raw/SENS_4G_LSB_PER_G);
00510                 accData.yAxis.scaled = (accData.yAxis.raw/SENS_4G_LSB_PER_G);
00511                 accData.zAxis.scaled = (accData.zAxis.raw/SENS_4G_LSB_PER_G);
00512             break;
00513             
00514             case SENS_8G:
00515                 accData.xAxis.scaled = (accData.xAxis.raw/SENS_8G_LSB_PER_G);
00516                 accData.yAxis.scaled = (accData.yAxis.raw/SENS_8G_LSB_PER_G);
00517                 accData.zAxis.scaled = (accData.zAxis.raw/SENS_8G_LSB_PER_G);
00518             break;
00519             
00520             case SENS_16G:
00521                 accData.xAxis.scaled = (accData.xAxis.raw/SENS_16G_LSB_PER_G);
00522                 accData.yAxis.scaled = (accData.yAxis.raw/SENS_16G_LSB_PER_G);
00523                 accData.zAxis.scaled = (accData.zAxis.raw/SENS_16G_LSB_PER_G);
00524             break;
00525         }
00526         
00527         sensorTime.raw = ((localData[14] << 16) | (localData[13] << 8) | 
00528                            localData[12]);
00529         sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
00530     }
00531     
00532     return rtnVal;
00533 }
00534 
00535 
00536 //***************************************************************************** 
00537 int32_t BMI160::getSensorTime(SensorTime &sensorTime)
00538 {
00539     uint8_t localData[3];
00540     int32_t rtnVal = readBlock(SENSORTIME_0, SENSORTIME_2, localData);
00541     
00542     if(rtnVal == RTN_NO_ERROR)
00543     {
00544         sensorTime.raw = ((localData[2] << 16) | (localData[1] << 8) | 
00545                            localData[0]);
00546         sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
00547     }
00548     
00549     return rtnVal;
00550 }
00551 
00552 
00553 //*****************************************************************************
00554 int32_t BMI160::getTemperature(float *temp)
00555 {
00556     uint8_t data[2];
00557     uint16_t rawTemp;
00558     
00559     int32_t rtnVal = readBlock(TEMPERATURE_0, TEMPERATURE_1, data);
00560     if(rtnVal == RTN_NO_ERROR)
00561     {
00562         rawTemp = ((data[1] << 8) | data[0]);
00563         if(rawTemp & 0x8000)
00564         {
00565             *temp = (23.0F - ((0x10000 - rawTemp)/512.0F));
00566         }
00567         else
00568         {
00569             *temp = ((rawTemp/512.0F) + 23.0F);
00570         }
00571     }
00572     
00573     return rtnVal;
00574 }