diff --git a/components/sensors/icm42670/CMakeLists.txt b/components/sensors/icm42670/CMakeLists.txt index d796dedc6..23eda2c4d 100644 --- a/components/sensors/icm42670/CMakeLists.txt +++ b/components/sensors/icm42670/CMakeLists.txt @@ -1,5 +1,5 @@ if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.3") - set(REQ esp_driver_i2c) + set(REQ esp_driver_i2c esp_driver_spi) else() set(REQ driver) endif() diff --git a/components/sensors/icm42670/README.md b/components/sensors/icm42670/README.md index 0bea3686a..fdb9a5b80 100644 --- a/components/sensors/icm42670/README.md +++ b/components/sensors/icm42670/README.md @@ -3,7 +3,7 @@ [![Component Registry](https://components.espressif.com/components/espressif/icm42670/badge.svg)](https://components.espressif.com/components/espressif/icm42670) ![maintenance-status](https://img.shields.io/badge/maintenance-passively--maintained-yellowgreen.svg) -C driver for Invensense ICM42607/ICM42670 6-axis gyroscope and accelerometer based on I2C communication. +C driver for Invensense ICM42607/ICM42670 6-axis gyroscope and accelerometer based on I2C/SPI communication. ## Features @@ -12,10 +12,6 @@ C driver for Invensense ICM42607/ICM42670 6-axis gyroscope and accelerometer bas - Configure gyroscope and accelerometer sensitivity. - ICM42607/ICM42670 power down mode. -## Limitations - -- Only I2C communication is supported. - ## Get Started This driver, along with many other components from this repository, can be used as a package from [Espressif's IDF Component Registry](https://components.espressif.com). To include this driver in your project, run the following idf.py from the project's root directory: diff --git a/components/sensors/icm42670/icm42670.c b/components/sensors/icm42670/icm42670.c index a4d6ad512..9f37e6746 100644 --- a/components/sensors/icm42670/icm42670.c +++ b/components/sensors/icm42670/icm42670.c @@ -16,41 +16,44 @@ #include "iot_sensor_hub.h" #include "icm42670.h" -#define I2C_CLK_SPEED 400000 +#define ICM42670_I2C_CLK_SPEED 400000 +#define ICM42670_SPI_CLK_SPEED 1000000 -#define ALPHA 0.97f /*!< Weight of gyroscope */ -#define RAD_TO_DEG 57.27272727f /*!< Radians to degrees */ +#define ALPHA 0.97f /*!< Weight of gyroscope */ +#define RAD_TO_DEG 57.27272727f /*!< Radians to degrees */ #define ICM42607_ID 0x60 #define ICM42670_ID 0x67 /* ICM42670 register */ -#define ICM42670_WHOAMI 0x75 -#define ICM42670_GYRO_CONFIG0 0x20 -#define ICM42670_ACCEL_CONFIG0 0x21 -#define ICM42670_TEMP_CONFIG 0x22 -#define ICM42670_PWR_MGMT0 0x1F -#define ICM42670_TEMP_DATA 0x09 -#define ICM42670_ACCEL_DATA 0x0B -#define ICM42670_GYRO_DATA 0x11 +#define ICM42670_WHOAMI 0x75 +#define ICM42670_GYRO_CONFIG0 0x20 +#define ICM42670_ACCEL_CONFIG0 0x21 +#define ICM42670_TEMP_CONFIG 0x22 +#define ICM42670_PWR_MGMT0 0x1F +#define ICM42670_TEMP_DATA 0x09 +#define ICM42670_ACCEL_DATA 0x0B +#define ICM42670_GYRO_DATA 0x11 /* Sensitivity of the gyroscope */ #define GYRO_FS_2000_SENSITIVITY (16.4) #define GYRO_FS_1000_SENSITIVITY (32.8) -#define GYRO_FS_500_SENSITIVITY (65.5) -#define GYRO_FS_250_SENSITIVITY (131.0) +#define GYRO_FS_500_SENSITIVITY (65.5) +#define GYRO_FS_250_SENSITIVITY (131.0) /* Sensitivity of the accelerometer */ #define ACCE_FS_16G_SENSITIVITY (2048) -#define ACCE_FS_8G_SENSITIVITY (4096) -#define ACCE_FS_4G_SENSITIVITY (8192) -#define ACCE_FS_2G_SENSITIVITY (16384) +#define ACCE_FS_8G_SENSITIVITY (4096) +#define ACCE_FS_4G_SENSITIVITY (8192) +#define ACCE_FS_2G_SENSITIVITY (16384) /******************************************************************************* -* Types definitions -*******************************************************************************/ + * Types definitions + *******************************************************************************/ typedef struct { + bool using_spi; + spi_device_handle_t spi_handle; i2c_master_dev_handle_t i2c_handle; bool initialized_filter; uint64_t previous_measurement_us; @@ -58,51 +61,72 @@ typedef struct { } icm42670_dev_t; /******************************************************************************* -* Function definitions -*******************************************************************************/ + * Function definitions + *******************************************************************************/ static esp_err_t icm42670_write(icm42670_handle_t sensor, const uint8_t reg_start_addr, const uint8_t *data_buf, const uint8_t data_len); static esp_err_t icm42670_read(icm42670_handle_t sensor, const uint8_t reg_start_addr, uint8_t *data_buf, const uint8_t data_len); static esp_err_t icm42670_get_raw_value(icm42670_handle_t sensor, uint8_t reg, icm42670_raw_value_t *value); - +static esp_err_t check_device_present(icm42670_handle_t sensor); /******************************************************************************* -* Local variables -*******************************************************************************/ + * Local variables + *******************************************************************************/ static const char *TAG = "ICM42670"; /******************************************************************************* -* Public API functions -*******************************************************************************/ + * Public API functions + *******************************************************************************/ esp_err_t icm42670_create(i2c_master_bus_handle_t i2c_bus, const uint8_t dev_addr, icm42670_handle_t *handle_ret) { esp_err_t ret = ESP_OK; // Allocate memory and init the driver object - icm42670_dev_t *sensor = (icm42670_dev_t *) calloc(1, sizeof(icm42670_dev_t)); - ESP_RETURN_ON_FALSE(sensor != NULL, ESP_ERR_NO_MEM, TAG, "Not enough memory"); + icm42670_dev_t *sensor = (icm42670_dev_t *)calloc(1, sizeof(icm42670_dev_t)); + ESP_RETURN_ON_FALSE(sensor, ESP_ERR_NO_MEM, TAG, "Not enough memory"); // Add new I2C device const i2c_device_config_t i2c_dev_cfg = { .device_address = dev_addr, - .scl_speed_hz = I2C_CLK_SPEED, + .scl_speed_hz = ICM42670_I2C_CLK_SPEED, }; ESP_GOTO_ON_ERROR(i2c_master_bus_add_device(i2c_bus, &i2c_dev_cfg, &sensor->i2c_handle), err, TAG, "Failed to add new I2C device"); assert(sensor->i2c_handle); // Check device presence - uint8_t dev_id = 0; - icm42670_get_deviceid(sensor, &dev_id); - ESP_GOTO_ON_FALSE(dev_id == ICM42607_ID - || dev_id == ICM42670_ID, ESP_ERR_NOT_FOUND, err, TAG, "Incorrect Device ID (0x%02x).", dev_id); + ESP_GOTO_ON_ERROR(check_device_present(sensor), err, TAG, "Incorrect device ID received"); - ESP_LOGD(TAG, "Found device %s, ID: 0x%02x", (dev_id == ICM42607_ID ? "ICM42607" : "ICM42670"), dev_id); *handle_ret = sensor; + return ESP_OK; + +err: + icm42670_delete(sensor); return ret; +} + +esp_err_t icm42670_create_spi(spi_host_device_t spi_bus, gpio_num_t cs_pin, icm42670_handle_t *handle_ret) +{ + esp_err_t ret = ESP_OK; + icm42670_dev_t *sensor = (icm42670_dev_t *)calloc(1, sizeof(icm42670_dev_t)); + ESP_RETURN_ON_FALSE(sensor, ESP_ERR_NO_MEM, TAG, "Not enough memory"); + sensor->using_spi = true; + + spi_device_interface_config_t dev_cfg = { + .clock_speed_hz = ICM42670_SPI_CLK_SPEED, + .spics_io_num = cs_pin, + .mode = 3, + .queue_size = 1, + }; + ESP_GOTO_ON_ERROR(spi_bus_add_device(spi_bus, &dev_cfg, &sensor->spi_handle), err, TAG, "Failed to add new SPI device"); + assert(sensor->spi_handle); + ESP_GOTO_ON_ERROR(check_device_present(sensor), err, TAG, "Incorrect device ID received"); + + *handle_ret = sensor; + return ESP_OK; err: icm42670_delete(sensor); return ret; @@ -110,9 +134,10 @@ esp_err_t icm42670_create(i2c_master_bus_handle_t i2c_bus, const uint8_t dev_add void icm42670_delete(icm42670_handle_t sensor) { - icm42670_dev_t *sens = (icm42670_dev_t *) sensor; - - if (sens->i2c_handle) { + icm42670_dev_t *sens = (icm42670_dev_t *)sensor; + if (sens->using_spi && sens->spi_handle) { + spi_bus_remove_device(sens->spi_handle); + } else if (sens->i2c_handle) { i2c_master_bus_rm_device(sens->i2c_handle); } @@ -333,9 +358,23 @@ esp_err_t icm42670_get_temp_value(icm42670_handle_t sensor, float *value) } /******************************************************************************* -* Private functions -*******************************************************************************/ + * Private functions + *******************************************************************************/ +static esp_err_t check_device_present(icm42670_handle_t sensor) +{ + uint8_t dev_id = 0; + esp_err_t ret = icm42670_get_deviceid(sensor, &dev_id); + if (ret != ESP_OK) { + return ret; + } + if (dev_id != ICM42607_ID && dev_id != ICM42670_ID) { + ESP_LOGD(TAG, "Incorrect Device ID (0x%02x).", dev_id); + return ESP_ERR_NOT_FOUND; + } + ESP_LOGD(TAG, "Found device %s, ID: 0x%02x", (dev_id == ICM42607_ID ? "ICM42607" : "ICM42670"), dev_id); + return ESP_OK; +} static esp_err_t icm42670_get_raw_value(icm42670_handle_t sensor, uint8_t reg, icm42670_raw_value_t *value) { esp_err_t ret = ESP_FAIL; @@ -360,30 +399,52 @@ static esp_err_t icm42670_get_raw_value(icm42670_handle_t sensor, uint8_t reg, i static esp_err_t icm42670_write(icm42670_handle_t sensor, const uint8_t reg_start_addr, const uint8_t *data_buf, const uint8_t data_len) { - icm42670_dev_t *sens = (icm42670_dev_t *) sensor; + icm42670_dev_t *sens = (icm42670_dev_t *)sensor; assert(sens); assert(data_len < 5); uint8_t write_buff[5] = {reg_start_addr}; memcpy(&write_buff[1], data_buf, data_len); - return i2c_master_transmit(sens->i2c_handle, write_buff, data_len + 1, -1); + if (sens->using_spi) { + spi_transaction_t trans = { + .length = (data_len + 1) * 8, // Total length in bits + .tx_buffer = write_buff, + }; + return spi_device_transmit(sens->spi_handle, &trans); + } else { + return i2c_master_transmit(sens->i2c_handle, write_buff, data_len + 1, -1); + } } - static esp_err_t icm42670_read(icm42670_handle_t sensor, const uint8_t reg_start_addr, uint8_t *data_buf, const uint8_t data_len) { - uint8_t reg_buff[] = {reg_start_addr}; - icm42670_dev_t *sens = (icm42670_dev_t *) sensor; - assert(sens); - - /* Write register number and read data */ - return i2c_master_transmit_receive(sens->i2c_handle, reg_buff, sizeof(reg_buff), data_buf, data_len, -1); + icm42670_dev_t *sens = (icm42670_dev_t *)sensor; + assert(sens && data_buf && data_len <= 6); + esp_err_t ret; + if (sens->using_spi) { + uint8_t tx_buf[7] = {reg_start_addr | 0x80}; // Set MSB for read operation + uint8_t rx_buf[7] = {0}; // Buffer to receive data (including the register address) + spi_transaction_t trans = { + .length = (data_len + 1) * 8, // Total length in bits + .tx_buffer = tx_buf, + .rx_buffer = rx_buf, + }; + ret = spi_device_transmit(sens->spi_handle, &trans); + if (ret == ESP_OK) { + memcpy(data_buf, &rx_buf[1], data_len); // Skip the first byte (register address) + } + } else { + uint8_t reg_buff[] = {reg_start_addr}; + /* Write register number and read data */ + ret = i2c_master_transmit_receive(sens->i2c_handle, reg_buff, sizeof(reg_buff), data_buf, data_len, -1); + } + return ret; } esp_err_t icm42670_complimentory_filter(icm42670_handle_t sensor, const icm42670_value_t *const acce_value, const icm42670_value_t *const gyro_value, complimentary_angle_t *const complimentary_angle) { - icm42670_dev_t *sens = (icm42670_dev_t *) sensor; + icm42670_dev_t *sens = (icm42670_dev_t *)sensor; float measurement_delta; uint64_t current_time_us; float acc_roll_angle; @@ -392,9 +453,11 @@ esp_err_t icm42670_complimentory_filter(icm42670_handle_t sensor, const icm42670 float gyro_pitch_angle; acc_roll_angle = (atan2(acce_value->y, - sqrt(acce_value->x * acce_value->x + acce_value->z * acce_value->z)) * RAD_TO_DEG); + sqrt(acce_value->x * acce_value->x + acce_value->z * acce_value->z)) * + RAD_TO_DEG); acc_pitch_angle = (atan2(-acce_value->x, - sqrt(acce_value->y * acce_value->y + acce_value->z * acce_value->z)) * RAD_TO_DEG); + sqrt(acce_value->y * acce_value->y + acce_value->z * acce_value->z)) * + RAD_TO_DEG); if (!sens->initialized_filter) { sens->initialized_filter = true; @@ -411,9 +474,11 @@ esp_err_t icm42670_complimentory_filter(icm42670_handle_t sensor, const icm42670 gyro_pitch_angle = gyro_value->y * measurement_delta; complimentary_angle->roll = (ALPHA * (sens->previous_measurement.roll + gyro_roll_angle)) + (( - 1 - ALPHA) * acc_roll_angle); + 1 - ALPHA) * + acc_roll_angle); complimentary_angle->pitch = (ALPHA * (sens->previous_measurement.pitch + gyro_pitch_angle)) + (( - 1 - ALPHA) * acc_pitch_angle); + 1 - ALPHA) * + acc_pitch_angle); sens->previous_measurement.roll = complimentary_angle->roll; sens->previous_measurement.pitch = complimentary_angle->pitch; @@ -519,13 +584,13 @@ esp_err_t icm42670_impl_deinit(void) return ESP_OK; } -esp_err_t icm42670_impl_test (void) +esp_err_t icm42670_impl_test(void) { uint8_t device_id; return icm42670_get_deviceid(sensor_hub_icm42670_handle, &device_id); } -esp_err_t icm42670_impl_acquire_acce (float *acce_x, float *acce_y, float *acce_z) +esp_err_t icm42670_impl_acquire_acce(float *acce_x, float *acce_y, float *acce_z) { icm42670_value_t value; ESP_RETURN_ON_ERROR(icm42670_get_acce_value(sensor_hub_icm42670_handle, &value), TAG, diff --git a/components/sensors/icm42670/idf_component.yml b/components/sensors/icm42670/idf_component.yml index 5ccb8add5..d6ecec003 100644 --- a/components/sensors/icm42670/idf_component.yml +++ b/components/sensors/icm42670/idf_component.yml @@ -1,5 +1,5 @@ version: 2.1.0 -description: I2C driver for ICM 42670 6-Axis MotionTracking +description: I2C/SPI driver for ICM 42670 6-Axis MotionTracking url: https://github.com/espressif/esp-bsp/tree/master/components/sensors/icm42670 dependencies: idf: ">=5.2" diff --git a/components/sensors/icm42670/include/icm42670.h b/components/sensors/icm42670/include/icm42670.h index f12409900..297eeb046 100644 --- a/components/sensors/icm42670/include/icm42670.h +++ b/components/sensors/icm42670/include/icm42670.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,99 +7,100 @@ #pragma once #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #include "driver/i2c_master.h" - -#define ICM42670_I2C_ADDRESS 0x68 /*!< I2C address with AD0 pin low */ -#define ICM42670_I2C_ADDRESS_1 0x69 /*!< I2C address with AD0 pin high */ - -#define ICM42670_SIGNAL_PATH_RESET 0x02 /*!< Signal path reset */ -#define ICM42670_INT_CONFIG 0x06 /*!< Interrupt configuration */ -#define ICM42670_PWR_MGMT0 0x1F /*!< Power management 0 */ -#define ICM42670_APEX_CONFIG0 0x25 /*!< APEX configuration 0 */ -#define ICM42670_APEX_CONFIG1 0x26 /*!< APEX configuration 1 */ -#define ICM42670_WOM_CONFIG 0x27 /*!< Wake on Motion configuration */ -#define ICM42670_INT_SOURCE0 0x2B /*!< Interrupt source 0 */ -#define ICM42670_INT_SOURCE1 0x2C /*!< Interrupt source 1 */ -#define ICM42670_INTF_CONFIG0 0x35 /*!< Interface configuration 0 */ -#define ICM42670_INTF_CONFIG1 0x36 /*!< Interface configuration 1 */ -#define ICM42670_INT_STATUS 0x3A /*!< Interrupt status */ -#define ICM42670_INT_STATUS2 0x3B /*!< Interrupt status 2 */ -#define ICM42670_INT_STATUS3 0x3C /*!< Interrupt status 3 */ -#define ICM42670_BLK_SEL_W 0x79 /*! Select MREG1, MREG2, or MREG3 bank for writing */ -#define ICM42670_MADDR_W 0x7A /*! Set MREG* register address for writing */ -#define ICM42670_M_W 0x7B /*! Write MREG* register value */ -#define ICM42670_BLK_SEL_R 0x7C /*! Select MREG1, MREG2, or MREG3 bank for reading */ -#define ICM42670_MADDR_R 0x7D /*! Set MREG* register address for reading */ -#define ICM42670_M_R 0x7E /*! Read MREG* register value */ +#include "driver/spi_master.h" + +#define ICM42670_I2C_ADDRESS 0x68 /*!< I2C address with AD0 pin low */ +#define ICM42670_I2C_ADDRESS_1 0x69 /*!< I2C address with AD0 pin high */ + +#define ICM42670_SIGNAL_PATH_RESET 0x02 /*!< Signal path reset */ +#define ICM42670_INT_CONFIG 0x06 /*!< Interrupt configuration */ +#define ICM42670_PWR_MGMT0 0x1F /*!< Power management 0 */ +#define ICM42670_APEX_CONFIG0 0x25 /*!< APEX configuration 0 */ +#define ICM42670_APEX_CONFIG1 0x26 /*!< APEX configuration 1 */ +#define ICM42670_WOM_CONFIG 0x27 /*!< Wake on Motion configuration */ +#define ICM42670_INT_SOURCE0 0x2B /*!< Interrupt source 0 */ +#define ICM42670_INT_SOURCE1 0x2C /*!< Interrupt source 1 */ +#define ICM42670_INTF_CONFIG0 0x35 /*!< Interface configuration 0 */ +#define ICM42670_INTF_CONFIG1 0x36 /*!< Interface configuration 1 */ +#define ICM42670_INT_STATUS 0x3A /*!< Interrupt status */ +#define ICM42670_INT_STATUS2 0x3B /*!< Interrupt status 2 */ +#define ICM42670_INT_STATUS3 0x3C /*!< Interrupt status 3 */ +#define ICM42670_BLK_SEL_W 0x79 /*! Select MREG1, MREG2, or MREG3 bank for writing */ +#define ICM42670_MADDR_W 0x7A /*! Set MREG* register address for writing */ +#define ICM42670_M_W 0x7B /*! Write MREG* register value */ +#define ICM42670_BLK_SEL_R 0x7C /*! Select MREG1, MREG2, or MREG3 bank for reading */ +#define ICM42670_MADDR_R 0x7D /*! Set MREG* register address for reading */ +#define ICM42670_M_R 0x7E /*! Read MREG* register value */ // MREG1 Registers -#define ICM42670_MREG1_INT_CONFIG0 0x04 /*!< Interrupt configuration 0 */ -#define ICM42670_MREG1_INT_CONFIG1 0x05 /*!< Interrupt configuration 1 */ -#define ICM42670_MREG1_ACCEL_WOM_X_THR 0x4B /*!< WOM X threshold */ -#define ICM42670_MREG1_ACCEL_WOM_Y_THR 0x4C /*!< WOM Y threshold */ -#define ICM42670_MREG1_ACCEL_WOM_Z_THR 0x4D /*!< WOM Z threshold */ - +#define ICM42670_MREG1_INT_CONFIG0 0x04 /*!< Interrupt configuration 0 */ +#define ICM42670_MREG1_INT_CONFIG1 0x05 /*!< Interrupt configuration 1 */ +#define ICM42670_MREG1_ACCEL_WOM_X_THR 0x4B /*!< WOM X threshold */ +#define ICM42670_MREG1_ACCEL_WOM_Y_THR 0x4C /*!< WOM Y threshold */ +#define ICM42670_MREG1_ACCEL_WOM_Z_THR 0x4D /*!< WOM Z threshold */ typedef enum { - ACCE_FS_16G = 0, /*!< Accelerometer full scale range is +/- 16g */ - ACCE_FS_8G = 1, /*!< Accelerometer full scale range is +/- 8g */ - ACCE_FS_4G = 2, /*!< Accelerometer full scale range is +/- 4g */ - ACCE_FS_2G = 3, /*!< Accelerometer full scale range is +/- 2g */ + ACCE_FS_16G = 0, /*!< Accelerometer full scale range is +/- 16g */ + ACCE_FS_8G = 1, /*!< Accelerometer full scale range is +/- 8g */ + ACCE_FS_4G = 2, /*!< Accelerometer full scale range is +/- 4g */ + ACCE_FS_2G = 3, /*!< Accelerometer full scale range is +/- 2g */ } icm42670_acce_fs_t; typedef enum { - ACCE_PWR_OFF = 0, /*!< Accelerometer power off state */ - ACCE_PWR_ON = 1, /*!< Accelerometer power on state */ - ACCE_PWR_LOWPOWER = 2, /*!< Accelerometer low-power mode */ - ACCE_PWR_LOWNOISE = 3, /*!< Accelerometer low noise state */ + ACCE_PWR_OFF = 0, /*!< Accelerometer power off state */ + ACCE_PWR_ON = 1, /*!< Accelerometer power on state */ + ACCE_PWR_LOWPOWER = 2, /*!< Accelerometer low-power mode */ + ACCE_PWR_LOWNOISE = 3, /*!< Accelerometer low noise state */ } icm42670_acce_pwr_t; typedef enum { - ACCE_ODR_1600HZ = 5, /*!< Accelerometer ODR 1.6 kHz */ - ACCE_ODR_800HZ = 6, /*!< Accelerometer ODR 800 Hz */ - ACCE_ODR_400HZ = 7, /*!< Accelerometer ODR 400 Hz */ - ACCE_ODR_200HZ = 8, /*!< Accelerometer ODR 200 Hz */ - ACCE_ODR_100HZ = 9, /*!< Accelerometer ODR 100 Hz */ - ACCE_ODR_50HZ = 10, /*!< Accelerometer ODR 50 Hz */ - ACCE_ODR_25HZ = 11, /*!< Accelerometer ODR 25 Hz */ - ACCE_ODR_12_5HZ = 12, /*!< Accelerometer ODR 12.5 Hz */ - ACCE_ODR_6_25HZ = 13, /*!< Accelerometer ODR 6.25 Hz */ - ACCE_ODR_3_125HZ = 14, /*!< Accelerometer ODR 3.125 Hz */ + ACCE_ODR_1600HZ = 5, /*!< Accelerometer ODR 1.6 kHz */ + ACCE_ODR_800HZ = 6, /*!< Accelerometer ODR 800 Hz */ + ACCE_ODR_400HZ = 7, /*!< Accelerometer ODR 400 Hz */ + ACCE_ODR_200HZ = 8, /*!< Accelerometer ODR 200 Hz */ + ACCE_ODR_100HZ = 9, /*!< Accelerometer ODR 100 Hz */ + ACCE_ODR_50HZ = 10, /*!< Accelerometer ODR 50 Hz */ + ACCE_ODR_25HZ = 11, /*!< Accelerometer ODR 25 Hz */ + ACCE_ODR_12_5HZ = 12, /*!< Accelerometer ODR 12.5 Hz */ + ACCE_ODR_6_25HZ = 13, /*!< Accelerometer ODR 6.25 Hz */ + ACCE_ODR_3_125HZ = 14, /*!< Accelerometer ODR 3.125 Hz */ ACCE_ODR_1_5625HZ = 15, /*!< Accelerometer ODR 1.5625 Hz */ } icm42670_acce_odr_t; typedef enum { - GYRO_FS_2000DPS = 0, /*!< Gyroscope full scale range is +/- 2000 degree per sencond */ - GYRO_FS_1000DPS = 1, /*!< Gyroscope full scale range is +/- 1000 degree per sencond */ - GYRO_FS_500DPS = 2, /*!< Gyroscope full scale range is +/- 500 degree per sencond */ - GYRO_FS_250DPS = 3, /*!< Gyroscope full scale range is +/- 250 degree per sencond */ + GYRO_FS_2000DPS = 0, /*!< Gyroscope full scale range is +/- 2000 degree per sencond */ + GYRO_FS_1000DPS = 1, /*!< Gyroscope full scale range is +/- 1000 degree per sencond */ + GYRO_FS_500DPS = 2, /*!< Gyroscope full scale range is +/- 500 degree per sencond */ + GYRO_FS_250DPS = 3, /*!< Gyroscope full scale range is +/- 250 degree per sencond */ } icm42670_gyro_fs_t; typedef enum { - GYRO_PWR_OFF = 0, /*!< Gyroscope power off state */ - GYRO_PWR_STANDBY = 1, /*!< Gyroscope power standby state */ - GYRO_PWR_LOWNOISE = 3, /*!< Gyroscope power low noise state */ + GYRO_PWR_OFF = 0, /*!< Gyroscope power off state */ + GYRO_PWR_STANDBY = 1, /*!< Gyroscope power standby state */ + GYRO_PWR_LOWNOISE = 3, /*!< Gyroscope power low noise state */ } icm42670_gyro_pwr_t; typedef enum { GYRO_ODR_1600HZ = 5, /*!< Gyroscope ODR 1.6 kHz */ - GYRO_ODR_800HZ = 6, /*!< Gyroscope ODR 800 Hz */ - GYRO_ODR_400HZ = 7, /*!< Gyroscope ODR 400 Hz */ - GYRO_ODR_200HZ = 8, /*!< Gyroscope ODR 200 Hz */ - GYRO_ODR_100HZ = 9, /*!< Gyroscope ODR 100 Hz */ - GYRO_ODR_50HZ = 10, /*!< Gyroscope ODR 50 Hz */ - GYRO_ODR_25HZ = 11, /*!< Gyroscope ODR 25 Hz */ + GYRO_ODR_800HZ = 6, /*!< Gyroscope ODR 800 Hz */ + GYRO_ODR_400HZ = 7, /*!< Gyroscope ODR 400 Hz */ + GYRO_ODR_200HZ = 8, /*!< Gyroscope ODR 200 Hz */ + GYRO_ODR_100HZ = 9, /*!< Gyroscope ODR 100 Hz */ + GYRO_ODR_50HZ = 10, /*!< Gyroscope ODR 50 Hz */ + GYRO_ODR_25HZ = 11, /*!< Gyroscope ODR 25 Hz */ GYRO_ODR_12_5HZ = 12, /*!< Gyroscope ODR 12.5 Hz */ } icm42670_gyro_odr_t; typedef struct { - icm42670_acce_fs_t acce_fs; /*!< Accelerometer full scale range */ - icm42670_acce_odr_t acce_odr; /*!< Accelerometer ODR selection */ - icm42670_gyro_fs_t gyro_fs; /*!< Gyroscope full scale range */ - icm42670_gyro_odr_t gyro_odr; /*!< Gyroscope ODR selection */ + icm42670_acce_fs_t acce_fs; /*!< Accelerometer full scale range */ + icm42670_acce_odr_t acce_odr; /*!< Accelerometer ODR selection */ + icm42670_gyro_fs_t gyro_fs; /*!< Gyroscope full scale range */ + icm42670_gyro_odr_t gyro_odr; /*!< Gyroscope ODR selection */ } icm42670_cfg_t; typedef struct { @@ -122,7 +123,7 @@ typedef struct { typedef void *icm42670_handle_t; /** - * @brief Create and init sensor object + * @brief Create and init sensor object using I2C interface * * @param[in] i2c_bus I2C bus handle. Obtained from i2c_new_master_bus() * @param[in] dev_addr I2C device address of sensor. Can be ICM42670_I2C_ADDRESS or ICM42670_I2C_ADDRESS_1 @@ -136,6 +137,20 @@ typedef void *icm42670_handle_t; */ esp_err_t icm42670_create(i2c_master_bus_handle_t i2c_bus, const uint8_t dev_addr, icm42670_handle_t *handle_ret); +/** + * @brief Create and init sensor object using SPI interface + * + * @param[in] spi_bus SPI bus handle. Obtained from spi_new_master_bus() + * @param[in] cs_pin SPI chip select pin of sensor. Can be ICM42670_SPI_CS_PIN or ICM42670_SPI_CS_PI_1 + * @param[out] handle_ret Handle to created ICM42670 driver object + * + * @return + * - ESP_OK Success + * - ESP_ERR_NO_MEM Not enough memory for the driver + * - ESP_ERR_NOT_FOUND Sensor not found on the I2C bus + * - Others Error from underlying I2C driver + */ +esp_err_t icm42670_create_spi(spi_host_device_t spi_bus, gpio_num_t cs_pin, icm42670_handle_t *handle_ret); /** * @brief Delete and release a sensor object *