JeVois  1.22
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Loading...
Searching...
No Matches
ICM_20948.h
Go to the documentation of this file.
1/*
2
3A C++ interface to the ICM-20948
4
5*/
6
7#ifndef _ICM_20948_H_
8#define _ICM_20948_H_
9
10#include "util/ICM_20948_C.h" // The C backbone. ICM_20948_USE_DMP is defined in here.
12
13#include "Arduino.h" // Arduino support
14#include "Wire.h"
15#include "SPI.h"
16
17#define ICM_20948_ARD_UNUSED_PIN 0xFF
18
19// Base
21{
22private:
23 Stream *_debugSerial; //The stream to send debug messages to if enabled
24 bool _printDebug = false; //Flag to print the serial commands we are sending to the Serial port for debug
25
26 const uint8_t MAX_MAGNETOMETER_STARTS = 10; // This replaces maxTries
27
28protected:
30
31 float getTempC(int16_t val);
32 float getGyrDPS(int16_t axis_val);
33 float getAccMG(int16_t axis_val);
34 float getMagUT(int16_t axis_val);
35
36public:
37 ICM_20948(); // Constructor
38
39// Enable debug messages using the chosen Serial port (Stream)
40// Boards like the RedBoard Turbo use SerialUSB (not Serial).
41// But other boards like the SAMD51 Thing Plus use Serial (not SerialUSB).
42// These lines let the code compile cleanly on as many SAMD boards as possible.
43#if defined(ARDUINO_ARCH_SAMD) // Is this a SAMD board?
44#if defined(USB_VID) // Is the USB Vendor ID defined?
45#if (USB_VID == 0x1B4F) // Is this a SparkFun board?
46#if !defined(ARDUINO_SAMD51_THING_PLUS) & !defined(ARDUINO_SAMD51_MICROMOD) // If it is not a SAMD51 Thing Plus or SAMD51 MicroMod
47 void enableDebugging(Stream &debugPort = SerialUSB); //Given a port to print to, enable debug messages.
48#else
49 void enableDebugging(Stream &debugPort = Serial); //Given a port to print to, enable debug messages.
50#endif
51#else
52 void enableDebugging(Stream &debugPort = Serial); //Given a port to print to, enable debug messages.
53#endif
54#else
55 void enableDebugging(Stream &debugPort = Serial); //Given a port to print to, enable debug messages.
56#endif
57#else
58 void enableDebugging(Stream &debugPort = Serial); //Given a port to print to, enable debug messages.
59#endif
60
61 void disableDebugging(void); //Turn off debug statements
62
64
65 // gfvalvo's flash string helper code: https://forum.arduino.cc/index.php?topic=533118.msg3634809#msg3634809
66 void debugPrint(const char *);
67 void debugPrint(const __FlashStringHelper *);
68 void debugPrintln(const char *);
69 void debugPrintln(const __FlashStringHelper *);
70 void doDebugPrint(char (*)(const char *), const char *, bool newLine = false);
71
72 void debugPrintf(int i);
73 void debugPrintf(float f);
74
75 ICM_20948_AGMT_t agmt; // Acceleometer, Gyroscope, Magenetometer, and Temperature data
76 ICM_20948_AGMT_t getAGMT(void); // Updates the agmt field in the object and also returns a copy directly
77
78 float magX(void); // micro teslas
79 float magY(void); // micro teslas
80 float magZ(void); // micro teslas
81
82 float accX(void); // milli g's
83 float accY(void); // milli g's
84 float accZ(void); // milli g's
85
86 float gyrX(void); // degrees per second
87 float gyrY(void); // degrees per second
88 float gyrZ(void); // degrees per second
89
90 float temp(void); // degrees celsius
91
92 ICM_20948_Status_e status; // Status from latest operation
93 const char *statusString(ICM_20948_Status_e stat = ICM_20948_Stat_NUM); // Returns a human-readable status message. Defaults to status member, but prints string for supplied status if supplied
94
95 // Device Level
96 ICM_20948_Status_e setBank(uint8_t bank); // Sets the bank
97 ICM_20948_Status_e swReset(void); // Performs a SW reset
98 ICM_20948_Status_e sleep(bool on = false); // Set sleep mode for the chip
99 ICM_20948_Status_e lowPower(bool on = true); // Set low power mode for the chip
101 ICM_20948_Status_e checkID(void); // Return 'ICM_20948_Stat_Ok' if whoami matches ICM_20948_WHOAMI
102
103 bool dataReady(void); // Returns 'true' if data is ready
104 uint8_t getWhoAmI(void); // Return whoami in out prarmeter
105 bool isConnected(void); // Returns true if communications with the device are sucessful
106
107 // Internal Sensor Options
108 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
111 ICM_20948_Status_e enableDLPF(uint8_t sensor_id_bm, bool enable);
113
114 // Interrupts on INT and FSYNC Pins
116
119 ICM_20948_Status_e cfgIntLatch(bool latching); // If not latching then the interrupt is a 50 us pulse
120 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
122 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
123
132
133 ICM_20948_Status_e WOMLogic(uint8_t enable, uint8_t mode);
135
136 // Interface Options
137 ICM_20948_Status_e i2cMasterPassthrough(bool passthrough = true);
140
141 //Used for configuring peripherals 0-3
142 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);
143 ICM_20948_Status_e i2cControllerPeriph4Transaction(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len, bool Rw, bool send_reg_addr = true);
144
145 //Provided for backward-compatibility only. Please update to i2cControllerConfigurePeripheral and i2cControllerPeriph4Transaction.
146 //https://www.oshwa.org/2020/06/29/a-resolution-to-redefine-spi-pin-names/
147 ICM_20948_Status_e i2cMasterConfigureSlave(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);
148 ICM_20948_Status_e i2cMasterSLV4Transaction(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len, bool Rw, bool send_reg_addr = true);
149
150 //Used for configuring the Magnetometer
151 ICM_20948_Status_e i2cMasterSingleW(uint8_t addr, uint8_t reg, uint8_t data);
152 uint8_t i2cMasterSingleR(uint8_t addr, uint8_t reg);
153
154 // Default Setup
155 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.
156
157 // direct read/write
158 ICM_20948_Status_e read(uint8_t reg, uint8_t *pdata, uint32_t len);
159 ICM_20948_Status_e write(uint8_t reg, uint8_t *pdata, uint32_t len);
160
161 //Mag specific
162 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.
167
168 //FIFO
169 ICM_20948_Status_e enableFIFO(bool enable = true);
171 ICM_20948_Status_e setFIFOmode(bool snapshot = false); // Default to Stream (non-Snapshot) mode
173 ICM_20948_Status_e readFIFO(uint8_t *data, uint8_t len = 1);
174
175 //DMP
176
177 //Gyro Bias
184 //Accel Bias
191 //CPass Bias
198
199 // Done:
200 // Configure DMP start address through PRGM_STRT_ADDRH/PRGM_STRT_ADDRL
201 // Load Firmware
202 // Configure Accel scaling to DMP
203 // Configure Compass mount matrix and scale to DMP
204 // Reset FIFO
205 // Reset DMP
206 // Enable DMP interrupt
207 // Configuring DMP to output data to FIFO: set DATA_OUT_CTL1, DATA_OUT_CTL2, DATA_INTR_CTL and MOTION_EVENT_CTL
208 // Configuring DMP to output data at multiple ODRs
209 // Configure DATA_RDY_STATUS
210 // Configuring Accel calibration
211 // Configuring Compass calibration
212 // Configuring Gyro gain
213 // Configuring Accel gain
214 // Configure I2C_SLV0 and I2C_SLV1 to: request mag data from the hidden reserved AK09916 registers; trigger Single Measurements
215 // Configure I2C Master ODR (default to 68.75Hz)
216
217 // To Do:
218 // Additional FIFO output control: FIFO_WATERMARK, BM_BATCH_MASK, BM_BATCH_CNTR, BM_BATCH_THLD
219 // Configuring DMP features: PED_STD_STEPCTR, PED_STD_TIMECTR
220 // Enabling Activity Recognition (BAC) feature
221 // Enabling Significant Motion Detect (SMD) feature
222 // Enabling Tilt Detector feature
223 // Enabling Pick Up Gesture feature
224 // Enabling Fsync detection feature
225 // Biases: add save and load methods
226
227 ICM_20948_Status_e enableDMP(bool enable = true);
233 ICM_20948_Status_e writeDMPmems(unsigned short reg, unsigned int length, const unsigned char *data);
234 ICM_20948_Status_e readDMPmems(unsigned short reg, unsigned int length, unsigned char *data);
237 ICM_20948_Status_e setGyroSF(unsigned char div, int gyro_level);
238 ICM_20948_Status_e initializeDMP(void) __attribute__((weak)); // Combine all of the DMP start-up code in one place. Can be overwritten if required
239};
240
241// I2C
242
243// Forward declarations of TwoWire and Wire for board/variant combinations that don't have a default 'SPI'
244//class TwoWire; // Commented by PaulZC 21/2/8 - this was causing compilation to fail on the Arduino NANO 33 BLE
245//extern TwoWire Wire; // Commented by PaulZC 21/2/8 - this was causing compilation to fail on the Arduino NANO 33 BLE
246
248{
249private:
250protected:
251public:
252 TwoWire *_i2c;
253 uint8_t _addr;
254 uint8_t _ad0;
257
258 ICM_20948_I2C(); // Constructor
259
260 virtual ICM_20948_Status_e begin(TwoWire &wirePort = Wire, bool ad0val = true, uint8_t ad0pin = ICM_20948_ARD_UNUSED_PIN);
261};
262
263// SPI
264#define ICM_20948_SPI_DEFAULT_FREQ 4000000
265#define ICM_20948_SPI_DEFAULT_ORDER MSBFIRST
266#define ICM_20948_SPI_DEFAULT_MODE SPI_MODE0
267
268// Forward declarations of SPIClass and SPI for board/variant combinations that don't have a default 'SPI'
269//class SPIClass; // Commented by PaulZC 21/2/8 - this was causing compilation to fail on the Arduino NANO 33 BLE
270//extern SPIClass SPI; // Commented by PaulZC 21/2/8 - this was causing compilation to fail on the Arduino NANO 33 BLE
271
273{
274private:
275protected:
276public:
277 SPIClass *_spi;
278 SPISettings _spisettings;
279 uint8_t _cs;
281
282 ICM_20948_SPI(); // Constructor
283
284 ICM_20948_Status_e begin(uint8_t csPin, SPIClass &spiPort = SPI, uint32_t SPIFreq = ICM_20948_SPI_DEFAULT_FREQ);
285};
286
287#endif /* _ICM_20948_H_ */
AK09916_Reg_Addr_e
#define DMP_START_ADDRESS
#define ICM_20948_SPI_DEFAULT_FREQ
Definition ICM_20948.h:264
#define ICM_20948_ARD_UNUSED_PIN
Definition ICM_20948.h:17
ICM_20948_Status_e
Definition ICM_20948_C.h:50
@ ICM_20948_Stat_NUM
Definition ICM_20948_C.h:68
DMP_ODR_Registers
inv_icm20948_sensor
Sensor identifier for control function.
ICM_20948_PWR_MGMT_1_CLKSEL_e
TwoWire * _i2c
Definition ICM_20948.h:252
virtual ICM_20948_Status_e begin(TwoWire &wirePort=Wire, bool ad0val=true, uint8_t ad0pin=ICM_20948_ARD_UNUSED_PIN)
ICM_20948_Serif_t _serif
Definition ICM_20948.h:256
uint8_t _ad0
Definition ICM_20948.h:254
uint8_t _addr
Definition ICM_20948.h:253
ICM_20948_Status_e begin(uint8_t csPin, SPIClass &spiPort=SPI, uint32_t SPIFreq=ICM_20948_SPI_DEFAULT_FREQ)
uint8_t _cs
Definition ICM_20948.h:279
ICM_20948_Serif_t _serif
Definition ICM_20948.h:280
SPIClass * _spi
Definition ICM_20948.h:277
SPISettings _spisettings
Definition ICM_20948.h:278
float magY(void)
ICM_20948_Status_e setBiasAccelZ(int32_t newValue)
float accZ(void)
float magX(void)
ICM_20948_Status_e intEnableWOM(bool enable)
ICM_20948_Status_e clearInterrupts(void)
ICM_20948_Status_e WOMLogic(uint8_t enable, uint8_t mode)
ICM_20948_Status_e readFIFO(uint8_t *data, uint8_t len=1)
bool dataReady(void)
float magZ(void)
ICM_20948_Status_e readDMPmems(unsigned short reg, unsigned int length, unsigned char *data)
ICM_20948_Status_e setBiasCPassZ(int32_t newValue)
ICM_20948_Status_e setDLPFcfg(uint8_t sensor_id_bm, ICM_20948_dlpcfg_t cfg)
float accX(void)
ICM_20948_Status_e read(uint8_t reg, uint8_t *pdata, uint32_t len)
ICM_20948_Status_e getBiasGyroZ(int32_t *bias)
void debugPrint(const char *)
void debugPrintln(const char *)
float getMagUT(int16_t axis_val)
ICM_20948_Status_e writeMag(AK09916_Reg_Addr_e reg, uint8_t *pdata)
ICM_20948_Status_e getBiasGyroX(int32_t *bias)
ICM_20948_Status_e setBiasAccelX(int32_t newValue)
ICM_20948_Status_e cfgFsyncIntMode(bool interrupt_mode)
ICM_20948_Status_e cfgFsyncActiveLow(bool active_low)
ICM_20948_AGMT_t agmt
Definition ICM_20948.h:75
ICM_20948_Status_e setBank(uint8_t bank)
ICM_20948_Status_e intEnableWOF(bool enable)
ICM_20948_Status_e getBiasCPassZ(int32_t *bias)
ICM_20948_Status_e enableDMP(bool enable=true)
ICM_20948_Status_e enableDLPF(uint8_t sensor_id_bm, bool enable)
void doDebugPrint(char(*)(const char *), const char *, bool newLine=false)
ICM_20948_Status_e intEnableDMP(bool enable)
ICM_20948_Status_e readDMPdataFromFIFO(icm_20948_DMP_data_t *data)
void debugPrintf(float f)
ICM_20948_Status_e getBiasGyroY(int32_t *bias)
ICM_20948_Status_e resetMag()
void debugPrint(const __FlashStringHelper *)
ICM_20948_Status_e setFullScale(uint8_t sensor_id_bm, ICM_20948_fss_t fss)
ICM_20948_Status_e getBiasAccelY(int32_t *bias)
uint8_t getWhoAmI(void)
ICM_20948_Status_e setFIFOmode(bool snapshot=false)
ICM_20948_Status_e resetDMP(void)
ICM_20948_Status_e intEnableOverflowFIFO(uint8_t bm_enable)
ICM_20948_Status_e i2cMasterPassthrough(bool passthrough=true)
ICM_20948_Status_e status
Definition ICM_20948.h:92
void disableDebugging(void)
uint8_t i2cMasterSingleR(uint8_t addr, uint8_t reg)
ICM_20948_Status_e writeDMPmems(unsigned short reg, unsigned int length, const unsigned char *data)
ICM_20948_Status_e intEnableI2C(bool enable)
ICM_20948_Status_e cfgIntActiveLow(bool active_low)
uint8_t readMag(AK09916_Reg_Addr_e reg)
ICM_20948_Status_e setDMPODRrate(enum DMP_ODR_Registers odr_reg, int interval)
float temp(void)
ICM_20948_Status_e write(uint8_t reg, uint8_t *pdata, uint32_t len)
ICM_20948_Status_e cfgIntAnyReadToClear(bool enabled)
ICM_20948_Status_e enableFIFO(bool enable=true)
ICM_20948_Status_e i2cMasterEnable(bool enable=true)
const char * statusString(ICM_20948_Status_e stat=ICM_20948_Stat_NUM)
ICM_20948_Status_e setBiasCPassY(int32_t newValue)
ICM_20948_Status_e intEnableRawDataReady(bool enable)
ICM_20948_Status_e setBiasCPassX(int32_t newValue)
ICM_20948_Status_e setBiasGyroZ(int32_t newValue)
ICM_20948_Status_e getBiasCPassX(int32_t *bias)
float getAccMG(int16_t axis_val)
ICM_20948_Status_e startupMagnetometer(bool minimal=false)
ICM_20948_Status_e setBiasAccelY(int32_t newValue)
ICM_20948_Status_e i2cMasterSingleW(uint8_t addr, uint8_t reg, uint8_t data)
float accY(void)
ICM_20948_Status_e swReset(void)
ICM_20948_Status_e setSampleMode(uint8_t sensor_id_bm, uint8_t lp_config_cycle_mode)
ICM_20948_Status_e i2cControllerPeriph4Transaction(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len, bool Rw, bool send_reg_addr=true)
ICM_20948_Status_e cfgIntLatch(bool latching)
void debugPrintStatus(ICM_20948_Status_e stat)
ICM_20948_Status_e intEnableWatermarkFIFO(uint8_t bm_enable)
ICM_20948_Status_e getBiasAccelX(int32_t *bias)
ICM_20948_Status_e startupDefault(bool minimal=false)
ICM_20948_Status_e WOMThreshold(uint8_t threshold)
ICM_20948_Status_e getBiasCPassY(int32_t *bias)
ICM_20948_Device_t _device
Definition ICM_20948.h:29
float gyrZ(void)
ICM_20948_AGMT_t getAGMT(void)
float gyrX(void)
ICM_20948_Status_e setClockSource(ICM_20948_PWR_MGMT_1_CLKSEL_e source)
ICM_20948_Status_e intEnablePLL(bool enable)
ICM_20948_Status_e setBiasGyroX(int32_t newValue)
ICM_20948_Status_e getFIFOcount(uint16_t *count)
bool isConnected(void)
ICM_20948_Status_e checkID(void)
float getGyrDPS(int16_t axis_val)
ICM_20948_Status_e enableDMPSensorInt(enum inv_icm20948_sensor sensor, bool enable=true)
void debugPrintf(int i)
float gyrY(void)
ICM_20948_Status_e loadDMPFirmware(void)
ICM_20948_Status_e lowPower(bool on=true)
ICM_20948_Status_e initializeDMP(void) __attribute__((weak))
void enableDebugging(Stream &debugPort=Serial)
float getTempC(int16_t val)
ICM_20948_Status_e enableDMPSensor(enum inv_icm20948_sensor sensor, bool enable=true)
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)
ICM_20948_Status_e i2cMasterConfigureSlave(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)
ICM_20948_Status_e getBiasAccelZ(int32_t *bias)
ICM_20948_Status_e resetFIFO(void)
ICM_20948_Status_e magWhoIAm(void)
ICM_20948_Status_e setGyroSF(unsigned char div, int gyro_level)
ICM_20948_Status_e setSampleRate(uint8_t sensor_id_bm, ICM_20948_smplrt_t smplrt)
ICM_20948_Status_e sleep(bool on=false)
ICM_20948_Status_e cfgIntOpenDrain(bool open_drain)
void debugPrintln(const __FlashStringHelper *)
ICM_20948_Status_e setDMPstartAddress(unsigned short address=DMP_START_ADDRESS)
ICM_20948_Status_e setBiasGyroY(int32_t newValue)
ICM_20948_Status_e i2cMasterReset()
ICM_20948_Status_e i2cMasterSLV4Transaction(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len, bool Rw, bool send_reg_addr=true)