BMI160 Initial

Dependents:   MAX32630HSP3_IMU_HelloWorld MAX32630HSP3_IMU_HelloWorld MAX32630HSP3_Pitch_Charles Maxim_Squeeks

Committer:
j3
Date:
Tue Dec 20 21:20:22 2016 +0000
Revision:
15:dc35ccc0b08e
Parent:
14:646eb94fa2eb
Child:
16:12782f5d4aa4
working

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 case SENS_2G:
j3 15:dc35ccc0b08e 134 data.scaled = (data.raw/SENS_2G_LSB_PER_G);
j3 9:ca6b5fecdd63 135 break;
j3 9:ca6b5fecdd63 136
j3 9:ca6b5fecdd63 137 case SENS_4G:
j3 15:dc35ccc0b08e 138 data.scaled = (data.raw/SENS_4G_LSB_PER_G);
j3 9:ca6b5fecdd63 139 break;
j3 9:ca6b5fecdd63 140
j3 9:ca6b5fecdd63 141 case SENS_8G:
j3 15:dc35ccc0b08e 142 data.scaled = (data.raw/SENS_8G_LSB_PER_G);
j3 9:ca6b5fecdd63 143 break;
j3 9:ca6b5fecdd63 144
j3 9:ca6b5fecdd63 145 case SENS_16G:
j3 15:dc35ccc0b08e 146 data.scaled = (data.raw/SENS_16G_LSB_PER_G);
j3 9:ca6b5fecdd63 147 break;
j3 9:ca6b5fecdd63 148 }
j3 8:a89b529b1d96 149 }
j3 8:a89b529b1d96 150
j3 8:a89b529b1d96 151 return rtnVal;
j3 8:a89b529b1d96 152 }
j3 8:a89b529b1d96 153
j3 8:a89b529b1d96 154
j3 8:a89b529b1d96 155 //*****************************************************************************
j3 12:64931a80340d 156 int32_t BMI160::getAccXYZ(SensorData &data, AccRange range)
j3 8:a89b529b1d96 157 {
j3 8:a89b529b1d96 158 uint8_t localData[6];
j3 8:a89b529b1d96 159 int32_t rtnVal = readBlock(DATA_14, DATA_19, localData);
j3 8:a89b529b1d96 160
j3 8:a89b529b1d96 161 if(rtnVal == RTN_NO_ERROR)
j3 8:a89b529b1d96 162 {
j3 8:a89b529b1d96 163 data.xAxis.raw = ((localData[1] << 8) | localData[0]);
j3 8:a89b529b1d96 164 data.yAxis.raw = ((localData[3] << 8) | localData[2]);
j3 8:a89b529b1d96 165 data.zAxis.raw = ((localData[5] << 8) | localData[4]);
j3 8:a89b529b1d96 166
j3 12:64931a80340d 167 switch(range)
j3 9:ca6b5fecdd63 168 {
j3 9:ca6b5fecdd63 169 case SENS_2G:
j3 15:dc35ccc0b08e 170 data.xAxis.scaled = (data.xAxis.raw/SENS_2G_LSB_PER_G);
j3 15:dc35ccc0b08e 171 data.yAxis.scaled = (data.yAxis.raw/SENS_2G_LSB_PER_G);
j3 15:dc35ccc0b08e 172 data.zAxis.scaled = (data.zAxis.raw/SENS_2G_LSB_PER_G);
j3 9:ca6b5fecdd63 173 break;
j3 9:ca6b5fecdd63 174
j3 9:ca6b5fecdd63 175 case SENS_4G:
j3 15:dc35ccc0b08e 176 data.xAxis.scaled = (data.xAxis.raw/SENS_4G_LSB_PER_G);
j3 15:dc35ccc0b08e 177 data.yAxis.scaled = (data.yAxis.raw/SENS_4G_LSB_PER_G);
j3 15:dc35ccc0b08e 178 data.zAxis.scaled = (data.zAxis.raw/SENS_4G_LSB_PER_G);
j3 9:ca6b5fecdd63 179 break;
j3 9:ca6b5fecdd63 180
j3 9:ca6b5fecdd63 181 case SENS_8G:
j3 15:dc35ccc0b08e 182 data.xAxis.scaled = (data.xAxis.raw/SENS_8G_LSB_PER_G);
j3 15:dc35ccc0b08e 183 data.yAxis.scaled = (data.yAxis.raw/SENS_8G_LSB_PER_G);
j3 15:dc35ccc0b08e 184 data.zAxis.scaled = (data.zAxis.raw/SENS_8G_LSB_PER_G);
j3 9:ca6b5fecdd63 185 break;
j3 9:ca6b5fecdd63 186
j3 9:ca6b5fecdd63 187 case SENS_16G:
j3 15:dc35ccc0b08e 188 data.xAxis.scaled = (data.xAxis.raw/SENS_16G_LSB_PER_G);
j3 15:dc35ccc0b08e 189 data.yAxis.scaled = (data.yAxis.raw/SENS_16G_LSB_PER_G);
j3 15:dc35ccc0b08e 190 data.zAxis.scaled = (data.zAxis.raw/SENS_16G_LSB_PER_G);
j3 9:ca6b5fecdd63 191 break;
j3 9:ca6b5fecdd63 192 }
j3 8:a89b529b1d96 193 }
j3 8:a89b529b1d96 194
j3 8:a89b529b1d96 195 return rtnVal;
j3 8:a89b529b1d96 196 }
j3 10:9e219f2f1fb3 197
j3 10:9e219f2f1fb3 198
j3 10:9e219f2f1fb3 199 //*****************************************************************************
j3 15:dc35ccc0b08e 200 int32_t BMI160::getAccXYZandSensorTime(SensorData &data, SensorTime &sensorTime, AccRange range)
j3 15:dc35ccc0b08e 201 {
j3 15:dc35ccc0b08e 202 uint8_t localData[9];
j3 15:dc35ccc0b08e 203 int32_t rtnVal = readBlock(DATA_14, SENSORTIME_2, localData);
j3 15:dc35ccc0b08e 204 if(rtnVal == RTN_NO_ERROR)
j3 15:dc35ccc0b08e 205 {
j3 15:dc35ccc0b08e 206 data.xAxis.raw = ((localData[1] << 8) | localData[0]);
j3 15:dc35ccc0b08e 207 data.yAxis.raw = ((localData[3] << 8) | localData[2]);
j3 15:dc35ccc0b08e 208 data.zAxis.raw = ((localData[5] << 8) | localData[4]);
j3 15:dc35ccc0b08e 209
j3 15:dc35ccc0b08e 210 switch(range)
j3 15:dc35ccc0b08e 211 {
j3 15:dc35ccc0b08e 212 case SENS_2G:
j3 15:dc35ccc0b08e 213 data.xAxis.scaled = (data.xAxis.raw/SENS_2G_LSB_PER_G);
j3 15:dc35ccc0b08e 214 data.yAxis.scaled = (data.yAxis.raw/SENS_2G_LSB_PER_G);
j3 15:dc35ccc0b08e 215 data.zAxis.scaled = (data.zAxis.raw/SENS_2G_LSB_PER_G);
j3 15:dc35ccc0b08e 216 break;
j3 15:dc35ccc0b08e 217
j3 15:dc35ccc0b08e 218 case SENS_4G:
j3 15:dc35ccc0b08e 219 data.xAxis.scaled = (data.xAxis.raw/SENS_4G_LSB_PER_G);
j3 15:dc35ccc0b08e 220 data.yAxis.scaled = (data.yAxis.raw/SENS_4G_LSB_PER_G);
j3 15:dc35ccc0b08e 221 data.zAxis.scaled = (data.zAxis.raw/SENS_4G_LSB_PER_G);
j3 15:dc35ccc0b08e 222 break;
j3 15:dc35ccc0b08e 223
j3 15:dc35ccc0b08e 224 case SENS_8G:
j3 15:dc35ccc0b08e 225 data.xAxis.scaled = (data.xAxis.raw/SENS_8G_LSB_PER_G);
j3 15:dc35ccc0b08e 226 data.yAxis.scaled = (data.yAxis.raw/SENS_8G_LSB_PER_G);
j3 15:dc35ccc0b08e 227 data.zAxis.scaled = (data.zAxis.raw/SENS_8G_LSB_PER_G);
j3 15:dc35ccc0b08e 228 break;
j3 15:dc35ccc0b08e 229
j3 15:dc35ccc0b08e 230 case SENS_16G:
j3 15:dc35ccc0b08e 231 data.xAxis.scaled = (data.xAxis.raw/SENS_16G_LSB_PER_G);
j3 15:dc35ccc0b08e 232 data.yAxis.scaled = (data.yAxis.raw/SENS_16G_LSB_PER_G);
j3 15:dc35ccc0b08e 233 data.zAxis.scaled = (data.zAxis.raw/SENS_16G_LSB_PER_G);
j3 15:dc35ccc0b08e 234 break;
j3 15:dc35ccc0b08e 235 }
j3 15:dc35ccc0b08e 236
j3 15:dc35ccc0b08e 237 sensorTime.raw = ((localData[8] << 16) | (localData[7] << 8) |
j3 15:dc35ccc0b08e 238 localData[6]);
j3 15:dc35ccc0b08e 239 sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
j3 15:dc35ccc0b08e 240 }
j3 15:dc35ccc0b08e 241
j3 15:dc35ccc0b08e 242 return rtnVal;
j3 15:dc35ccc0b08e 243 }
j3 15:dc35ccc0b08e 244
j3 15:dc35ccc0b08e 245
j3 15:dc35ccc0b08e 246 //*****************************************************************************
j3 15:dc35ccc0b08e 247 int32_t BMI160::getSensorTime(SensorTime &sensorTime)
j3 10:9e219f2f1fb3 248 {
j3 10:9e219f2f1fb3 249 uint8_t localData[3];
j3 10:9e219f2f1fb3 250 int32_t rtnVal = readBlock(SENSORTIME_0, SENSORTIME_2, localData);
j3 10:9e219f2f1fb3 251
j3 10:9e219f2f1fb3 252 if(rtnVal == RTN_NO_ERROR)
j3 10:9e219f2f1fb3 253 {
j3 15:dc35ccc0b08e 254 sensorTime.raw = ((localData[2] << 16) | (localData[1] << 8) |
j3 15:dc35ccc0b08e 255 localData[0]);
j3 15:dc35ccc0b08e 256 sensorTime.seconds = (sensorTime.raw * SENSOR_TIME_LSB);
j3 10:9e219f2f1fb3 257 }
j3 10:9e219f2f1fb3 258
j3 10:9e219f2f1fb3 259 return rtnVal;
j3 10:9e219f2f1fb3 260 }
j3 10:9e219f2f1fb3 261
j3 12:64931a80340d 262
j3 12:64931a80340d 263 //*****************************************************************************
j3 12:64931a80340d 264 int32_t BMI160::getTemperature(float *temp)
j3 12:64931a80340d 265 {
j3 12:64931a80340d 266 uint8_t data[2];
j3 12:64931a80340d 267 uint16_t rawTemp;
j3 12:64931a80340d 268
j3 12:64931a80340d 269 int32_t rtnVal = readBlock(TEMPERATURE_0, TEMPERATURE_1, data);
j3 12:64931a80340d 270 if(rtnVal == RTN_NO_ERROR)
j3 12:64931a80340d 271 {
j3 12:64931a80340d 272 rawTemp = ((data[1] << 8) | data[0]);
j3 12:64931a80340d 273 if(rawTemp & 0x8000)
j3 12:64931a80340d 274 {
j3 12:64931a80340d 275 *temp = (23.0F - ((0x10000 - rawTemp)/512.0F));
j3 12:64931a80340d 276 }
j3 12:64931a80340d 277 else
j3 12:64931a80340d 278 {
j3 12:64931a80340d 279 *temp = ((rawTemp/512.0F) + 23.0F);
j3 12:64931a80340d 280 }
j3 12:64931a80340d 281 }
j3 12:64931a80340d 282
j3 12:64931a80340d 283 return rtnVal;
j3 12:64931a80340d 284 }