Library for Bosch Sensortech BMI160 IMU

Dependents:   MAX32630FTHR_BALANCE_BOT MPSMAX_copy MAX32630FTHR_BALANCE_BOT SELF_BALANCING_BOT

Committer:
j3
Date:
Tue Dec 20 19:32:26 2016 +0000
Revision:
14:646eb94fa2eb
Parent:
12:64931a80340d
Child:
15:dc35ccc0b08e
working on docs

Who changed what in which revision?

UserRevisionLine numberNew contents of line
j3 3:e1770675eca4 1 /**********************************************************************
j3 3:e1770675eca4 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
j3 3:e1770675eca4 3 *
j3 3:e1770675eca4 4 * Permission is hereby granted, free of charge, to any person obtaining a
j3 3:e1770675eca4 5 * copy of this software and associated documentation files (the "Software"),
j3 3:e1770675eca4 6 * to deal in the Software without restriction, including without limitation
j3 3:e1770675eca4 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
j3 3:e1770675eca4 8 * and/or sell copies of the Software, and to permit persons to whom the
j3 3:e1770675eca4 9 * Software is furnished to do so, subject to the following conditions:
j3 3:e1770675eca4 10 *
j3 3:e1770675eca4 11 * The above copyright notice and this permission notice shall be included
j3 3:e1770675eca4 12 * in all copies or substantial portions of the Software.
j3 3:e1770675eca4 13 *
j3 3:e1770675eca4 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
j3 3:e1770675eca4 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
j3 3:e1770675eca4 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
j3 3:e1770675eca4 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
j3 3:e1770675eca4 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
j3 3:e1770675eca4 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
j3 3:e1770675eca4 20 * OTHER DEALINGS IN THE SOFTWARE.
j3 3:e1770675eca4 21 *
j3 3:e1770675eca4 22 * Except as contained in this notice, the name of Maxim Integrated
j3 3:e1770675eca4 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
j3 3:e1770675eca4 24 * Products, Inc. Branding Policy.
j3 3:e1770675eca4 25 *
j3 3:e1770675eca4 26 * The mere transfer of this software does not imply any licenses
j3 3:e1770675eca4 27 * of trade secrets, proprietary technology, copyrights, patents,
j3 3:e1770675eca4 28 * trademarks, maskwork rights, or any other form of intellectual
j3 3:e1770675eca4 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
j3 3:e1770675eca4 30 * ownership rights.
j3 3:e1770675eca4 31 **********************************************************************/
j3 3:e1770675eca4 32
j3 3:e1770675eca4 33
j3 3:e1770675eca4 34 #include "bmi160.h"
j3 3:e1770675eca4 35
j3 3:e1770675eca4 36
j3 9:ca6b5fecdd63 37 const struct BMI160::AccConfig BMI160::DEFAULT_ACC_CONFIG = {SENS_2G, ACC_US_OFF, ACC_BWP_2, ACC_ODR_8};
j3 9:ca6b5fecdd63 38
j3 9:ca6b5fecdd63 39
j3 3:e1770675eca4 40 //*****************************************************************************
j3 5:35e032c8d8aa 41 int32_t BMI160::setSensorPowerMode(Sensors sensor, PowerModes pwrMode)
j3 3:e1770675eca4 42 {
j3 3:e1770675eca4 43 int32_t rtnVal = -1;
j3 3:e1770675eca4 44
j3 5:35e032c8d8aa 45 switch(sensor)
j3 5:35e032c8d8aa 46 {
j3 5:35e032c8d8aa 47 case MAG:
j3 5:35e032c8d8aa 48 rtnVal = writeRegister(CMD, (MAG_SET_PMU_MODE | pwrMode));
j3 5:35e032c8d8aa 49 break;
j3 5:35e032c8d8aa 50
j3 5:35e032c8d8aa 51 case GYRO:
j3 5:35e032c8d8aa 52 rtnVal = writeRegister(CMD, (GYR_SET_PMU_MODE | pwrMode));
j3 5:35e032c8d8aa 53 break;
j3 5:35e032c8d8aa 54
j3 5:35e032c8d8aa 55 case ACC:
j3 5:35e032c8d8aa 56 rtnVal = writeRegister(CMD, (ACC_SET_PMU_MODE | pwrMode));
j3 5:35e032c8d8aa 57 break;
j3 5:35e032c8d8aa 58
j3 5:35e032c8d8aa 59 default:
j3 5:35e032c8d8aa 60 rtnVal = -1;
j3 5:35e032c8d8aa 61 break;
j3 5:35e032c8d8aa 62 }
j3 5:35e032c8d8aa 63
j3 3:e1770675eca4 64 return rtnVal;
j3 3:e1770675eca4 65 }
j3 5:35e032c8d8aa 66
j3 5:35e032c8d8aa 67
j3 5:35e032c8d8aa 68 //*****************************************************************************
j3 14:646eb94fa2eb 69 int32_t BMI160::setAccConfig(const AccConfig &config)
j3 5:35e032c8d8aa 70 {
j3 5:35e032c8d8aa 71 uint8_t data[2];
j3 5:35e032c8d8aa 72
j3 14:646eb94fa2eb 73 data[0] = ((config.us << ACC_US_POS) | (config.bwp << ACC_BWP_POS) |
j3 14:646eb94fa2eb 74 (config.odr << ACC_ODR_POS));
j3 14:646eb94fa2eb 75 data[1] = config.range;
j3 12:64931a80340d 76
j3 14:646eb94fa2eb 77 return writeBlock(ACC_CONF, ACC_RANGE, data);
j3 14:646eb94fa2eb 78 }
j3 14:646eb94fa2eb 79
j3 14:646eb94fa2eb 80
j3 14:646eb94fa2eb 81 //*****************************************************************************
j3 14:646eb94fa2eb 82 int32_t BMI160::getAccConfig(AccConfig &config)
j3 14:646eb94fa2eb 83 {
j3 14:646eb94fa2eb 84 uint8_t data[2];
j3 14:646eb94fa2eb 85 int32_t rtnVal = readBlock(ACC_CONF, ACC_RANGE, data);
j3 14:646eb94fa2eb 86
j3 14:646eb94fa2eb 87 if(rtnVal == RTN_NO_ERROR)
j3 14:646eb94fa2eb 88 {
j3 14:646eb94fa2eb 89 config.range = static_cast<BMI160::AccRange>(
j3 14:646eb94fa2eb 90 (data[1] & ACC_RANGE_MASK));
j3 14:646eb94fa2eb 91 config.us = static_cast<BMI160::AccUnderSampling>(
j3 14:646eb94fa2eb 92 ((data[0] & ACC_US_MASK) >> ACC_US_POS));
j3 14:646eb94fa2eb 93 config.bwp = static_cast<BMI160::AccBandWidthParam>(
j3 14:646eb94fa2eb 94 ((data[0] & ACC_BWP_MASK) >> ACC_BWP_POS));
j3 14:646eb94fa2eb 95 config.odr = static_cast<BMI160::AccOutPutDataRate>(
j3 14:646eb94fa2eb 96 ((data[0] & ACC_ODR_MASK) >> ACC_ODR_POS));
j3 14:646eb94fa2eb 97 }
j3 5:35e032c8d8aa 98
j3 5:35e032c8d8aa 99 return rtnVal;
j3 5:35e032c8d8aa 100 }
j3 8:a89b529b1d96 101
j3 8:a89b529b1d96 102
j3 8:a89b529b1d96 103 //*****************************************************************************
j3 12:64931a80340d 104 int32_t BMI160::getAccAxis(SensorAxis axis, AxisData &data, AccRange range)
j3 8:a89b529b1d96 105 {
j3 8:a89b529b1d96 106 uint8_t localData[2];
j3 8:a89b529b1d96 107 int32_t rtnVal;
j3 8:a89b529b1d96 108
j3 8:a89b529b1d96 109 switch(axis)
j3 8:a89b529b1d96 110 {
j3 8:a89b529b1d96 111 case X_AXIS:
j3 8:a89b529b1d96 112 rtnVal = readBlock(DATA_14, DATA_15, localData);
j3 8:a89b529b1d96 113 break;
j3 8:a89b529b1d96 114
j3 8:a89b529b1d96 115 case Y_AXIS:
j3 8:a89b529b1d96 116 rtnVal = readBlock(DATA_16, DATA_17, localData);
j3 8:a89b529b1d96 117 break;
j3 8:a89b529b1d96 118
j3 8:a89b529b1d96 119 case Z_AXIS:
j3 8:a89b529b1d96 120 rtnVal = readBlock(DATA_18, DATA_19, localData);
j3 8:a89b529b1d96 121 break;
j3 8:a89b529b1d96 122
j3 8:a89b529b1d96 123 default:
j3 8:a89b529b1d96 124 rtnVal = -1;
j3 8:a89b529b1d96 125 break;
j3 8:a89b529b1d96 126 }
j3 8:a89b529b1d96 127
j3 8:a89b529b1d96 128 if(rtnVal == RTN_NO_ERROR)
j3 8:a89b529b1d96 129 {
j3 8:a89b529b1d96 130 data.raw = ((localData[1] << 8) | localData[0]);
j3 12:64931a80340d 131 switch(range)
j3 9:ca6b5fecdd63 132 {
j3 9:ca6b5fecdd63 133 //magic numbers are typical values for LSB/g from EC table
j3 9:ca6b5fecdd63 134 case SENS_2G:
j3 9:ca6b5fecdd63 135 data.scaled = (data.raw/16384.0F);
j3 9:ca6b5fecdd63 136 break;
j3 9:ca6b5fecdd63 137
j3 9:ca6b5fecdd63 138 case SENS_4G:
j3 9:ca6b5fecdd63 139 data.scaled = (data.raw/8192.0F);
j3 9:ca6b5fecdd63 140 break;
j3 9:ca6b5fecdd63 141
j3 9:ca6b5fecdd63 142 case SENS_8G:
j3 9:ca6b5fecdd63 143 data.scaled = (data.raw/4096.0F);
j3 9:ca6b5fecdd63 144 break;
j3 9:ca6b5fecdd63 145
j3 9:ca6b5fecdd63 146 case SENS_16G:
j3 9:ca6b5fecdd63 147 data.scaled = (data.raw/2048.0F);
j3 9:ca6b5fecdd63 148 break;
j3 9:ca6b5fecdd63 149 }
j3 8:a89b529b1d96 150 }
j3 8:a89b529b1d96 151
j3 8:a89b529b1d96 152 return rtnVal;
j3 8:a89b529b1d96 153 }
j3 8:a89b529b1d96 154
j3 8:a89b529b1d96 155
j3 8:a89b529b1d96 156 //*****************************************************************************
j3 12:64931a80340d 157 int32_t BMI160::getAccXYZ(SensorData &data, AccRange range)
j3 8:a89b529b1d96 158 {
j3 8:a89b529b1d96 159 uint8_t localData[6];
j3 8:a89b529b1d96 160 int32_t rtnVal = readBlock(DATA_14, DATA_19, localData);
j3 8:a89b529b1d96 161
j3 8:a89b529b1d96 162 if(rtnVal == RTN_NO_ERROR)
j3 8:a89b529b1d96 163 {
j3 8:a89b529b1d96 164 data.xAxis.raw = ((localData[1] << 8) | localData[0]);
j3 8:a89b529b1d96 165 data.yAxis.raw = ((localData[3] << 8) | localData[2]);
j3 8:a89b529b1d96 166 data.zAxis.raw = ((localData[5] << 8) | localData[4]);
j3 8:a89b529b1d96 167
j3 12:64931a80340d 168 switch(range)
j3 9:ca6b5fecdd63 169 {
j3 9:ca6b5fecdd63 170 //magic numbers are typical values for LSB/g from EC table
j3 9:ca6b5fecdd63 171 case SENS_2G:
j3 9:ca6b5fecdd63 172 data.xAxis.scaled = (data.xAxis.raw/16384.0F);
j3 9:ca6b5fecdd63 173 data.yAxis.scaled = (data.yAxis.raw/16384.0F);
j3 9:ca6b5fecdd63 174 data.zAxis.scaled = (data.zAxis.raw/16384.0F);
j3 9:ca6b5fecdd63 175 break;
j3 9:ca6b5fecdd63 176
j3 9:ca6b5fecdd63 177 case SENS_4G:
j3 9:ca6b5fecdd63 178 data.xAxis.scaled = (data.xAxis.raw/8192.0F);
j3 9:ca6b5fecdd63 179 data.yAxis.scaled = (data.yAxis.raw/8192.0F);
j3 9:ca6b5fecdd63 180 data.zAxis.scaled = (data.zAxis.raw/8192.0F);
j3 9:ca6b5fecdd63 181 break;
j3 9:ca6b5fecdd63 182
j3 9:ca6b5fecdd63 183 case SENS_8G:
j3 9:ca6b5fecdd63 184 data.xAxis.scaled = (data.xAxis.raw/4096.0F);
j3 9:ca6b5fecdd63 185 data.yAxis.scaled = (data.yAxis.raw/4096.0F);
j3 9:ca6b5fecdd63 186 data.zAxis.scaled = (data.zAxis.raw/4096.0F);
j3 9:ca6b5fecdd63 187 break;
j3 9:ca6b5fecdd63 188
j3 9:ca6b5fecdd63 189 case SENS_16G:
j3 9:ca6b5fecdd63 190 data.xAxis.scaled = (data.xAxis.raw/2048.0F);
j3 9:ca6b5fecdd63 191 data.yAxis.scaled = (data.yAxis.raw/2048.0F);
j3 9:ca6b5fecdd63 192 data.zAxis.scaled = (data.zAxis.raw/2048.0F);
j3 9:ca6b5fecdd63 193 break;
j3 9:ca6b5fecdd63 194 }
j3 8:a89b529b1d96 195 }
j3 8:a89b529b1d96 196
j3 8:a89b529b1d96 197 return rtnVal;
j3 8:a89b529b1d96 198 }
j3 10:9e219f2f1fb3 199
j3 10:9e219f2f1fb3 200
j3 10:9e219f2f1fb3 201 //*****************************************************************************
j3 10:9e219f2f1fb3 202 int32_t BMI160::getSensorTime(float *data)
j3 10:9e219f2f1fb3 203 {
j3 10:9e219f2f1fb3 204 uint8_t localData[3];
j3 10:9e219f2f1fb3 205 int32_t rtnVal = readBlock(SENSORTIME_0, SENSORTIME_2, localData);
j3 10:9e219f2f1fb3 206
j3 10:9e219f2f1fb3 207 if(rtnVal == RTN_NO_ERROR)
j3 10:9e219f2f1fb3 208 {
j3 10:9e219f2f1fb3 209 *data = (((localData[2] << 16) | (localData[1] << 8) | localData[0]) * 39e-6);
j3 10:9e219f2f1fb3 210 }
j3 10:9e219f2f1fb3 211
j3 10:9e219f2f1fb3 212 return rtnVal;
j3 10:9e219f2f1fb3 213 }
j3 10:9e219f2f1fb3 214
j3 12:64931a80340d 215
j3 12:64931a80340d 216 //*****************************************************************************
j3 12:64931a80340d 217 int32_t BMI160::getTemperature(float *temp)
j3 12:64931a80340d 218 {
j3 12:64931a80340d 219 uint8_t data[2];
j3 12:64931a80340d 220 uint16_t rawTemp;
j3 12:64931a80340d 221
j3 12:64931a80340d 222 int32_t rtnVal = readBlock(TEMPERATURE_0, TEMPERATURE_1, data);
j3 12:64931a80340d 223 if(rtnVal == RTN_NO_ERROR)
j3 12:64931a80340d 224 {
j3 12:64931a80340d 225 rawTemp = ((data[1] << 8) | data[0]);
j3 12:64931a80340d 226 if(rawTemp & 0x8000)
j3 12:64931a80340d 227 {
j3 12:64931a80340d 228 *temp = (23.0F - ((0x10000 - rawTemp)/512.0F));
j3 12:64931a80340d 229 }
j3 12:64931a80340d 230 else
j3 12:64931a80340d 231 {
j3 12:64931a80340d 232 *temp = ((rawTemp/512.0F) + 23.0F);
j3 12:64931a80340d 233 }
j3 12:64931a80340d 234 }
j3 12:64931a80340d 235
j3 12:64931a80340d 236 return rtnVal;
j3 12:64931a80340d 237 }