Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
icm20948.h
- Committer:
- eric11fr
- Date:
- 2021-03-19
- Revision:
- 0:efb1550773f1
- Child:
- 1:8459e28d77a1
File content as of revision 0:efb1550773f1:
/* Note: The ICM-20948 is an I2C sensor and uses the Arduino Wire library. */ #ifndef _ICM20948_H_ #define _ICM20948_H_ #include <SPI.h> #include <Wire.h> #define SERIAL_DEBUG true // See also ICM-20948 Datasheet, Register Map and Descriptions, Revision 1.3, // https://www.invensense.com/wp-content/uploads/2016/06/DS-000189-ICM-20948-v1.3.pdf // and AK09916 Datasheet and Register Map // https://www.akm.com/akm/en/file/datasheet/AK09916C.pdf //Magnetometer Registers #define AK09916_ADDRESS 0x0C #define WHO_AM_I_AK09916 0x01 // (AKA WIA2) should return 0x09 #define AK09916_ST1 0x10 // data ready status bit 0 #define AK09916_XOUT_L 0x11 // data #define AK09916_XOUT_H 0x12 #define AK09916_YOUT_L 0x13 #define AK09916_YOUT_H 0x14 #define AK09916_ZOUT_L 0x15 #define AK09916_ZOUT_H 0x16 #define AK09916_ST2 0x18 // Data overflow bit 3 and data read error status bit 2 #define AK09916_CNTL 0x30 // Power down (0000), single-measurement (0001), self-test (1000) and Fuse ROM (1111) modes on bits 3:0 #define AK09916_CNTL2 0x31 // Normal (0), Reset (1) // ICM-20948 // USER BANK 0 REGISTER MAP #define WHO_AM_I_ICM20948 0x00 // Should return 0xEA #define USER_CTRL 0x03 // Bit 7 enable DMP, bit 3 reset DMP #define LP_CONFIG 0x05 // Not found in MPU-9250 #define PWR_MGMT_1 0x06 // Device defaults to the SLEEP mode #define PWR_MGMT_2 0x07 #define INT_PIN_CFG 0x0F #define INT_ENABLE 0x10 #define INT_ENABLE_1 0x11 // Not found in MPU-9250 #define INT_ENABLE_2 0x12 // Not found in MPU-9250 #define INT_ENABLE_3 0x13 // Not found in MPU-9250 #define I2C_MST_STATUS 0x17 #define INT_STATUS 0x19 #define INT_STATUS_1 0x1A // Not found in MPU-9250 #define INT_STATUS_2 0x1B // Not found in MPU-9250 #define INT_STATUS_3 0x1C // Not found in MPU-9250 #define DELAY_TIMEH 0x28 // Not found in MPU-9250 #define DELAY_TIMEL 0x29 // Not found in MPU-9250 #define ACCEL_XOUT_H 0x2D #define ACCEL_XOUT_L 0x2E #define ACCEL_YOUT_H 0x2F #define ACCEL_YOUT_L 0x30 #define ACCEL_ZOUT_H 0x31 #define ACCEL_ZOUT_L 0x32 #define GYRO_XOUT_H 0x33 #define GYRO_XOUT_L 0x34 #define GYRO_YOUT_H 0x35 #define GYRO_YOUT_L 0x36 #define GYRO_ZOUT_H 0x37 #define GYRO_ZOUT_L 0x38 #define TEMP_OUT_H 0x39 #define TEMP_OUT_L 0x3A #define EXT_SENS_DATA_00 0x3B #define EXT_SENS_DATA_01 0x3C #define EXT_SENS_DATA_02 0x3D #define EXT_SENS_DATA_03 0x3E #define EXT_SENS_DATA_04 0x3F #define EXT_SENS_DATA_05 0x40 #define EXT_SENS_DATA_06 0x41 #define EXT_SENS_DATA_07 0x42 #define EXT_SENS_DATA_08 0x43 #define EXT_SENS_DATA_09 0x44 #define EXT_SENS_DATA_10 0x45 #define EXT_SENS_DATA_11 0x46 #define EXT_SENS_DATA_12 0x47 #define EXT_SENS_DATA_13 0x48 #define EXT_SENS_DATA_14 0x49 #define EXT_SENS_DATA_15 0x4A #define EXT_SENS_DATA_16 0x4B #define EXT_SENS_DATA_17 0x4C #define EXT_SENS_DATA_18 0x4D #define EXT_SENS_DATA_19 0x4E #define EXT_SENS_DATA_20 0x4F #define EXT_SENS_DATA_21 0x50 #define EXT_SENS_DATA_22 0x51 #define EXT_SENS_DATA_23 0x52 #define FIFO_EN_1 0x66 #define FIFO_EN_2 0x67 // Not found in MPU-9250 #define FIFO_RST 0x68 // Not found in MPU-9250 #define FIFO_MODE 0x69 // Not found in MPU-9250 #define FIFO_COUNTH 0x70 #define FIFO_COUNTL 0x71 #define FIFO_R_W 0x72 #define DATA_RDY_STATUS 0x74 // Not found in MPU-9250 #define FIFO_CFG 0x76 // Not found in MPU-9250 #define REG_BANK_SEL 0x7F // Not found in MPU-9250 // USER BANK 1 REGISTER MAP #define SELF_TEST_X_GYRO 0x02 #define SELF_TEST_Y_GYRO 0x03 #define SELF_TEST_Z_GYRO 0x04 #define SELF_TEST_X_ACCEL 0x0E #define SELF_TEST_Y_ACCEL 0x0F #define SELF_TEST_Z_ACCEL 0x10 #define XA_OFFSET_H 0x14 #define XA_OFFSET_L 0x15 #define YA_OFFSET_H 0x17 #define YA_OFFSET_L 0x18 #define ZA_OFFSET_H 0x1A #define ZA_OFFSET_L 0x1B #define TIMEBASE_CORRECTION_PLL 0x28 // USER BANK 2 REGISTER MAP #define GYRO_SMPLRT_DIV 0x00 // Not found in MPU-9250 #define GYRO_CONFIG_1 0x01 // Not found in MPU-9250 #define GYRO_CONFIG_2 0x02 // Not found in MPU-9250 #define XG_OFFSET_H 0x03 // User-defined trim values for gyroscope #define XG_OFFSET_L 0x04 #define YG_OFFSET_H 0x05 #define YG_OFFSET_L 0x06 #define ZG_OFFSET_H 0x07 #define ZG_OFFSET_L 0x08 #define ODR_ALIGN_EN 0x09 // Not found in MPU-9250 #define ACCEL_SMPLRT_DIV_1 0x10 // Not found in MPU-9250 #define ACCEL_SMPLRT_DIV_2 0x11 // Not found in MPU-9250 #define ACCEL_INTEL_CTRL 0x12 // Not found in MPU-9250 #define ACCEL_WOM_THR 0x13 // Not found in MPU-9250 (could be WOM_THR) #define ACCEL_CONFIG 0x14 #define ACCEL_CONFIG_2 0x15 // Not found in MPU-9250 (could be ACCEL_CONFIG2) #define FSYNC_CONFIG 0x52 // Not found in MPU-9250 #define TEMP_CONFIG 0x53 // Not found in MPU-9250 #define MOD_CTRL_USR 0x54 // Not found in MPU-9250 // USER BANK 3 REGISTER MAP #define I2C_MST_ODR_CONFIG 0x00 // Not found in MPU-9250 #define I2C_MST_CTRL 0x01 #define I2C_MST_DELAY_CTRL 0x02 #define I2C_SLV0_ADDR 0x03 #define I2C_SLV0_REG 0x04 #define I2C_SLV0_CTRL 0x05 #define I2C_SLV0_DO 0x06 #define I2C_SLV1_ADDR 0x07 #define I2C_SLV1_REG 0x08 #define I2C_SLV1_CTRL 0x09 #define I2C_SLV1_DO 0x0A #define I2C_SLV2_ADDR 0x0B #define I2C_SLV2_REG 0x0C #define I2C_SLV2_CTRL 0x0D #define I2C_SLV2_DO 0x0E #define I2C_SLV3_ADDR 0x0F #define I2C_SLV3_REG 0x10 #define I2C_SLV3_CTRL 0x11 #define I2C_SLV3_DO 0x12 #define I2C_SLV4_ADDR 0x13 #define I2C_SLV4_REG 0x14 #define I2C_SLV4_CTRL 0x15 #define I2C_SLV4_DO 0x16 #define I2C_SLV4_DI 0x17 // Using the ICM-20948 breakout board, ADO is set to 1 // Seven-bit device address is 1000100 for ADO = 0 and 1000101 for ADO = 1 #define ADO 1 #if ADO #define ICM20948_ADDRESS 0x69 // Device address when ADO = 1 #else #define ICM20948_ADDRESS 0x68 // Device address when ADO = 0 #define AK09916_ADDRESS 0x0C // Address of magnetometer #endif // AD0 #define READ_FLAG 0x80 #define NOT_SPI -1 #define SPI_DATA_RATE 1000000 // 1MHz is the max speed of the ICM-20948 //#define SPI_DATA_RATE 1000000 // 1MHz is the max speed of the ICM-20948 #define SPI_MODE SPI_MODE3 class ICM20948 { protected: // Set initial input parameters enum Ascale { AFS_2G = 0, AFS_4G, AFS_8G, AFS_16G }; enum Gscale { GFS_250DPS = 0, GFS_500DPS, GFS_1000DPS, GFS_2000DPS }; enum Mscale { MFS_14BITS = 0, // 0.6 mG per LSB MFS_16BITS // 0.15 mG per LSB }; enum M_MODE { M_8HZ = 0x02, // 8 Hz update M_100HZ = 0x06 // 100 Hz continuous magnetometer }; // TODO: Add setter methods for this hard coded stuff // Specify sensor full scale uint8_t Gscale = GFS_250DPS; uint8_t Ascale = AFS_2G; // 2 for 8 Hz, 6 for 100 Hz continuous magnetometer data read uint8_t Mmode = M_100HZ; // SPI chip select pin int8_t _csPin; uint8_t writeByteWire(uint8_t, uint8_t, uint8_t); uint8_t writeByteSPI(uint8_t, uint8_t); uint8_t readByteSPI(uint8_t subAddress); uint8_t readByteWire(uint8_t address, uint8_t subAddress); bool magInit(); void kickHardware(); void select(); void deselect(); // TODO: Remove this next line public: uint8_t ak09916WhoAmI_SPI(); public: float pitch, yaw, roll; float temperature; // Stores the real internal chip temperature in Celsius int16_t tempCount; // Temperature raw count output uint32_t delt_t = 0; // Used to control display output rate uint32_t count = 0, sumCount = 0; // used to control display output rate float deltat = 0.0f, sum = 0.0f; // integration interval for both filter schemes uint32_t lastUpdate = 0, firstUpdate = 0; // used to calculate integration interval uint32_t Now = 0; // used to calculate integration interval int16_t gyroCount[3]; // Stores the 16-bit signed gyro sensor output int16_t magCount[3]; // Stores the 16-bit signed magnetometer sensor output // Scale resolutions per LSB for the sensors float aRes, gRes, mRes; // Variables to hold latest sensor data values float ax, ay, az, gx, gy, gz, mx, my, mz; // Factory mag calibration and mag bias float factoryMagCalibration[3] = {0, 0, 0}, factoryMagBias[3] = {0, 0, 0}; // Bias corrections for gyro, accelerometer, and magnetometer float gyroBias[3] = {0, 0, 0}, accelBias[3] = {0, 0, 0}, magBias[3] = {0, 0, 0}, magScale[3] = {0, 0, 0}; float selfTest[6]; // Stores the 16-bit signed accelerometer sensor output int16_t accelCount[3]; // Public method declarations ICM20948(int8_t csPin=NOT_SPI); void getMres(); void getGres(); void getAres(); void readAccelData(int16_t *); void readGyroData(int16_t *); void readMagData(int16_t *); int16_t readTempData(); void updateTime(); void initAK09916(); void initICM20948(); void calibrateICM20948(float * gyroBias, float * accelBias); void ICM20948SelfTest(float * destination); void magCalICM20948(float * dest1, float * dest2); uint8_t writeByte(uint8_t, uint8_t, uint8_t); uint8_t readByte(uint8_t, uint8_t); uint8_t readBytes(uint8_t, uint8_t, uint8_t, uint8_t *); // TODO: make SPI/Wire private uint8_t readBytesSPI(uint8_t, uint8_t, uint8_t *); uint8_t readBytesWire(uint8_t, uint8_t, uint8_t, uint8_t *); bool isInI2cMode() { return _csPin == -1; } bool begin(); }; // class ICM20948 #endif // _ICM20948_H_