Modified Arduino library for ICM_20948 IMU for Nucleo boards

Committer:
saloutos
Date:
Mon Jan 31 03:25:31 2022 +0000
Revision:
0:894b603d32ee
modified ICM_20948 Arduino library for Nucleo boards

Who changed what in which revision?

UserRevisionLine numberNew contents of line
saloutos 0:894b603d32ee 1 /*
saloutos 0:894b603d32ee 2
saloutos 0:894b603d32ee 3 A C++ interface to the ICM-20948
saloutos 0:894b603d32ee 4
saloutos 0:894b603d32ee 5 */
saloutos 0:894b603d32ee 6
saloutos 0:894b603d32ee 7
saloutos 0:894b603d32ee 8 // Modified from Arduino library at https://github.com/sparkfun/SparkFun_ICM-20948_ArduinoLibrary
saloutos 0:894b603d32ee 9
saloutos 0:894b603d32ee 10 #ifndef _ICM_20948_H_
saloutos 0:894b603d32ee 11 #define _ICM_20948_H_
saloutos 0:894b603d32ee 12
saloutos 0:894b603d32ee 13 #include "util/ICM_20948_C.h" // The C backbone. ICM_20948_USE_DMP is defined in here.
saloutos 0:894b603d32ee 14 #include "util/AK09916_REGISTERS.h"
saloutos 0:894b603d32ee 15
saloutos 0:894b603d32ee 16 #include "mbed.h"
saloutos 0:894b603d32ee 17
saloutos 0:894b603d32ee 18 #define ICM_20948_ARD_UNUSED_PIN 0xFF
saloutos 0:894b603d32ee 19
saloutos 0:894b603d32ee 20 // Base
saloutos 0:894b603d32ee 21 class ICM_20948
saloutos 0:894b603d32ee 22 {
saloutos 0:894b603d32ee 23 private:
saloutos 0:894b603d32ee 24
saloutos 0:894b603d32ee 25
saloutos 0:894b603d32ee 26 const uint8_t MAX_MAGNETOMETER_STARTS = 10; // This replaces maxTries
saloutos 0:894b603d32ee 27
saloutos 0:894b603d32ee 28 protected:
saloutos 0:894b603d32ee 29 ICM_20948_Device_t _device;
saloutos 0:894b603d32ee 30
saloutos 0:894b603d32ee 31 float getTempC(int16_t val);
saloutos 0:894b603d32ee 32 float getGyrDPS(int16_t axis_val);
saloutos 0:894b603d32ee 33 float getAccMG(int16_t axis_val);
saloutos 0:894b603d32ee 34 float getMagUT(int16_t axis_val);
saloutos 0:894b603d32ee 35
saloutos 0:894b603d32ee 36 public:
saloutos 0:894b603d32ee 37 ICM_20948(); // Constructor
saloutos 0:894b603d32ee 38
saloutos 0:894b603d32ee 39 Serial *_debugSerial; // change to serial port
saloutos 0:894b603d32ee 40 bool _printDebug = false; //Flag to print the serial commands we are sending to the Serial port for debug
saloutos 0:894b603d32ee 41
saloutos 0:894b603d32ee 42 void enableDebugging(Serial &debugPort); // TODO: check this syntax
saloutos 0:894b603d32ee 43
saloutos 0:894b603d32ee 44 void disableDebugging(void); //Turn off debug statements
saloutos 0:894b603d32ee 45
saloutos 0:894b603d32ee 46 void debugPrintStatus(ICM_20948_Status_e stat);
saloutos 0:894b603d32ee 47
saloutos 0:894b603d32ee 48 ICM_20948_AGMT_t agmt; // Acceleometer, Gyroscope, Magenetometer, and Temperature data
saloutos 0:894b603d32ee 49 ICM_20948_AGMT_t getAGMT(void); // Updates the agmt field in the object and also returns a copy directly
saloutos 0:894b603d32ee 50
saloutos 0:894b603d32ee 51 float magX(void); // micro teslas
saloutos 0:894b603d32ee 52 float magY(void); // micro teslas
saloutos 0:894b603d32ee 53 float magZ(void); // micro teslas
saloutos 0:894b603d32ee 54
saloutos 0:894b603d32ee 55 float accX(void); // milli g's
saloutos 0:894b603d32ee 56 float accY(void); // milli g's
saloutos 0:894b603d32ee 57 float accZ(void); // milli g's
saloutos 0:894b603d32ee 58
saloutos 0:894b603d32ee 59 float gyrX(void); // degrees per second
saloutos 0:894b603d32ee 60 float gyrY(void); // degrees per second
saloutos 0:894b603d32ee 61 float gyrZ(void); // degrees per second
saloutos 0:894b603d32ee 62
saloutos 0:894b603d32ee 63 float temp(void); // degrees celsius
saloutos 0:894b603d32ee 64
saloutos 0:894b603d32ee 65 ICM_20948_Status_e status; // Status from latest operation
saloutos 0:894b603d32ee 66
saloutos 0:894b603d32ee 67 // Device Level
saloutos 0:894b603d32ee 68 ICM_20948_Status_e setBank(uint8_t bank); // Sets the bank
saloutos 0:894b603d32ee 69 ICM_20948_Status_e swReset(void); // Performs a SW reset
saloutos 0:894b603d32ee 70 ICM_20948_Status_e sleep(bool on = false); // Set sleep mode for the chip
saloutos 0:894b603d32ee 71 ICM_20948_Status_e lowPower(bool on = true); // Set low power mode for the chip
saloutos 0:894b603d32ee 72 ICM_20948_Status_e setClockSource(ICM_20948_PWR_MGMT_1_CLKSEL_e source); // Choose clock source
saloutos 0:894b603d32ee 73 ICM_20948_Status_e checkID(void); // Return 'ICM_20948_Stat_Ok' if whoami matches ICM_20948_WHOAMI
saloutos 0:894b603d32ee 74
saloutos 0:894b603d32ee 75 bool dataReady(void); // Returns 'true' if data is ready
saloutos 0:894b603d32ee 76 uint8_t getWhoAmI(void); // Return whoami in out prarmeter
saloutos 0:894b603d32ee 77 bool isConnected(void); // Returns true if communications with the device are sucessful
saloutos 0:894b603d32ee 78
saloutos 0:894b603d32ee 79 // Internal Sensor Options
saloutos 0:894b603d32ee 80 ICM_20948_Status_e setSampleMode(uint8_t sensor_id_bm, uint8_t lp_config_cycle_mode); // Use to set accel, gyro, and I2C master into cycled or continuous modes
saloutos 0:894b603d32ee 81 ICM_20948_Status_e setFullScale(uint8_t sensor_id_bm, ICM_20948_fss_t fss);
saloutos 0:894b603d32ee 82 ICM_20948_Status_e setDLPFcfg(uint8_t sensor_id_bm, ICM_20948_dlpcfg_t cfg);
saloutos 0:894b603d32ee 83 ICM_20948_Status_e enableDLPF(uint8_t sensor_id_bm, bool enable);
saloutos 0:894b603d32ee 84 ICM_20948_Status_e setSampleRate(uint8_t sensor_id_bm, ICM_20948_smplrt_t smplrt);
saloutos 0:894b603d32ee 85
saloutos 0:894b603d32ee 86 // Interrupts on INT and FSYNC Pins
saloutos 0:894b603d32ee 87 ICM_20948_Status_e clearInterrupts(void);
saloutos 0:894b603d32ee 88
saloutos 0:894b603d32ee 89 ICM_20948_Status_e cfgIntActiveLow(bool active_low);
saloutos 0:894b603d32ee 90 ICM_20948_Status_e cfgIntOpenDrain(bool open_drain);
saloutos 0:894b603d32ee 91 ICM_20948_Status_e cfgIntLatch(bool latching); // If not latching then the interrupt is a 50 us pulse
saloutos 0:894b603d32ee 92 ICM_20948_Status_e cfgIntAnyReadToClear(bool enabled); // If enabled, *ANY* read will clear the INT_STATUS register. So if you have multiple interrupt sources enabled be sure to read INT_STATUS first
saloutos 0:894b603d32ee 93 ICM_20948_Status_e cfgFsyncActiveLow(bool active_low);
saloutos 0:894b603d32ee 94 ICM_20948_Status_e cfgFsyncIntMode(bool interrupt_mode); // Can use FSYNC as an interrupt input that sets the I2C Master Status register's PASS_THROUGH bit
saloutos 0:894b603d32ee 95
saloutos 0:894b603d32ee 96 ICM_20948_Status_e intEnableI2C(bool enable);
saloutos 0:894b603d32ee 97 ICM_20948_Status_e intEnableDMP(bool enable);
saloutos 0:894b603d32ee 98 ICM_20948_Status_e intEnablePLL(bool enable);
saloutos 0:894b603d32ee 99 ICM_20948_Status_e intEnableWOM(bool enable);
saloutos 0:894b603d32ee 100 ICM_20948_Status_e intEnableWOF(bool enable);
saloutos 0:894b603d32ee 101 ICM_20948_Status_e intEnableRawDataReady(bool enable);
saloutos 0:894b603d32ee 102 ICM_20948_Status_e intEnableOverflowFIFO(uint8_t bm_enable);
saloutos 0:894b603d32ee 103 ICM_20948_Status_e intEnableWatermarkFIFO(uint8_t bm_enable);
saloutos 0:894b603d32ee 104
saloutos 0:894b603d32ee 105 ICM_20948_Status_e WOMThreshold(uint8_t threshold);
saloutos 0:894b603d32ee 106
saloutos 0:894b603d32ee 107 // Interface Options
saloutos 0:894b603d32ee 108 ICM_20948_Status_e i2cMasterPassthrough(bool passthrough = true);
saloutos 0:894b603d32ee 109 ICM_20948_Status_e i2cMasterEnable(bool enable = true);
saloutos 0:894b603d32ee 110 ICM_20948_Status_e i2cMasterReset();
saloutos 0:894b603d32ee 111
saloutos 0:894b603d32ee 112 //Used for configuring peripherals 0-3
saloutos 0:894b603d32ee 113 ICM_20948_Status_e i2cControllerConfigurePeripheral(uint8_t peripheral, uint8_t addr, uint8_t reg, uint8_t len, bool Rw = true, bool enable = true, bool data_only = false, bool grp = false, bool swap = false, uint8_t dataOut = 0);
saloutos 0:894b603d32ee 114 ICM_20948_Status_e i2cControllerPeriph4Transaction(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len, bool Rw, bool send_reg_addr = true);
saloutos 0:894b603d32ee 115
saloutos 0:894b603d32ee 116 //Used for configuring the Magnetometer
saloutos 0:894b603d32ee 117 ICM_20948_Status_e i2cMasterSingleW(uint8_t addr, uint8_t reg, uint8_t data);
saloutos 0:894b603d32ee 118 uint8_t i2cMasterSingleR(uint8_t addr, uint8_t reg);
saloutos 0:894b603d32ee 119
saloutos 0:894b603d32ee 120 // Default Setup
saloutos 0:894b603d32ee 121 ICM_20948_Status_e startupDefault(bool minimal = false); // If minimal is true, several startup steps are skipped. If ICM_20948_USE_DMP is defined, .begin will call startupDefault with minimal set to true.
saloutos 0:894b603d32ee 122
saloutos 0:894b603d32ee 123 // direct read/write
saloutos 0:894b603d32ee 124 ICM_20948_Status_e read(uint8_t reg, uint8_t *pdata, uint32_t len);
saloutos 0:894b603d32ee 125 ICM_20948_Status_e write(uint8_t reg, uint8_t *pdata, uint32_t len);
saloutos 0:894b603d32ee 126
saloutos 0:894b603d32ee 127 //Mag specific
saloutos 0:894b603d32ee 128 ICM_20948_Status_e startupMagnetometer(bool minimal = false); // If minimal is true, several startup steps are skipped. The mag then needs to be set up manually for the DMP.
saloutos 0:894b603d32ee 129 ICM_20948_Status_e magWhoIAm(void);
saloutos 0:894b603d32ee 130 uint8_t readMag(AK09916_Reg_Addr_e reg);
saloutos 0:894b603d32ee 131 ICM_20948_Status_e writeMag(AK09916_Reg_Addr_e reg, uint8_t *pdata);
saloutos 0:894b603d32ee 132 ICM_20948_Status_e resetMag();
saloutos 0:894b603d32ee 133
saloutos 0:894b603d32ee 134 //FIFO
saloutos 0:894b603d32ee 135 ICM_20948_Status_e enableFIFO(bool enable = true);
saloutos 0:894b603d32ee 136 ICM_20948_Status_e resetFIFO(void);
saloutos 0:894b603d32ee 137 ICM_20948_Status_e setFIFOmode(bool snapshot = false); // Default to Stream (non-Snapshot) mode
saloutos 0:894b603d32ee 138 ICM_20948_Status_e getFIFOcount(uint16_t *count);
saloutos 0:894b603d32ee 139 ICM_20948_Status_e readFIFO(uint8_t *data, uint8_t len = 1);
saloutos 0:894b603d32ee 140
saloutos 0:894b603d32ee 141 //DMP
saloutos 0:894b603d32ee 142
saloutos 0:894b603d32ee 143 // Done:
saloutos 0:894b603d32ee 144 // Configure DMP start address through PRGM_STRT_ADDRH/PRGM_STRT_ADDRL
saloutos 0:894b603d32ee 145 // Load Firmware
saloutos 0:894b603d32ee 146 // Configure Accel scaling to DMP
saloutos 0:894b603d32ee 147 // Configure Compass mount matrix and scale to DMP
saloutos 0:894b603d32ee 148 // Reset FIFO
saloutos 0:894b603d32ee 149 // Reset DMP
saloutos 0:894b603d32ee 150 // Enable DMP interrupt
saloutos 0:894b603d32ee 151 // Configuring DMP to output data to FIFO: set DATA_OUT_CTL1, DATA_OUT_CTL2, DATA_INTR_CTL and MOTION_EVENT_CTL
saloutos 0:894b603d32ee 152 // Configuring DMP to output data at multiple ODRs
saloutos 0:894b603d32ee 153 // Configure DATA_RDY_STATUS
saloutos 0:894b603d32ee 154 // Configuring Accel calibration
saloutos 0:894b603d32ee 155 // Configuring Compass calibration
saloutos 0:894b603d32ee 156 // Configuring Gyro gain
saloutos 0:894b603d32ee 157 // Configuring Accel gain
saloutos 0:894b603d32ee 158 // Configure I2C_SLV0 and I2C_SLV1 to: request mag data from the hidden reserved AK09916 registers; trigger Single Measurements
saloutos 0:894b603d32ee 159 // Configure I2C Master ODR (default to 68.75Hz)
saloutos 0:894b603d32ee 160
saloutos 0:894b603d32ee 161 // To Do:
saloutos 0:894b603d32ee 162 // Additional FIFO output control: FIFO_WATERMARK, BM_BATCH_MASK, BM_BATCH_CNTR, BM_BATCH_THLD
saloutos 0:894b603d32ee 163 // Configuring DMP features: PED_STD_STEPCTR, PED_STD_TIMECTR
saloutos 0:894b603d32ee 164 // Enabling Activity Recognition (BAC) feature
saloutos 0:894b603d32ee 165 // Enabling Significant Motion Detect (SMD) feature
saloutos 0:894b603d32ee 166 // Enabling Tilt Detector feature
saloutos 0:894b603d32ee 167 // Enabling Pick Up Gesture feature
saloutos 0:894b603d32ee 168 // Enabling Fsync detection feature
saloutos 0:894b603d32ee 169 // Biases: add save and load methods
saloutos 0:894b603d32ee 170
saloutos 0:894b603d32ee 171 ICM_20948_Status_e enableDMP(bool enable = true);
saloutos 0:894b603d32ee 172 ICM_20948_Status_e resetDMP(void);
saloutos 0:894b603d32ee 173 ICM_20948_Status_e loadDMPFirmware(void);
saloutos 0:894b603d32ee 174 ICM_20948_Status_e setDMPstartAddress(unsigned short address = DMP_START_ADDRESS);
saloutos 0:894b603d32ee 175 ICM_20948_Status_e enableDMPSensor(enum inv_icm20948_sensor sensor, bool enable = true);
saloutos 0:894b603d32ee 176 ICM_20948_Status_e enableDMPSensorInt(enum inv_icm20948_sensor sensor, bool enable = true);
saloutos 0:894b603d32ee 177 ICM_20948_Status_e writeDMPmems(unsigned short reg, unsigned int length, const unsigned char *data);
saloutos 0:894b603d32ee 178 ICM_20948_Status_e readDMPmems(unsigned short reg, unsigned int length, unsigned char *data);
saloutos 0:894b603d32ee 179 ICM_20948_Status_e setDMPODRrate(enum DMP_ODR_Registers odr_reg, int interval);
saloutos 0:894b603d32ee 180 ICM_20948_Status_e readDMPdataFromFIFO(icm_20948_DMP_data_t *data);
saloutos 0:894b603d32ee 181 ICM_20948_Status_e setGyroSF(unsigned char div, int gyro_level);
saloutos 0:894b603d32ee 182 ICM_20948_Status_e initializeDMP(void) __attribute__((weak)); // Combine all of the DMP start-up code in one place. Can be overwritten if required
saloutos 0:894b603d32ee 183 };
saloutos 0:894b603d32ee 184
saloutos 0:894b603d32ee 185 // SPI
saloutos 0:894b603d32ee 186 #define ICM_20948_SPI_DEFAULT_FREQ 4000000
saloutos 0:894b603d32ee 187 #define ICM_20948_SPI_DEFAULT_ORDER MSBFIRST
saloutos 0:894b603d32ee 188 #define ICM_20948_SPI_DEFAULT_MODE SPI_MODE0
saloutos 0:894b603d32ee 189
saloutos 0:894b603d32ee 190 class ICM_20948_SPI : public ICM_20948
saloutos 0:894b603d32ee 191 {
saloutos 0:894b603d32ee 192 private:
saloutos 0:894b603d32ee 193 protected:
saloutos 0:894b603d32ee 194 public:
saloutos 0:894b603d32ee 195
saloutos 0:894b603d32ee 196 SPI *_spi;
saloutos 0:894b603d32ee 197 DigitalOut *_cs;
saloutos 0:894b603d32ee 198 ICM_20948_Serif_t _serif;
saloutos 0:894b603d32ee 199
saloutos 0:894b603d32ee 200 ICM_20948_SPI(); // Constructor
saloutos 0:894b603d32ee 201
saloutos 0:894b603d32ee 202 // ICM_20948_Status_e begin(uint8_t csPin, SPIClass &spiPort = SPI, uint32_t SPIFreq = ICM_20948_SPI_DEFAULT_FREQ);
saloutos 0:894b603d32ee 203 ICM_20948_Status_e begin(DigitalOut &cspin, SPI &spiPort, uint32_t SPIFreq = ICM_20948_SPI_DEFAULT_FREQ); // TODO: check this!
saloutos 0:894b603d32ee 204 };
saloutos 0:894b603d32ee 205
saloutos 0:894b603d32ee 206 #endif /* _ICM_20948_H_ */