This quick start covers the portable callback model first, then the two included adapter paths: ESP-IDF and STM32 HAL. The driver core is plain C and does not depend on either platform.
What You Need To Provide
Fill an ICM42670_Config with sensor ranges, output data rates, and a small transport layer.
| Config Field | Required | Purpose |
read_reg | Yes | Read one or more sensor registers |
write_reg | Yes | Write one or more sensor registers |
delay_ms | Yes | Blocking millisecond delay used during init and mode changes |
handle | Yes | User pointer forwarded into read_reg and write_reg |
accel_odr | Recommended | Accelerometer output data rate |
accel_fs | Recommended | Accelerometer full-scale range |
gyro_odr | Recommended | Gyroscope output data rate |
gyro_fs | Recommended | Gyroscope full-scale range |
gyro_offsets | Optional | Raw gyro offsets subtracted by ICM42670_ReadGyroDps() |
1. Use The Portable Callback Path
If your platform does not use one of the included adapters, wire the callbacks directly.
static int8_t app_read_reg(void *handle, uint8_t reg, uint8_t *data,
uint16_t len) {
return 0;
}
static int8_t app_write_reg(void *handle, uint8_t reg, const uint8_t *data,
uint16_t len) {
return 0;
}
static void app_delay_ms(uint32_t ms) {
}
.accel_fs = ICM42670_ACCEL_FS_4G,
.gyro_odr = ICM42670_ODR_100_HZ,
.gyro_fs = ICM42670_GYRO_FS_500_DPS,
.handle = &your_bus_state,
.read_reg = app_read_reg,
.write_reg = app_write_reg,
.delay_ms = app_delay_ms,
};
}
ICM42670_Status_t ICM42670_Init(ICM42670_Config *config)
Initialize the device and enter 6-axis low-noise mode.
Definition ICM42670_driver.c:239
Core ICM-42670-P configuration and sensor read API.
@ ICM42670_OK
Definition ICM42670_driver.h:24
Platform-independent driver configuration.
Definition ICM42670_driver.h:172
ICM42670_Odr_t accel_odr
Definition ICM42670_driver.h:174
2. Read Accel, Gyro, And Temperature
float temp_c = 0.0f;
}
ICM42670_Status_t ICM42670_ReadAccelG(const ICM42670_Config *config, ICM42670_Accel_t *accel)
Read accelerometer data converted to g.
Definition ICM42670_driver.c:343
ICM42670_Status_t ICM42670_ReadGyroDps(const ICM42670_Config *config, ICM42670_Gyro_t *gyro)
Read gyroscope data converted to degrees per second.
Definition ICM42670_driver.c:363
ICM42670_Status_t ICM42670_ReadTempC(const ICM42670_Config *config, float *temp_c)
Read temperature converted to degrees Celsius.
Definition ICM42670_driver.c:386
Scaled accelerometer sample in g.
Definition ICM42670_driver.h:32
Scaled gyroscope sample in degrees per second.
Definition ICM42670_driver.h:41
Raw read helpers are also available:
int16_t accel_raw[3] = {0};
int16_t gyro_raw[3] = {0};
int16_t temp_raw = 0;
ICM42670_Status_t ICM42670_ReadAccelRaw(const ICM42670_Config *config, int16_t accel_raw[3])
Read raw accelerometer counts.
Definition ICM42670_driver.c:288
ICM42670_Status_t ICM42670_ReadGyroRaw(const ICM42670_Config *config, int16_t gyro_raw[3])
Read raw gyroscope counts.
Definition ICM42670_driver.c:307
ICM42670_Status_t ICM42670_ReadTempRaw(const ICM42670_Config *config, int16_t *temp_raw)
Read the raw temperature register value.
Definition ICM42670_driver.c:326
3. ESP-IDF I2C Adapter
In a normal ESP-IDF app, add the component dependency:
idf.py add-dependency "sleepypandas/icm42670_driver^0.1.2"
idf.py reconfigure
Then use the adapter to create the ESP-IDF bus/device and populate the portable driver config.
#include "driver/gpio.h"
#include "driver/i2c_master.h"
#include "esp_log.h"
static const char *TAG = "ICM42670";
void app_main(void) {
.accel_fs = ICM42670_ACCEL_FS_4G,
.gyro_odr = ICM42670_ODR_100_HZ,
.gyro_fs = ICM42670_GYRO_FS_500_DPS,
};
GPIO_NUM_22, 0x68, 400000);
if (err != ESP_OK) {
ESP_LOGE(TAG, "I2C adapter init failed: %s", esp_err_to_name(err));
return;
}
ESP_LOGE(TAG, "IMU init failed. Check wiring and address.");
return;
}
}
esp_err_t ICM42670_ESP_I2C_Init(ICM42670_Config *config, ICM42670_ESP_I2CBus *bus, int i2c_port, gpio_num_t sda_pin, gpio_num_t scl_pin, uint8_t device_addr, uint32_t scl_speed_hz)
Create an ESP-IDF I2C bus/device and populate ICM42670_Config.
Definition ICM42670_esp_idf.c:36
esp_err_t ICM42670_ESP_I2C_Deinit(ICM42670_ESP_I2CBus *bus)
Release ESP-IDF I2C resources owned by this adapter.
Definition ICM42670_esp_idf.c:106
ESP-IDF I2C and SPI transport adapters for the ICM-42670-P driver.
ESP-IDF I2C bus state used by the portable driver callbacks.
Definition ICM42670_esp_idf.h:27
If your application already owns the ESP-IDF I2C device handle, use ICM42670_ESP_I2C_AttachDevice() instead of creating another bus/device.
4. STM32 HAL Adapter
For STM32 projects, initialize the CubeMX-generated peripherals first, then let the adapter populate the same portable ICM42670_Config.
#include "main.h"
extern SPI_HandleTypeDef hspi1;
.accel_fs = ICM42670_ACCEL_FS_4G,
.gyro_odr = ICM42670_ODR_100_HZ,
.gyro_fs = ICM42670_GYRO_FS_500_DPS,
};
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI1_Init();
Error_Handler();
}
Error_Handler();
}
while (1) {
HAL_Delay(100);
}
}
ICM42670_Status_t ICM42670_STM32_SPI_INIT(ICM42670_Config *config, ICM42670_STM32_SPIBus *bus, SPI_HandleTypeDef *hspi, GPIO_TypeDef *cs_port, uint16_t cs_pin)
Configure an ICM42670_Config for STM32 HAL SPI access.
Definition ICM42670_stm32_hal.c:66
STM32 HAL transport adapters for the ICM-42670-P driver.
STM32 SPI bus state used by the portable driver callbacks.
Definition ICM42670_stm32_hal.h:19
STM32 I2C and I3C helpers follow the same pattern when the matching HAL module is enabled.
5. Optional Features
Include only the optional module you need:
Optional APEX motion feature API for the ICM-42670-P.
Simple FIFO and interrupt routing API for the ICM-42670-P.
Simple FSYNC API for the ICM-42670-P.
6. Bring-Up Checklist
- Confirm the device address or SPI chip-select wiring.
- Confirm
WHO_AM_I reads 0x67.
- Start at
100 Hz and moderate ranges such as 4 g and 500 dps.
- For ESP-IDF I2C timeouts, re-check SDA/SCL pins, pullups, address, and bus ownership before changing driver code.
- For STM32 SPI, drive chip select high before the first transfer and verify the SPI mode expected by the sensor.
Next