33This is a C-compatible interface to the features presented by the ICM 20948 9-axis device
44The imementation of the interface is flexible
55
6- */
7-
6+ */
87
98#ifndef _ICM_20948_C_H_
109#define _ICM_20948_C_H_
@@ -14,123 +13,135 @@ The imementation of the interface is flexible
1413#include <stddef.h>
1514
1615#include "ICM_20948_REGISTERS.h"
17- #include "ICM_20948_ENUMERATIONS.h" // This is to give users access to usable value definiitons
16+ #include "ICM_20948_ENUMERATIONS.h" // This is to give users access to usable value definiitons
1817#include "AK09916_ENUMERATIONS.h"
1918
2019#ifdef __cplusplus
21- extern "C" {
22- #endif /* __cplusplus */
23-
24- #define ICM_20948_I2C_ADDR_AD0 0x68 // Or 0x69 when AD0 is high
25- #define ICM_20948_I2C_ADDR_AD1 0x69 //
26- #define ICM_20948_WHOAMI 0xEA
27-
28- #define MAG_AK09916_I2C_ADDR 0x0C
29- #define MAG_AK09916_WHO_AM_I 0x4809
30- #define MAG_REG_WHO_AM_I 0x00
31-
32- typedef enum {
33- ICM_20948_Stat_Ok = 0x00 , // The only return code that means all is well
34- ICM_20948_Stat_Err , // A general error
35- ICM_20948_Stat_NotImpl , // Returned by virtual functions that are not implemented
36- ICM_20948_Stat_ParamErr ,
37- ICM_20948_Stat_WrongID ,
38- ICM_20948_Stat_InvalSensor , // Tried to apply a function to a sensor that does not support it (e.g. DLPF to the temperature sensor)
39- ICM_20948_Stat_NoData ,
40- ICM_20948_Stat_SensorNotSupported ,
41-
42- ICM_20948_Stat_NUM ,
43- ICM_20948_Stat_Unknown ,
44- }ICM_20948_Status_e ;
45-
46- typedef enum {
47- ICM_20948_Internal_Acc = (1 << 0 ),
48- ICM_20948_Internal_Gyr = (1 << 1 ),
49- ICM_20948_Internal_Mag = (1 << 2 ),
50- ICM_20948_Internal_Tmp = (1 << 3 ),
51- ICM_20948_Internal_Mst = (1 << 4 ), // I2C Master Ineternal
52- }ICM_20948_InternalSensorID_bm ; // A bitmask of internal sensor IDs
53-
54- typedef union {
55- int16_t i16bit [3 ];
56- uint8_t u8bit [6 ];
57- }ICM_20948_axis3bit16_t ;
58-
59- typedef union {
60- int16_t i16bit ;
61- uint8_t u8bit [2 ];
62- }ICM_20948_axis1bit16_t ;
63-
64- typedef struct {
65- uint8_t a : 2 ;
66- uint8_t g : 2 ;
67- uint8_t reserved_0 : 4 ;
68- }ICM_20948_fss_t ; // Holds full-scale settings to be able to extract measurements with units
69-
70- typedef struct {
71- uint8_t a ;
72- uint8_t g ;
73- }ICM_20948_dlpcfg_t ; // Holds digital low pass filter settings. Members are type ICM_20948_ACCEL_CONFIG_DLPCFG_e
74-
75- typedef struct {
76- uint16_t a ;
77- uint8_t g ;
78- }ICM_20948_smplrt_t ;
79-
80- typedef struct {
81- uint8_t I2C_MST_INT_EN : 1 ;
82- uint8_t DMP_INT1_EN : 1 ;
83- uint8_t PLL_RDY_EN : 1 ;
84- uint8_t WOM_INT_EN : 1 ;
85- uint8_t REG_WOF_EN : 1 ;
86- uint8_t RAW_DATA_0_RDY_EN : 1 ;
87- uint8_t FIFO_OVERFLOW_EN_4 : 1 ;
88- uint8_t FIFO_OVERFLOW_EN_3 : 1 ;
89- uint8_t FIFO_OVERFLOW_EN_2 : 1 ;
90- uint8_t FIFO_OVERFLOW_EN_1 : 1 ;
91- uint8_t FIFO_OVERFLOW_EN_0 : 1 ;
92- uint8_t FIFO_WM_EN_4 : 1 ;
93- uint8_t FIFO_WM_EN_3 : 1 ;
94- uint8_t FIFO_WM_EN_2 : 1 ;
95- uint8_t FIFO_WM_EN_1 : 1 ;
96- uint8_t FIFO_WM_EN_0 : 1 ;
97- }ICM_20948_INT_enable_t ;
98-
99- typedef union {
100- ICM_20948_axis3bit16_t raw ;
101- struct {
102- int16_t x ;
103- int16_t y ;
104- int16_t z ;
105- }axes ;
106- }ICM_20948_axis3named_t ;
107-
108- typedef struct {
109- ICM_20948_axis3named_t acc ;
110- ICM_20948_axis3named_t gyr ;
111- ICM_20948_axis3named_t mag ;
112- union {
113- ICM_20948_axis1bit16_t raw ;
114- int16_t val ;
115- }tmp ;
116- ICM_20948_fss_t fss ; // Full-scale range settings for this measurement
117- }ICM_20948_AGMT_t ;
118-
119- typedef struct {
120- ICM_20948_Status_e (* write )( uint8_t regaddr , uint8_t * pdata , uint32_t len , void * user );
121- ICM_20948_Status_e (* read )( uint8_t regaddr , uint8_t * pdata , uint32_t len , void * user );
122- // void (*delay)(uint32_t ms);
123- void * user ;
124- }ICM_20948_Serif_t ; // This is the vtable of serial interface functions
125- extern const ICM_20948_Serif_t NullSerif ; // Here is a default for initialization (NULL)
126-
127- typedef struct {
128- const ICM_20948_Serif_t * _serif ; // Pointer to the assigned Serif (Serial Interface) vtable
129- }ICM_20948_Device_t ; // Definition of device struct type
130-
131-
132- // Here's the list of what I want to be able to do:
133- /*
20+ extern "C"
21+ {
22+ #endif /* __cplusplus */
23+
24+ #define ICM_20948_I2C_ADDR_AD0 0x68 // Or 0x69 when AD0 is high
25+ #define ICM_20948_I2C_ADDR_AD1 0x69 //
26+ #define ICM_20948_WHOAMI 0xEA
27+
28+ #define MAG_AK09916_I2C_ADDR 0x0C
29+ #define MAG_AK09916_WHO_AM_I 0x4809
30+ #define MAG_REG_WHO_AM_I 0x00
31+
32+ typedef enum
33+ {
34+ ICM_20948_Stat_Ok = 0x00 , // The only return code that means all is well
35+ ICM_20948_Stat_Err , // A general error
36+ ICM_20948_Stat_NotImpl , // Returned by virtual functions that are not implemented
37+ ICM_20948_Stat_ParamErr ,
38+ ICM_20948_Stat_WrongID ,
39+ ICM_20948_Stat_InvalSensor , // Tried to apply a function to a sensor that does not support it (e.g. DLPF to the temperature sensor)
40+ ICM_20948_Stat_NoData ,
41+ ICM_20948_Stat_SensorNotSupported ,
42+
43+ ICM_20948_Stat_NUM ,
44+ ICM_20948_Stat_Unknown ,
45+ } ICM_20948_Status_e ;
46+
47+ typedef enum
48+ {
49+ ICM_20948_Internal_Acc = (1 << 0 ),
50+ ICM_20948_Internal_Gyr = (1 << 1 ),
51+ ICM_20948_Internal_Mag = (1 << 2 ),
52+ ICM_20948_Internal_Tmp = (1 << 3 ),
53+ ICM_20948_Internal_Mst = (1 << 4 ), // I2C Master Ineternal
54+ } ICM_20948_InternalSensorID_bm ; // A bitmask of internal sensor IDs
55+
56+ typedef union {
57+ int16_t i16bit [3 ];
58+ uint8_t u8bit [6 ];
59+ } ICM_20948_axis3bit16_t ;
60+
61+ typedef union {
62+ int16_t i16bit ;
63+ uint8_t u8bit [2 ];
64+ } ICM_20948_axis1bit16_t ;
65+
66+ typedef struct
67+ {
68+ uint8_t a : 2 ;
69+ uint8_t g : 2 ;
70+ uint8_t reserved_0 : 4 ;
71+ } ICM_20948_fss_t ; // Holds full-scale settings to be able to extract measurements with units
72+
73+ typedef struct
74+ {
75+ uint8_t a ;
76+ uint8_t g ;
77+ } ICM_20948_dlpcfg_t ; // Holds digital low pass filter settings. Members are type ICM_20948_ACCEL_CONFIG_DLPCFG_e
78+
79+ typedef struct
80+ {
81+ uint16_t a ;
82+ uint8_t g ;
83+ } ICM_20948_smplrt_t ;
84+
85+ typedef struct
86+ {
87+ uint8_t I2C_MST_INT_EN : 1 ;
88+ uint8_t DMP_INT1_EN : 1 ;
89+ uint8_t PLL_RDY_EN : 1 ;
90+ uint8_t WOM_INT_EN : 1 ;
91+ uint8_t REG_WOF_EN : 1 ;
92+ uint8_t RAW_DATA_0_RDY_EN : 1 ;
93+ uint8_t FIFO_OVERFLOW_EN_4 : 1 ;
94+ uint8_t FIFO_OVERFLOW_EN_3 : 1 ;
95+ uint8_t FIFO_OVERFLOW_EN_2 : 1 ;
96+ uint8_t FIFO_OVERFLOW_EN_1 : 1 ;
97+ uint8_t FIFO_OVERFLOW_EN_0 : 1 ;
98+ uint8_t FIFO_WM_EN_4 : 1 ;
99+ uint8_t FIFO_WM_EN_3 : 1 ;
100+ uint8_t FIFO_WM_EN_2 : 1 ;
101+ uint8_t FIFO_WM_EN_1 : 1 ;
102+ uint8_t FIFO_WM_EN_0 : 1 ;
103+ } ICM_20948_INT_enable_t ;
104+
105+ typedef union {
106+ ICM_20948_axis3bit16_t raw ;
107+ struct
108+ {
109+ int16_t x ;
110+ int16_t y ;
111+ int16_t z ;
112+ } axes ;
113+ } ICM_20948_axis3named_t ;
114+
115+ typedef struct
116+ {
117+ ICM_20948_axis3named_t acc ;
118+ ICM_20948_axis3named_t gyr ;
119+ ICM_20948_axis3named_t mag ;
120+ union {
121+ ICM_20948_axis1bit16_t raw ;
122+ int16_t val ;
123+ } tmp ;
124+ ICM_20948_fss_t fss ; // Full-scale range settings for this measurement
125+ uint8_t magStat1 ;
126+ uint8_t magStat2 ;
127+ } ICM_20948_AGMT_t ;
128+
129+ typedef struct
130+ {
131+ ICM_20948_Status_e (* write )(uint8_t regaddr , uint8_t * pdata , uint32_t len , void * user );
132+ ICM_20948_Status_e (* read )(uint8_t regaddr , uint8_t * pdata , uint32_t len , void * user );
133+ // void (*delay)(uint32_t ms);
134+ void * user ;
135+ } ICM_20948_Serif_t ; // This is the vtable of serial interface functions
136+ extern const ICM_20948_Serif_t NullSerif ; // Here is a default for initialization (NULL)
137+
138+ typedef struct
139+ {
140+ const ICM_20948_Serif_t * _serif ; // Pointer to the assigned Serif (Serial Interface) vtable
141+ } ICM_20948_Device_t ; // Definition of device struct type
142+
143+ // Here's the list of what I want to be able to do:
144+ /*
134145
135146perform a generic startup routine that sets most things in the optimal performance range
136147Read / check against Who Am I
@@ -154,62 +165,54 @@ callbacks for the user to respond to interrupt events
154165
155166*/
156167
157- // ICM_20948_Status_e ICM_20948_Startup( ICM_20948_Device_t* pdev ); // For the time being this performs a standardized startup routine
158-
159-
160- 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
161-
162- // use the device's serif to perform a read or write
163- 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
164- ICM_20948_Status_e ICM_20948_execute_w ( ICM_20948_Device_t * pdev , uint8_t regaddr , uint8_t * pdata , uint32_t len );
165-
166-
167- // Single-shot I2C on Master IF
168- ICM_20948_Status_e ICM_20948_i2c_master_slv4_txn ( ICM_20948_Device_t * pdev , uint8_t addr , uint8_t reg , uint8_t * data , uint8_t len , bool Rw , bool send_reg_addr );
169- ICM_20948_Status_e ICM_20948_i2c_master_single_w ( ICM_20948_Device_t * pdev , uint8_t addr , uint8_t reg , uint8_t * data );
170- ICM_20948_Status_e ICM_20948_i2c_master_single_r ( ICM_20948_Device_t * pdev , uint8_t addr , uint8_t reg , uint8_t * data );
171-
172-
173- // Device Level
174- ICM_20948_Status_e ICM_20948_set_bank ( ICM_20948_Device_t * pdev , uint8_t bank ); // Sets the bank
175- ICM_20948_Status_e ICM_20948_sw_reset ( ICM_20948_Device_t * pdev ); // Performs a SW reset
176- ICM_20948_Status_e ICM_20948_sleep ( ICM_20948_Device_t * pdev , bool on ); // Set sleep mode for the chip
177- ICM_20948_Status_e ICM_20948_low_power ( ICM_20948_Device_t * pdev , bool on ); // Set low power mode for the chip
178- ICM_20948_Status_e ICM_20948_set_clock_source ( ICM_20948_Device_t * pdev , ICM_20948_PWR_MGMT_1_CLKSEL_e source ); // Choose clock source
179- ICM_20948_Status_e ICM_20948_get_who_am_i ( ICM_20948_Device_t * pdev , uint8_t * whoami ); // Return whoami in out prarmeter
180- ICM_20948_Status_e ICM_20948_check_id ( ICM_20948_Device_t * pdev ); // Return 'ICM_20948_Stat_Ok' if whoami matches ICM_20948_WHOAMI
181- ICM_20948_Status_e ICM_20948_data_ready ( ICM_20948_Device_t * pdev ); // Returns 'Ok' if data is ready
168+ // ICM_20948_Status_e ICM_20948_Startup( ICM_20948_Device_t* pdev ); // For the time being this performs a standardized startup routine
182169
183- // Interrupt Configuration
184- 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 ); // Set the INT pin configuration
185- 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
170+ 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
186171
187- // Internal Sensor Options
188- 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
189- ICM_20948_Status_e ICM_20948_set_full_scale ( ICM_20948_Device_t * pdev , ICM_20948_InternalSensorID_bm sensors , ICM_20948_fss_t fss );
190- ICM_20948_Status_e ICM_20948_set_dlpf_cfg ( ICM_20948_Device_t * pdev , ICM_20948_InternalSensorID_bm sensors , ICM_20948_dlpcfg_t cfg );
191- ICM_20948_Status_e ICM_20948_enable_dlpf ( ICM_20948_Device_t * pdev , ICM_20948_InternalSensorID_bm sensors , bool enable );
192- ICM_20948_Status_e ICM_20948_set_sample_rate ( ICM_20948_Device_t * pdev , ICM_20948_InternalSensorID_bm sensors , ICM_20948_smplrt_t smplrt );
172+ // use the device's serif to perform a read or write
173+ 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
174+ ICM_20948_Status_e ICM_20948_execute_w (ICM_20948_Device_t * pdev , uint8_t regaddr , uint8_t * pdata , uint32_t len );
193175
194- // Interface Things
195- ICM_20948_Status_e ICM_20948_i2c_master_passthrough ( ICM_20948_Device_t * pdev , bool passthrough );
196- ICM_20948_Status_e ICM_20948_i2c_master_enable ( ICM_20948_Device_t * pdev , bool enable );
197- ICM_20948_Status_e ICM_20948_i2c_master_configure_slave ( ICM_20948_Device_t * pdev , uint8_t slave , uint8_t addr , uint8_t reg , uint8_t len , bool Rw , bool enable , bool data_only , bool grp , bool swap );
176+ // Single-shot I2C on Master IF
177+ ICM_20948_Status_e ICM_20948_i2c_master_slv4_txn ( ICM_20948_Device_t * pdev , uint8_t addr , uint8_t reg , uint8_t * data , uint8_t len , bool Rw , bool send_reg_addr );
178+ ICM_20948_Status_e ICM_20948_i2c_master_single_w ( ICM_20948_Device_t * pdev , uint8_t addr , uint8_t reg , uint8_t * data );
179+ ICM_20948_Status_e ICM_20948_i2c_master_single_r ( ICM_20948_Device_t * pdev , uint8_t addr , uint8_t reg , uint8_t * data );
198180
181+ // Device Level
182+ ICM_20948_Status_e ICM_20948_set_bank (ICM_20948_Device_t * pdev , uint8_t bank ); // Sets the bank
183+ ICM_20948_Status_e ICM_20948_sw_reset (ICM_20948_Device_t * pdev ); // Performs a SW reset
184+ ICM_20948_Status_e ICM_20948_sleep (ICM_20948_Device_t * pdev , bool on ); // Set sleep mode for the chip
185+ ICM_20948_Status_e ICM_20948_low_power (ICM_20948_Device_t * pdev , bool on ); // Set low power mode for the chip
186+ ICM_20948_Status_e ICM_20948_set_clock_source (ICM_20948_Device_t * pdev , ICM_20948_PWR_MGMT_1_CLKSEL_e source ); // Choose clock source
187+ ICM_20948_Status_e ICM_20948_get_who_am_i (ICM_20948_Device_t * pdev , uint8_t * whoami ); // Return whoami in out prarmeter
188+ ICM_20948_Status_e ICM_20948_check_id (ICM_20948_Device_t * pdev ); // Return 'ICM_20948_Stat_Ok' if whoami matches ICM_20948_WHOAMI
189+ ICM_20948_Status_e ICM_20948_data_ready (ICM_20948_Device_t * pdev ); // Returns 'Ok' if data is ready
199190
191+ // Interrupt Configuration
192+ 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 ); // Set the INT pin configuration
193+ 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
200194
201- // Higher Level
202- ICM_20948_Status_e ICM_20948_get_agmt ( ICM_20948_Device_t * pdev , ICM_20948_AGMT_t * p );
195+ // Internal Sensor Options
196+ 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
197+ ICM_20948_Status_e ICM_20948_set_full_scale (ICM_20948_Device_t * pdev , ICM_20948_InternalSensorID_bm sensors , ICM_20948_fss_t fss );
198+ ICM_20948_Status_e ICM_20948_set_dlpf_cfg (ICM_20948_Device_t * pdev , ICM_20948_InternalSensorID_bm sensors , ICM_20948_dlpcfg_t cfg );
199+ ICM_20948_Status_e ICM_20948_enable_dlpf (ICM_20948_Device_t * pdev , ICM_20948_InternalSensorID_bm sensors , bool enable );
200+ ICM_20948_Status_e ICM_20948_set_sample_rate (ICM_20948_Device_t * pdev , ICM_20948_InternalSensorID_bm sensors , ICM_20948_smplrt_t smplrt );
203201
202+ // Interface Things
203+ ICM_20948_Status_e ICM_20948_i2c_master_passthrough (ICM_20948_Device_t * pdev , bool passthrough );
204+ ICM_20948_Status_e ICM_20948_i2c_master_enable (ICM_20948_Device_t * pdev , bool enable );
205+ ICM_20948_Status_e ICM_20948_i2c_master_reset (ICM_20948_Device_t * pdev );
206+ ICM_20948_Status_e ICM_20948_i2c_master_configure_slave (ICM_20948_Device_t * pdev , uint8_t slave , uint8_t addr , uint8_t reg , uint8_t len , bool Rw , bool enable , bool data_only , bool grp , bool swap );
204207
208+ // Higher Level
209+ ICM_20948_Status_e ICM_20948_get_agmt (ICM_20948_Device_t * pdev , ICM_20948_AGMT_t * p );
205210
211+ ICM_20948_Status_e ICM_20948_get_agmt (ICM_20948_Device_t * pdev , ICM_20948_AGMT_t * p );
206212
213+ // ToDo:
207214
208-
209-
210- // ToDo:
211-
212- /*
215+ /*
213216 Want to access magnetometer throught the I2C master interface...
214217
215218 // If using the I2C master to read from the magnetometer
@@ -223,15 +226,8 @@ ICM_20948_Status_e ICM_20948_get_agmt ( ICM_20948_Device_t* pdev, ICM_
223226 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
224227*/
225228
226-
227-
228-
229-
230-
231-
232-
233229#ifdef __cplusplus
234230}
235- #endif /* __cplusplus */
231+ #endif /* __cplusplus */
236232
237- #endif /* _ICM_20948_C_H_ */
233+ #endif /* _ICM_20948_C_H_ */
0 commit comments