JeVois  1.22
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Loading...
Searching...
No Matches
ICM_20948_C.h
Go to the documentation of this file.
1/*
2
3This is a C-compatible interface to the features presented by the ICM 20948 9-axis device
4The imementation of the interface is flexible
5
6*/
7
8#ifndef _ICM_20948_C_H_
9#define _ICM_20948_C_H_
10
11#include <stdint.h>
12#include <stdbool.h>
13#include <stddef.h>
14
15#include "ICM_20948_REGISTERS.h"
16#include "ICM_20948_ENUMERATIONS.h" // This is to give users access to usable value definiitons
18#include "ICM_20948_DMP.h"
19
20#ifdef __cplusplus
21extern "C"
22{
23#endif /* __cplusplus */
24
25extern int memcmp(const void *, const void *, size_t); // Avoid compiler warnings
26
27// Define if the DMP will be supported
28// Note: you must have 14290/14301 Bytes of program memory available to store the DMP firmware!
29//#define ICM_20948_USE_DMP // Uncomment this line to enable DMP support. You can of course use ICM_20948_USE_DMP as a compiler flag too
30
31// There are two versions of the InvenSense DMP firmware for the ICM20948 - with slightly different sizes
32#define DMP_CODE_SIZE 14301 /* eMD-SmartMotion-ICM20948-1.1.0-MP */
33//#define DMP_CODE_SIZE 14290 /* ICM20948_eMD_nucleo_1.0 */
34
35
36#define ICM_20948_I2C_ADDR_AD0 0x68 // Or 0x69 when AD0 is high
37#define ICM_20948_I2C_ADDR_AD1 0x69 //
38#define ICM_20948_WHOAMI 0xEA
39
40#define MAG_AK09916_I2C_ADDR 0x0C
41#define MAG_AK09916_WHO_AM_I 0x4809
42#define MAG_REG_WHO_AM_I 0x00
43
44/** @brief Max size that can be read across I2C or SPI data lines */
45#define INV_MAX_SERIAL_READ 16
46/** @brief Max size that can be written across I2C or SPI data lines */
47#define INV_MAX_SERIAL_WRITE 16
48
49 typedef enum
50 {
51 ICM_20948_Stat_Ok = 0x00, // The only return code that means all is well
52 ICM_20948_Stat_Err, // A general error
53 ICM_20948_Stat_NotImpl, // Returned by virtual functions that are not implemented
56 ICM_20948_Stat_InvalSensor, // Tried to apply a function to a sensor that does not support it (e.g. DLPF to the temperature sensor)
59 ICM_20948_Stat_DMPNotSupported, // DMP not supported (no #define ICM_20948_USE_DMP)
60 ICM_20948_Stat_DMPVerifyFail, // DMP was written but did not verify correctly
61 ICM_20948_Stat_FIFONoDataAvail, // FIFO contains no data
62 ICM_20948_Stat_FIFOIncompleteData, // FIFO contained incomplete data
63 ICM_20948_Stat_FIFOMoreDataAvail, // FIFO contains more data
66 ICM_20948_Stat_InvalDMPRegister, // Invalid DMP Register
67
71
72 typedef enum
73 {
78 ICM_20948_Internal_Mst = (1 << 4), // I2C Master Ineternal
79 } ICM_20948_InternalSensorID_bm; // A bitmask of internal sensor IDs
80
81 typedef union
82 {
83 int16_t i16bit[3];
84 uint8_t u8bit[6];
86
87 typedef union
88 {
89 int16_t i16bit;
90 uint8_t u8bit[2];
92
93 typedef struct
94 {
95 uint8_t a : 2;
96 uint8_t g : 2;
97 uint8_t reserved_0 : 4;
98 } ICM_20948_fss_t; // Holds full-scale settings to be able to extract measurements with units
99
100 typedef struct
101 {
102 uint8_t a;
103 uint8_t g;
104 } ICM_20948_dlpcfg_t; // Holds digital low pass filter settings. Members are type ICM_20948_ACCEL_CONFIG_DLPCFG_e
105
106 typedef struct
107 {
108 uint16_t a;
109 uint8_t g;
111
112 typedef struct
113 {
114 uint8_t I2C_MST_INT_EN : 1;
115 uint8_t DMP_INT1_EN : 1;
116 uint8_t PLL_RDY_EN : 1;
117 uint8_t WOM_INT_EN : 1;
118 uint8_t REG_WOF_EN : 1;
119 uint8_t RAW_DATA_0_RDY_EN : 1;
125 uint8_t FIFO_WM_EN_4 : 1;
126 uint8_t FIFO_WM_EN_3 : 1;
127 uint8_t FIFO_WM_EN_2 : 1;
128 uint8_t FIFO_WM_EN_1 : 1;
129 uint8_t FIFO_WM_EN_0 : 1;
131
132 typedef union
133 {
135 struct
136 {
137 int16_t x;
138 int16_t y;
139 int16_t z;
140 } axes;
142
143 typedef struct
144 {
148 union
149 {
151 int16_t val;
152 } tmp;
153 ICM_20948_fss_t fss; // Full-scale range settings for this measurement
154 uint8_t magStat1;
155 uint8_t magStat2;
157
158 typedef struct
159 {
160 ICM_20948_Status_e (*write)(uint8_t regaddr, uint8_t *pdata, uint32_t len, void *user);
161 ICM_20948_Status_e (*read)(uint8_t regaddr, uint8_t *pdata, uint32_t len, void *user);
162 // void (*delay)(uint32_t ms);
163 void *user;
164 } ICM_20948_Serif_t; // This is the vtable of serial interface functions
165 extern const ICM_20948_Serif_t NullSerif; // Here is a default for initialization (NULL)
166
167 typedef struct
168 {
169 const ICM_20948_Serif_t *_serif; // Pointer to the assigned Serif (Serial Interface) vtable
170 bool _dmp_firmware_available; // Indicates if the DMP firmware has been included. It
171 bool _firmware_loaded; // Indicates if DMP has been loaded
172 uint8_t _last_bank; // Keep track of which bank was selected last - to avoid unnecessary writes
173 uint8_t _last_mems_bank; // Keep track of which bank was selected last - to avoid unnecessary writes
174 int32_t _gyroSF; // Use this to record the GyroSF, calculated by inv_icm20948_set_gyro_sf
176 uint32_t _enabled_Android_0; // Keep track of which Android sensors are enabled: 0-31
177 uint32_t _enabled_Android_1; // Keep track of which Android sensors are enabled: 32-
178 uint32_t _enabled_Android_intr_0; // Keep track of which Android sensor interrupts are enabled: 0-31
179 uint32_t _enabled_Android_intr_1; // Keep track of which Android sensor interrupts are enabled: 32-
180 uint16_t _dataOutCtl1; // Diagnostics: record the setting of DATA_OUT_CTL1
181 uint16_t _dataOutCtl2; // Diagnostics: record the setting of DATA_OUT_CTL2
182 uint16_t _dataRdyStatus; // Diagnostics: record the setting of DATA_RDY_STATUS
183 uint16_t _motionEventCtl; // Diagnostics: record the setting of MOTION_EVENT_CTL
184 uint16_t _dataIntrCtl; // Diagnostics: record the setting of DATA_INTR_CTL
185 } ICM_20948_Device_t; // Definition of device struct type
186
187 ICM_20948_Status_e ICM_20948_init_struct(ICM_20948_Device_t *pdev); // Initialize ICM_20948_Device_t
188
189 // ICM_20948_Status_e ICM_20948_Startup( ICM_20948_Device_t* pdev ); // For the time being this performs a standardized startup routine
190
191 ICM_20948_Status_e ICM_20948_link_serif(ICM_20948_Device_t *pdev, const ICM_20948_Serif_t *s); // Links a SERIF structure to the device
192
193 // use the device's serif to perform a read or write
194 ICM_20948_Status_e ICM_20948_execute_r(ICM_20948_Device_t *pdev, uint8_t regaddr, uint8_t *pdata, uint32_t len); // Executes a R or W witht he serif vt as long as the pointers are not null
195 ICM_20948_Status_e ICM_20948_execute_w(ICM_20948_Device_t *pdev, uint8_t regaddr, uint8_t *pdata, uint32_t len);
196
197 // Single-shot I2C on Master IF
198 ICM_20948_Status_e ICM_20948_i2c_controller_periph4_txn(ICM_20948_Device_t *pdev, uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len, bool Rw, bool send_reg_addr);
199 ICM_20948_Status_e ICM_20948_i2c_master_single_w(ICM_20948_Device_t *pdev, uint8_t addr, uint8_t reg, uint8_t *data);
200 ICM_20948_Status_e ICM_20948_i2c_master_single_r(ICM_20948_Device_t *pdev, uint8_t addr, uint8_t reg, uint8_t *data);
201
202 // Device Level
203 ICM_20948_Status_e ICM_20948_set_bank(ICM_20948_Device_t *pdev, uint8_t bank); // Sets the bank
204 ICM_20948_Status_e ICM_20948_sw_reset(ICM_20948_Device_t *pdev); // Performs a SW reset
205 ICM_20948_Status_e ICM_20948_sleep(ICM_20948_Device_t *pdev, bool on); // Set sleep mode for the chip
206 ICM_20948_Status_e ICM_20948_low_power(ICM_20948_Device_t *pdev, bool on); // Set low power mode for the chip
208 ICM_20948_Status_e ICM_20948_get_who_am_i(ICM_20948_Device_t *pdev, uint8_t *whoami); // Return whoami in out prarmeter
209 ICM_20948_Status_e ICM_20948_check_id(ICM_20948_Device_t *pdev); // Return 'ICM_20948_Stat_Ok' if whoami matches ICM_20948_WHOAMI
210 ICM_20948_Status_e ICM_20948_data_ready(ICM_20948_Device_t *pdev); // Returns 'Ok' if data is ready
211
212 // Interrupt Configuration
214 ICM_20948_Status_e ICM_20948_int_enable(ICM_20948_Device_t *pdev, ICM_20948_INT_enable_t *write, ICM_20948_INT_enable_t *read); // Write and or read the interrupt enable information. If non-null the write operation occurs before the read, so as to verify that the write was successful
215
216 // WoM Enable Logic configuration
218
219 // WoM Threshold Level Configuration
220 ICM_20948_Status_e ICM_20948_wom_threshold(ICM_20948_Device_t *pdev, ICM_20948_ACCEL_WOM_THR_t *write, ICM_20948_ACCEL_WOM_THR_t *read); // Write and or read the Wake on Motion threshold. If non-null the write operation occurs before the read, so as to verify that the write was successful
221
222 // Internal Sensor Options
223 ICM_20948_Status_e ICM_20948_set_sample_mode(ICM_20948_Device_t *pdev, ICM_20948_InternalSensorID_bm sensors, ICM_20948_LP_CONFIG_CYCLE_e mode); // Use to set accel, gyro, and I2C master into cycled or continuous modes
228
229 // Interface Things
233 ICM_20948_Status_e ICM_20948_i2c_controller_configure_peripheral(ICM_20948_Device_t *pdev, uint8_t peripheral, uint8_t addr, uint8_t reg, uint8_t len, bool Rw, bool enable, bool data_only, bool grp, bool swap, uint8_t dataOut);
234
235 // Higher Level
237
238 // FIFO
239
244 ICM_20948_Status_e ICM_20948_read_FIFO(ICM_20948_Device_t *pdev, uint8_t *data, uint8_t len);
245
246 // DMP
247
252
253 /** @brief Loads the DMP firmware from SRAM
254 * @param[in] data pointer where the image
255 * @param[in] size size if the image
256 * @param[in] load_addr address to loading the image
257 * @return 0 in case of success, -1 for any error
258 */
259 ICM_20948_Status_e inv_icm20948_firmware_load(ICM_20948_Device_t *pdev, const unsigned char *data, unsigned short size, unsigned short load_addr);
260 /**
261 * @brief Write data to a register in DMP memory
262 * @param[in] DMP memory address
263 * @param[in] number of byte to be written
264 * @param[out] output data from the register
265 * @return 0 if successful.
266 */
267 ICM_20948_Status_e inv_icm20948_write_mems(ICM_20948_Device_t *pdev, unsigned short reg, unsigned int length, const unsigned char *data);
268 /**
269 * @brief Read data from a register in DMP memory
270 * @param[in] DMP memory address
271 * @param[in] number of byte to be read
272 * @param[in] input data from the register
273 * @return 0 if successful.
274 */
275 ICM_20948_Status_e inv_icm20948_read_mems(ICM_20948_Device_t *pdev, unsigned short reg, unsigned int length, unsigned char *data);
276
278 ICM_20948_Status_e inv_icm20948_enable_dmp_sensor(ICM_20948_Device_t *pdev, enum inv_icm20948_sensor sensor, int state); // State is actually boolean
279 ICM_20948_Status_e inv_icm20948_enable_dmp_sensor_int(ICM_20948_Device_t *pdev, enum inv_icm20948_sensor sensor, int state); // State is actually boolean
282
284 ICM_20948_Status_e inv_icm20948_set_gyro_sf(ICM_20948_Device_t *pdev, unsigned char div, int gyro_level);
285
286 // ToDo:
287
288 /*
289 Want to access magnetometer throught the I2C master interface...
290
291 // If using the I2C master to read from the magnetometer
292 // Enable the I2C master to talk to the magnetometer through the ICM 20948
293 myICM.i2cMasterEnable( true );
294 SERIAL_PORT.print(F("Enabling the I2C master returned ")); SERIAL_PORT.println(myICM.statusString());
295 myICM.i2cControllerConfigurePeripheral ( 0, MAG_AK09916_I2C_ADDR, REG_ST1, 9, true, true, false, false, false );
296 SERIAL_PORT.print(F("Configuring the magnetometer peripheral returned ")); SERIAL_PORT.println(myICM.statusString());
297
298 // Operate the I2C master in duty-cycled mode
299 myICM.setSampleMode( (ICM_20948_Internal_Mst | ICM_20948_Internal_Gyr), ICM_20948_Sample_Mode_Cycled ); // options: ICM_20948_Sample_Mode_Continuous or ICM_20948_Sample_Mode_Cycled
300*/
301
302#ifdef __cplusplus
303}
304#endif /* __cplusplus */
305
306#endif /* _ICM_20948_C_H_ */
ICM_20948_Status_e ICM_20948_reset_DMP(ICM_20948_Device_t *pdev)
int memcmp(const void *, const void *, size_t)
ICM_20948_Status_e ICM_20948_i2c_master_reset(ICM_20948_Device_t *pdev)
ICM_20948_Status_e ICM_20948_enable_FIFO(ICM_20948_Device_t *pdev, bool enable)
uint8_t sensor_type_2_android_sensor(enum inv_icm20948_sensor sensor)
ICM_20948_Status_e inv_icm20948_write_mems(ICM_20948_Device_t *pdev, unsigned short reg, unsigned int length, const unsigned char *data)
Write data to a register in DMP memory.
ICM_20948_Status_e ICM_20948_sleep(ICM_20948_Device_t *pdev, bool on)
ICM_20948_Status_e inv_icm20948_read_dmp_data(ICM_20948_Device_t *pdev, icm_20948_DMP_data_t *data)
ICM_20948_Status_e ICM_20948_wom_threshold(ICM_20948_Device_t *pdev, ICM_20948_ACCEL_WOM_THR_t *write, ICM_20948_ACCEL_WOM_THR_t *read)
ICM_20948_Status_e inv_icm20948_enable_dmp_sensor_int(ICM_20948_Device_t *pdev, enum inv_icm20948_sensor sensor, int state)
ICM_20948_Status_e ICM_20948_set_FIFO_mode(ICM_20948_Device_t *pdev, bool snapshot)
ICM_20948_Status_e inv_icm20948_set_gyro_sf(ICM_20948_Device_t *pdev, unsigned char div, int gyro_level)
ICM_20948_Status_e ICM_20948_set_clock_source(ICM_20948_Device_t *pdev, ICM_20948_PWR_MGMT_1_CLKSEL_e source)
ICM_20948_Status_e ICM_20948_set_sample_rate(ICM_20948_Device_t *pdev, ICM_20948_InternalSensorID_bm sensors, ICM_20948_smplrt_t smplrt)
ICM_20948_InternalSensorID_bm
Definition ICM_20948_C.h:73
@ ICM_20948_Internal_Acc
Definition ICM_20948_C.h:74
@ ICM_20948_Internal_Mag
Definition ICM_20948_C.h:76
@ ICM_20948_Internal_Gyr
Definition ICM_20948_C.h:75
@ ICM_20948_Internal_Tmp
Definition ICM_20948_C.h:77
@ ICM_20948_Internal_Mst
Definition ICM_20948_C.h:78
ICM_20948_Status_e ICM_20948_set_full_scale(ICM_20948_Device_t *pdev, ICM_20948_InternalSensorID_bm sensors, ICM_20948_fss_t fss)
ICM_20948_Status_e ICM_20948_int_pin_cfg(ICM_20948_Device_t *pdev, ICM_20948_INT_PIN_CFG_t *write, ICM_20948_INT_PIN_CFG_t *read)
ICM_20948_Status_e ICM_20948_get_who_am_i(ICM_20948_Device_t *pdev, uint8_t *whoami)
ICM_20948_Status_e ICM_20948_i2c_controller_periph4_txn(ICM_20948_Device_t *pdev, uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len, bool Rw, bool send_reg_addr)
ICM_20948_Status_e ICM_20948_int_enable(ICM_20948_Device_t *pdev, ICM_20948_INT_enable_t *write, ICM_20948_INT_enable_t *read)
ICM_20948_Status_e
Definition ICM_20948_C.h:50
@ ICM_20948_Stat_InvalDMPRegister
Definition ICM_20948_C.h:66
@ ICM_20948_Stat_NoData
Definition ICM_20948_C.h:57
@ ICM_20948_Stat_Unknown
Definition ICM_20948_C.h:69
@ ICM_20948_Stat_ParamErr
Definition ICM_20948_C.h:54
@ ICM_20948_Stat_FIFONoDataAvail
Definition ICM_20948_C.h:61
@ ICM_20948_Stat_FIFOIncompleteData
Definition ICM_20948_C.h:62
@ ICM_20948_Stat_WrongID
Definition ICM_20948_C.h:55
@ ICM_20948_Stat_FIFOMoreDataAvail
Definition ICM_20948_C.h:63
@ ICM_20948_Stat_NotImpl
Definition ICM_20948_C.h:53
@ ICM_20948_Stat_NUM
Definition ICM_20948_C.h:68
@ ICM_20948_Stat_Ok
Definition ICM_20948_C.h:51
@ ICM_20948_Stat_DMPNotSupported
Definition ICM_20948_C.h:59
@ ICM_20948_Stat_DMPVerifyFail
Definition ICM_20948_C.h:60
@ ICM_20948_Stat_InvalSensor
Definition ICM_20948_C.h:56
@ ICM_20948_Stat_Err
Definition ICM_20948_C.h:52
@ ICM_20948_Stat_SensorNotSupported
Definition ICM_20948_C.h:58
@ ICM_20948_Stat_UnrecognisedDMPHeader
Definition ICM_20948_C.h:64
@ ICM_20948_Stat_UnrecognisedDMPHeader2
Definition ICM_20948_C.h:65
enum inv_icm20948_sensor inv_icm20948_sensor_android_2_sensor_type(int sensor)
ICM_20948_Status_e inv_icm20948_firmware_load(ICM_20948_Device_t *pdev, const unsigned char *data, unsigned short size, unsigned short load_addr)
Loads the DMP firmware from SRAM.
ICM_20948_Status_e ICM_20948_check_id(ICM_20948_Device_t *pdev)
const ICM_20948_Serif_t NullSerif
ICM_20948_Status_e ICM_20948_data_ready(ICM_20948_Device_t *pdev)
ICM_20948_Status_e inv_icm20948_set_dmp_sensor_period(ICM_20948_Device_t *pdev, enum DMP_ODR_Registers odr_reg, uint16_t interval)
ICM_20948_Status_e inv_icm20948_read_mems(ICM_20948_Device_t *pdev, unsigned short reg, unsigned int length, unsigned char *data)
Read data from a register in DMP memory.
ICM_20948_Status_e ICM_20948_get_FIFO_count(ICM_20948_Device_t *pdev, uint16_t *count)
ICM_20948_Status_e ICM_20948_set_dmp_start_address(ICM_20948_Device_t *pdev, unsigned short address)
ICM_20948_Status_e ICM_20948_i2c_master_passthrough(ICM_20948_Device_t *pdev, bool passthrough)
ICM_20948_Status_e ICM_20948_read_FIFO(ICM_20948_Device_t *pdev, uint8_t *data, uint8_t len)
ICM_20948_Status_e ICM_20948_get_agmt(ICM_20948_Device_t *pdev, ICM_20948_AGMT_t *p)
ICM_20948_Status_e inv_icm20948_enable_dmp_sensor(ICM_20948_Device_t *pdev, enum inv_icm20948_sensor sensor, int state)
ICM_20948_Status_e ICM_20948_execute_r(ICM_20948_Device_t *pdev, uint8_t regaddr, uint8_t *pdata, uint32_t len)
ICM_20948_Status_e ICM_20948_i2c_controller_configure_peripheral(ICM_20948_Device_t *pdev, uint8_t peripheral, uint8_t addr, uint8_t reg, uint8_t len, bool Rw, bool enable, bool data_only, bool grp, bool swap, uint8_t dataOut)
ICM_20948_Status_e ICM_20948_set_dlpf_cfg(ICM_20948_Device_t *pdev, ICM_20948_InternalSensorID_bm sensors, ICM_20948_dlpcfg_t cfg)
ICM_20948_Status_e ICM_20948_i2c_master_enable(ICM_20948_Device_t *pdev, bool enable)
ICM_20948_Status_e ICM_20948_enable_dlpf(ICM_20948_Device_t *pdev, ICM_20948_InternalSensorID_bm sensors, bool enable)
ICM_20948_Status_e ICM_20948_execute_w(ICM_20948_Device_t *pdev, uint8_t regaddr, uint8_t *pdata, uint32_t len)
ICM_20948_Status_e ICM_20948_sw_reset(ICM_20948_Device_t *pdev)
ICM_20948_Status_e ICM_20948_set_sample_mode(ICM_20948_Device_t *pdev, ICM_20948_InternalSensorID_bm sensors, ICM_20948_LP_CONFIG_CYCLE_e mode)
ICM_20948_Status_e ICM_20948_firmware_load(ICM_20948_Device_t *pdev)
ICM_20948_Status_e ICM_20948_i2c_master_single_r(ICM_20948_Device_t *pdev, uint8_t addr, uint8_t reg, uint8_t *data)
ICM_20948_Status_e ICM_20948_i2c_master_single_w(ICM_20948_Device_t *pdev, uint8_t addr, uint8_t reg, uint8_t *data)
ICM_20948_Status_e ICM_20948_reset_FIFO(ICM_20948_Device_t *pdev)
ICM_20948_Status_e ICM_20948_init_struct(ICM_20948_Device_t *pdev)
ICM_20948_Status_e ICM_20948_low_power(ICM_20948_Device_t *pdev, bool on)
ICM_20948_Status_e ICM_20948_set_bank(ICM_20948_Device_t *pdev, uint8_t bank)
ICM_20948_Status_e ICM_20948_enable_DMP(ICM_20948_Device_t *pdev, bool enable)
ICM_20948_Status_e ICM_20948_link_serif(ICM_20948_Device_t *pdev, const ICM_20948_Serif_t *s)
ICM_20948_Status_e ICM_20948_wom_logic(ICM_20948_Device_t *pdev, ICM_20948_ACCEL_INTEL_CTRL_t *write, ICM_20948_ACCEL_INTEL_CTRL_t *read)
DMP_ODR_Registers
inv_icm20948_sensor
Sensor identifier for control function.
ICM_20948_PWR_MGMT_1_CLKSEL_e
ICM_20948_LP_CONFIG_CYCLE_e
ICM_20948_axis3named_t acc
ICM_20948_fss_t fss
ICM_20948_axis1bit16_t raw
ICM_20948_axis3named_t mag
ICM_20948_axis3named_t gyr
uint16_t _dataRdyStatus
uint32_t _enabled_Android_0
uint32_t _enabled_Android_1
uint16_t _motionEventCtl
uint32_t _enabled_Android_intr_1
const ICM_20948_Serif_t * _serif
uint32_t _enabled_Android_intr_0
uint8_t reserved_0
Definition ICM_20948_C.h:97
ICM_20948_axis3bit16_t raw