JDI_MIP on ThunderBoardSense2(Silicon-Labs)

JDI_MIP (LPM013M126A) Sample on ThunderBoard2(Silicon-Labs)

/media/uploads/STakayama/mip8_tb2_sample0_.jpg LPM013M126A /media/uploads/STakayama/mip8_tb2_sample1.jpg

Links

https://os.mbed.com/teams/JapanDisplayInc/

https://os.mbed.com/teams/JapanDisplayInc/wiki/MIP-reflective-color-display

Committer:
STakayama
Date:
Tue Jan 22 10:23:39 2019 +0000
Revision:
13:9fb661dd4b2a
Parent:
10:525bcf8907fc
BackColor = Cyan

Who changed what in which revision?

UserRevisionLine numberNew contents of line
STakayama 10:525bcf8907fc 1 /***************************************************************************//**
STakayama 10:525bcf8907fc 2 * @file ICM20648.cpp
STakayama 10:525bcf8907fc 3 *******************************************************************************
STakayama 10:525bcf8907fc 4 * @section License
STakayama 10:525bcf8907fc 5 * <b>(C) Copyright 2017 Silicon Labs, http://www.silabs.com</b>
STakayama 10:525bcf8907fc 6 *******************************************************************************
STakayama 10:525bcf8907fc 7 *
STakayama 10:525bcf8907fc 8 * SPDX-License-Identifier: Apache-2.0
STakayama 10:525bcf8907fc 9 *
STakayama 10:525bcf8907fc 10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
STakayama 10:525bcf8907fc 11 * not use this file except in compliance with the License.
STakayama 10:525bcf8907fc 12 * You may obtain a copy of the License at
STakayama 10:525bcf8907fc 13 *
STakayama 10:525bcf8907fc 14 * http://www.apache.org/licenses/LICENSE-2.0
STakayama 10:525bcf8907fc 15 *
STakayama 10:525bcf8907fc 16 * Unless required by applicable law or agreed to in writing, software
STakayama 10:525bcf8907fc 17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
STakayama 10:525bcf8907fc 18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
STakayama 10:525bcf8907fc 19 * See the License for the specific language governing permissions and
STakayama 10:525bcf8907fc 20 * limitations under the License.
STakayama 10:525bcf8907fc 21 *
STakayama 10:525bcf8907fc 22 ******************************************************************************/
STakayama 10:525bcf8907fc 23
STakayama 10:525bcf8907fc 24 #include "ICM20648.h"
STakayama 10:525bcf8907fc 25
STakayama 10:525bcf8907fc 26 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
STakayama 10:525bcf8907fc 27
STakayama 10:525bcf8907fc 28 /**************************************************************************//**
STakayama 10:525bcf8907fc 29 * @name Error Codes
STakayama 10:525bcf8907fc 30 * @{
STakayama 10:525bcf8907fc 31 ******************************************************************************/
STakayama 10:525bcf8907fc 32 #define ICM20648_OK 0x0000 /**< No errors */
STakayama 10:525bcf8907fc 33 #define ICM20648_ERROR_INVALID_DEVICE_ID 0x0001 /**< Invalid device ID */
STakayama 10:525bcf8907fc 34 /**@}*/
STakayama 10:525bcf8907fc 35
STakayama 10:525bcf8907fc 36 /**************************************************************************//**
STakayama 10:525bcf8907fc 37 * @name ICM20648 register banks
STakayama 10:525bcf8907fc 38 * @{
STakayama 10:525bcf8907fc 39 ******************************************************************************/
STakayama 10:525bcf8907fc 40 #define ICM20648_BANK_0 (0 << 7) /**< Register bank 0 */
STakayama 10:525bcf8907fc 41 #define ICM20648_BANK_1 (1 << 7) /**< Register bank 1 */
STakayama 10:525bcf8907fc 42 #define ICM20648_BANK_2 (2 << 7) /**< Register bank 2 */
STakayama 10:525bcf8907fc 43 #define ICM20648_BANK_3 (3 << 7) /**< Register bank 3 */
STakayama 10:525bcf8907fc 44 /**@}*/
STakayama 10:525bcf8907fc 45
STakayama 10:525bcf8907fc 46 /**************************************************************************//**
STakayama 10:525bcf8907fc 47 * @name Register and associated bit definitions
STakayama 10:525bcf8907fc 48 * @{
STakayama 10:525bcf8907fc 49 ******************************************************************************/
STakayama 10:525bcf8907fc 50 /***********************/
STakayama 10:525bcf8907fc 51 /* Bank 0 register map */
STakayama 10:525bcf8907fc 52 /***********************/
STakayama 10:525bcf8907fc 53 #define ICM20648_REG_WHO_AM_I (ICM20648_BANK_0 | 0x00) /**< Device ID register */
STakayama 10:525bcf8907fc 54
STakayama 10:525bcf8907fc 55 #define ICM20648_REG_USER_CTRL (ICM20648_BANK_0 | 0x03) /**< User control register */
STakayama 10:525bcf8907fc 56 #define ICM20648_BIT_DMP_EN 0x80 /**< DMP enable bit */
STakayama 10:525bcf8907fc 57 #define ICM20648_BIT_FIFO_EN 0x40 /**< FIFO enable bit */
STakayama 10:525bcf8907fc 58 #define ICM20648_BIT_I2C_MST_EN 0x20 /**< I2C master I/F enable bit */
STakayama 10:525bcf8907fc 59 #define ICM20648_BIT_I2C_IF_DIS 0x10 /**< Disable I2C, enable SPI bit */
STakayama 10:525bcf8907fc 60 #define ICM20648_BIT_DMP_RST 0x08 /**< DMP module reset bit */
STakayama 10:525bcf8907fc 61 #define ICM20648_BIT_DIAMOND_DMP_RST 0x04 /**< SRAM module reset bit */
STakayama 10:525bcf8907fc 62
STakayama 10:525bcf8907fc 63 #define ICM20648_REG_LP_CONFIG (ICM20648_BANK_0 | 0x05) /**< Low Power mode config register */
STakayama 10:525bcf8907fc 64 #define ICM20648_BIT_I2C_MST_CYCLE 0x40 /**< I2C master cycle mode enable */
STakayama 10:525bcf8907fc 65 #define ICM20648_BIT_ACCEL_CYCLE 0x20 /**< Accelerometer cycle mode enable */
STakayama 10:525bcf8907fc 66 #define ICM20648_BIT_GYRO_CYCLE 0x10 /**< Gyroscope cycle mode enable */
STakayama 10:525bcf8907fc 67
STakayama 10:525bcf8907fc 68 #define ICM20648_REG_PWR_MGMT_1 (ICM20648_BANK_0 | 0x06) /**< Power Management 1 register */
STakayama 10:525bcf8907fc 69 #define ICM20648_BIT_H_RESET 0x80 /**< Device reset bit */
STakayama 10:525bcf8907fc 70 #define ICM20648_BIT_SLEEP 0x40 /**< Sleep mode enable bit */
STakayama 10:525bcf8907fc 71 #define ICM20648_BIT_LP_EN 0x20 /**< Low Power feature enable bit */
STakayama 10:525bcf8907fc 72 #define ICM20648_BIT_TEMP_DIS 0x08 /**< Temperature sensor disable bit */
STakayama 10:525bcf8907fc 73 #define ICM20648_BIT_CLK_PLL 0x01 /**< Auto clock source selection setting */
STakayama 10:525bcf8907fc 74
STakayama 10:525bcf8907fc 75 #define ICM20648_REG_PWR_MGMT_2 (ICM20648_BANK_0 | 0x07) /**< Power Management 2 register */
STakayama 10:525bcf8907fc 76 #define ICM20648_BIT_PWR_ACCEL_STBY 0x38 /**< Disable accelerometer */
STakayama 10:525bcf8907fc 77 #define ICM20648_BIT_PWR_GYRO_STBY 0x07 /**< Disable gyroscope */
STakayama 10:525bcf8907fc 78 #define ICM20648_BIT_PWR_ALL_OFF 0x7F /**< Disable both accel and gyro */
STakayama 10:525bcf8907fc 79
STakayama 10:525bcf8907fc 80 #define ICM20648_REG_INT_PIN_CFG (ICM20648_BANK_0 | 0x0F) /**< Interrupt Pin Configuration register */
STakayama 10:525bcf8907fc 81 #define ICM20648_BIT_INT_ACTL 0x80 /**< Active low setting bit */
STakayama 10:525bcf8907fc 82 #define ICM20648_BIT_INT_OPEN 0x40 /**< Open collector onfiguration bit */
STakayama 10:525bcf8907fc 83 #define ICM20648_BIT_INT_LATCH_EN 0x20 /**< Latch enable bit */
STakayama 10:525bcf8907fc 84
STakayama 10:525bcf8907fc 85 #define ICM20648_REG_INT_ENABLE (ICM20648_BANK_0 | 0x10) /**< Interrupt Enable register */
STakayama 10:525bcf8907fc 86 #define ICM20648_BIT_WOM_INT_EN 0x08 /**< Wake-up On Motion enable bit */
STakayama 10:525bcf8907fc 87
STakayama 10:525bcf8907fc 88 #define ICM20648_REG_INT_ENABLE_1 (ICM20648_BANK_0 | 0x11) /**< Interrupt Enable 1 register */
STakayama 10:525bcf8907fc 89 #define ICM20648_BIT_RAW_DATA_0_RDY_EN 0x01 /**< Raw data ready interrupt enable bit */
STakayama 10:525bcf8907fc 90
STakayama 10:525bcf8907fc 91 #define ICM20648_REG_INT_ENABLE_2 (ICM20648_BANK_0 | 0x12) /**< Interrupt Enable 2 register */
STakayama 10:525bcf8907fc 92 #define ICM20648_BIT_FIFO_OVERFLOW_EN_0 0x01 /**< FIFO overflow interrupt enable bit */
STakayama 10:525bcf8907fc 93
STakayama 10:525bcf8907fc 94 #define ICM20648_REG_INT_ENABLE_3 (ICM20648_BANK_0 | 0x13) /**< Interrupt Enable 2 register */
STakayama 10:525bcf8907fc 95
STakayama 10:525bcf8907fc 96 #define ICM20648_REG_INT_STATUS (ICM20648_BANK_0 | 0x19) /**< Interrupt Status register */
STakayama 10:525bcf8907fc 97 #define ICM20648_BIT_WOM_INT 0x08 /**< Wake-up on motion interrupt occured bit */
STakayama 10:525bcf8907fc 98 #define ICM20648_BIT_PLL_RDY 0x04 /**< PLL ready interrupt occured bit */
STakayama 10:525bcf8907fc 99
STakayama 10:525bcf8907fc 100 #define ICM20648_REG_INT_STATUS_1 (ICM20648_BANK_0 | 0x1A) /**< Interrupt Status 1 register */
STakayama 10:525bcf8907fc 101 #define ICM20648_BIT_RAW_DATA_0_RDY_INT 0x01 /**< Raw data ready interrupt occured bit */
STakayama 10:525bcf8907fc 102
STakayama 10:525bcf8907fc 103 #define ICM20648_REG_INT_STATUS_2 (ICM20648_BANK_0 | 0x1B) /**< Interrupt Status 2 register */
STakayama 10:525bcf8907fc 104
STakayama 10:525bcf8907fc 105 #define ICM20648_REG_ACCEL_XOUT_H_SH (ICM20648_BANK_0 | 0x2D) /**< Accelerometer X-axis data high byte */
STakayama 10:525bcf8907fc 106 #define ICM20648_REG_ACCEL_XOUT_L_SH (ICM20648_BANK_0 | 0x2E) /**< Accelerometer X-axis data low byte */
STakayama 10:525bcf8907fc 107 #define ICM20648_REG_ACCEL_YOUT_H_SH (ICM20648_BANK_0 | 0x2F) /**< Accelerometer Y-axis data high byte */
STakayama 10:525bcf8907fc 108 #define ICM20648_REG_ACCEL_YOUT_L_SH (ICM20648_BANK_0 | 0x30) /**< Accelerometer Y-axis data low byte */
STakayama 10:525bcf8907fc 109 #define ICM20648_REG_ACCEL_ZOUT_H_SH (ICM20648_BANK_0 | 0x31) /**< Accelerometer Z-axis data high byte */
STakayama 10:525bcf8907fc 110 #define ICM20648_REG_ACCEL_ZOUT_L_SH (ICM20648_BANK_0 | 0x32) /**< Accelerometer Z-axis data low byte */
STakayama 10:525bcf8907fc 111
STakayama 10:525bcf8907fc 112 #define ICM20648_REG_GYRO_XOUT_H_SH (ICM20648_BANK_0 | 0x33) /**< Gyroscope X-axis data high byte */
STakayama 10:525bcf8907fc 113 #define ICM20648_REG_GYRO_XOUT_L_SH (ICM20648_BANK_0 | 0x34) /**< Gyroscope X-axis data low byte */
STakayama 10:525bcf8907fc 114 #define ICM20648_REG_GYRO_YOUT_H_SH (ICM20648_BANK_0 | 0x35) /**< Gyroscope Y-axis data high byte */
STakayama 10:525bcf8907fc 115 #define ICM20648_REG_GYRO_YOUT_L_SH (ICM20648_BANK_0 | 0x36) /**< Gyroscope Y-axis data low byte */
STakayama 10:525bcf8907fc 116 #define ICM20648_REG_GYRO_ZOUT_H_SH (ICM20648_BANK_0 | 0x37) /**< Gyroscope Z-axis data high byte */
STakayama 10:525bcf8907fc 117 #define ICM20648_REG_GYRO_ZOUT_L_SH (ICM20648_BANK_0 | 0x38) /**< Gyroscope Z-axis data low byte */
STakayama 10:525bcf8907fc 118
STakayama 10:525bcf8907fc 119 #define ICM20648_REG_TEMPERATURE_H (ICM20648_BANK_0 | 0x39) /**< Temperature data high byte */
STakayama 10:525bcf8907fc 120 #define ICM20648_REG_TEMPERATURE_L (ICM20648_BANK_0 | 0x3A) /**< Temperature data low byte */
STakayama 10:525bcf8907fc 121 #define ICM20648_REG_TEMP_CONFIG (ICM20648_BANK_0 | 0x53) /**< Temperature Configuration register */
STakayama 10:525bcf8907fc 122
STakayama 10:525bcf8907fc 123 #define ICM20648_REG_FIFO_EN_1 (ICM20648_BANK_0 | 0x66) /**< FIFO Enable 1 register */
STakayama 10:525bcf8907fc 124
STakayama 10:525bcf8907fc 125 #define ICM20648_REG_FIFO_EN_2 (ICM20648_BANK_0 | 0x67) /**< FIFO Enable 2 register */
STakayama 10:525bcf8907fc 126 #define ICM20648_BIT_ACCEL_FIFO_EN 0x10 /**< Enable writing acceleration data to FIFO bit */
STakayama 10:525bcf8907fc 127 #define ICM20648_BITS_GYRO_FIFO_EN 0x0E /**< Enable writing gyroscope data to FIFO bit */
STakayama 10:525bcf8907fc 128
STakayama 10:525bcf8907fc 129 #define ICM20648_REG_FIFO_RST (ICM20648_BANK_0 | 0x68) /**< FIFO Reset register */
STakayama 10:525bcf8907fc 130 #define ICM20648_REG_FIFO_MODE (ICM20648_BANK_0 | 0x69) /**< FIFO Mode register */
STakayama 10:525bcf8907fc 131
STakayama 10:525bcf8907fc 132 #define ICM20648_REG_FIFO_COUNT_H (ICM20648_BANK_0 | 0x70) /**< FIFO data count high byte */
STakayama 10:525bcf8907fc 133 #define ICM20648_REG_FIFO_COUNT_L (ICM20648_BANK_0 | 0x71) /**< FIFO data count low byte */
STakayama 10:525bcf8907fc 134 #define ICM20648_REG_FIFO_R_W (ICM20648_BANK_0 | 0x72) /**< FIFO Read/Write register */
STakayama 10:525bcf8907fc 135
STakayama 10:525bcf8907fc 136 #define ICM20648_REG_DATA_RDY_STATUS (ICM20648_BANK_0 | 0x74) /**< Data Ready Status register */
STakayama 10:525bcf8907fc 137 #define ICM20648_BIT_RAW_DATA_0_RDY 0x01 /**< Raw Data Ready bit */
STakayama 10:525bcf8907fc 138
STakayama 10:525bcf8907fc 139 #define ICM20648_REG_FIFO_CFG (ICM20648_BANK_0 | 0x76) /**< FIFO Configuration register */
STakayama 10:525bcf8907fc 140 #define ICM20648_BIT_MULTI_FIFO_CFG 0x01 /**< Interrupt status for each sensor is required */
STakayama 10:525bcf8907fc 141 #define ICM20648_BIT_SINGLE_FIFO_CFG 0x00 /**< Interrupt status for only a single sensor is required */
STakayama 10:525bcf8907fc 142
STakayama 10:525bcf8907fc 143 /***********************/
STakayama 10:525bcf8907fc 144 /* Bank 1 register map */
STakayama 10:525bcf8907fc 145 /***********************/
STakayama 10:525bcf8907fc 146 #define ICM20648_REG_XA_OFFSET_H (ICM20648_BANK_1 | 0x14) /**< Acceleration sensor X-axis offset cancellation high byte */
STakayama 10:525bcf8907fc 147 #define ICM20648_REG_XA_OFFSET_L (ICM20648_BANK_1 | 0x15) /**< Acceleration sensor X-axis offset cancellation low byte */
STakayama 10:525bcf8907fc 148 #define ICM20648_REG_YA_OFFSET_H (ICM20648_BANK_1 | 0x17) /**< Acceleration sensor Y-axis offset cancellation high byte */
STakayama 10:525bcf8907fc 149 #define ICM20648_REG_YA_OFFSET_L (ICM20648_BANK_1 | 0x18) /**< Acceleration sensor Y-axis offset cancellation low byte */
STakayama 10:525bcf8907fc 150 #define ICM20648_REG_ZA_OFFSET_H (ICM20648_BANK_1 | 0x1A) /**< Acceleration sensor Z-axis offset cancellation high byte */
STakayama 10:525bcf8907fc 151 #define ICM20648_REG_ZA_OFFSET_L (ICM20648_BANK_1 | 0x1B) /**< Acceleration sensor Z-axis offset cancellation low byte */
STakayama 10:525bcf8907fc 152
STakayama 10:525bcf8907fc 153 #define ICM20648_REG_TIMEBASE_CORR_PLL (ICM20648_BANK_1 | 0x28) /**< PLL Timebase Correction register */
STakayama 10:525bcf8907fc 154
STakayama 10:525bcf8907fc 155 /***********************/
STakayama 10:525bcf8907fc 156 /* Bank 2 register map */
STakayama 10:525bcf8907fc 157 /***********************/
STakayama 10:525bcf8907fc 158 #define ICM20648_REG_GYRO_SMPLRT_DIV (ICM20648_BANK_2 | 0x00) /**< Gyroscope Sample Rate Divider regiser */
STakayama 10:525bcf8907fc 159
STakayama 10:525bcf8907fc 160 #define ICM20648_REG_GYRO_CONFIG_1 (ICM20648_BANK_2 | 0x01) /**< Gyroscope Configuration 1 register */
STakayama 10:525bcf8907fc 161 #define ICM20648_BIT_GYRO_FCHOICE 0x01 /**< Gyro Digital Low-Pass Filter enable bit */
STakayama 10:525bcf8907fc 162 #define ICM20648_SHIFT_GYRO_FS_SEL 1 /**< Gyro Full Scale Select bit shift */
STakayama 10:525bcf8907fc 163 #define ICM20648_SHIFT_GYRO_DLPCFG 3 /**< Gyro DLPF Config bit shift */
STakayama 10:525bcf8907fc 164 #define ICM20648_MASK_GYRO_FULLSCALE 0x06 /**< Gyro Full Scale Select bitmask */
STakayama 10:525bcf8907fc 165 #define ICM20648_MASK_GYRO_BW 0x39 /**< Gyro Bandwidth Select bitmask */
STakayama 10:525bcf8907fc 166 #define ICM20648_GYRO_FULLSCALE_250DPS (0x00 << ICM20648_SHIFT_GYRO_FS_SEL) /**< Gyro Full Scale = 250 deg/sec */
STakayama 10:525bcf8907fc 167 #define ICM20648_GYRO_FULLSCALE_500DPS (0x01 << ICM20648_SHIFT_GYRO_FS_SEL) /**< Gyro Full Scale = 500 deg/sec */
STakayama 10:525bcf8907fc 168 #define ICM20648_GYRO_FULLSCALE_1000DPS (0x02 << ICM20648_SHIFT_GYRO_FS_SEL) /**< Gyro Full Scale = 1000 deg/sec */
STakayama 10:525bcf8907fc 169 #define ICM20648_GYRO_FULLSCALE_2000DPS (0x03 << ICM20648_SHIFT_GYRO_FS_SEL) /**< Gyro Full Scale = 2000 deg/sec */
STakayama 10:525bcf8907fc 170 #define ICM20648_GYRO_BW_12100HZ (0x00 << ICM20648_SHIFT_GYRO_DLPCFG) /**< Gyro Bandwidth = 12100 Hz */
STakayama 10:525bcf8907fc 171 #define ICM20648_GYRO_BW_360HZ ( (0x07 << ICM20648_SHIFT_GYRO_DLPCFG) | ICM20648_BIT_GYRO_FCHOICE) /**< Gyro Bandwidth = 360 Hz */
STakayama 10:525bcf8907fc 172 #define ICM20648_GYRO_BW_200HZ ( (0x00 << ICM20648_SHIFT_GYRO_DLPCFG) | ICM20648_BIT_GYRO_FCHOICE) /**< Gyro Bandwidth = 200 Hz */
STakayama 10:525bcf8907fc 173 #define ICM20648_GYRO_BW_150HZ ( (0x01 << ICM20648_SHIFT_GYRO_DLPCFG) | ICM20648_BIT_GYRO_FCHOICE) /**< Gyro Bandwidth = 150 Hz */
STakayama 10:525bcf8907fc 174 #define ICM20648_GYRO_BW_120HZ ( (0x02 << ICM20648_SHIFT_GYRO_DLPCFG) | ICM20648_BIT_GYRO_FCHOICE) /**< Gyro Bandwidth = 120 Hz */
STakayama 10:525bcf8907fc 175 #define ICM20648_GYRO_BW_51HZ ( (0x03 << ICM20648_SHIFT_GYRO_DLPCFG) | ICM20648_BIT_GYRO_FCHOICE) /**< Gyro Bandwidth = 51 Hz */
STakayama 10:525bcf8907fc 176 #define ICM20648_GYRO_BW_24HZ ( (0x04 << ICM20648_SHIFT_GYRO_DLPCFG) | ICM20648_BIT_GYRO_FCHOICE) /**< Gyro Bandwidth = 24 Hz */
STakayama 10:525bcf8907fc 177 #define ICM20648_GYRO_BW_12HZ ( (0x05 << ICM20648_SHIFT_GYRO_DLPCFG) | ICM20648_BIT_GYRO_FCHOICE) /**< Gyro Bandwidth = 12 Hz */
STakayama 10:525bcf8907fc 178 #define ICM20648_GYRO_BW_6HZ ( (0x06 << ICM20648_SHIFT_GYRO_DLPCFG) | ICM20648_BIT_GYRO_FCHOICE) /**< Gyro Bandwidth = 6 Hz */
STakayama 10:525bcf8907fc 179
STakayama 10:525bcf8907fc 180 #define ICM20648_REG_GYRO_CONFIG_2 (ICM20648_BANK_2 | 0x02) /**< Gyroscope Configuration 2 register */
STakayama 10:525bcf8907fc 181 #define ICM20648_BIT_GYRO_CTEN 0x38 /**< Gyroscope Self-Test Enable bits */
STakayama 10:525bcf8907fc 182
STakayama 10:525bcf8907fc 183 #define ICM20648_REG_XG_OFFS_USRH (ICM20648_BANK_2 | 0x03) /**< Gyroscope sensor X-axis offset cancellation high byte */
STakayama 10:525bcf8907fc 184 #define ICM20648_REG_XG_OFFS_USRL (ICM20648_BANK_2 | 0x04) /**< Gyroscope sensor X-axis offset cancellation low byte */
STakayama 10:525bcf8907fc 185 #define ICM20648_REG_YG_OFFS_USRH (ICM20648_BANK_2 | 0x05) /**< Gyroscope sensor Y-axis offset cancellation high byte */
STakayama 10:525bcf8907fc 186 #define ICM20648_REG_YG_OFFS_USRL (ICM20648_BANK_2 | 0x06) /**< Gyroscope sensor Y-axis offset cancellation low byte */
STakayama 10:525bcf8907fc 187 #define ICM20648_REG_ZG_OFFS_USRH (ICM20648_BANK_2 | 0x07) /**< Gyroscope sensor Z-axis offset cancellation high byte */
STakayama 10:525bcf8907fc 188 #define ICM20648_REG_ZG_OFFS_USRL (ICM20648_BANK_2 | 0x08) /**< Gyroscope sensor Z-axis offset cancellation low byte */
STakayama 10:525bcf8907fc 189
STakayama 10:525bcf8907fc 190 #define ICM20648_REG_ODR_ALIGN_EN (ICM20648_BANK_2 | 0x09) /**< Output Data Rate start time alignment */
STakayama 10:525bcf8907fc 191
STakayama 10:525bcf8907fc 192 #define ICM20648_REG_ACCEL_SMPLRT_DIV_1 (ICM20648_BANK_2 | 0x10) /**< Acceleration Sensor Sample Rate Divider 1 register */
STakayama 10:525bcf8907fc 193 #define ICM20648_REG_ACCEL_SMPLRT_DIV_2 (ICM20648_BANK_2 | 0x11) /**< Acceleration Sensor Sample Rate Divider 2 register */
STakayama 10:525bcf8907fc 194
STakayama 10:525bcf8907fc 195 #define ICM20648_REG_ACCEL_INTEL_CTRL (ICM20648_BANK_2 | 0x12) /**< Accelerometer Hardware Intelligence Control register */
STakayama 10:525bcf8907fc 196 #define ICM20648_BIT_ACCEL_INTEL_EN 0x02 /**< Wake-up On Motion enable bit */
STakayama 10:525bcf8907fc 197 #define ICM20648_BIT_ACCEL_INTEL_MODE 0x01 /**< WOM algorithm selection bit */
STakayama 10:525bcf8907fc 198
STakayama 10:525bcf8907fc 199 #define ICM20648_REG_ACCEL_WOM_THR (ICM20648_BANK_2 | 0x13) /**< Wake-up On Motion Threshold register */
STakayama 10:525bcf8907fc 200
STakayama 10:525bcf8907fc 201 #define ICM20648_REG_ACCEL_CONFIG (ICM20648_BANK_2 | 0x14) /**< Accelerometer Configuration register */
STakayama 10:525bcf8907fc 202 #define ICM20648_BIT_ACCEL_FCHOICE 0x01 /**< Accel Digital Low-Pass Filter enable bit */
STakayama 10:525bcf8907fc 203 #define ICM20648_SHIFT_ACCEL_FS 1 /**< Accel Full Scale Select bit shift */
STakayama 10:525bcf8907fc 204 #define ICM20648_SHIFT_ACCEL_DLPCFG 3 /**< Accel DLPF Config bit shift */
STakayama 10:525bcf8907fc 205 #define ICM20648_MASK_ACCEL_FULLSCALE 0x06 /**< Accel Full Scale Select bitmask */
STakayama 10:525bcf8907fc 206 #define ICM20648_MASK_ACCEL_BW 0x39 /**< Accel Bandwidth Select bitmask */
STakayama 10:525bcf8907fc 207 #define ICM20648_ACCEL_FULLSCALE_2G (0x00 << ICM20648_SHIFT_ACCEL_FS) /**< Accel Full Scale = 2 g */
STakayama 10:525bcf8907fc 208 #define ICM20648_ACCEL_FULLSCALE_4G (0x01 << ICM20648_SHIFT_ACCEL_FS) /**< Accel Full Scale = 4 g */
STakayama 10:525bcf8907fc 209 #define ICM20648_ACCEL_FULLSCALE_8G (0x02 << ICM20648_SHIFT_ACCEL_FS) /**< Accel Full Scale = 8 g */
STakayama 10:525bcf8907fc 210 #define ICM20648_ACCEL_FULLSCALE_16G (0x03 << ICM20648_SHIFT_ACCEL_FS) /**< Accel Full Scale = 16 g */
STakayama 10:525bcf8907fc 211 #define ICM20648_ACCEL_BW_1210HZ (0x00 << ICM20648_SHIFT_ACCEL_DLPCFG) /**< Accel Bandwidth = 1210 Hz */
STakayama 10:525bcf8907fc 212 #define ICM20648_ACCEL_BW_470HZ ( (0x07 << ICM20648_SHIFT_ACCEL_DLPCFG) | ICM20648_BIT_ACCEL_FCHOICE) /**< Accel Bandwidth = 470 Hz */
STakayama 10:525bcf8907fc 213 #define ICM20648_ACCEL_BW_246HZ ( (0x00 << ICM20648_SHIFT_ACCEL_DLPCFG) | ICM20648_BIT_ACCEL_FCHOICE) /**< Accel Bandwidth = 246 Hz */
STakayama 10:525bcf8907fc 214 #define ICM20648_ACCEL_BW_111HZ ( (0x02 << ICM20648_SHIFT_ACCEL_DLPCFG) | ICM20648_BIT_ACCEL_FCHOICE) /**< Accel Bandwidth = 111 Hz */
STakayama 10:525bcf8907fc 215 #define ICM20648_ACCEL_BW_50HZ ( (0x03 << ICM20648_SHIFT_ACCEL_DLPCFG) | ICM20648_BIT_ACCEL_FCHOICE) /**< Accel Bandwidth = 50 Hz */
STakayama 10:525bcf8907fc 216 #define ICM20648_ACCEL_BW_24HZ ( (0x04 << ICM20648_SHIFT_ACCEL_DLPCFG) | ICM20648_BIT_ACCEL_FCHOICE) /**< Accel Bandwidth = 24 Hz */
STakayama 10:525bcf8907fc 217 #define ICM20648_ACCEL_BW_12HZ ( (0x05 << ICM20648_SHIFT_ACCEL_DLPCFG) | ICM20648_BIT_ACCEL_FCHOICE) /**< Accel Bandwidth = 12 Hz */
STakayama 10:525bcf8907fc 218 #define ICM20648_ACCEL_BW_6HZ ( (0x06 << ICM20648_SHIFT_ACCEL_DLPCFG) | ICM20648_BIT_ACCEL_FCHOICE) /**< Accel Bandwidth = 6 Hz */
STakayama 10:525bcf8907fc 219
STakayama 10:525bcf8907fc 220 #define ICM20648_REG_ACCEL_CONFIG_2 (ICM20648_BANK_2 | 0x15) /**< Accelerometer Configuration 2 register */
STakayama 10:525bcf8907fc 221 #define ICM20648_BIT_ACCEL_CTEN 0x1C /**< Accelerometer Self-Test Enable bits */
STakayama 10:525bcf8907fc 222
STakayama 10:525bcf8907fc 223 /***********************/
STakayama 10:525bcf8907fc 224 /* Bank 3 register map */
STakayama 10:525bcf8907fc 225 /***********************/
STakayama 10:525bcf8907fc 226 #define ICM20648_REG_I2C_MST_ODR_CONFIG (ICM20648_BANK_3 | 0x00) /**< I2C Master Output Data Rate Configuration register */
STakayama 10:525bcf8907fc 227
STakayama 10:525bcf8907fc 228 #define ICM20648_REG_I2C_MST_CTRL (ICM20648_BANK_3 | 0x01) /**< I2C Master Control register */
STakayama 10:525bcf8907fc 229 #define ICM20648_BIT_I2C_MST_P_NSR 0x10 /**< Stop between reads enabling bit */
STakayama 10:525bcf8907fc 230
STakayama 10:525bcf8907fc 231 #define ICM20648_REG_I2C_MST_DELAY_CTRL (ICM20648_BANK_3 | 0x02) /**< I2C Master Delay Control register */
STakayama 10:525bcf8907fc 232 #define ICM20648_BIT_SLV0_DLY_EN 0x01 /**< I2C Slave0 Delay Enable bit */
STakayama 10:525bcf8907fc 233 #define ICM20648_BIT_SLV1_DLY_EN 0x02 /**< I2C Slave1 Delay Enable bit */
STakayama 10:525bcf8907fc 234 #define ICM20648_BIT_SLV2_DLY_EN 0x04 /**< I2C Slave2 Delay Enable bit */
STakayama 10:525bcf8907fc 235 #define ICM20648_BIT_SLV3_DLY_EN 0x08 /**< I2C Slave3 Delay Enable bit */
STakayama 10:525bcf8907fc 236
STakayama 10:525bcf8907fc 237 #define ICM20648_REG_I2C_SLV0_ADDR (ICM20648_BANK_3 | 0x03) /**< I2C Slave0 Physical Address register */
STakayama 10:525bcf8907fc 238 #define ICM20648_REG_I2C_SLV0_REG (ICM20648_BANK_3 | 0x04) /**< I2C Slave0 Register Address register */
STakayama 10:525bcf8907fc 239 #define ICM20648_REG_I2C_SLV0_CTRL (ICM20648_BANK_3 | 0x05) /**< I2C Slave0 Control register */
STakayama 10:525bcf8907fc 240 #define ICM20648_REG_I2C_SLV0_DO (ICM20648_BANK_3 | 0x06) /**< I2C Slave0 Data Out register */
STakayama 10:525bcf8907fc 241
STakayama 10:525bcf8907fc 242 #define ICM20648_REG_I2C_SLV1_ADDR (ICM20648_BANK_3 | 0x07) /**< I2C Slave1 Physical Address register */
STakayama 10:525bcf8907fc 243 #define ICM20648_REG_I2C_SLV1_REG (ICM20648_BANK_3 | 0x08) /**< I2C Slave1 Register Address register */
STakayama 10:525bcf8907fc 244 #define ICM20648_REG_I2C_SLV1_CTRL (ICM20648_BANK_3 | 0x09) /**< I2C Slave1 Control register */
STakayama 10:525bcf8907fc 245 #define ICM20648_REG_I2C_SLV1_DO (ICM20648_BANK_3 | 0x0A) /**< I2C Slave1 Data Out register */
STakayama 10:525bcf8907fc 246
STakayama 10:525bcf8907fc 247 #define ICM20648_REG_I2C_SLV2_ADDR (ICM20648_BANK_3 | 0x0B) /**< I2C Slave2 Physical Address register */
STakayama 10:525bcf8907fc 248 #define ICM20648_REG_I2C_SLV2_REG (ICM20648_BANK_3 | 0x0C) /**< I2C Slave2 Register Address register */
STakayama 10:525bcf8907fc 249 #define ICM20648_REG_I2C_SLV2_CTRL (ICM20648_BANK_3 | 0x0D) /**< I2C Slave2 Control register */
STakayama 10:525bcf8907fc 250 #define ICM20648_REG_I2C_SLV2_DO (ICM20648_BANK_3 | 0x0E) /**< I2C Slave2 Data Out register */
STakayama 10:525bcf8907fc 251
STakayama 10:525bcf8907fc 252 #define ICM20648_REG_I2C_SLV3_ADDR (ICM20648_BANK_3 | 0x0F) /**< I2C Slave3 Physical Address register */
STakayama 10:525bcf8907fc 253 #define ICM20648_REG_I2C_SLV3_REG (ICM20648_BANK_3 | 0x10) /**< I2C Slave3 Register Address register */
STakayama 10:525bcf8907fc 254 #define ICM20648_REG_I2C_SLV3_CTRL (ICM20648_BANK_3 | 0x11) /**< I2C Slave3 Control register */
STakayama 10:525bcf8907fc 255 #define ICM20648_REG_I2C_SLV3_DO (ICM20648_BANK_3 | 0x12) /**< I2C Slave3 Data Out register */
STakayama 10:525bcf8907fc 256
STakayama 10:525bcf8907fc 257 #define ICM20648_REG_I2C_SLV4_ADDR (ICM20648_BANK_3 | 0x13) /**< I2C Slave4 Physical Address register */
STakayama 10:525bcf8907fc 258 #define ICM20648_REG_I2C_SLV4_REG (ICM20648_BANK_3 | 0x14) /**< I2C Slave4 Register Address register */
STakayama 10:525bcf8907fc 259 #define ICM20648_REG_I2C_SLV4_CTRL (ICM20648_BANK_3 | 0x15) /**< I2C Slave4 Control register */
STakayama 10:525bcf8907fc 260 #define ICM20648_REG_I2C_SLV4_DO (ICM20648_BANK_3 | 0x16) /**< I2C Slave4 Data Out register */
STakayama 10:525bcf8907fc 261 #define ICM20648_REG_I2C_SLV4_DI (ICM20648_BANK_3 | 0x17) /**< I2C Slave4 Data In register */
STakayama 10:525bcf8907fc 262
STakayama 10:525bcf8907fc 263 #define ICM20648_BIT_I2C_SLV_EN 0x80 /**< I2C Slave Enable bit */
STakayama 10:525bcf8907fc 264 #define ICM20648_BIT_I2C_BYTE_SW 0x40 /**< I2C Slave Byte Swap enable bit */
STakayama 10:525bcf8907fc 265 #define ICM20648_BIT_I2C_REG_DIS 0x20 /**< I2C Slave Do Not Write Register Value bit */
STakayama 10:525bcf8907fc 266 #define ICM20648_BIT_I2C_GRP 0x10 /**< I2C Slave Group bit */
STakayama 10:525bcf8907fc 267 #define ICM20648_BIT_I2C_READ 0x80 /**< I2C Slave R/W bit */
STakayama 10:525bcf8907fc 268
STakayama 10:525bcf8907fc 269 /* Register common for all banks */
STakayama 10:525bcf8907fc 270 #define ICM20648_REG_BANK_SEL 0x7F /**< Bank Select register */
STakayama 10:525bcf8907fc 271
STakayama 10:525bcf8907fc 272 #define ICM20648_DEVICE_ID 0xE0 /**< ICM20648 Device ID value */
STakayama 10:525bcf8907fc 273 #define ICM20948_DEVICE_ID 0xEA /**< ICM20948 Device ID value */
STakayama 10:525bcf8907fc 274 /**@}*/
STakayama 10:525bcf8907fc 275
STakayama 10:525bcf8907fc 276 /** @endcond */
STakayama 10:525bcf8907fc 277
STakayama 10:525bcf8907fc 278
STakayama 10:525bcf8907fc 279 ICM20648::ICM20648(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName irq) : m_SPI(mosi, miso, sclk), m_CS(cs, 1), m_IRQ(irq)
STakayama 10:525bcf8907fc 280 {
STakayama 10:525bcf8907fc 281 m_IRQ.disable_irq();
STakayama 10:525bcf8907fc 282 m_IRQ.fall(Callback<void(void)>(this, &ICM20648::irq_handler));
STakayama 10:525bcf8907fc 283 }
STakayama 10:525bcf8907fc 284
STakayama 10:525bcf8907fc 285 ICM20648::~ICM20648(void)
STakayama 10:525bcf8907fc 286 {
STakayama 10:525bcf8907fc 287 }
STakayama 10:525bcf8907fc 288
STakayama 10:525bcf8907fc 289 bool ICM20648::open()
STakayama 10:525bcf8907fc 290 {
STakayama 10:525bcf8907fc 291 uint8_t data;
STakayama 10:525bcf8907fc 292
STakayama 10:525bcf8907fc 293 reset();
STakayama 10:525bcf8907fc 294
STakayama 10:525bcf8907fc 295 /* Disable I2C interface, use SPI */
STakayama 10:525bcf8907fc 296 write_register(ICM20648_REG_USER_CTRL, ICM20648_BIT_I2C_IF_DIS);
STakayama 10:525bcf8907fc 297
STakayama 10:525bcf8907fc 298 /* Read Who am I register, should get 0x71 */
STakayama 10:525bcf8907fc 299 read_register(ICM20648_REG_WHO_AM_I, 1, &data);
STakayama 10:525bcf8907fc 300
STakayama 10:525bcf8907fc 301 /* If not - return */
STakayama 10:525bcf8907fc 302 if ( (data != ICM20648_DEVICE_ID) && (data != ICM20948_DEVICE_ID) ) {
STakayama 10:525bcf8907fc 303 return false;
STakayama 10:525bcf8907fc 304 }
STakayama 10:525bcf8907fc 305
STakayama 10:525bcf8907fc 306 /* Auto selects the best available clock source – PLL if ready, else use the Internal oscillator */
STakayama 10:525bcf8907fc 307 write_register(ICM20648_REG_PWR_MGMT_1, ICM20648_BIT_CLK_PLL);
STakayama 10:525bcf8907fc 308
STakayama 10:525bcf8907fc 309 /* PLL startup time - maybe it is too long but better be on the safe side, no spec in the datasheet */
STakayama 10:525bcf8907fc 310 wait_ms(30);
STakayama 10:525bcf8907fc 311
STakayama 10:525bcf8907fc 312 /* INT pin: active low, open drain, IT status read clears. It seems that latched mode does not work, the INT pin cannot be cleared if set */
STakayama 10:525bcf8907fc 313 write_register(ICM20648_REG_INT_PIN_CFG, ICM20648_BIT_INT_ACTL | ICM20648_BIT_INT_OPEN);
STakayama 10:525bcf8907fc 314
STakayama 10:525bcf8907fc 315 return true;
STakayama 10:525bcf8907fc 316 }
STakayama 10:525bcf8907fc 317
STakayama 10:525bcf8907fc 318 /** Perform a measurement
STakayama 10:525bcf8907fc 319 *
STakayama 10:525bcf8907fc 320 * @returns true if measurement was successful
STakayama 10:525bcf8907fc 321 */
STakayama 10:525bcf8907fc 322 bool ICM20648::measure()
STakayama 10:525bcf8907fc 323 {
STakayama 10:525bcf8907fc 324
STakayama 10:525bcf8907fc 325 }
STakayama 10:525bcf8907fc 326
STakayama 10:525bcf8907fc 327 /** Do a measurement on the gyroscope
STakayama 10:525bcf8907fc 328 *
STakayama 10:525bcf8907fc 329 * @param[out] gyr_x Gyroscope measurement on X axis
STakayama 10:525bcf8907fc 330 * @param[out] gyr_y Gyroscope measurement on Y axis
STakayama 10:525bcf8907fc 331 * @param[out] gyr_z Gyroscope measurement on Z axis
STakayama 10:525bcf8907fc 332 *
STakayama 10:525bcf8907fc 333 * @returns true if measurement was successful
STakayama 10:525bcf8907fc 334 */
STakayama 10:525bcf8907fc 335 bool ICM20648::get_gyroscope(float *gyr_x, float *gyr_y, float *gyr_z)
STakayama 10:525bcf8907fc 336 {
STakayama 10:525bcf8907fc 337 float buf[3];
STakayama 10:525bcf8907fc 338 if(read_gyro_data(buf)) {
STakayama 10:525bcf8907fc 339 return false;
STakayama 10:525bcf8907fc 340 }
STakayama 10:525bcf8907fc 341
STakayama 10:525bcf8907fc 342 *gyr_x = buf[0];
STakayama 10:525bcf8907fc 343 *gyr_y = buf[1];
STakayama 10:525bcf8907fc 344 *gyr_z = buf[2];
STakayama 10:525bcf8907fc 345 }
STakayama 10:525bcf8907fc 346
STakayama 10:525bcf8907fc 347 /** Do a measurement on the accelerometer
STakayama 10:525bcf8907fc 348 *
STakayama 10:525bcf8907fc 349 * @param[out] acc_x Accelerometer measurement on X axis
STakayama 10:525bcf8907fc 350 * @param[out] acc_y Accelerometer measurement on Y axis
STakayama 10:525bcf8907fc 351 * @param[out] acc_z Accelerometer measurement on Z axis
STakayama 10:525bcf8907fc 352 *
STakayama 10:525bcf8907fc 353 * @returns true if measurement was successful
STakayama 10:525bcf8907fc 354 */
STakayama 10:525bcf8907fc 355 bool ICM20648::get_accelerometer(float *acc_x, float *acc_y, float *acc_z)
STakayama 10:525bcf8907fc 356 {
STakayama 10:525bcf8907fc 357 float buf[3];
STakayama 10:525bcf8907fc 358 if(read_accel_data(buf)) {
STakayama 10:525bcf8907fc 359 return false;
STakayama 10:525bcf8907fc 360 }
STakayama 10:525bcf8907fc 361
STakayama 10:525bcf8907fc 362 *acc_x = buf[0];
STakayama 10:525bcf8907fc 363 *acc_y = buf[1];
STakayama 10:525bcf8907fc 364 *acc_z = buf[2];
STakayama 10:525bcf8907fc 365 }
STakayama 10:525bcf8907fc 366
STakayama 10:525bcf8907fc 367 bool ICM20648::get_temperature(float *temperature)
STakayama 10:525bcf8907fc 368 {
STakayama 10:525bcf8907fc 369 read_temperature(temperature);
STakayama 10:525bcf8907fc 370 return true;
STakayama 10:525bcf8907fc 371 }
STakayama 10:525bcf8907fc 372
STakayama 10:525bcf8907fc 373 /***************************************************************************//**
STakayama 10:525bcf8907fc 374 * @brief
STakayama 10:525bcf8907fc 375 * Reads register from the ICM20648 device
STakayama 10:525bcf8907fc 376 *
STakayama 10:525bcf8907fc 377 * @param[in] addr
STakayama 10:525bcf8907fc 378 * The register address to read from in the sensor
STakayama 10:525bcf8907fc 379 * Bit[8:7] - bank address
STakayama 10:525bcf8907fc 380 * Bit[6:0] - register address
STakayama 10:525bcf8907fc 381 *
STakayama 10:525bcf8907fc 382 * @param[in] numBytes
STakayama 10:525bcf8907fc 383 * The number of bytes to read
STakayama 10:525bcf8907fc 384 *
STakayama 10:525bcf8907fc 385 * @param[out] data
STakayama 10:525bcf8907fc 386 * The data read from the register
STakayama 10:525bcf8907fc 387 *
STakayama 10:525bcf8907fc 388 * @return
STakayama 10:525bcf8907fc 389 * None
STakayama 10:525bcf8907fc 390 ******************************************************************************/
STakayama 10:525bcf8907fc 391 void ICM20648::read_register(uint16_t addr, int numBytes, uint8_t *data)
STakayama 10:525bcf8907fc 392 {
STakayama 10:525bcf8907fc 393 uint8_t regAddr;
STakayama 10:525bcf8907fc 394 uint8_t bank;
STakayama 10:525bcf8907fc 395
STakayama 10:525bcf8907fc 396 regAddr = (uint8_t) (addr & 0x7F);
STakayama 10:525bcf8907fc 397 bank = (uint8_t) (addr >> 7);
STakayama 10:525bcf8907fc 398
STakayama 10:525bcf8907fc 399 select_bank(bank);
STakayama 10:525bcf8907fc 400
STakayama 10:525bcf8907fc 401 /* Enable chip select */
STakayama 10:525bcf8907fc 402 m_CS = 0;
STakayama 10:525bcf8907fc 403
STakayama 10:525bcf8907fc 404 /* Set R/W bit to 1 - read */
STakayama 10:525bcf8907fc 405 m_SPI.write(regAddr | 0x80);
STakayama 10:525bcf8907fc 406 /* Transmit 0's to provide clock and read the data */
STakayama 10:525bcf8907fc 407 m_SPI.write(NULL, 0, (char*)data, numBytes);
STakayama 10:525bcf8907fc 408
STakayama 10:525bcf8907fc 409 /* Disable chip select */
STakayama 10:525bcf8907fc 410 m_CS = 1;
STakayama 10:525bcf8907fc 411
STakayama 10:525bcf8907fc 412 return;
STakayama 10:525bcf8907fc 413 }
STakayama 10:525bcf8907fc 414
STakayama 10:525bcf8907fc 415 /***************************************************************************//**
STakayama 10:525bcf8907fc 416 * @brief
STakayama 10:525bcf8907fc 417 * Writes a register in the ICM20648 device
STakayama 10:525bcf8907fc 418 *
STakayama 10:525bcf8907fc 419 * @param[in] addr
STakayama 10:525bcf8907fc 420 * The register address to write
STakayama 10:525bcf8907fc 421 * Bit[8:7] - bank address
STakayama 10:525bcf8907fc 422 * Bit[6:0] - register address
STakayama 10:525bcf8907fc 423 *
STakayama 10:525bcf8907fc 424 * @param[in] data
STakayama 10:525bcf8907fc 425 * The data to write to the register
STakayama 10:525bcf8907fc 426 *
STakayama 10:525bcf8907fc 427 * @return
STakayama 10:525bcf8907fc 428 * None
STakayama 10:525bcf8907fc 429 ******************************************************************************/
STakayama 10:525bcf8907fc 430 void ICM20648::write_register(uint16_t addr, uint8_t data)
STakayama 10:525bcf8907fc 431 {
STakayama 10:525bcf8907fc 432 uint8_t regAddr;
STakayama 10:525bcf8907fc 433 uint8_t bank;
STakayama 10:525bcf8907fc 434
STakayama 10:525bcf8907fc 435 regAddr = (uint8_t) (addr & 0x7F);
STakayama 10:525bcf8907fc 436 bank = (uint8_t) (addr >> 7);
STakayama 10:525bcf8907fc 437
STakayama 10:525bcf8907fc 438 select_bank(bank);
STakayama 10:525bcf8907fc 439
STakayama 10:525bcf8907fc 440 /* Enable chip select */
STakayama 10:525bcf8907fc 441 m_CS = 0;
STakayama 10:525bcf8907fc 442
STakayama 10:525bcf8907fc 443 /* clear R/W bit - write, send the address */
STakayama 10:525bcf8907fc 444 m_SPI.write(regAddr & 0x7F);
STakayama 10:525bcf8907fc 445 m_SPI.write(data);
STakayama 10:525bcf8907fc 446
STakayama 10:525bcf8907fc 447 /* Disable chip select */
STakayama 10:525bcf8907fc 448 m_CS = 1;
STakayama 10:525bcf8907fc 449
STakayama 10:525bcf8907fc 450 return;
STakayama 10:525bcf8907fc 451 }
STakayama 10:525bcf8907fc 452
STakayama 10:525bcf8907fc 453 /***************************************************************************//**
STakayama 10:525bcf8907fc 454 * @brief
STakayama 10:525bcf8907fc 455 * Select the desired register bank
STakayama 10:525bcf8907fc 456 *
STakayama 10:525bcf8907fc 457 * @param[in] bank
STakayama 10:525bcf8907fc 458 * The address of the register bank (0..3)
STakayama 10:525bcf8907fc 459 *
STakayama 10:525bcf8907fc 460 * @return
STakayama 10:525bcf8907fc 461 * None
STakayama 10:525bcf8907fc 462 ******************************************************************************/
STakayama 10:525bcf8907fc 463 void ICM20648::select_bank(uint8_t bank)
STakayama 10:525bcf8907fc 464 {
STakayama 10:525bcf8907fc 465 /* Enable chip select */
STakayama 10:525bcf8907fc 466 m_CS = 0;
STakayama 10:525bcf8907fc 467
STakayama 10:525bcf8907fc 468 /* clear R/W bit - write, send the address */
STakayama 10:525bcf8907fc 469 m_SPI.write(ICM20648_REG_BANK_SEL);
STakayama 10:525bcf8907fc 470 m_SPI.write((uint8_t)(bank << 4));
STakayama 10:525bcf8907fc 471
STakayama 10:525bcf8907fc 472 /* Disable chip select */
STakayama 10:525bcf8907fc 473 m_CS = 1;
STakayama 10:525bcf8907fc 474
STakayama 10:525bcf8907fc 475 return;
STakayama 10:525bcf8907fc 476 }
STakayama 10:525bcf8907fc 477
STakayama 10:525bcf8907fc 478 /***************************************************************************//**
STakayama 10:525bcf8907fc 479 * @brief
STakayama 10:525bcf8907fc 480 * Performs soft reset on the ICM20648 chip
STakayama 10:525bcf8907fc 481 *
STakayama 10:525bcf8907fc 482 * @return
STakayama 10:525bcf8907fc 483 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 484 ******************************************************************************/
STakayama 10:525bcf8907fc 485 uint32_t ICM20648::reset(void)
STakayama 10:525bcf8907fc 486 {
STakayama 10:525bcf8907fc 487 /* Set H_RESET bit to initiate soft reset */
STakayama 10:525bcf8907fc 488 write_register(ICM20648_REG_PWR_MGMT_1, ICM20648_BIT_H_RESET);
STakayama 10:525bcf8907fc 489
STakayama 10:525bcf8907fc 490 /* Wait 100ms to complete the reset sequence */
STakayama 10:525bcf8907fc 491 wait_ms(100);
STakayama 10:525bcf8907fc 492
STakayama 10:525bcf8907fc 493 return ICM20648_OK;
STakayama 10:525bcf8907fc 494 }
STakayama 10:525bcf8907fc 495
STakayama 10:525bcf8907fc 496 /***************************************************************************//**
STakayama 10:525bcf8907fc 497 * @brief
STakayama 10:525bcf8907fc 498 * Sets the sample rate both of the accelerometer and the gyroscope.
STakayama 10:525bcf8907fc 499 *
STakayama 10:525bcf8907fc 500 * @param[in] sampleRate
STakayama 10:525bcf8907fc 501 * The desired sample rate in Hz. Since the resolution of the sample rate
STakayama 10:525bcf8907fc 502 * divider is different in the accel and gyro stages it is possible that
STakayama 10:525bcf8907fc 503 * the two sensor will have different sample rate set.
STakayama 10:525bcf8907fc 504 *
STakayama 10:525bcf8907fc 505 * @return
STakayama 10:525bcf8907fc 506 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 507 ******************************************************************************/
STakayama 10:525bcf8907fc 508 uint32_t ICM20648::set_sample_rate(float sampleRate)
STakayama 10:525bcf8907fc 509 {
STakayama 10:525bcf8907fc 510 set_gyro_sample_rate(sampleRate);
STakayama 10:525bcf8907fc 511 set_accel_sample_rate(sampleRate);
STakayama 10:525bcf8907fc 512
STakayama 10:525bcf8907fc 513 return ICM20648_OK;
STakayama 10:525bcf8907fc 514 }
STakayama 10:525bcf8907fc 515
STakayama 10:525bcf8907fc 516 /***************************************************************************//**
STakayama 10:525bcf8907fc 517 * @brief
STakayama 10:525bcf8907fc 518 * Sets the sample rate of the accelerometer
STakayama 10:525bcf8907fc 519 *
STakayama 10:525bcf8907fc 520 * @param[in] sampleRate
STakayama 10:525bcf8907fc 521 * The desired sample rate in Hz
STakayama 10:525bcf8907fc 522 *
STakayama 10:525bcf8907fc 523 * @return
STakayama 10:525bcf8907fc 524 * The actual sample rate. May be different from the desired value because
STakayama 10:525bcf8907fc 525 * of the finite and discrete number of divider settings
STakayama 10:525bcf8907fc 526 ******************************************************************************/
STakayama 10:525bcf8907fc 527 float ICM20648::set_gyro_sample_rate(float sampleRate)
STakayama 10:525bcf8907fc 528 {
STakayama 10:525bcf8907fc 529 uint8_t gyroDiv;
STakayama 10:525bcf8907fc 530 float gyroSampleRate;
STakayama 10:525bcf8907fc 531
STakayama 10:525bcf8907fc 532 /* Calculate the sample rate divider */
STakayama 10:525bcf8907fc 533 gyroSampleRate = (1125.0 / sampleRate) - 1.0;
STakayama 10:525bcf8907fc 534
STakayama 10:525bcf8907fc 535 /* Check if it fits in the divider register */
STakayama 10:525bcf8907fc 536 if ( gyroSampleRate > 255.0 ) {
STakayama 10:525bcf8907fc 537 gyroSampleRate = 255.0;
STakayama 10:525bcf8907fc 538 }
STakayama 10:525bcf8907fc 539
STakayama 10:525bcf8907fc 540 if ( gyroSampleRate < 0 ) {
STakayama 10:525bcf8907fc 541 gyroSampleRate = 0.0;
STakayama 10:525bcf8907fc 542 }
STakayama 10:525bcf8907fc 543
STakayama 10:525bcf8907fc 544 /* Write the value to the register */
STakayama 10:525bcf8907fc 545 gyroDiv = (uint8_t) gyroSampleRate;
STakayama 10:525bcf8907fc 546 write_register(ICM20648_REG_GYRO_SMPLRT_DIV, gyroDiv);
STakayama 10:525bcf8907fc 547
STakayama 10:525bcf8907fc 548 /* Calculate the actual sample rate from the divider value */
STakayama 10:525bcf8907fc 549 gyroSampleRate = 1125.0 / (gyroDiv + 1);
STakayama 10:525bcf8907fc 550
STakayama 10:525bcf8907fc 551 return gyroSampleRate;
STakayama 10:525bcf8907fc 552 }
STakayama 10:525bcf8907fc 553
STakayama 10:525bcf8907fc 554 /***************************************************************************//**
STakayama 10:525bcf8907fc 555 * @brief
STakayama 10:525bcf8907fc 556 * Sets the sample rate of the gyroscope
STakayama 10:525bcf8907fc 557 *
STakayama 10:525bcf8907fc 558 * @param[in] sampleRate
STakayama 10:525bcf8907fc 559 * The desired sample rate in Hz
STakayama 10:525bcf8907fc 560 *
STakayama 10:525bcf8907fc 561 * @return
STakayama 10:525bcf8907fc 562 * The actual sample rate. May be different from the desired value because
STakayama 10:525bcf8907fc 563 * of the finite and discrete number of divider settings
STakayama 10:525bcf8907fc 564 ******************************************************************************/
STakayama 10:525bcf8907fc 565 float ICM20648::set_accel_sample_rate(float sampleRate)
STakayama 10:525bcf8907fc 566 {
STakayama 10:525bcf8907fc 567 uint16_t accelDiv;
STakayama 10:525bcf8907fc 568 float accelSampleRate;
STakayama 10:525bcf8907fc 569
STakayama 10:525bcf8907fc 570 /* Calculate the sample rate divider */
STakayama 10:525bcf8907fc 571 accelSampleRate = (1125.0 / sampleRate) - 1.0;
STakayama 10:525bcf8907fc 572
STakayama 10:525bcf8907fc 573 /* Check if it fits in the divider registers */
STakayama 10:525bcf8907fc 574 if ( accelSampleRate > 4095.0 ) {
STakayama 10:525bcf8907fc 575 accelSampleRate = 4095.0;
STakayama 10:525bcf8907fc 576 }
STakayama 10:525bcf8907fc 577
STakayama 10:525bcf8907fc 578 if ( accelSampleRate < 0 ) {
STakayama 10:525bcf8907fc 579 accelSampleRate = 0.0;
STakayama 10:525bcf8907fc 580 }
STakayama 10:525bcf8907fc 581
STakayama 10:525bcf8907fc 582 /* Write the value to the registers */
STakayama 10:525bcf8907fc 583 accelDiv = (uint16_t) accelSampleRate;
STakayama 10:525bcf8907fc 584 write_register(ICM20648_REG_ACCEL_SMPLRT_DIV_1, (uint8_t) (accelDiv >> 8) );
STakayama 10:525bcf8907fc 585 write_register(ICM20648_REG_ACCEL_SMPLRT_DIV_2, (uint8_t) (accelDiv & 0xFF) );
STakayama 10:525bcf8907fc 586
STakayama 10:525bcf8907fc 587 /* Calculate the actual sample rate from the divider value */
STakayama 10:525bcf8907fc 588 accelSampleRate = 1125.0 / (accelDiv + 1);
STakayama 10:525bcf8907fc 589
STakayama 10:525bcf8907fc 590 return accelSampleRate;
STakayama 10:525bcf8907fc 591 }
STakayama 10:525bcf8907fc 592
STakayama 10:525bcf8907fc 593 /***************************************************************************//**
STakayama 10:525bcf8907fc 594 * @brief
STakayama 10:525bcf8907fc 595 * Sets the bandwidth of the gyroscope
STakayama 10:525bcf8907fc 596 *
STakayama 10:525bcf8907fc 597 * @param[in] gyroBw
STakayama 10:525bcf8907fc 598 * The desired bandwidth value. Use the ICM20648_GYRO_BW_xHZ macros, which
STakayama 10:525bcf8907fc 599 * are defined in the icm20648.h file. The value of x can be
STakayama 10:525bcf8907fc 600 * 6, 12, 24, 51, 120, 150, 200, 360 or 12100.
STakayama 10:525bcf8907fc 601 *
STakayama 10:525bcf8907fc 602 * @return
STakayama 10:525bcf8907fc 603 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 604 ******************************************************************************/
STakayama 10:525bcf8907fc 605 uint32_t ICM20648::set_gyro_bandwidth(uint8_t gyroBw)
STakayama 10:525bcf8907fc 606 {
STakayama 10:525bcf8907fc 607 uint8_t reg;
STakayama 10:525bcf8907fc 608
STakayama 10:525bcf8907fc 609 /* Read the GYRO_CONFIG_1 register */
STakayama 10:525bcf8907fc 610 read_register(ICM20648_REG_GYRO_CONFIG_1, 1, &reg);
STakayama 10:525bcf8907fc 611 reg &= ~(ICM20648_MASK_GYRO_BW);
STakayama 10:525bcf8907fc 612
STakayama 10:525bcf8907fc 613 /* Write the new bandwidth value to the gyro config register */
STakayama 10:525bcf8907fc 614 reg |= (gyroBw & ICM20648_MASK_GYRO_BW);
STakayama 10:525bcf8907fc 615 write_register(ICM20648_REG_GYRO_CONFIG_1, reg);
STakayama 10:525bcf8907fc 616
STakayama 10:525bcf8907fc 617 return ICM20648_OK;
STakayama 10:525bcf8907fc 618 }
STakayama 10:525bcf8907fc 619
STakayama 10:525bcf8907fc 620 /***************************************************************************//**
STakayama 10:525bcf8907fc 621 * @brief
STakayama 10:525bcf8907fc 622 * Sets the bandwidth of the accelerometer
STakayama 10:525bcf8907fc 623 *
STakayama 10:525bcf8907fc 624 * @param[in] accelBw
STakayama 10:525bcf8907fc 625 * The desired bandwidth value. Use the ICM20648_ACCEL_BW_yHZ macros, which
STakayama 10:525bcf8907fc 626 * are defined in the icm20648.h file. The value of y can be
STakayama 10:525bcf8907fc 627 * 6, 12, 24, 50, 111, 246, 470 or 1210.
STakayama 10:525bcf8907fc 628 *
STakayama 10:525bcf8907fc 629 * @return
STakayama 10:525bcf8907fc 630 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 631 ******************************************************************************/
STakayama 10:525bcf8907fc 632 uint32_t ICM20648::set_accel_bandwidth(uint8_t accelBw)
STakayama 10:525bcf8907fc 633 {
STakayama 10:525bcf8907fc 634 uint8_t reg;
STakayama 10:525bcf8907fc 635
STakayama 10:525bcf8907fc 636 /* Read the GYRO_CONFIG_1 register */
STakayama 10:525bcf8907fc 637 read_register(ICM20648_REG_ACCEL_CONFIG, 1, &reg);
STakayama 10:525bcf8907fc 638 reg &= ~(ICM20648_MASK_ACCEL_BW);
STakayama 10:525bcf8907fc 639
STakayama 10:525bcf8907fc 640 /* Write the new bandwidth value to the gyro config register */
STakayama 10:525bcf8907fc 641 reg |= (accelBw & ICM20648_MASK_ACCEL_BW);
STakayama 10:525bcf8907fc 642 write_register(ICM20648_REG_ACCEL_CONFIG, reg);
STakayama 10:525bcf8907fc 643
STakayama 10:525bcf8907fc 644 return ICM20648_OK;
STakayama 10:525bcf8907fc 645 }
STakayama 10:525bcf8907fc 646
STakayama 10:525bcf8907fc 647 /***************************************************************************//**
STakayama 10:525bcf8907fc 648 * @brief
STakayama 10:525bcf8907fc 649 * Reads the raw acceleration value and converts to g value based on
STakayama 10:525bcf8907fc 650 * the actual resolution
STakayama 10:525bcf8907fc 651 *
STakayama 10:525bcf8907fc 652 * @param[out] accel
STakayama 10:525bcf8907fc 653 * A 3-element array of float numbers containing the acceleration values
STakayama 10:525bcf8907fc 654 * for the x, y and z axes in g units.
STakayama 10:525bcf8907fc 655 *
STakayama 10:525bcf8907fc 656 * @return
STakayama 10:525bcf8907fc 657 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 658 ******************************************************************************/
STakayama 10:525bcf8907fc 659 uint32_t ICM20648::read_accel_data(float *accel)
STakayama 10:525bcf8907fc 660 {
STakayama 10:525bcf8907fc 661 uint8_t rawData[6];
STakayama 10:525bcf8907fc 662 float accelRes;
STakayama 10:525bcf8907fc 663 int16_t temp;
STakayama 10:525bcf8907fc 664
STakayama 10:525bcf8907fc 665 /* Retrieve the current resolution */
STakayama 10:525bcf8907fc 666 get_accel_resolution(&accelRes);
STakayama 10:525bcf8907fc 667
STakayama 10:525bcf8907fc 668 /* Read the six raw data registers into data array */
STakayama 10:525bcf8907fc 669 read_register(ICM20648_REG_ACCEL_XOUT_H_SH, 6, &rawData[0]);
STakayama 10:525bcf8907fc 670
STakayama 10:525bcf8907fc 671 /* Convert the MSB and LSB into a signed 16-bit value and multiply by the resolution to get the G value */
STakayama 10:525bcf8907fc 672 temp = ( (int16_t) rawData[0] << 8) | rawData[1];
STakayama 10:525bcf8907fc 673 accel[0] = (float) temp * accelRes;
STakayama 10:525bcf8907fc 674 temp = ( (int16_t) rawData[2] << 8) | rawData[3];
STakayama 10:525bcf8907fc 675 accel[1] = (float) temp * accelRes;
STakayama 10:525bcf8907fc 676 temp = ( (int16_t) rawData[4] << 8) | rawData[5];
STakayama 10:525bcf8907fc 677 accel[2] = (float) temp * accelRes;
STakayama 10:525bcf8907fc 678
STakayama 10:525bcf8907fc 679 return ICM20648_OK;
STakayama 10:525bcf8907fc 680 }
STakayama 10:525bcf8907fc 681
STakayama 10:525bcf8907fc 682 /***************************************************************************//**
STakayama 10:525bcf8907fc 683 * @brief
STakayama 10:525bcf8907fc 684 * Reads the raw gyroscope value and converts to deg/sec value based on
STakayama 10:525bcf8907fc 685 * the actual resolution
STakayama 10:525bcf8907fc 686 *
STakayama 10:525bcf8907fc 687 * @param[out] gyro
STakayama 10:525bcf8907fc 688 * A 3-element array of float numbers containing the gyroscope values
STakayama 10:525bcf8907fc 689 * for the x, y and z axes in deg/sec units.
STakayama 10:525bcf8907fc 690 *
STakayama 10:525bcf8907fc 691 * @return
STakayama 10:525bcf8907fc 692 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 693 ******************************************************************************/
STakayama 10:525bcf8907fc 694 uint32_t ICM20648::read_gyro_data(float *gyro)
STakayama 10:525bcf8907fc 695 {
STakayama 10:525bcf8907fc 696 uint8_t rawData[6];
STakayama 10:525bcf8907fc 697 float gyroRes;
STakayama 10:525bcf8907fc 698 int16_t temp;
STakayama 10:525bcf8907fc 699
STakayama 10:525bcf8907fc 700 /* Retrieve the current resolution */
STakayama 10:525bcf8907fc 701 get_gyro_resolution(&gyroRes);
STakayama 10:525bcf8907fc 702
STakayama 10:525bcf8907fc 703 /* Read the six raw data registers into data array */
STakayama 10:525bcf8907fc 704 read_register(ICM20648_REG_GYRO_XOUT_H_SH, 6, &rawData[0]);
STakayama 10:525bcf8907fc 705
STakayama 10:525bcf8907fc 706 /* Convert the MSB and LSB into a signed 16-bit value and multiply by the resolution to get the dps value */
STakayama 10:525bcf8907fc 707 temp = ( (int16_t) rawData[0] << 8) | rawData[1];
STakayama 10:525bcf8907fc 708 gyro[0] = (float) temp * gyroRes;
STakayama 10:525bcf8907fc 709 temp = ( (int16_t) rawData[2] << 8) | rawData[3];
STakayama 10:525bcf8907fc 710 gyro[1] = (float) temp * gyroRes;
STakayama 10:525bcf8907fc 711 temp = ( (int16_t) rawData[4] << 8) | rawData[5];
STakayama 10:525bcf8907fc 712 gyro[2] = (float) temp * gyroRes;
STakayama 10:525bcf8907fc 713
STakayama 10:525bcf8907fc 714 return ICM20648_OK;
STakayama 10:525bcf8907fc 715 }
STakayama 10:525bcf8907fc 716
STakayama 10:525bcf8907fc 717 /***************************************************************************//**
STakayama 10:525bcf8907fc 718 * @brief
STakayama 10:525bcf8907fc 719 * Gets the actual resolution of the accelerometer
STakayama 10:525bcf8907fc 720 *
STakayama 10:525bcf8907fc 721 * @param[out] accelRes
STakayama 10:525bcf8907fc 722 * The resolution in g/bit units
STakayama 10:525bcf8907fc 723 *
STakayama 10:525bcf8907fc 724 * @return
STakayama 10:525bcf8907fc 725 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 726 ******************************************************************************/
STakayama 10:525bcf8907fc 727 uint32_t ICM20648::get_accel_resolution(float *accelRes)
STakayama 10:525bcf8907fc 728 {
STakayama 10:525bcf8907fc 729 uint8_t reg;
STakayama 10:525bcf8907fc 730
STakayama 10:525bcf8907fc 731 /* Read the actual acceleration full scale setting */
STakayama 10:525bcf8907fc 732 read_register(ICM20648_REG_ACCEL_CONFIG, 1, &reg);
STakayama 10:525bcf8907fc 733 reg &= ICM20648_MASK_ACCEL_FULLSCALE;
STakayama 10:525bcf8907fc 734
STakayama 10:525bcf8907fc 735 /* Calculate the resolution */
STakayama 10:525bcf8907fc 736 switch ( reg ) {
STakayama 10:525bcf8907fc 737 case ICM20648_ACCEL_FULLSCALE_2G:
STakayama 10:525bcf8907fc 738 *accelRes = 2.0 / 32768.0;
STakayama 10:525bcf8907fc 739 break;
STakayama 10:525bcf8907fc 740
STakayama 10:525bcf8907fc 741 case ICM20648_ACCEL_FULLSCALE_4G:
STakayama 10:525bcf8907fc 742 *accelRes = 4.0 / 32768.0;
STakayama 10:525bcf8907fc 743 break;
STakayama 10:525bcf8907fc 744
STakayama 10:525bcf8907fc 745 case ICM20648_ACCEL_FULLSCALE_8G:
STakayama 10:525bcf8907fc 746 *accelRes = 8.0 / 32768.0;
STakayama 10:525bcf8907fc 747 break;
STakayama 10:525bcf8907fc 748
STakayama 10:525bcf8907fc 749 case ICM20648_ACCEL_FULLSCALE_16G:
STakayama 10:525bcf8907fc 750 *accelRes = 16.0 / 32768.0;
STakayama 10:525bcf8907fc 751 break;
STakayama 10:525bcf8907fc 752 }
STakayama 10:525bcf8907fc 753
STakayama 10:525bcf8907fc 754 return ICM20648_OK;
STakayama 10:525bcf8907fc 755 }
STakayama 10:525bcf8907fc 756
STakayama 10:525bcf8907fc 757 /***************************************************************************//**
STakayama 10:525bcf8907fc 758 * @brief
STakayama 10:525bcf8907fc 759 * Gets the actual resolution of the gyroscope
STakayama 10:525bcf8907fc 760 *
STakayama 10:525bcf8907fc 761 * @param[out] gyroRes
STakayama 10:525bcf8907fc 762 * The actual resolution in (deg/sec)/bit units
STakayama 10:525bcf8907fc 763 *
STakayama 10:525bcf8907fc 764 * @return
STakayama 10:525bcf8907fc 765 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 766 ******************************************************************************/
STakayama 10:525bcf8907fc 767 uint32_t ICM20648::get_gyro_resolution(float *gyroRes)
STakayama 10:525bcf8907fc 768 {
STakayama 10:525bcf8907fc 769 uint8_t reg;
STakayama 10:525bcf8907fc 770
STakayama 10:525bcf8907fc 771 /* Read the actual gyroscope full scale setting */
STakayama 10:525bcf8907fc 772 read_register(ICM20648_REG_GYRO_CONFIG_1, 1, &reg);
STakayama 10:525bcf8907fc 773 reg &= ICM20648_MASK_GYRO_FULLSCALE;
STakayama 10:525bcf8907fc 774
STakayama 10:525bcf8907fc 775 /* Calculate the resolution */
STakayama 10:525bcf8907fc 776 switch ( reg ) {
STakayama 10:525bcf8907fc 777 case ICM20648_GYRO_FULLSCALE_250DPS:
STakayama 10:525bcf8907fc 778 *gyroRes = 250.0 / 32768.0;
STakayama 10:525bcf8907fc 779 break;
STakayama 10:525bcf8907fc 780
STakayama 10:525bcf8907fc 781 case ICM20648_GYRO_FULLSCALE_500DPS:
STakayama 10:525bcf8907fc 782 *gyroRes = 500.0 / 32768.0;
STakayama 10:525bcf8907fc 783 break;
STakayama 10:525bcf8907fc 784
STakayama 10:525bcf8907fc 785 case ICM20648_GYRO_FULLSCALE_1000DPS:
STakayama 10:525bcf8907fc 786 *gyroRes = 1000.0 / 32768.0;
STakayama 10:525bcf8907fc 787 break;
STakayama 10:525bcf8907fc 788
STakayama 10:525bcf8907fc 789 case ICM20648_GYRO_FULLSCALE_2000DPS:
STakayama 10:525bcf8907fc 790 *gyroRes = 2000.0 / 32768.0;
STakayama 10:525bcf8907fc 791 break;
STakayama 10:525bcf8907fc 792 }
STakayama 10:525bcf8907fc 793
STakayama 10:525bcf8907fc 794 return ICM20648_OK;
STakayama 10:525bcf8907fc 795 }
STakayama 10:525bcf8907fc 796
STakayama 10:525bcf8907fc 797 /***************************************************************************//**
STakayama 10:525bcf8907fc 798 * @brief
STakayama 10:525bcf8907fc 799 * Sets the full scale value of the accelerometer
STakayama 10:525bcf8907fc 800 *
STakayama 10:525bcf8907fc 801 * @param[in] accelFs
STakayama 10:525bcf8907fc 802 * The desired full scale value. Use the ICM20648_ACCEL_FULLSCALE_xG
STakayama 10:525bcf8907fc 803 * macros, which are defined in the icm20648.h file. The value of x can be
STakayama 10:525bcf8907fc 804 * 2, 4, 8 or 16.
STakayama 10:525bcf8907fc 805 *
STakayama 10:525bcf8907fc 806 * @return
STakayama 10:525bcf8907fc 807 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 808 ******************************************************************************/
STakayama 10:525bcf8907fc 809 uint32_t ICM20648::set_accel_fullscale(uint8_t accelFs)
STakayama 10:525bcf8907fc 810 {
STakayama 10:525bcf8907fc 811 uint8_t reg;
STakayama 10:525bcf8907fc 812
STakayama 10:525bcf8907fc 813 accelFs &= ICM20648_MASK_ACCEL_FULLSCALE;
STakayama 10:525bcf8907fc 814 read_register(ICM20648_REG_ACCEL_CONFIG, 1, &reg);
STakayama 10:525bcf8907fc 815 reg &= ~(ICM20648_MASK_ACCEL_FULLSCALE);
STakayama 10:525bcf8907fc 816 reg |= accelFs;
STakayama 10:525bcf8907fc 817 write_register(ICM20648_REG_ACCEL_CONFIG, reg);
STakayama 10:525bcf8907fc 818
STakayama 10:525bcf8907fc 819 return ICM20648_OK;
STakayama 10:525bcf8907fc 820 }
STakayama 10:525bcf8907fc 821
STakayama 10:525bcf8907fc 822 /***************************************************************************//**
STakayama 10:525bcf8907fc 823 * @brief
STakayama 10:525bcf8907fc 824 * Sets the full scale value of the gyroscope
STakayama 10:525bcf8907fc 825 *
STakayama 10:525bcf8907fc 826 * @param[in] gyroFs
STakayama 10:525bcf8907fc 827 * The desired full scale value. Use the ICM20648_GYRO_FULLSCALE_yDPS
STakayama 10:525bcf8907fc 828 * macros, which are defined in the icm20648.h file. The value of y can be
STakayama 10:525bcf8907fc 829 * 250, 500, 1000 or 2000.
STakayama 10:525bcf8907fc 830 *
STakayama 10:525bcf8907fc 831 * @return
STakayama 10:525bcf8907fc 832 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 833 ******************************************************************************/
STakayama 10:525bcf8907fc 834 uint32_t ICM20648::set_gyro_fullscale(uint8_t gyroFs)
STakayama 10:525bcf8907fc 835 {
STakayama 10:525bcf8907fc 836 uint8_t reg;
STakayama 10:525bcf8907fc 837
STakayama 10:525bcf8907fc 838 gyroFs &= ICM20648_MASK_GYRO_FULLSCALE;
STakayama 10:525bcf8907fc 839 read_register(ICM20648_REG_GYRO_CONFIG_1, 1, &reg);
STakayama 10:525bcf8907fc 840 reg &= ~(ICM20648_MASK_GYRO_FULLSCALE);
STakayama 10:525bcf8907fc 841 reg |= gyroFs;
STakayama 10:525bcf8907fc 842 write_register(ICM20648_REG_GYRO_CONFIG_1, reg);
STakayama 10:525bcf8907fc 843
STakayama 10:525bcf8907fc 844 return ICM20648_OK;
STakayama 10:525bcf8907fc 845 }
STakayama 10:525bcf8907fc 846
STakayama 10:525bcf8907fc 847 /***************************************************************************//**
STakayama 10:525bcf8907fc 848 * @brief
STakayama 10:525bcf8907fc 849 * Enables or disables the sleep mode of the device
STakayama 10:525bcf8907fc 850 *
STakayama 10:525bcf8907fc 851 * @param[in] enable
STakayama 10:525bcf8907fc 852 * If true, sleep mode is enabled. Set to false to disable sleep mode.
STakayama 10:525bcf8907fc 853 *
STakayama 10:525bcf8907fc 854 * @return
STakayama 10:525bcf8907fc 855 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 856 ******************************************************************************/
STakayama 10:525bcf8907fc 857 uint32_t ICM20648::enable_sleepmode(bool enable)
STakayama 10:525bcf8907fc 858 {
STakayama 10:525bcf8907fc 859 uint8_t reg;
STakayama 10:525bcf8907fc 860
STakayama 10:525bcf8907fc 861 read_register(ICM20648_REG_PWR_MGMT_1, 1, &reg);
STakayama 10:525bcf8907fc 862
STakayama 10:525bcf8907fc 863 if ( enable ) {
STakayama 10:525bcf8907fc 864 /* Sleep: set the SLEEP bit */
STakayama 10:525bcf8907fc 865 reg |= ICM20648_BIT_SLEEP;
STakayama 10:525bcf8907fc 866 } else {
STakayama 10:525bcf8907fc 867 /* Wake up: clear the SLEEP bit */
STakayama 10:525bcf8907fc 868 reg &= ~(ICM20648_BIT_SLEEP);
STakayama 10:525bcf8907fc 869 }
STakayama 10:525bcf8907fc 870
STakayama 10:525bcf8907fc 871 write_register(ICM20648_REG_PWR_MGMT_1, reg);
STakayama 10:525bcf8907fc 872
STakayama 10:525bcf8907fc 873 return ICM20648_OK;
STakayama 10:525bcf8907fc 874 }
STakayama 10:525bcf8907fc 875
STakayama 10:525bcf8907fc 876 /***************************************************************************//**
STakayama 10:525bcf8907fc 877 * @brief
STakayama 10:525bcf8907fc 878 * Enables or disables the cycle mode operation of the accel and gyro
STakayama 10:525bcf8907fc 879 *
STakayama 10:525bcf8907fc 880 * @param[in] enable
STakayama 10:525bcf8907fc 881 * If true both the accel and gyro sensors will operate in cycle mode. If
STakayama 10:525bcf8907fc 882 * false the senors working in continuous mode.
STakayama 10:525bcf8907fc 883 *
STakayama 10:525bcf8907fc 884 * @return
STakayama 10:525bcf8907fc 885 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 886 ******************************************************************************/
STakayama 10:525bcf8907fc 887 uint32_t ICM20648::enable_cyclemode(bool enable)
STakayama 10:525bcf8907fc 888 {
STakayama 10:525bcf8907fc 889 uint8_t reg;
STakayama 10:525bcf8907fc 890
STakayama 10:525bcf8907fc 891 reg = 0x00;
STakayama 10:525bcf8907fc 892
STakayama 10:525bcf8907fc 893 if ( enable ) {
STakayama 10:525bcf8907fc 894 reg = ICM20648_BIT_ACCEL_CYCLE | ICM20648_BIT_GYRO_CYCLE;
STakayama 10:525bcf8907fc 895 }
STakayama 10:525bcf8907fc 896
STakayama 10:525bcf8907fc 897 write_register(ICM20648_REG_LP_CONFIG, reg);
STakayama 10:525bcf8907fc 898
STakayama 10:525bcf8907fc 899 return ICM20648_OK;
STakayama 10:525bcf8907fc 900 }
STakayama 10:525bcf8907fc 901
STakayama 10:525bcf8907fc 902 /***************************************************************************//**
STakayama 10:525bcf8907fc 903 * @brief
STakayama 10:525bcf8907fc 904 * Enables or disables the sensors in the ICM20648 chip
STakayama 10:525bcf8907fc 905 *
STakayama 10:525bcf8907fc 906 * @param[in] accel
STakayama 10:525bcf8907fc 907 * If true enables the acceleration sensor
STakayama 10:525bcf8907fc 908 *
STakayama 10:525bcf8907fc 909 * @param[in] gyro
STakayama 10:525bcf8907fc 910 * If true enables the gyroscope sensor
STakayama 10:525bcf8907fc 911 *
STakayama 10:525bcf8907fc 912 * @param[in] temp
STakayama 10:525bcf8907fc 913 * If true enables the temperature sensor
STakayama 10:525bcf8907fc 914 *
STakayama 10:525bcf8907fc 915 * @return
STakayama 10:525bcf8907fc 916 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 917 ******************************************************************************/
STakayama 10:525bcf8907fc 918 uint32_t ICM20648::enable_sensor(bool accel, bool gyro, bool temp)
STakayama 10:525bcf8907fc 919 {
STakayama 10:525bcf8907fc 920 uint8_t pwrManagement1;
STakayama 10:525bcf8907fc 921 uint8_t pwrManagement2;
STakayama 10:525bcf8907fc 922
STakayama 10:525bcf8907fc 923 read_register(ICM20648_REG_PWR_MGMT_1, 1, &pwrManagement1);
STakayama 10:525bcf8907fc 924 pwrManagement2 = 0;
STakayama 10:525bcf8907fc 925
STakayama 10:525bcf8907fc 926 /* To enable the accelerometer clear the DISABLE_ACCEL bits in PWR_MGMT_2 */
STakayama 10:525bcf8907fc 927 if ( accel ) {
STakayama 10:525bcf8907fc 928 pwrManagement2 &= ~(ICM20648_BIT_PWR_ACCEL_STBY);
STakayama 10:525bcf8907fc 929 } else {
STakayama 10:525bcf8907fc 930 pwrManagement2 |= ICM20648_BIT_PWR_ACCEL_STBY;
STakayama 10:525bcf8907fc 931 }
STakayama 10:525bcf8907fc 932
STakayama 10:525bcf8907fc 933 /* To enable gyro clear the DISABLE_GYRO bits in PWR_MGMT_2 */
STakayama 10:525bcf8907fc 934 if ( gyro ) {
STakayama 10:525bcf8907fc 935 pwrManagement2 &= ~(ICM20648_BIT_PWR_GYRO_STBY);
STakayama 10:525bcf8907fc 936 } else {
STakayama 10:525bcf8907fc 937 pwrManagement2 |= ICM20648_BIT_PWR_GYRO_STBY;
STakayama 10:525bcf8907fc 938 }
STakayama 10:525bcf8907fc 939
STakayama 10:525bcf8907fc 940 /* To enable the temperature sensor clear the TEMP_DIS bit in PWR_MGMT_1 */
STakayama 10:525bcf8907fc 941 if ( temp ) {
STakayama 10:525bcf8907fc 942 pwrManagement1 &= ~(ICM20648_BIT_TEMP_DIS);
STakayama 10:525bcf8907fc 943 } else {
STakayama 10:525bcf8907fc 944 pwrManagement1 |= ICM20648_BIT_TEMP_DIS;
STakayama 10:525bcf8907fc 945 }
STakayama 10:525bcf8907fc 946
STakayama 10:525bcf8907fc 947 /* Write back the modified values */
STakayama 10:525bcf8907fc 948 write_register(ICM20648_REG_PWR_MGMT_1, pwrManagement1);
STakayama 10:525bcf8907fc 949 write_register(ICM20648_REG_PWR_MGMT_2, pwrManagement2);
STakayama 10:525bcf8907fc 950
STakayama 10:525bcf8907fc 951 return ICM20648_OK;
STakayama 10:525bcf8907fc 952 }
STakayama 10:525bcf8907fc 953
STakayama 10:525bcf8907fc 954 /***************************************************************************//**
STakayama 10:525bcf8907fc 955 * @brief
STakayama 10:525bcf8907fc 956 * Enables or disables the sensors in low power mode in the ICM20648 chip
STakayama 10:525bcf8907fc 957 *
STakayama 10:525bcf8907fc 958 * @param[in] enAccel
STakayama 10:525bcf8907fc 959 * If true enables the acceleration sensor in low power mode
STakayama 10:525bcf8907fc 960 *
STakayama 10:525bcf8907fc 961 * @param[in] enGyro
STakayama 10:525bcf8907fc 962 * If true enables the gyroscope sensor in low power mode
STakayama 10:525bcf8907fc 963 *
STakayama 10:525bcf8907fc 964 * @param[in] enTemp
STakayama 10:525bcf8907fc 965 * If true enables the temperature sensor in low power mode
STakayama 10:525bcf8907fc 966 *
STakayama 10:525bcf8907fc 967 * @return
STakayama 10:525bcf8907fc 968 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 969 ******************************************************************************/
STakayama 10:525bcf8907fc 970 uint32_t ICM20648::enter_lowpowermode(bool enAccel, bool enGyro, bool enTemp)
STakayama 10:525bcf8907fc 971 {
STakayama 10:525bcf8907fc 972 uint8_t data;
STakayama 10:525bcf8907fc 973
STakayama 10:525bcf8907fc 974 read_register(ICM20648_REG_PWR_MGMT_1, 1, &data);
STakayama 10:525bcf8907fc 975
STakayama 10:525bcf8907fc 976 if ( enAccel || enGyro || enTemp ) {
STakayama 10:525bcf8907fc 977 /* Make sure that the chip is not in sleep */
STakayama 10:525bcf8907fc 978 enable_sleepmode(false);
STakayama 10:525bcf8907fc 979
STakayama 10:525bcf8907fc 980 /* And in continuous mode */
STakayama 10:525bcf8907fc 981 enable_cyclemode(false);
STakayama 10:525bcf8907fc 982
STakayama 10:525bcf8907fc 983 /* Enable the accelerometer and the gyroscope*/
STakayama 10:525bcf8907fc 984 enable_sensor(enAccel, enGyro, enTemp);
STakayama 10:525bcf8907fc 985 wait_ms(50);
STakayama 10:525bcf8907fc 986
STakayama 10:525bcf8907fc 987 /* Enable cycle mode */
STakayama 10:525bcf8907fc 988 enable_cyclemode(true);
STakayama 10:525bcf8907fc 989
STakayama 10:525bcf8907fc 990 /* Set the LP_EN bit to enable low power mode */
STakayama 10:525bcf8907fc 991 data |= ICM20648_BIT_LP_EN;
STakayama 10:525bcf8907fc 992 } else {
STakayama 10:525bcf8907fc 993 /* Enable continuous mode */
STakayama 10:525bcf8907fc 994 enable_cyclemode(false);
STakayama 10:525bcf8907fc 995
STakayama 10:525bcf8907fc 996 /* Clear the LP_EN bit to disable low power mode */
STakayama 10:525bcf8907fc 997 data &= ~ICM20648_BIT_LP_EN;
STakayama 10:525bcf8907fc 998 }
STakayama 10:525bcf8907fc 999
STakayama 10:525bcf8907fc 1000 /* Write the updated value to the PWR_MGNT_1 register */
STakayama 10:525bcf8907fc 1001 write_register(ICM20648_REG_PWR_MGMT_1, data);
STakayama 10:525bcf8907fc 1002
STakayama 10:525bcf8907fc 1003 return ICM20648_OK;
STakayama 10:525bcf8907fc 1004 }
STakayama 10:525bcf8907fc 1005
STakayama 10:525bcf8907fc 1006 /***************************************************************************//**
STakayama 10:525bcf8907fc 1007 * @brief
STakayama 10:525bcf8907fc 1008 * Enables or disables the interrupts in the ICM20648 chip
STakayama 10:525bcf8907fc 1009 *
STakayama 10:525bcf8907fc 1010 * @param[in] dataReadyEnable
STakayama 10:525bcf8907fc 1011 * If true enables the Raw Data Ready interrupt, otherwise disables.
STakayama 10:525bcf8907fc 1012 *
STakayama 10:525bcf8907fc 1013 * @param[in] womEnable
STakayama 10:525bcf8907fc 1014 * If true enables the Wake-up On Motion interrupt, otherwise disables.
STakayama 10:525bcf8907fc 1015 *
STakayama 10:525bcf8907fc 1016 * @return
STakayama 10:525bcf8907fc 1017 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 1018 ******************************************************************************/
STakayama 10:525bcf8907fc 1019 uint32_t ICM20648::enable_irq(bool dataReadyEnable, bool womEnable)
STakayama 10:525bcf8907fc 1020 {
STakayama 10:525bcf8907fc 1021 uint8_t intEnable;
STakayama 10:525bcf8907fc 1022
STakayama 10:525bcf8907fc 1023 /* All interrupts disabled by default */
STakayama 10:525bcf8907fc 1024 intEnable = 0;
STakayama 10:525bcf8907fc 1025
STakayama 10:525bcf8907fc 1026 /* Enable one or both of the interrupt sources if required */
STakayama 10:525bcf8907fc 1027 if ( womEnable ) {
STakayama 10:525bcf8907fc 1028 intEnable = ICM20648_BIT_WOM_INT_EN;
STakayama 10:525bcf8907fc 1029 }
STakayama 10:525bcf8907fc 1030 /* Write value to register */
STakayama 10:525bcf8907fc 1031 write_register(ICM20648_REG_INT_ENABLE, intEnable);
STakayama 10:525bcf8907fc 1032
STakayama 10:525bcf8907fc 1033 /* All interrupts disabled by default */
STakayama 10:525bcf8907fc 1034 intEnable = 0;
STakayama 10:525bcf8907fc 1035
STakayama 10:525bcf8907fc 1036 if ( dataReadyEnable ) {
STakayama 10:525bcf8907fc 1037 intEnable = ICM20648_BIT_RAW_DATA_0_RDY_EN;
STakayama 10:525bcf8907fc 1038 }
STakayama 10:525bcf8907fc 1039
STakayama 10:525bcf8907fc 1040 /* Write value to register */
STakayama 10:525bcf8907fc 1041 write_register(ICM20648_REG_INT_ENABLE_1, intEnable);
STakayama 10:525bcf8907fc 1042
STakayama 10:525bcf8907fc 1043 return ICM20648_OK;
STakayama 10:525bcf8907fc 1044 }
STakayama 10:525bcf8907fc 1045
STakayama 10:525bcf8907fc 1046 /***************************************************************************//**
STakayama 10:525bcf8907fc 1047 * @brief
STakayama 10:525bcf8907fc 1048 * Reads the interrupt status registers of the ICM20648 chip
STakayama 10:525bcf8907fc 1049 *
STakayama 10:525bcf8907fc 1050 * @param[out] intStatus
STakayama 10:525bcf8907fc 1051 * The content the four interrupt registers. LSByte is INT_STATUS, MSByte is
STakayama 10:525bcf8907fc 1052 * INT_STATUS_3
STakayama 10:525bcf8907fc 1053 *
STakayama 10:525bcf8907fc 1054 * @return
STakayama 10:525bcf8907fc 1055 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 1056 ******************************************************************************/
STakayama 10:525bcf8907fc 1057 uint32_t ICM20648::read_irqstatus(uint32_t *int_status)
STakayama 10:525bcf8907fc 1058 {
STakayama 10:525bcf8907fc 1059 uint8_t reg[4];
STakayama 10:525bcf8907fc 1060
STakayama 10:525bcf8907fc 1061 read_register(ICM20648_REG_INT_STATUS, 4, reg);
STakayama 10:525bcf8907fc 1062 *int_status = (uint32_t) reg[0];
STakayama 10:525bcf8907fc 1063 *int_status |= ( ( (uint32_t) reg[1]) << 8);
STakayama 10:525bcf8907fc 1064 *int_status |= ( ( (uint32_t) reg[2]) << 16);
STakayama 10:525bcf8907fc 1065 *int_status |= ( ( (uint32_t) reg[3]) << 24);
STakayama 10:525bcf8907fc 1066
STakayama 10:525bcf8907fc 1067 return ICM20648_OK;
STakayama 10:525bcf8907fc 1068 }
STakayama 10:525bcf8907fc 1069
STakayama 10:525bcf8907fc 1070 /***************************************************************************//**
STakayama 10:525bcf8907fc 1071 * @brief
STakayama 10:525bcf8907fc 1072 * Checks if new data is available for read
STakayama 10:525bcf8907fc 1073 *
STakayama 10:525bcf8907fc 1074 * @return
STakayama 10:525bcf8907fc 1075 * Returns true if the Raw Data Ready interrupt bit set, false otherwise
STakayama 10:525bcf8907fc 1076 ******************************************************************************/
STakayama 10:525bcf8907fc 1077 bool ICM20648::is_data_ready(void)
STakayama 10:525bcf8907fc 1078 {
STakayama 10:525bcf8907fc 1079 uint8_t status;
STakayama 10:525bcf8907fc 1080 bool ret;
STakayama 10:525bcf8907fc 1081
STakayama 10:525bcf8907fc 1082 ret = false;
STakayama 10:525bcf8907fc 1083 read_register(ICM20648_REG_INT_STATUS_1, 1, &status);
STakayama 10:525bcf8907fc 1084
STakayama 10:525bcf8907fc 1085 if ( status & ICM20648_BIT_RAW_DATA_0_RDY_INT ) {
STakayama 10:525bcf8907fc 1086 ret = true;
STakayama 10:525bcf8907fc 1087 }
STakayama 10:525bcf8907fc 1088
STakayama 10:525bcf8907fc 1089 return ret;
STakayama 10:525bcf8907fc 1090 }
STakayama 10:525bcf8907fc 1091
STakayama 10:525bcf8907fc 1092 /***************************************************************************//**
STakayama 10:525bcf8907fc 1093 * @brief
STakayama 10:525bcf8907fc 1094 * Sets up and enables the Wake-up On Motion feature
STakayama 10:525bcf8907fc 1095 *
STakayama 10:525bcf8907fc 1096 * @param[in] enable
STakayama 10:525bcf8907fc 1097 * If true enables the WOM feature, disables otherwise
STakayama 10:525bcf8907fc 1098 *
STakayama 10:525bcf8907fc 1099 * @param[in] womThreshold
STakayama 10:525bcf8907fc 1100 * Threshold value for the Wake on Motion Interrupt for ACCEL x/y/z axes.
STakayama 10:525bcf8907fc 1101 * LSB = 4mg. Range is 0mg to 1020mg
STakayama 10:525bcf8907fc 1102 *
STakayama 10:525bcf8907fc 1103 * @param[in] sampleRate
STakayama 10:525bcf8907fc 1104 * The desired sample rate of the accel sensor in Hz
STakayama 10:525bcf8907fc 1105 *
STakayama 10:525bcf8907fc 1106 * @return
STakayama 10:525bcf8907fc 1107 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 1108 ******************************************************************************/
STakayama 10:525bcf8907fc 1109 uint32_t ICM20648::enable_wake_on_motion(bool enable, uint8_t womThreshold, float sampleRate)
STakayama 10:525bcf8907fc 1110 {
STakayama 10:525bcf8907fc 1111 if ( enable ) {
STakayama 10:525bcf8907fc 1112 /* Make sure that the chip is not in sleep */
STakayama 10:525bcf8907fc 1113 enable_sleepmode(false);
STakayama 10:525bcf8907fc 1114
STakayama 10:525bcf8907fc 1115 /* And in continuous mode */
STakayama 10:525bcf8907fc 1116 enable_cyclemode(false);
STakayama 10:525bcf8907fc 1117
STakayama 10:525bcf8907fc 1118 /* Enable only the accelerometer */
STakayama 10:525bcf8907fc 1119 enable_sensor(true, false, false);
STakayama 10:525bcf8907fc 1120
STakayama 10:525bcf8907fc 1121 /* Set sample rate */
STakayama 10:525bcf8907fc 1122 set_sample_rate(sampleRate);
STakayama 10:525bcf8907fc 1123
STakayama 10:525bcf8907fc 1124 /* Set the bandwidth to 1210Hz */
STakayama 10:525bcf8907fc 1125 set_accel_bandwidth(ICM20648_ACCEL_BW_1210HZ);
STakayama 10:525bcf8907fc 1126
STakayama 10:525bcf8907fc 1127 /* Accel: 2G full scale */
STakayama 10:525bcf8907fc 1128 set_accel_fullscale(ICM20648_ACCEL_FULLSCALE_2G);
STakayama 10:525bcf8907fc 1129
STakayama 10:525bcf8907fc 1130 /* Enable the Wake On Motion interrupt */
STakayama 10:525bcf8907fc 1131 enable_irq(false, true);
STakayama 10:525bcf8907fc 1132 wait_ms(50);
STakayama 10:525bcf8907fc 1133
STakayama 10:525bcf8907fc 1134 /* Enable Wake On Motion feature */
STakayama 10:525bcf8907fc 1135 write_register(ICM20648_REG_ACCEL_INTEL_CTRL, ICM20648_BIT_ACCEL_INTEL_EN | ICM20648_BIT_ACCEL_INTEL_MODE);
STakayama 10:525bcf8907fc 1136
STakayama 10:525bcf8907fc 1137 /* Set the wake on motion threshold value */
STakayama 10:525bcf8907fc 1138 write_register(ICM20648_REG_ACCEL_WOM_THR, womThreshold);
STakayama 10:525bcf8907fc 1139
STakayama 10:525bcf8907fc 1140 /* Enable low power mode */
STakayama 10:525bcf8907fc 1141 enter_lowpowermode(true, false, false);
STakayama 10:525bcf8907fc 1142 } else {
STakayama 10:525bcf8907fc 1143 /* Disable Wake On Motion feature */
STakayama 10:525bcf8907fc 1144 write_register(ICM20648_REG_ACCEL_INTEL_CTRL, 0x00);
STakayama 10:525bcf8907fc 1145
STakayama 10:525bcf8907fc 1146 /* Disable the Wake On Motion interrupt */
STakayama 10:525bcf8907fc 1147 enable_irq(false, false);
STakayama 10:525bcf8907fc 1148
STakayama 10:525bcf8907fc 1149 /* Disable cycle mode */
STakayama 10:525bcf8907fc 1150 enable_cyclemode(false);
STakayama 10:525bcf8907fc 1151 }
STakayama 10:525bcf8907fc 1152
STakayama 10:525bcf8907fc 1153 return ICM20648_OK;
STakayama 10:525bcf8907fc 1154 }
STakayama 10:525bcf8907fc 1155
STakayama 10:525bcf8907fc 1156 /***************************************************************************//**
STakayama 10:525bcf8907fc 1157 * @brief
STakayama 10:525bcf8907fc 1158 * Accelerometer and gyroscope calibration function. Reads the gyroscope
STakayama 10:525bcf8907fc 1159 * and accelerometer values while the device is at rest and in level. The
STakayama 10:525bcf8907fc 1160 * resulting values are loaded to the accel and gyro bias registers to cancel
STakayama 10:525bcf8907fc 1161 * the static offset error.
STakayama 10:525bcf8907fc 1162 *
STakayama 10:525bcf8907fc 1163 * @param[out] accelBiasScaled
STakayama 10:525bcf8907fc 1164 * The mesured acceleration sensor bias in mg
STakayama 10:525bcf8907fc 1165 *
STakayama 10:525bcf8907fc 1166 * @param[out] gyroBiasScaled
STakayama 10:525bcf8907fc 1167 * The mesured gyro sensor bias in deg/sec
STakayama 10:525bcf8907fc 1168 *
STakayama 10:525bcf8907fc 1169 * @return
STakayama 10:525bcf8907fc 1170 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 1171 ******************************************************************************/
STakayama 10:525bcf8907fc 1172 uint32_t ICM20648::calibrate(float *accelBiasScaled, float *gyroBiasScaled)
STakayama 10:525bcf8907fc 1173 {
STakayama 10:525bcf8907fc 1174 uint8_t data[12];
STakayama 10:525bcf8907fc 1175 uint16_t i, packetCount, fifoCount;
STakayama 10:525bcf8907fc 1176 int32_t gyroBias[3] = { 0, 0, 0 };
STakayama 10:525bcf8907fc 1177 int32_t accelBias[3] = { 0, 0, 0 };
STakayama 10:525bcf8907fc 1178 int32_t accelTemp[3];
STakayama 10:525bcf8907fc 1179 int32_t gyroTemp[3];
STakayama 10:525bcf8907fc 1180 int32_t accelBiasFactory[3];
STakayama 10:525bcf8907fc 1181 int32_t gyroBiasStored[3];
STakayama 10:525bcf8907fc 1182 float gyroRes, accelRes;
STakayama 10:525bcf8907fc 1183
STakayama 10:525bcf8907fc 1184 /* Enable the accelerometer and the gyro */
STakayama 10:525bcf8907fc 1185 enable_sensor(true, true, false);
STakayama 10:525bcf8907fc 1186
STakayama 10:525bcf8907fc 1187 /* Set 1kHz sample rate */
STakayama 10:525bcf8907fc 1188 set_sample_rate(1100.0);
STakayama 10:525bcf8907fc 1189
STakayama 10:525bcf8907fc 1190 /* 246Hz BW for the accelerometer and 200Hz for the gyroscope */
STakayama 10:525bcf8907fc 1191 set_accel_bandwidth(ICM20648_ACCEL_BW_246HZ);
STakayama 10:525bcf8907fc 1192 set_gyro_bandwidth(ICM20648_GYRO_BW_12HZ);
STakayama 10:525bcf8907fc 1193
STakayama 10:525bcf8907fc 1194 /* Set the most sensitive range: 2G full scale and 250dps full scale */
STakayama 10:525bcf8907fc 1195 set_accel_fullscale(ICM20648_ACCEL_FULLSCALE_2G);
STakayama 10:525bcf8907fc 1196 set_gyro_fullscale(ICM20648_GYRO_FULLSCALE_250DPS);
STakayama 10:525bcf8907fc 1197
STakayama 10:525bcf8907fc 1198 /* Retrieve the resolution per bit */
STakayama 10:525bcf8907fc 1199 get_accel_resolution(&accelRes);
STakayama 10:525bcf8907fc 1200 get_gyro_resolution(&gyroRes);
STakayama 10:525bcf8907fc 1201
STakayama 10:525bcf8907fc 1202 /* The accel sensor needs max 30ms, the gyro max 35ms to fully start */
STakayama 10:525bcf8907fc 1203 /* Experiments show that the gyro needs more time to get reliable results */
STakayama 10:525bcf8907fc 1204 wait_ms(50);
STakayama 10:525bcf8907fc 1205
STakayama 10:525bcf8907fc 1206 /* Disable the FIFO */
STakayama 10:525bcf8907fc 1207 write_register(ICM20648_REG_USER_CTRL, ICM20648_BIT_FIFO_EN);
STakayama 10:525bcf8907fc 1208 write_register(ICM20648_REG_FIFO_MODE, 0x0F);
STakayama 10:525bcf8907fc 1209
STakayama 10:525bcf8907fc 1210 /* Enable accelerometer and gyro to store the data in FIFO */
STakayama 10:525bcf8907fc 1211 write_register(ICM20648_REG_FIFO_EN_2, ICM20648_BIT_ACCEL_FIFO_EN | ICM20648_BITS_GYRO_FIFO_EN);
STakayama 10:525bcf8907fc 1212
STakayama 10:525bcf8907fc 1213 /* Reset the FIFO */
STakayama 10:525bcf8907fc 1214 write_register(ICM20648_REG_FIFO_RST, 0x0F);
STakayama 10:525bcf8907fc 1215 write_register(ICM20648_REG_FIFO_RST, 0x00);
STakayama 10:525bcf8907fc 1216
STakayama 10:525bcf8907fc 1217 /* Enable the FIFO */
STakayama 10:525bcf8907fc 1218 write_register(ICM20648_REG_USER_CTRL, ICM20648_BIT_FIFO_EN);
STakayama 10:525bcf8907fc 1219
STakayama 10:525bcf8907fc 1220 /* The max FIFO size is 4096 bytes, one set of measurements takes 12 bytes */
STakayama 10:525bcf8907fc 1221 /* (3 axes, 2 sensors, 2 bytes each value ) 340 samples use 4080 bytes of FIFO */
STakayama 10:525bcf8907fc 1222 /* Loop until at least 4080 samples gathered */
STakayama 10:525bcf8907fc 1223 fifoCount = 0;
STakayama 10:525bcf8907fc 1224 while ( fifoCount < 4080 ) {
STakayama 10:525bcf8907fc 1225 wait_ms(5);
STakayama 10:525bcf8907fc 1226 /* Read FIFO sample count */
STakayama 10:525bcf8907fc 1227 read_register(ICM20648_REG_FIFO_COUNT_H, 2, &data[0]);
STakayama 10:525bcf8907fc 1228 /* Convert to a 16 bit value */
STakayama 10:525bcf8907fc 1229 fifoCount = ( (uint16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1230 }
STakayama 10:525bcf8907fc 1231
STakayama 10:525bcf8907fc 1232 /* Disable accelerometer and gyro to store the data in FIFO */
STakayama 10:525bcf8907fc 1233 write_register(ICM20648_REG_FIFO_EN_2, 0x00);
STakayama 10:525bcf8907fc 1234
STakayama 10:525bcf8907fc 1235 /* Read FIFO sample count */
STakayama 10:525bcf8907fc 1236 read_register(ICM20648_REG_FIFO_COUNT_H, 2, &data[0]);
STakayama 10:525bcf8907fc 1237
STakayama 10:525bcf8907fc 1238 /* Convert to a 16 bit value */
STakayama 10:525bcf8907fc 1239 fifoCount = ( (uint16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1240
STakayama 10:525bcf8907fc 1241 /* Calculate the number of data sets (3 axis of accel an gyro, two bytes each = 12 bytes) */
STakayama 10:525bcf8907fc 1242 packetCount = fifoCount / 12;
STakayama 10:525bcf8907fc 1243
STakayama 10:525bcf8907fc 1244 /* Retrieve the data from the FIFO */
STakayama 10:525bcf8907fc 1245 for ( i = 0; i < packetCount; i++ ) {
STakayama 10:525bcf8907fc 1246 read_register(ICM20648_REG_FIFO_R_W, 12, &data[0]);
STakayama 10:525bcf8907fc 1247 /* Convert to 16 bit signed accel and gyro x,y and z values */
STakayama 10:525bcf8907fc 1248 accelTemp[0] = ( (int16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1249 accelTemp[1] = ( (int16_t) (data[2] << 8) | data[3]);
STakayama 10:525bcf8907fc 1250 accelTemp[2] = ( (int16_t) (data[4] << 8) | data[5]);
STakayama 10:525bcf8907fc 1251 gyroTemp[0] = ( (int16_t) (data[6] << 8) | data[7]);
STakayama 10:525bcf8907fc 1252 gyroTemp[1] = ( (int16_t) (data[8] << 8) | data[9]);
STakayama 10:525bcf8907fc 1253 gyroTemp[2] = ( (int16_t) (data[10] << 8) | data[11]);
STakayama 10:525bcf8907fc 1254
STakayama 10:525bcf8907fc 1255 /* Sum the values */
STakayama 10:525bcf8907fc 1256 accelBias[0] += accelTemp[0];
STakayama 10:525bcf8907fc 1257 accelBias[1] += accelTemp[1];
STakayama 10:525bcf8907fc 1258 accelBias[2] += accelTemp[2];
STakayama 10:525bcf8907fc 1259 gyroBias[0] += gyroTemp[0];
STakayama 10:525bcf8907fc 1260 gyroBias[1] += gyroTemp[1];
STakayama 10:525bcf8907fc 1261 gyroBias[2] += gyroTemp[2];
STakayama 10:525bcf8907fc 1262 }
STakayama 10:525bcf8907fc 1263
STakayama 10:525bcf8907fc 1264 /* Divide by packet count to get the average */
STakayama 10:525bcf8907fc 1265 accelBias[0] /= packetCount;
STakayama 10:525bcf8907fc 1266 accelBias[1] /= packetCount;
STakayama 10:525bcf8907fc 1267 accelBias[2] /= packetCount;
STakayama 10:525bcf8907fc 1268 gyroBias[0] /= packetCount;
STakayama 10:525bcf8907fc 1269 gyroBias[1] /= packetCount;
STakayama 10:525bcf8907fc 1270 gyroBias[2] /= packetCount;
STakayama 10:525bcf8907fc 1271
STakayama 10:525bcf8907fc 1272 /* Acceleormeter: add or remove (depending on the orientation of the chip) 1G (gravity) from the Z axis value */
STakayama 10:525bcf8907fc 1273 if ( accelBias[2] > 0L ) {
STakayama 10:525bcf8907fc 1274 accelBias[2] -= (int32_t) (1.0 / accelRes);
STakayama 10:525bcf8907fc 1275 } else {
STakayama 10:525bcf8907fc 1276 accelBias[2] += (int32_t) (1.0 / accelRes);
STakayama 10:525bcf8907fc 1277 }
STakayama 10:525bcf8907fc 1278
STakayama 10:525bcf8907fc 1279 /* Convert the values to degrees per sec for displaying */
STakayama 10:525bcf8907fc 1280 gyroBiasScaled[0] = (float) gyroBias[0] * gyroRes;
STakayama 10:525bcf8907fc 1281 gyroBiasScaled[1] = (float) gyroBias[1] * gyroRes;
STakayama 10:525bcf8907fc 1282 gyroBiasScaled[2] = (float) gyroBias[2] * gyroRes;
STakayama 10:525bcf8907fc 1283
STakayama 10:525bcf8907fc 1284 /* Read stored gyro trim values. After reset these values are all 0 */
STakayama 10:525bcf8907fc 1285 read_register(ICM20648_REG_XG_OFFS_USRH, 2, &data[0]);
STakayama 10:525bcf8907fc 1286 gyroBiasStored[0] = ( (int16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1287 read_register(ICM20648_REG_YG_OFFS_USRH, 2, &data[0]);
STakayama 10:525bcf8907fc 1288 gyroBiasStored[1] = ( (int16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1289 read_register(ICM20648_REG_ZG_OFFS_USRH, 2, &data[0]);
STakayama 10:525bcf8907fc 1290 gyroBiasStored[2] = ( (int16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1291
STakayama 10:525bcf8907fc 1292 /* The gyro bias should be stored in 1000dps full scaled format. We measured in 250dps to get */
STakayama 10:525bcf8907fc 1293 /* the best sensitivity, so need to divide by 4 */
STakayama 10:525bcf8907fc 1294 /* Substract from the stored calibration value */
STakayama 10:525bcf8907fc 1295 gyroBiasStored[0] -= gyroBias[0] / 4;
STakayama 10:525bcf8907fc 1296 gyroBiasStored[1] -= gyroBias[1] / 4;
STakayama 10:525bcf8907fc 1297 gyroBiasStored[2] -= gyroBias[2] / 4;
STakayama 10:525bcf8907fc 1298
STakayama 10:525bcf8907fc 1299 /* Split the values into two bytes */
STakayama 10:525bcf8907fc 1300 data[0] = (gyroBiasStored[0] >> 8) & 0xFF;
STakayama 10:525bcf8907fc 1301 data[1] = (gyroBiasStored[0]) & 0xFF;
STakayama 10:525bcf8907fc 1302 data[2] = (gyroBiasStored[1] >> 8) & 0xFF;
STakayama 10:525bcf8907fc 1303 data[3] = (gyroBiasStored[1]) & 0xFF;
STakayama 10:525bcf8907fc 1304 data[4] = (gyroBiasStored[2] >> 8) & 0xFF;
STakayama 10:525bcf8907fc 1305 data[5] = (gyroBiasStored[2]) & 0xFF;
STakayama 10:525bcf8907fc 1306
STakayama 10:525bcf8907fc 1307 /* Write the gyro bias values to the chip */
STakayama 10:525bcf8907fc 1308 write_register(ICM20648_REG_XG_OFFS_USRH, data[0]);
STakayama 10:525bcf8907fc 1309 write_register(ICM20648_REG_XG_OFFS_USRL, data[1]);
STakayama 10:525bcf8907fc 1310 write_register(ICM20648_REG_YG_OFFS_USRH, data[2]);
STakayama 10:525bcf8907fc 1311 write_register(ICM20648_REG_YG_OFFS_USRL, data[3]);
STakayama 10:525bcf8907fc 1312 write_register(ICM20648_REG_ZG_OFFS_USRH, data[4]);
STakayama 10:525bcf8907fc 1313 write_register(ICM20648_REG_ZG_OFFS_USRL, data[5]);
STakayama 10:525bcf8907fc 1314
STakayama 10:525bcf8907fc 1315 /* Calculate the accelerometer bias values to store in the hardware accelerometer bias registers. These registers contain */
STakayama 10:525bcf8907fc 1316 /* factory trim values which must be added to the calculated accelerometer biases; on boot up these registers will hold */
STakayama 10:525bcf8907fc 1317 /* non-zero values. In addition, bit 0 of the lower byte must be preserved since it is used for temperature */
STakayama 10:525bcf8907fc 1318 /* compensation calculations(? the datasheet is not clear). Accelerometer bias registers expect bias input */
STakayama 10:525bcf8907fc 1319 /* as 2048 LSB per g, so that the accelerometer biases calculated above must be divided by 8. */
STakayama 10:525bcf8907fc 1320
STakayama 10:525bcf8907fc 1321 /* Read factory accelerometer trim values */
STakayama 10:525bcf8907fc 1322 read_register(ICM20648_REG_XA_OFFSET_H, 2, &data[0]);
STakayama 10:525bcf8907fc 1323 accelBiasFactory[0] = ( (int16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1324 read_register(ICM20648_REG_YA_OFFSET_H, 2, &data[0]);
STakayama 10:525bcf8907fc 1325 accelBiasFactory[1] = ( (int16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1326 read_register(ICM20648_REG_ZA_OFFSET_H, 2, &data[0]);
STakayama 10:525bcf8907fc 1327 accelBiasFactory[2] = ( (int16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1328
STakayama 10:525bcf8907fc 1329 /* Construct total accelerometer bias, including calculated average accelerometer bias from above */
STakayama 10:525bcf8907fc 1330 /* Scale the 2g full scale (most sensitive range) results to 16g full scale - divide by 8 */
STakayama 10:525bcf8907fc 1331 /* Clear the last bit (temperature compensation? - the datasheet is not clear) */
STakayama 10:525bcf8907fc 1332 /* Substract from the factory calibration value */
STakayama 10:525bcf8907fc 1333
STakayama 10:525bcf8907fc 1334 accelBiasFactory[0] -= ( (accelBias[0] / 8) & ~1);
STakayama 10:525bcf8907fc 1335 accelBiasFactory[1] -= ( (accelBias[1] / 8) & ~1);
STakayama 10:525bcf8907fc 1336 accelBiasFactory[2] -= ( (accelBias[2] / 8) & ~1);
STakayama 10:525bcf8907fc 1337
STakayama 10:525bcf8907fc 1338 /* Split the values into two bytes */
STakayama 10:525bcf8907fc 1339 data[0] = (accelBiasFactory[0] >> 8) & 0xFF;
STakayama 10:525bcf8907fc 1340 data[1] = (accelBiasFactory[0]) & 0xFF;
STakayama 10:525bcf8907fc 1341 data[2] = (accelBiasFactory[1] >> 8) & 0xFF;
STakayama 10:525bcf8907fc 1342 data[3] = (accelBiasFactory[1]) & 0xFF;
STakayama 10:525bcf8907fc 1343 data[4] = (accelBiasFactory[2] >> 8) & 0xFF;
STakayama 10:525bcf8907fc 1344 data[5] = (accelBiasFactory[2]) & 0xFF;
STakayama 10:525bcf8907fc 1345
STakayama 10:525bcf8907fc 1346 /* Store them in the accelerometer offset registers */
STakayama 10:525bcf8907fc 1347 write_register(ICM20648_REG_XA_OFFSET_H, data[0]);
STakayama 10:525bcf8907fc 1348 write_register(ICM20648_REG_XA_OFFSET_L, data[1]);
STakayama 10:525bcf8907fc 1349 write_register(ICM20648_REG_YA_OFFSET_H, data[2]);
STakayama 10:525bcf8907fc 1350 write_register(ICM20648_REG_YA_OFFSET_L, data[3]);
STakayama 10:525bcf8907fc 1351 write_register(ICM20648_REG_ZA_OFFSET_H, data[4]);
STakayama 10:525bcf8907fc 1352 write_register(ICM20648_REG_ZA_OFFSET_L, data[5]);
STakayama 10:525bcf8907fc 1353
STakayama 10:525bcf8907fc 1354 /* Convert the values to G for displaying */
STakayama 10:525bcf8907fc 1355 accelBiasScaled[0] = (float) accelBias[0] * accelRes;
STakayama 10:525bcf8907fc 1356 accelBiasScaled[1] = (float) accelBias[1] * accelRes;
STakayama 10:525bcf8907fc 1357 accelBiasScaled[2] = (float) accelBias[2] * accelRes;
STakayama 10:525bcf8907fc 1358
STakayama 10:525bcf8907fc 1359 /* Turn off FIFO */
STakayama 10:525bcf8907fc 1360 write_register(ICM20648_REG_USER_CTRL, 0x00);
STakayama 10:525bcf8907fc 1361
STakayama 10:525bcf8907fc 1362 /* Disable all sensors */
STakayama 10:525bcf8907fc 1363 enable_sensor(false, false, false);
STakayama 10:525bcf8907fc 1364
STakayama 10:525bcf8907fc 1365 return ICM20648_OK;
STakayama 10:525bcf8907fc 1366 }
STakayama 10:525bcf8907fc 1367
STakayama 10:525bcf8907fc 1368 /***************************************************************************//**
STakayama 10:525bcf8907fc 1369 * @brief
STakayama 10:525bcf8907fc 1370 * Gyroscope calibration function. Reads the gyroscope
STakayama 10:525bcf8907fc 1371 * values while the device is at rest and in level. The
STakayama 10:525bcf8907fc 1372 * resulting values are loaded to the gyro bias registers to cancel
STakayama 10:525bcf8907fc 1373 * the static offset error.
STakayama 10:525bcf8907fc 1374 *
STakayama 10:525bcf8907fc 1375 * @param[out] gyroBiasScaled
STakayama 10:525bcf8907fc 1376 * The mesured gyro sensor bias in deg/sec
STakayama 10:525bcf8907fc 1377 *
STakayama 10:525bcf8907fc 1378 * @return
STakayama 10:525bcf8907fc 1379 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 1380 ******************************************************************************/
STakayama 10:525bcf8907fc 1381 uint32_t ICM20648::calibrate_gyro(float *gyroBiasScaled)
STakayama 10:525bcf8907fc 1382 {
STakayama 10:525bcf8907fc 1383 uint8_t data[12];
STakayama 10:525bcf8907fc 1384 uint16_t i, packetCount, fifoCount;
STakayama 10:525bcf8907fc 1385 int32_t gyroBias[3] = { 0, 0, 0 };
STakayama 10:525bcf8907fc 1386 int32_t gyroTemp[3];
STakayama 10:525bcf8907fc 1387 int32_t gyroBiasStored[3];
STakayama 10:525bcf8907fc 1388 float gyroRes;
STakayama 10:525bcf8907fc 1389
STakayama 10:525bcf8907fc 1390 /* Enable the accelerometer and the gyro */
STakayama 10:525bcf8907fc 1391 enable_sensor(true, true, false);
STakayama 10:525bcf8907fc 1392
STakayama 10:525bcf8907fc 1393 /* Set 1kHz sample rate */
STakayama 10:525bcf8907fc 1394 set_sample_rate(1100.0);
STakayama 10:525bcf8907fc 1395
STakayama 10:525bcf8907fc 1396 /* Configure bandwidth for gyroscope to 12Hz */
STakayama 10:525bcf8907fc 1397 set_gyro_bandwidth(ICM20648_GYRO_BW_12HZ);
STakayama 10:525bcf8907fc 1398
STakayama 10:525bcf8907fc 1399 /* Configure sensitivity to 250dps full scale */
STakayama 10:525bcf8907fc 1400 set_gyro_fullscale(ICM20648_GYRO_FULLSCALE_250DPS);
STakayama 10:525bcf8907fc 1401
STakayama 10:525bcf8907fc 1402 /* Retrieve the resolution per bit */
STakayama 10:525bcf8907fc 1403 get_gyro_resolution(&gyroRes);
STakayama 10:525bcf8907fc 1404
STakayama 10:525bcf8907fc 1405 /* The accel sensor needs max 30ms, the gyro max 35ms to fully start */
STakayama 10:525bcf8907fc 1406 /* Experiments show that the gyro needs more time to get reliable results */
STakayama 10:525bcf8907fc 1407 wait_ms(50);
STakayama 10:525bcf8907fc 1408
STakayama 10:525bcf8907fc 1409 /* Disable the FIFO */
STakayama 10:525bcf8907fc 1410 write_register(ICM20648_REG_USER_CTRL, ICM20648_BIT_FIFO_EN);
STakayama 10:525bcf8907fc 1411 write_register(ICM20648_REG_FIFO_MODE, 0x0F);
STakayama 10:525bcf8907fc 1412
STakayama 10:525bcf8907fc 1413 /* Enable accelerometer and gyro to store the data in FIFO */
STakayama 10:525bcf8907fc 1414 write_register(ICM20648_REG_FIFO_EN_2, ICM20648_BITS_GYRO_FIFO_EN);
STakayama 10:525bcf8907fc 1415
STakayama 10:525bcf8907fc 1416 /* Reset the FIFO */
STakayama 10:525bcf8907fc 1417 write_register(ICM20648_REG_FIFO_RST, 0x0F);
STakayama 10:525bcf8907fc 1418 write_register(ICM20648_REG_FIFO_RST, 0x00);
STakayama 10:525bcf8907fc 1419
STakayama 10:525bcf8907fc 1420 /* Enable the FIFO */
STakayama 10:525bcf8907fc 1421 write_register(ICM20648_REG_USER_CTRL, ICM20648_BIT_FIFO_EN);
STakayama 10:525bcf8907fc 1422
STakayama 10:525bcf8907fc 1423 /* The max FIFO size is 4096 bytes, one set of measurements takes 12 bytes */
STakayama 10:525bcf8907fc 1424 /* (3 axes, 2 sensors, 2 bytes each value ) 340 samples use 4080 bytes of FIFO */
STakayama 10:525bcf8907fc 1425 /* Loop until at least 4080 samples gathered */
STakayama 10:525bcf8907fc 1426 fifoCount = 0;
STakayama 10:525bcf8907fc 1427 while ( fifoCount < 4080 ) {
STakayama 10:525bcf8907fc 1428 wait_ms(5);
STakayama 10:525bcf8907fc 1429
STakayama 10:525bcf8907fc 1430 /* Read FIFO sample count */
STakayama 10:525bcf8907fc 1431 read_register(ICM20648_REG_FIFO_COUNT_H, 2, &data[0]);
STakayama 10:525bcf8907fc 1432
STakayama 10:525bcf8907fc 1433 /* Convert to a 16 bit value */
STakayama 10:525bcf8907fc 1434 fifoCount = ( (uint16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1435 }
STakayama 10:525bcf8907fc 1436
STakayama 10:525bcf8907fc 1437 /* Disable accelerometer and gyro to store the data in FIFO */
STakayama 10:525bcf8907fc 1438 write_register(ICM20648_REG_FIFO_EN_2, 0x00);
STakayama 10:525bcf8907fc 1439
STakayama 10:525bcf8907fc 1440 /* Read FIFO sample count */
STakayama 10:525bcf8907fc 1441 read_register(ICM20648_REG_FIFO_COUNT_H, 2, &data[0]);
STakayama 10:525bcf8907fc 1442
STakayama 10:525bcf8907fc 1443 /* Convert to a 16 bit value */
STakayama 10:525bcf8907fc 1444 fifoCount = ( (uint16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1445
STakayama 10:525bcf8907fc 1446 /* Calculate the number of data sets (3 axis of accel an gyro, two bytes each = 12 bytes) */
STakayama 10:525bcf8907fc 1447 packetCount = fifoCount / 12;
STakayama 10:525bcf8907fc 1448
STakayama 10:525bcf8907fc 1449 /* Retrieve the data from the FIFO */
STakayama 10:525bcf8907fc 1450 for ( i = 0; i < packetCount; i++ ) {
STakayama 10:525bcf8907fc 1451 read_register(ICM20648_REG_FIFO_R_W, 12, &data[0]);
STakayama 10:525bcf8907fc 1452 /* Convert to 16 bit signed accel and gyro x,y and z values */
STakayama 10:525bcf8907fc 1453 gyroTemp[0] = ( (int16_t) (data[6] << 8) | data[7]);
STakayama 10:525bcf8907fc 1454 gyroTemp[1] = ( (int16_t) (data[8] << 8) | data[9]);
STakayama 10:525bcf8907fc 1455 gyroTemp[2] = ( (int16_t) (data[10] << 8) | data[11]);
STakayama 10:525bcf8907fc 1456
STakayama 10:525bcf8907fc 1457 /* Sum the values */
STakayama 10:525bcf8907fc 1458 gyroBias[0] += gyroTemp[0];
STakayama 10:525bcf8907fc 1459 gyroBias[1] += gyroTemp[1];
STakayama 10:525bcf8907fc 1460 gyroBias[2] += gyroTemp[2];
STakayama 10:525bcf8907fc 1461 }
STakayama 10:525bcf8907fc 1462
STakayama 10:525bcf8907fc 1463 /* Divide by packet count to get the average */
STakayama 10:525bcf8907fc 1464 gyroBias[0] /= packetCount;
STakayama 10:525bcf8907fc 1465 gyroBias[1] /= packetCount;
STakayama 10:525bcf8907fc 1466 gyroBias[2] /= packetCount;
STakayama 10:525bcf8907fc 1467
STakayama 10:525bcf8907fc 1468 /* Convert the values to degrees per sec for displaying */
STakayama 10:525bcf8907fc 1469 gyroBiasScaled[0] = (float) gyroBias[0] * gyroRes;
STakayama 10:525bcf8907fc 1470 gyroBiasScaled[1] = (float) gyroBias[1] * gyroRes;
STakayama 10:525bcf8907fc 1471 gyroBiasScaled[2] = (float) gyroBias[2] * gyroRes;
STakayama 10:525bcf8907fc 1472
STakayama 10:525bcf8907fc 1473 /* Read stored gyro trim values. After reset these values are all 0 */
STakayama 10:525bcf8907fc 1474 read_register(ICM20648_REG_XG_OFFS_USRH, 2, &data[0]);
STakayama 10:525bcf8907fc 1475 gyroBiasStored[0] = ( (int16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1476
STakayama 10:525bcf8907fc 1477 read_register(ICM20648_REG_YG_OFFS_USRH, 2, &data[0]);
STakayama 10:525bcf8907fc 1478 gyroBiasStored[1] = ( (int16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1479
STakayama 10:525bcf8907fc 1480 read_register(ICM20648_REG_ZG_OFFS_USRH, 2, &data[0]);
STakayama 10:525bcf8907fc 1481 gyroBiasStored[2] = ( (int16_t) (data[0] << 8) | data[1]);
STakayama 10:525bcf8907fc 1482
STakayama 10:525bcf8907fc 1483 /* The gyro bias should be stored in 1000dps full scaled format. We measured in 250dps to get */
STakayama 10:525bcf8907fc 1484 /* the best sensitivity, so need to divide by 4 */
STakayama 10:525bcf8907fc 1485 /* Substract from the stored calibration value */
STakayama 10:525bcf8907fc 1486 gyroBiasStored[0] -= gyroBias[0] / 4;
STakayama 10:525bcf8907fc 1487 gyroBiasStored[1] -= gyroBias[1] / 4;
STakayama 10:525bcf8907fc 1488 gyroBiasStored[2] -= gyroBias[2] / 4;
STakayama 10:525bcf8907fc 1489
STakayama 10:525bcf8907fc 1490 /* Split the values into two bytes */
STakayama 10:525bcf8907fc 1491 data[0] = (gyroBiasStored[0] >> 8) & 0xFF;
STakayama 10:525bcf8907fc 1492 data[1] = (gyroBiasStored[0]) & 0xFF;
STakayama 10:525bcf8907fc 1493 data[2] = (gyroBiasStored[1] >> 8) & 0xFF;
STakayama 10:525bcf8907fc 1494 data[3] = (gyroBiasStored[1]) & 0xFF;
STakayama 10:525bcf8907fc 1495 data[4] = (gyroBiasStored[2] >> 8) & 0xFF;
STakayama 10:525bcf8907fc 1496 data[5] = (gyroBiasStored[2]) & 0xFF;
STakayama 10:525bcf8907fc 1497
STakayama 10:525bcf8907fc 1498 /* Write the gyro bias values to the chip */
STakayama 10:525bcf8907fc 1499 write_register(ICM20648_REG_XG_OFFS_USRH, data[0]);
STakayama 10:525bcf8907fc 1500 write_register(ICM20648_REG_XG_OFFS_USRL, data[1]);
STakayama 10:525bcf8907fc 1501 write_register(ICM20648_REG_YG_OFFS_USRH, data[2]);
STakayama 10:525bcf8907fc 1502 write_register(ICM20648_REG_YG_OFFS_USRL, data[3]);
STakayama 10:525bcf8907fc 1503 write_register(ICM20648_REG_ZG_OFFS_USRH, data[4]);
STakayama 10:525bcf8907fc 1504 write_register(ICM20648_REG_ZG_OFFS_USRL, data[5]);
STakayama 10:525bcf8907fc 1505
STakayama 10:525bcf8907fc 1506 /* Turn off FIFO */
STakayama 10:525bcf8907fc 1507 write_register(ICM20648_REG_USER_CTRL, 0x00);
STakayama 10:525bcf8907fc 1508
STakayama 10:525bcf8907fc 1509 /* Disable all sensors */
STakayama 10:525bcf8907fc 1510 enable_sensor(false, false, false);
STakayama 10:525bcf8907fc 1511
STakayama 10:525bcf8907fc 1512 return ICM20648_OK;
STakayama 10:525bcf8907fc 1513 }
STakayama 10:525bcf8907fc 1514
STakayama 10:525bcf8907fc 1515 /***************************************************************************//**
STakayama 10:525bcf8907fc 1516 * @brief
STakayama 10:525bcf8907fc 1517 * Reads the temperature sensor raw value and converts to Celsius.
STakayama 10:525bcf8907fc 1518 *
STakayama 10:525bcf8907fc 1519 * @param[out] temperature
STakayama 10:525bcf8907fc 1520 * The mesured temperature in Celsius
STakayama 10:525bcf8907fc 1521 *
STakayama 10:525bcf8907fc 1522 * @return
STakayama 10:525bcf8907fc 1523 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 1524 ******************************************************************************/
STakayama 10:525bcf8907fc 1525 uint32_t ICM20648::read_temperature(float *temperature)
STakayama 10:525bcf8907fc 1526 {
STakayama 10:525bcf8907fc 1527 uint8_t data[2];
STakayama 10:525bcf8907fc 1528 int16_t raw_temp;
STakayama 10:525bcf8907fc 1529
STakayama 10:525bcf8907fc 1530 /* Read temperature registers */
STakayama 10:525bcf8907fc 1531 read_register(ICM20648_REG_TEMPERATURE_H, 2, data);
STakayama 10:525bcf8907fc 1532
STakayama 10:525bcf8907fc 1533 /* Convert to int16 */
STakayama 10:525bcf8907fc 1534 raw_temp = (int16_t) ( (data[0] << 8) + data[1]);
STakayama 10:525bcf8907fc 1535
STakayama 10:525bcf8907fc 1536 /* Calculate the Celsius value from the raw reading */
STakayama 10:525bcf8907fc 1537 *temperature = ( (float) raw_temp / 333.87) + 21.0;
STakayama 10:525bcf8907fc 1538
STakayama 10:525bcf8907fc 1539 return ICM20648_OK;
STakayama 10:525bcf8907fc 1540 }
STakayama 10:525bcf8907fc 1541
STakayama 10:525bcf8907fc 1542 /***************************************************************************//**
STakayama 10:525bcf8907fc 1543 * @brief
STakayama 10:525bcf8907fc 1544 * Reads the device ID of the ICM20648
STakayama 10:525bcf8907fc 1545 *
STakayama 10:525bcf8907fc 1546 * @param[out] devID
STakayama 10:525bcf8907fc 1547 * The ID of the device read from teh WHO_AM_I register. Expected value? 0xE0
STakayama 10:525bcf8907fc 1548 *
STakayama 10:525bcf8907fc 1549 * @return
STakayama 10:525bcf8907fc 1550 * Returns zero on OK, non-zero otherwise
STakayama 10:525bcf8907fc 1551 ******************************************************************************/
STakayama 10:525bcf8907fc 1552 uint32_t ICM20648::get_device_id(uint8_t *device_id)
STakayama 10:525bcf8907fc 1553 {
STakayama 10:525bcf8907fc 1554 read_register(ICM20648_REG_WHO_AM_I, 1, device_id);
STakayama 10:525bcf8907fc 1555
STakayama 10:525bcf8907fc 1556 return ICM20648_OK;
STakayama 10:525bcf8907fc 1557 }
STakayama 10:525bcf8907fc 1558
STakayama 10:525bcf8907fc 1559 void ICM20648::irq_handler(void)
STakayama 10:525bcf8907fc 1560 {
STakayama 10:525bcf8907fc 1561
STakayama 10:525bcf8907fc 1562 }