Simple driver for the TDK InvenSense ICM20648 6-axis IMU

Dependents:   TBSense2_Sensor_Demo

Information

All examples in this repo are considered EXPERIMENTAL QUALITY, meaning this code has been created as one-off proof-of-concept and is suitable as a demonstration for experimental purposes only. This code will not be regularly maintained by Silicon Labs and there is no guarantee that these projects will work across all environments, SDK versions and hardware.

Committer:
stevew817
Date:
Sun Nov 12 20:09:19 2017 +0100
Revision:
0:296308a935f5
Initial driver code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
stevew817 0:296308a935f5 1 /***************************************************************************//**
stevew817 0:296308a935f5 2 * @file ICM20648.h
stevew817 0:296308a935f5 3 *******************************************************************************
stevew817 0:296308a935f5 4 * @section License
stevew817 0:296308a935f5 5 * <b>(C) Copyright 2017 Silicon Labs, http://www.silabs.com</b>
stevew817 0:296308a935f5 6 *******************************************************************************
stevew817 0:296308a935f5 7 *
stevew817 0:296308a935f5 8 * SPDX-License-Identifier: Apache-2.0
stevew817 0:296308a935f5 9 *
stevew817 0:296308a935f5 10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
stevew817 0:296308a935f5 11 * not use this file except in compliance with the License.
stevew817 0:296308a935f5 12 * You may obtain a copy of the License at
stevew817 0:296308a935f5 13 *
stevew817 0:296308a935f5 14 * http://www.apache.org/licenses/LICENSE-2.0
stevew817 0:296308a935f5 15 *
stevew817 0:296308a935f5 16 * Unless required by applicable law or agreed to in writing, software
stevew817 0:296308a935f5 17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
stevew817 0:296308a935f5 18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
stevew817 0:296308a935f5 19 * See the License for the specific language governing permissions and
stevew817 0:296308a935f5 20 * limitations under the License.
stevew817 0:296308a935f5 21 *
stevew817 0:296308a935f5 22 ******************************************************************************/
stevew817 0:296308a935f5 23
stevew817 0:296308a935f5 24 #ifndef ICM20648_H
stevew817 0:296308a935f5 25 #define ICM20648_H
stevew817 0:296308a935f5 26
stevew817 0:296308a935f5 27 #include "mbed.h"
stevew817 0:296308a935f5 28
stevew817 0:296308a935f5 29 /** ICM20648 class.
stevew817 0:296308a935f5 30 * Used for taking accelerometer and gyroscope measurements.
stevew817 0:296308a935f5 31 *
stevew817 0:296308a935f5 32 * Example:
stevew817 0:296308a935f5 33 * @code
stevew817 0:296308a935f5 34 * #include "mbed.h"
stevew817 0:296308a935f5 35 * #include "ICM20648.h"
stevew817 0:296308a935f5 36 *
stevew817 0:296308a935f5 37 * //Create an ICM20648 object
stevew817 0:296308a935f5 38 * ICM20648 sensor(PC4, PC5);
stevew817 0:296308a935f5 39 *
stevew817 0:296308a935f5 40 * int main()
stevew817 0:296308a935f5 41 * {
stevew817 0:296308a935f5 42 * //Try to open the ICM20648
stevew817 0:296308a935f5 43 * if (sensor.open()) {
stevew817 0:296308a935f5 44 * printf("Device detected!\n");
stevew817 0:296308a935f5 45 *
stevew817 0:296308a935f5 46 * while (1) {
stevew817 0:296308a935f5 47 * float acc_x, acc_y, acc_z;
stevew817 0:296308a935f5 48 * float gyr_x, gyr_y, gyr_z;
stevew817 0:296308a935f5 49 *
stevew817 0:296308a935f5 50 * sensor.measure();
stevew817 0:296308a935f5 51 *
stevew817 0:296308a935f5 52 * sensor.get_accelerometer(&acc_x, &acc_y, &acc_z);
stevew817 0:296308a935f5 53 * sensor.get_gyroscope(&gyr_x, &gyr_y, &gyr_z);
stevew817 0:296308a935f5 54 *
stevew817 0:296308a935f5 55 * //Print the current accelerometer measurement
stevew817 0:296308a935f5 56 * printf("acc: %.3f %.3f %.3f\n", acc_x, acc_y, acc_z);
stevew817 0:296308a935f5 57 * //Print the current gyroscope measurement
stevew817 0:296308a935f5 58 * printf("gyr: %.3f %.3f %.3f\n", gyr_x, gyr_y, gyr_z);
stevew817 0:296308a935f5 59 *
stevew817 0:296308a935f5 60 * //Sleep for 0.5 seconds
stevew817 0:296308a935f5 61 * wait(0.5);
stevew817 0:296308a935f5 62 * }
stevew817 0:296308a935f5 63 * } else {
stevew817 0:296308a935f5 64 * error("Device not detected!\n");
stevew817 0:296308a935f5 65 * }
stevew817 0:296308a935f5 66 * }
stevew817 0:296308a935f5 67 * @endcode
stevew817 0:296308a935f5 68 */
stevew817 0:296308a935f5 69 class ICM20648
stevew817 0:296308a935f5 70 {
stevew817 0:296308a935f5 71 public:
stevew817 0:296308a935f5 72
stevew817 0:296308a935f5 73 /** Create an ICM20648 object connected to the specified SPI pins
stevew817 0:296308a935f5 74 *
stevew817 0:296308a935f5 75 * @param mosi The SPI MOSI pin.
stevew817 0:296308a935f5 76 * @param miso The SPI MISO pin.
stevew817 0:296308a935f5 77 * @param sclk The SPI clock pin.
stevew817 0:296308a935f5 78 * @param cs The SPI Chip Select pin.
stevew817 0:296308a935f5 79 * @param irq The ICM20648 irq pin.
stevew817 0:296308a935f5 80 */
stevew817 0:296308a935f5 81 ICM20648(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName irq = NC);
stevew817 0:296308a935f5 82
stevew817 0:296308a935f5 83 /**
stevew817 0:296308a935f5 84 * ICM20648 destructor
stevew817 0:296308a935f5 85 */
stevew817 0:296308a935f5 86 ~ICM20648(void);
stevew817 0:296308a935f5 87
stevew817 0:296308a935f5 88 /** Probe for the ICM20648 and try to initialize the sensor
stevew817 0:296308a935f5 89 *
stevew817 0:296308a935f5 90 * @returns
stevew817 0:296308a935f5 91 * 'true' if the device exists on the bus,
stevew817 0:296308a935f5 92 * 'false' if the device doesn't exist on the bus.
stevew817 0:296308a935f5 93 */
stevew817 0:296308a935f5 94 bool open();
stevew817 0:296308a935f5 95
stevew817 0:296308a935f5 96 /** Perform a measurement
stevew817 0:296308a935f5 97 *
stevew817 0:296308a935f5 98 * @returns true if measurement was successful
stevew817 0:296308a935f5 99 */
stevew817 0:296308a935f5 100 bool measure();
stevew817 0:296308a935f5 101
stevew817 0:296308a935f5 102 /** Do a measurement on the gyroscope
stevew817 0:296308a935f5 103 *
stevew817 0:296308a935f5 104 * @param[out] gyr_x Gyroscope measurement on X axis
stevew817 0:296308a935f5 105 * @param[out] gyr_y Gyroscope measurement on Y axis
stevew817 0:296308a935f5 106 * @param[out] gyr_z Gyroscope measurement on Z axis
stevew817 0:296308a935f5 107 *
stevew817 0:296308a935f5 108 * @returns true if measurement was successful
stevew817 0:296308a935f5 109 */
stevew817 0:296308a935f5 110 bool get_gyroscope(float *gyr_x, float *gyr_y, float *gyr_z);
stevew817 0:296308a935f5 111
stevew817 0:296308a935f5 112 /** Do a measurement on the accelerometer
stevew817 0:296308a935f5 113 *
stevew817 0:296308a935f5 114 * @param[out] acc_x Accelerometer measurement on X axis
stevew817 0:296308a935f5 115 * @param[out] acc_y Accelerometer measurement on Y axis
stevew817 0:296308a935f5 116 * @param[out] acc_z Accelerometer measurement on Z axis
stevew817 0:296308a935f5 117 *
stevew817 0:296308a935f5 118 * @returns true if measurement was successful
stevew817 0:296308a935f5 119 */
stevew817 0:296308a935f5 120 bool get_accelerometer(float *acc_x, float *acc_y, float *acc_z);
stevew817 0:296308a935f5 121
stevew817 0:296308a935f5 122 /** Do a measurement of the temperature sensor
stevew817 0:296308a935f5 123 *
stevew817 0:296308a935f5 124 * @param[out] temperature Measured temperature
stevew817 0:296308a935f5 125 *
stevew817 0:296308a935f5 126 * @returns true if measurement was successful
stevew817 0:296308a935f5 127 */
stevew817 0:296308a935f5 128 bool get_temperature(float *temperature);
stevew817 0:296308a935f5 129
stevew817 0:296308a935f5 130 private:
stevew817 0:296308a935f5 131 /* Private functions */
stevew817 0:296308a935f5 132 void read_register(uint16_t addr, int numBytes, uint8_t *data);
stevew817 0:296308a935f5 133 void write_register(uint16_t addr, uint8_t data);
stevew817 0:296308a935f5 134 void select_bank(uint8_t bank);
stevew817 0:296308a935f5 135 uint32_t reset(void);
stevew817 0:296308a935f5 136 uint32_t set_sample_rate(float sampleRate);
stevew817 0:296308a935f5 137 float set_gyro_sample_rate(float sampleRate);
stevew817 0:296308a935f5 138 float set_accel_sample_rate(float sampleRate);
stevew817 0:296308a935f5 139 uint32_t set_gyro_bandwidth(uint8_t gyroBw);
stevew817 0:296308a935f5 140 uint32_t set_accel_bandwidth(uint8_t accelBw);
stevew817 0:296308a935f5 141 uint32_t read_accel_data(float *accel);
stevew817 0:296308a935f5 142 uint32_t read_gyro_data(float *gyro);
stevew817 0:296308a935f5 143 uint32_t get_accel_resolution(float *accelRes);
stevew817 0:296308a935f5 144 uint32_t get_gyro_resolution(float *gyroRes);
stevew817 0:296308a935f5 145 uint32_t set_accel_fullscale(uint8_t accelFs);
stevew817 0:296308a935f5 146 uint32_t set_gyro_fullscale(uint8_t gyroFs);
stevew817 0:296308a935f5 147 uint32_t enable_sleepmode(bool enable);
stevew817 0:296308a935f5 148 uint32_t enable_cyclemode(bool enable);
stevew817 0:296308a935f5 149 uint32_t enable_sensor(bool accel, bool gyro, bool temp);
stevew817 0:296308a935f5 150 uint32_t enter_lowpowermode(bool enAccel, bool enGyro, bool enTemp);
stevew817 0:296308a935f5 151 uint32_t enable_irq(bool dataReadyEnable, bool womEnable);
stevew817 0:296308a935f5 152 uint32_t read_irqstatus(uint32_t *int_status);
stevew817 0:296308a935f5 153 bool is_data_ready(void);
stevew817 0:296308a935f5 154 uint32_t enable_wake_on_motion(bool enable, uint8_t womThreshold, float sampleRate);
stevew817 0:296308a935f5 155 uint32_t calibrate(float *accelBiasScaled, float *gyroBiasScaled);
stevew817 0:296308a935f5 156 uint32_t calibrate_gyro(float *gyroBiasScaled);
stevew817 0:296308a935f5 157 uint32_t read_temperature(float *temperature);
stevew817 0:296308a935f5 158 uint32_t get_device_id(uint8_t *device_id);
stevew817 0:296308a935f5 159
stevew817 0:296308a935f5 160 void irq_handler(void);
stevew817 0:296308a935f5 161
stevew817 0:296308a935f5 162 /* Member variables */
stevew817 0:296308a935f5 163 SPI m_SPI;
stevew817 0:296308a935f5 164 DigitalOut m_CS;
stevew817 0:296308a935f5 165 InterruptIn m_IRQ;
stevew817 0:296308a935f5 166 };
stevew817 0:296308a935f5 167
stevew817 0:296308a935f5 168 #endif