diff --git a/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts b/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts index 44f7c06a66d9..d0ae84882ed3 100644 --- a/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts +++ b/boards/nxp/vmu_rt1170/vmu_rt1170_mimxrt1176_cm7.dts @@ -243,36 +243,40 @@ }; }; -#include +#include &lpspi1 { status = "okay"; cs-gpios =<&gpio2 11 GPIO_ACTIVE_LOW>; - icm42688_0: icm42688p0@0 { - compatible = "invensense,icm42688"; + icm42686_0: icm42686p0@0 { + compatible = "invensense,icm42686", "invensense,icm4268x"; reg = <0>; int-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; spi-max-frequency = <24000000>; - accel-pwr-mode = ; - accel-odr = ; - accel-fs = ; - gyro-pwr-mode = ; - gyro-odr = ; - gyro-fs = ; - axis-align-x = ; - axis-align-y = ; + accel-pwr-mode = ; + accel-odr = ; + accel-fs = ; + gyro-pwr-mode = ; + gyro-odr = ; + gyro-fs = ; + axis-align-x = ; + axis-align-y = ; axis-align-z = ; + axis-align-x-sign = ; + axis-align-z-sign = ; fifo-hires; }; }; +#include + &lpspi2 { status = "okay"; cs-gpios =<&gpio3 24 GPIO_ACTIVE_LOW>; - icm42688_1: icm42688p1@0 { - compatible = "invensense,icm42688"; + icm42688_0: icm42688p0@0 { + compatible = "invensense,icm42688", "invensense,icm4268x"; reg = <0>; int-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>; spi-max-frequency = <24000000>; @@ -285,6 +289,7 @@ axis-align-x = ; axis-align-y = ; axis-align-z = ; + axis-align-x-sign = ; fifo-hires; }; }; diff --git a/boards/tdk/robokit1/robokit1-common.dtsi b/boards/tdk/robokit1/robokit1-common.dtsi index 69c032974b89..c4fc4e0e4bd0 100644 --- a/boards/tdk/robokit1/robokit1-common.dtsi +++ b/boards/tdk/robokit1/robokit1-common.dtsi @@ -101,7 +101,7 @@ status = "okay"; icm42688: icm42688p@0 { - compatible = "invensense,icm42688"; + compatible = "invensense,icm42688", "invensense,icm4268x"; reg = <0>; int-gpios = <&pioc 5 GPIO_ACTIVE_HIGH>; spi-max-frequency = <24000000>; diff --git a/doc/hardware/peripherals/sensor/device_tree.rst b/doc/hardware/peripherals/sensor/device_tree.rst index 8aa99655b3a2..7fb9efea880f 100644 --- a/doc/hardware/peripherals/sensor/device_tree.rst +++ b/doc/hardware/peripherals/sensor/device_tree.rst @@ -15,7 +15,7 @@ then be used in a boards devicetree to configure a sensor to its initial state. /* SPI bus options here, not shown */ accel_gyro0: icm42688p@0 { - compatible = "invensense,icm42688"; + compatible = "invensense,icm42688", "invensense,icm4268x"; reg = <0>; int-gpios = <&pioc 6 GPIO_ACTIVE_HIGH>; /* SoC specific pin to select for interrupt line */ spi-max-frequency = ; /* Maximum SPI bus frequency */ diff --git a/doc/releases/migration-guide-4.2.rst b/doc/releases/migration-guide-4.2.rst index b67ed2c8a0e1..d32ef3b088dc 100644 --- a/doc/releases/migration-guide-4.2.rst +++ b/doc/releases/migration-guide-4.2.rst @@ -312,6 +312,9 @@ Sensors * Renamed ``CONFIG_NPM1300_CHARGER`` to :kconfig:option:`CONFIG_NPM13XX_CHARGER` +* Nodes with compatible property :dtcompatible:`invensense,icm42688` now additionally need to also + include :dtcompatible:`invensense,icm4268x` in order to work. + Serial ======= diff --git a/drivers/sensor/tdk/CMakeLists.txt b/drivers/sensor/tdk/CMakeLists.txt index a7adf6185215..48e65ccfd343 100644 --- a/drivers/sensor/tdk/CMakeLists.txt +++ b/drivers/sensor/tdk/CMakeLists.txt @@ -4,7 +4,7 @@ # zephyr-keep-sorted-start add_subdirectory_ifdef(CONFIG_ICM40627 icm40627) add_subdirectory_ifdef(CONFIG_ICM42605 icm42605) -add_subdirectory_ifdef(CONFIG_ICM42688 icm42688) +add_subdirectory_ifdef(CONFIG_ICM4268X icm4268x) add_subdirectory_ifdef(CONFIG_ICM42X70 icm42x70) add_subdirectory_ifdef(CONFIG_ICM45686 icm45686) add_subdirectory_ifdef(CONFIG_ICP101XX icp101xx) diff --git a/drivers/sensor/tdk/Kconfig b/drivers/sensor/tdk/Kconfig index 9b9b6ae5ee1c..cb3e7600f025 100644 --- a/drivers/sensor/tdk/Kconfig +++ b/drivers/sensor/tdk/Kconfig @@ -4,7 +4,7 @@ # zephyr-keep-sorted-start source "drivers/sensor/tdk/icm40627/Kconfig" source "drivers/sensor/tdk/icm42605/Kconfig" -source "drivers/sensor/tdk/icm42688/Kconfig" +source "drivers/sensor/tdk/icm4268x/Kconfig" source "drivers/sensor/tdk/icm42x70/Kconfig" source "drivers/sensor/tdk/icm45686/Kconfig" source "drivers/sensor/tdk/icp101xx/Kconfig" diff --git a/drivers/sensor/tdk/icm42688/CMakeLists.txt b/drivers/sensor/tdk/icm42688/CMakeLists.txt deleted file mode 100644 index fbc63b6a4b22..000000000000 --- a/drivers/sensor/tdk/icm42688/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library() - -zephyr_library_sources( - icm42688.c - icm42688_common.c - icm42688_spi.c -) - -zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API icm42688_rtio.c) -zephyr_library_sources_ifdef(CONFIG_ICM42688_DECODER icm42688_decoder.c) -zephyr_library_sources_ifdef(CONFIG_ICM42688_STREAM icm42688_rtio_stream.c) -zephyr_library_sources_ifdef(CONFIG_ICM42688_TRIGGER icm42688_trigger.c) -zephyr_library_sources_ifdef(CONFIG_EMUL_ICM42688 icm42688_emul.c) -zephyr_include_directories_ifdef(CONFIG_EMUL_ICM42688 .) diff --git a/drivers/sensor/tdk/icm42688/icm42688.h b/drivers/sensor/tdk/icm42688/icm42688.h deleted file mode 100644 index ed2b96f4bbc4..000000000000 --- a/drivers/sensor/tdk/icm42688/icm42688.h +++ /dev/null @@ -1,620 +0,0 @@ -/* - * Copyright (c) 2022 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42688_H_ -#define ZEPHYR_DRIVERS_SENSOR_ICM42688_H_ - -#include -#include -#include -#include -#include -#include - -struct alignment { - int8_t index; - int8_t sign; -}; - -static inline uint8_t icm42688_accel_fs_to_reg(uint8_t g) -{ - if (g >= 16) { - return ICM42688_DT_ACCEL_FS_16; - } else if (g >= 8) { - return ICM42688_DT_ACCEL_FS_8; - } else if (g >= 4) { - return ICM42688_DT_ACCEL_FS_4; - } else { - return ICM42688_DT_ACCEL_FS_2; - } -} - -static inline void icm42688_accel_reg_to_fs(uint8_t fs, struct sensor_value *out) -{ - switch (fs) { - case ICM42688_DT_ACCEL_FS_16: - sensor_g_to_ms2(16, out); - return; - case ICM42688_DT_ACCEL_FS_8: - sensor_g_to_ms2(8, out); - return; - case ICM42688_DT_ACCEL_FS_4: - sensor_g_to_ms2(4, out); - return; - case ICM42688_DT_ACCEL_FS_2: - sensor_g_to_ms2(2, out); - return; - } -} - -static inline uint8_t icm42688_gyro_fs_to_reg(uint16_t dps) -{ - if (dps >= 2000) { - return ICM42688_DT_GYRO_FS_2000; - } else if (dps >= 1000) { - return ICM42688_DT_GYRO_FS_1000; - } else if (dps >= 500) { - return ICM42688_DT_GYRO_FS_500; - } else if (dps >= 250) { - return ICM42688_DT_GYRO_FS_250; - } else if (dps >= 125) { - return ICM42688_DT_GYRO_FS_125; - } else if (dps >= 62) { - return ICM42688_DT_GYRO_FS_62_5; - } else if (dps >= 31) { - return ICM42688_DT_GYRO_FS_31_25; - } else { - return ICM42688_DT_GYRO_FS_15_625; - } -} - -static inline void icm42688_gyro_reg_to_fs(uint8_t fs, struct sensor_value *out) -{ - switch (fs) { - case ICM42688_DT_GYRO_FS_2000: - sensor_degrees_to_rad(2000, out); - return; - case ICM42688_DT_GYRO_FS_1000: - sensor_degrees_to_rad(1000, out); - return; - case ICM42688_DT_GYRO_FS_500: - sensor_degrees_to_rad(500, out); - return; - case ICM42688_DT_GYRO_FS_250: - sensor_degrees_to_rad(250, out); - return; - case ICM42688_DT_GYRO_FS_125: - sensor_degrees_to_rad(125, out); - return; - case ICM42688_DT_GYRO_FS_62_5: - sensor_10udegrees_to_rad(6250000, out); - return; - case ICM42688_DT_GYRO_FS_31_25: - sensor_10udegrees_to_rad(3125000, out); - return; - case ICM42688_DT_GYRO_FS_15_625: - sensor_10udegrees_to_rad(1562500, out); - return; - } -} - -static inline uint8_t icm42688_accel_hz_to_reg(uint16_t hz) -{ - if (hz >= 32000) { - return ICM42688_DT_ACCEL_ODR_32000; - } else if (hz >= 16000) { - return ICM42688_DT_ACCEL_ODR_16000; - } else if (hz >= 8000) { - return ICM42688_DT_ACCEL_ODR_8000; - } else if (hz >= 4000) { - return ICM42688_DT_ACCEL_ODR_4000; - } else if (hz >= 2000) { - return ICM42688_DT_ACCEL_ODR_2000; - } else if (hz >= 1000) { - return ICM42688_DT_ACCEL_ODR_1000; - } else if (hz >= 500) { - return ICM42688_DT_ACCEL_ODR_500; - } else if (hz >= 200) { - return ICM42688_DT_ACCEL_ODR_200; - } else if (hz >= 100) { - return ICM42688_DT_ACCEL_ODR_100; - } else if (hz >= 50) { - return ICM42688_DT_ACCEL_ODR_50; - } else if (hz >= 25) { - return ICM42688_DT_ACCEL_ODR_25; - } else if (hz >= 12) { - return ICM42688_DT_ACCEL_ODR_12_5; - } else if (hz >= 6) { - return ICM42688_DT_ACCEL_ODR_6_25; - } else if (hz >= 3) { - return ICM42688_DT_ACCEL_ODR_3_125; - } else { - return ICM42688_DT_ACCEL_ODR_1_5625; - } -} - -static inline void icm42688_accel_reg_to_hz(uint8_t odr, struct sensor_value *out) -{ - switch (odr) { - case ICM42688_DT_ACCEL_ODR_32000: - out->val1 = 32000; - out->val2 = 0; - return; - case ICM42688_DT_ACCEL_ODR_16000: - out->val1 = 1600; - out->val2 = 0; - return; - case ICM42688_DT_ACCEL_ODR_8000: - out->val1 = 8000; - out->val2 = 0; - return; - case ICM42688_DT_ACCEL_ODR_4000: - out->val1 = 4000; - out->val2 = 0; - return; - case ICM42688_DT_ACCEL_ODR_2000: - out->val1 = 2000; - out->val2 = 0; - return; - case ICM42688_DT_ACCEL_ODR_1000: - out->val1 = 1000; - out->val2 = 0; - return; - case ICM42688_DT_ACCEL_ODR_500: - out->val1 = 500; - out->val2 = 0; - return; - case ICM42688_DT_ACCEL_ODR_200: - out->val1 = 200; - out->val2 = 0; - return; - case ICM42688_DT_ACCEL_ODR_100: - out->val1 = 100; - out->val2 = 0; - return; - case ICM42688_DT_ACCEL_ODR_50: - out->val1 = 50; - out->val2 = 0; - return; - case ICM42688_DT_ACCEL_ODR_25: - out->val1 = 25; - out->val2 = 0; - return; - case ICM42688_DT_ACCEL_ODR_12_5: - out->val1 = 12; - out->val2 = 500000; - return; - case ICM42688_DT_ACCEL_ODR_6_25: - out->val1 = 6; - out->val2 = 250000; - return; - case ICM42688_DT_ACCEL_ODR_3_125: - out->val1 = 3; - out->val2 = 125000; - return; - case ICM42688_DT_ACCEL_ODR_1_5625: - out->val1 = 1; - out->val2 = 562500; - return; - } -} - -static inline uint8_t icm42688_gyro_odr_to_reg(uint16_t hz) -{ - if (hz >= 32000) { - return ICM42688_DT_GYRO_ODR_32000; - } else if (hz >= 16000) { - return ICM42688_DT_GYRO_ODR_16000; - } else if (hz >= 8000) { - return ICM42688_DT_GYRO_ODR_8000; - } else if (hz >= 4000) { - return ICM42688_DT_GYRO_ODR_4000; - } else if (hz >= 2000) { - return ICM42688_DT_GYRO_ODR_2000; - } else if (hz >= 1000) { - return ICM42688_DT_GYRO_ODR_1000; - } else if (hz >= 500) { - return ICM42688_DT_GYRO_ODR_500; - } else if (hz >= 200) { - return ICM42688_DT_GYRO_ODR_200; - } else if (hz >= 100) { - return ICM42688_DT_GYRO_ODR_100; - } else if (hz >= 50) { - return ICM42688_DT_GYRO_ODR_50; - } else if (hz >= 25) { - return ICM42688_DT_GYRO_ODR_25; - } else { - return ICM42688_DT_GYRO_ODR_12_5; - } -} - -static inline void icm42688_gyro_reg_to_odr(uint8_t odr, struct sensor_value *out) -{ - switch (odr) { - case ICM42688_DT_GYRO_ODR_32000: - out->val1 = 32000; - out->val2 = 0; - return; - case ICM42688_DT_GYRO_ODR_16000: - out->val1 = 16000; - out->val2 = 0; - return; - case ICM42688_DT_GYRO_ODR_8000: - out->val1 = 8000; - out->val2 = 0; - return; - case ICM42688_DT_GYRO_ODR_4000: - out->val1 = 4000; - out->val2 = 0; - return; - case ICM42688_DT_GYRO_ODR_2000: - out->val1 = 2000; - out->val2 = 0; - return; - case ICM42688_DT_GYRO_ODR_1000: - out->val1 = 1000; - out->val2 = 0; - return; - case ICM42688_DT_GYRO_ODR_500: - out->val1 = 500; - out->val2 = 0; - return; - case ICM42688_DT_GYRO_ODR_200: - out->val1 = 200; - out->val2 = 0; - return; - case ICM42688_DT_GYRO_ODR_100: - out->val1 = 100; - out->val2 = 0; - return; - case ICM42688_DT_GYRO_ODR_50: - out->val1 = 50; - out->val2 = 0; - return; - case ICM42688_DT_GYRO_ODR_25: - out->val1 = 25; - out->val2 = 0; - return; - case ICM42688_DT_GYRO_ODR_12_5: - out->val1 = 12; - out->val2 = 500000; - return; - } -} - -/** - * @brief All sensor configuration options - */ -struct icm42688_cfg { - uint8_t accel_pwr_mode; - uint8_t accel_fs; - uint8_t accel_odr; - /* TODO accel signal processing options */ - - uint8_t gyro_pwr_mode; - uint8_t gyro_fs; - uint8_t gyro_odr; - /* TODO gyro signal processing options */ - - bool temp_dis; - /* TODO temp signal processing options */ - - /* TODO timestamp options */ - - bool fifo_en; - int32_t batch_ticks; - bool fifo_hires; - /* TODO additional FIFO options */ - - /* TODO interrupt options */ - bool interrupt1_drdy; - bool interrupt1_fifo_ths; - bool interrupt1_fifo_full; - struct alignment axis_align[3]; - uint8_t pin9_function; - uint16_t rtc_freq; -}; - -struct icm42688_trigger_entry { - struct sensor_trigger trigger; - sensor_trigger_handler_t handler; -}; - -/** - * @brief Device data (struct device) - */ -struct icm42688_dev_data { - struct icm42688_cfg cfg; -#ifdef CONFIG_ICM42688_TRIGGER -#if defined(CONFIG_ICM42688_TRIGGER_OWN_THREAD) - K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ICM42688_THREAD_STACK_SIZE); - struct k_thread thread; - struct k_sem gpio_sem; -#elif defined(CONFIG_ICM42688_TRIGGER_GLOBAL_THREAD) - struct k_work work; -#endif -#ifdef CONFIG_ICM42688_STREAM - struct rtio_iodev_sqe *streaming_sqe; - struct rtio *r; - struct rtio_iodev *spi_iodev; - uint8_t int_status; - uint16_t fifo_count; - uint64_t timestamp; - atomic_t reading_fifo; -#endif /* CONFIG_ICM42688_STREAM */ - const struct device *dev; - struct gpio_callback gpio_cb; - sensor_trigger_handler_t data_ready_handler; - const struct sensor_trigger *data_ready_trigger; - struct k_mutex mutex; -#endif /* CONFIG_ICM42688_TRIGGER */ - - int16_t readings[7]; -}; - -/** - * @brief Device config (struct device) - */ -struct icm42688_dev_cfg { - struct spi_dt_spec spi; - struct gpio_dt_spec gpio_int1; - struct gpio_dt_spec gpio_int2; -}; - -/** - * @brief Reset the sensor - * - * @param dev icm42688 device pointer - * - * @retval 0 success - * @retval -EINVAL Reset status or whoami register returned unexpected value. - */ -int icm42688_reset(const struct device *dev); - -/** - * @brief (Re)Configure the sensor with the given configuration - * - * @param dev icm42688 device pointer - * @param cfg icm42688_cfg pointer - * - * @retval 0 success - * @retval -errno Error - */ -int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg); - - -/** - * @brief Safely (re)Configure the sensor with the given configuration - * - * Will rollback to prior configuration if new configuration is invalid - * - * @param dev icm42688 device pointer - * @param cfg icm42688_cfg pointer - * - * @retval 0 success - * @retval -errno Error - */ -int icm42688_safely_configure(const struct device *dev, struct icm42688_cfg *cfg); - -/** - * @brief Reads all channels - * - * Regardless of what is enabled/disabled this reads all data registers - * as the time to read the 14 bytes at 1MHz is going to be 112 us which - * is less time than a SPI transaction takes to setup typically. - * - * @param dev icm42688 device pointer - * @param buf 14 byte buffer to store data values (7 channels, 2 bytes each) - * - * @retval 0 success - * @retval -errno Error - */ -int icm42688_read_all(const struct device *dev, uint8_t data[14]); - -/** - * @brief Convert icm42688 accelerometer value to useful g values - * - * @param cfg icm42688_cfg current device configuration - * @param in raw data value in int32_t format - * @param out_g whole G's output in int32_t - * @param out_ug micro (1/1000000) of a G output as int32_t - */ -static inline void icm42688_accel_g(struct icm42688_cfg *cfg, int32_t in, int32_t *out_g, - int32_t *out_ug) -{ - int32_t sensitivity; - - switch (cfg->accel_fs) { - case ICM42688_DT_ACCEL_FS_2: - sensitivity = 16384; - break; - case ICM42688_DT_ACCEL_FS_4: - sensitivity = 8192; - break; - case ICM42688_DT_ACCEL_FS_8: - sensitivity = 4096; - break; - case ICM42688_DT_ACCEL_FS_16: - sensitivity = 2048; - break; - default: - CODE_UNREACHABLE; - } - - /* Whole g's */ - *out_g = in / sensitivity; - - /* Micro g's */ - *out_ug = ((abs(in) - (abs((*out_g)) * sensitivity)) * 1000000) / sensitivity; -} - -/** - * @brief Convert icm42688 gyroscope value to useful deg/s values - * - * @param cfg icm42688_cfg current device configuration - * @param in raw data value in int32_t format - * @param out_dps whole deg/s output in int32_t - * @param out_udps micro (1/1000000) deg/s as int32_t - */ -static inline void icm42688_gyro_dps(const struct icm42688_cfg *cfg, int32_t in, int32_t *out_dps, - int32_t *out_udps) -{ - int64_t sensitivity; - - switch (cfg->gyro_fs) { - case ICM42688_DT_GYRO_FS_2000: - sensitivity = 164; - break; - case ICM42688_DT_GYRO_FS_1000: - sensitivity = 328; - break; - case ICM42688_DT_GYRO_FS_500: - sensitivity = 655; - break; - case ICM42688_DT_GYRO_FS_250: - sensitivity = 1310; - break; - case ICM42688_DT_GYRO_FS_125: - sensitivity = 2620; - break; - case ICM42688_DT_GYRO_FS_62_5: - sensitivity = 5243; - break; - case ICM42688_DT_GYRO_FS_31_25: - sensitivity = 10486; - break; - case ICM42688_DT_GYRO_FS_15_625: - sensitivity = 20972; - break; - default: - CODE_UNREACHABLE; - } - - int32_t in10 = in * 10; - - /* Whole deg/s */ - *out_dps = in10 / sensitivity; - - /* Micro deg/s */ - *out_udps = ((int64_t)(llabs(in10) - (llabs((*out_dps)) * sensitivity)) * 1000000LL) / - sensitivity; -} - -/** - * @brief Convert icm42688 accelerometer value to useful m/s^2 values - * - * @param cfg icm42688_cfg current device configuration - * @param in raw data value in int32_t format - * @param out_ms meters/s^2 (whole) output in int32_t - * @param out_ums micrometers/s^2 output as int32_t - */ -static inline void icm42688_accel_ms(const struct icm42688_cfg *cfg, int32_t in, int32_t *out_ms, - int32_t *out_ums) -{ - int64_t sensitivity; - - switch (cfg->accel_fs) { - case ICM42688_DT_ACCEL_FS_2: - sensitivity = 16384; - break; - case ICM42688_DT_ACCEL_FS_4: - sensitivity = 8192; - break; - case ICM42688_DT_ACCEL_FS_8: - sensitivity = 4096; - break; - case ICM42688_DT_ACCEL_FS_16: - sensitivity = 2048; - break; - default: - CODE_UNREACHABLE; - } - - /* Convert to micrometers/s^2 */ - int64_t in_ms = in * SENSOR_G; - - /* meters/s^2 whole values */ - *out_ms = in_ms / (sensitivity * 1000000LL); - - /* micrometers/s^2 */ - *out_ums = (in_ms - (*out_ms * sensitivity * 1000000LL)) / sensitivity; -} - -/** - * @brief Convert icm42688 gyroscope value to useful rad/s values - * - * @param cfg icm42688_cfg current device configuration - * @param in raw data value in int32_t format - * @param out_rads whole rad/s output in int32_t - * @param out_urads microrad/s as int32_t - */ -static inline void icm42688_gyro_rads(const struct icm42688_cfg *cfg, int32_t in, int32_t *out_rads, - int32_t *out_urads) -{ - int64_t sensitivity; - - switch (cfg->gyro_fs) { - case ICM42688_DT_GYRO_FS_2000: - sensitivity = 164; - break; - case ICM42688_DT_GYRO_FS_1000: - sensitivity = 328; - break; - case ICM42688_DT_GYRO_FS_500: - sensitivity = 655; - break; - case ICM42688_DT_GYRO_FS_250: - sensitivity = 1310; - break; - case ICM42688_DT_GYRO_FS_125: - sensitivity = 2620; - break; - case ICM42688_DT_GYRO_FS_62_5: - sensitivity = 5243; - break; - case ICM42688_DT_GYRO_FS_31_25: - sensitivity = 10486; - break; - case ICM42688_DT_GYRO_FS_15_625: - sensitivity = 20972; - break; - default: - CODE_UNREACHABLE; - } - - int64_t in10_rads = (int64_t)in * SENSOR_PI * 10LL; - - /* Whole rad/s */ - *out_rads = in10_rads / (sensitivity * 180LL * 1000000LL); - - /* microrad/s */ - *out_urads = - (in10_rads - (*out_rads * sensitivity * 180LL * 1000000LL)) / (sensitivity * 180LL); -} - -/** - * @brief Convert icm42688 temp value to useful celsius values - * - * @param cfg icm42688_cfg current device configuration - * @param in raw data value in int32_t format - * @param out_c whole celsius output in int32_t - * @param out_uc micro (1/1000000) celsius as int32_t - */ -static inline void icm42688_temp_c(int32_t in, int32_t *out_c, int32_t *out_uc) -{ - int64_t sensitivity = 13248; /* value equivalent for x100 1c */ - - /* Offset by 25 degrees Celsius */ - int64_t in100 = (in * 100) + (25 * sensitivity); - - /* Whole celsius */ - *out_c = in100 / sensitivity; - - /* Micro celsius */ - *out_uc = ((in100 - (*out_c) * sensitivity) * INT64_C(1000000)) / sensitivity; -} - -#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42688_H_ */ diff --git a/drivers/sensor/tdk/icm42688/icm42688_rtio.h b/drivers/sensor/tdk/icm42688/icm42688_rtio.h deleted file mode 100644 index a4d12b82a189..000000000000 --- a/drivers/sensor/tdk/icm42688/icm42688_rtio.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2023 Google LLC - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42688_RTIO_H_ -#define ZEPHYR_DRIVERS_SENSOR_ICM42688_RTIO_H_ - -#include -#include - -void icm42688_submit(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe); - -void icm42688_submit_stream(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe); - -void icm42688_fifo_event(const struct device *dev); - -#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42688_RTIO_H_ */ diff --git a/drivers/sensor/tdk/icm42688/icm42688_trigger.h b/drivers/sensor/tdk/icm42688/icm42688_trigger.h deleted file mode 100644 index e03975916181..000000000000 --- a/drivers/sensor/tdk/icm42688/icm42688_trigger.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2022 Intel Corporation - * Copyright (c) 2023 Google LLC - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42688_TRIGGER_H_ -#define ZEPHYR_DRIVERS_SENSOR_ICM42688_TRIGGER_H_ - -#include - -/** implement the trigger_set sensor api function */ -int icm42688_trigger_set(const struct device *dev, const struct sensor_trigger *trig, - sensor_trigger_handler_t handler); - -/** - * @brief initialize the icm42688 trigger system - * - * @param dev icm42688 device pointer - * @return int 0 on success, negative error code otherwise - */ -int icm42688_trigger_init(const struct device *dev); - -/** - * @brief enable the trigger gpio interrupt - * - * @param dev icm42688 device pointer - * @param new_cfg New configuration to use for the device - * @return int 0 on success, negative error code otherwise - */ -int icm42688_trigger_enable_interrupt(const struct device *dev, struct icm42688_cfg *new_cfg); - -/** - * @brief lock access to the icm42688 device driver - * - * @param dev icm42688 device pointer - */ -void icm42688_lock(const struct device *dev); - -/** - * @brief lock access to the icm42688 device driver - * - * @param dev icm42688 device pointer - */ -void icm42688_unlock(const struct device *dev); - -#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42688_TRIGGER_H_ */ diff --git a/drivers/sensor/tdk/icm4268x/CMakeLists.txt b/drivers/sensor/tdk/icm4268x/CMakeLists.txt new file mode 100644 index 000000000000..76a814f2baa8 --- /dev/null +++ b/drivers/sensor/tdk/icm4268x/CMakeLists.txt @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources( + icm4268x.c + icm4268x_common.c + icm4268x_spi.c +) + +zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API icm4268x_rtio.c) +zephyr_library_sources_ifdef(CONFIG_ICM4268X_DECODER icm4268x_decoder.c) +zephyr_library_sources_ifdef(CONFIG_ICM4268X_STREAM icm4268x_rtio_stream.c) +zephyr_library_sources_ifdef(CONFIG_ICM4268X_TRIGGER icm4268x_trigger.c) +zephyr_library_sources_ifdef(CONFIG_EMUL_ICM4268X icm4268x_emul.c) +zephyr_include_directories_ifdef(CONFIG_EMUL_ICM4268X .) diff --git a/drivers/sensor/tdk/icm42688/Kconfig b/drivers/sensor/tdk/icm4268x/Kconfig similarity index 51% rename from drivers/sensor/tdk/icm42688/Kconfig rename to drivers/sensor/tdk/icm4268x/Kconfig index 975c8e1825f6..eea2ad27774b 100644 --- a/drivers/sensor/tdk/icm42688/Kconfig +++ b/drivers/sensor/tdk/icm4268x/Kconfig @@ -1,85 +1,85 @@ -# ICM42688-P Six-Axis Motion Tracking device configuration options +# ICM4268X-P Six-Axis Motion Tracking device configuration options # # Copyright (c) 2022 Intel Corporation # Copyright (c) 2024 Croxel Inc. # # SPDX-License-Identifier: Apache-2.0 -menuconfig ICM42688 - bool "ICM42688 Six-Axis Motion Tracking Device" +menuconfig ICM4268X + bool "ICM4268X Six-Axis Motion Tracking Device" default y - depends on DT_HAS_INVENSENSE_ICM42688_ENABLED + depends on DT_HAS_INVENSENSE_ICM4268X_ENABLED select SPI select RTIO_WORKQ if SENSOR_ASYNC_API help - Enable driver for ICM42688 SPI-based six-axis motion tracking device. + Enable driver for ICM4268X SPI-based six-axis motion tracking device. -if ICM42688 +if ICM4268X -config EMUL_ICM42688 - bool "Emulator for the ICM42688" +config EMUL_ICM4268X + bool "Emulator for the ICM4268X" default y depends on EMUL help - Enable the hardware emulator for the ICM42688. Doing so allows exercising + Enable the hardware emulator for the ICM4268X. Doing so allows exercising sensor APIs for this IMU in native_sim and qemu. -config ICM42688_DECODER - bool "ICM42688 decoder logic" +config ICM4268X_DECODER + bool "ICM4268X decoder logic" default y select SENSOR_ASYNC_API help - Compile the ICM42688 decoder API which allows decoding raw data returned + Compile the ICM4268X decoder API which allows decoding raw data returned from the sensor. choice prompt "Trigger mode" - default ICM42688_TRIGGER_NONE if ICM42688_STREAM - default ICM42688_TRIGGER_GLOBAL_THREAD + default ICM4268X_TRIGGER_NONE if ICM4268X_STREAM + default ICM4268X_TRIGGER_GLOBAL_THREAD help Specify the type of triggering to be used by the driver -config ICM42688_TRIGGER_NONE +config ICM4268X_TRIGGER_NONE bool "No trigger" -config ICM42688_TRIGGER_GLOBAL_THREAD +config ICM4268X_TRIGGER_GLOBAL_THREAD bool "Use global thread" depends on GPIO - depends on $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM42688),int-gpios) - select ICM42688_TRIGGER + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM4268X),int-gpios) + select ICM4268X_TRIGGER -config ICM42688_TRIGGER_OWN_THREAD +config ICM4268X_TRIGGER_OWN_THREAD bool "Use own thread" depends on GPIO - depends on $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM42688),int-gpios) - select ICM42688_TRIGGER + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_INVENSENSE_ICM4268X),int-gpios) + select ICM4268X_TRIGGER endchoice -config ICM42688_STREAM +config ICM4268X_STREAM bool "Use hardware FIFO to stream data" - select ICM42688_TRIGGER + select ICM4268X_TRIGGER default y depends on SPI_RTIO depends on SENSOR_ASYNC_API help Use this config option to enable streaming sensor data via RTIO subsystem. -config ICM42688_TRIGGER +config ICM4268X_TRIGGER bool -config ICM42688_THREAD_PRIORITY +config ICM4268X_THREAD_PRIORITY int "Own thread priority" - depends on ICM42688_TRIGGER_OWN_THREAD + depends on ICM4268X_TRIGGER_OWN_THREAD default 10 help The priority of the thread used for handling interrupts. -config ICM42688_THREAD_STACK_SIZE +config ICM4268X_THREAD_STACK_SIZE int "Own thread stack size" - depends on ICM42688_TRIGGER_OWN_THREAD + depends on ICM4268X_TRIGGER_OWN_THREAD default 1024 help The thread stack size. -endif # ICM42688 +endif # ICM4268X diff --git a/drivers/sensor/tdk/icm42688/icm42688.c b/drivers/sensor/tdk/icm4268x/icm4268x.c similarity index 52% rename from drivers/sensor/tdk/icm42688/icm42688.c rename to drivers/sensor/tdk/icm4268x/icm4268x.c index 643ebc0a2bf5..4421e612bb94 100644 --- a/drivers/sensor/tdk/icm42688/icm42688.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x.c @@ -6,86 +6,86 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT invensense_icm42688 +#define DT_DRV_COMPAT invensense_icm4268x #include -#include +#include #include #include -#include "icm42688.h" -#include "icm42688_decoder.h" -#include "icm42688_reg.h" -#include "icm42688_rtio.h" -#include "icm42688_spi.h" -#include "icm42688_trigger.h" +#include "icm4268x.h" +#include "icm4268x_decoder.h" +#include "icm4268x_reg.h" +#include "icm4268x_rtio.h" +#include "icm4268x_spi.h" +#include "icm4268x_trigger.h" #include -LOG_MODULE_REGISTER(ICM42688, CONFIG_SENSOR_LOG_LEVEL); +LOG_MODULE_REGISTER(ICM4268X, CONFIG_SENSOR_LOG_LEVEL); -static void icm42688_convert_accel(struct sensor_value *val, int16_t raw_val, - struct icm42688_cfg *cfg) +static void icm4268x_convert_accel(struct sensor_value *val, int16_t raw_val, + struct icm4268x_cfg *cfg) { - icm42688_accel_ms(cfg, (int32_t)raw_val, &val->val1, &val->val2); + icm4268x_accel_ms(cfg, (int32_t)raw_val, &val->val1, &val->val2); } -static void icm42688_convert_gyro(struct sensor_value *val, int16_t raw_val, - struct icm42688_cfg *cfg) +static void icm4268x_convert_gyro(struct sensor_value *val, int16_t raw_val, + struct icm4268x_cfg *cfg) { - icm42688_gyro_rads(cfg, (int32_t)raw_val, &val->val1, &val->val2); + icm4268x_gyro_rads(cfg, (int32_t)raw_val, &val->val1, &val->val2); } -static inline void icm42688_convert_temp(struct sensor_value *val, int16_t raw_val) +static inline void icm4268x_convert_temp(struct sensor_value *val, int16_t raw_val) { - icm42688_temp_c((int32_t)raw_val, &val->val1, &val->val2); + icm4268x_temp_c((int32_t)raw_val, &val->val1, &val->val2); } -int icm42688_channel_parse_readings(enum sensor_channel chan, int16_t readings[7], - struct icm42688_cfg *cfg, struct sensor_value *val) +int icm4268x_channel_parse_readings(enum sensor_channel chan, int16_t readings[7], + struct icm4268x_cfg *cfg, struct sensor_value *val) { switch (chan) { case SENSOR_CHAN_ACCEL_XYZ: - icm42688_convert_accel(&val[0], + icm4268x_convert_accel(&val[0], cfg->axis_align[0].sign*readings[cfg->axis_align[0].index + 1], cfg); - icm42688_convert_accel(&val[1], + icm4268x_convert_accel(&val[1], cfg->axis_align[1].sign*readings[cfg->axis_align[1].index + 1], cfg); - icm42688_convert_accel(&val[2], + icm4268x_convert_accel(&val[2], cfg->axis_align[2].sign*readings[cfg->axis_align[2].index + 1], cfg); break; case SENSOR_CHAN_ACCEL_X: - icm42688_convert_accel(val, + icm4268x_convert_accel(val, cfg->axis_align[0].sign*readings[cfg->axis_align[0].index + 1], cfg); break; case SENSOR_CHAN_ACCEL_Y: - icm42688_convert_accel(val, + icm4268x_convert_accel(val, cfg->axis_align[1].sign*readings[cfg->axis_align[1].index + 1], cfg); break; case SENSOR_CHAN_ACCEL_Z: - icm42688_convert_accel(val, + icm4268x_convert_accel(val, cfg->axis_align[2].sign*readings[cfg->axis_align[2].index + 1], cfg); break; case SENSOR_CHAN_GYRO_XYZ: - icm42688_convert_gyro(&val[0], + icm4268x_convert_gyro(&val[0], cfg->axis_align[0].sign*readings[cfg->axis_align[0].index + 4], cfg); - icm42688_convert_gyro(&val[1], + icm4268x_convert_gyro(&val[1], cfg->axis_align[1].sign*readings[cfg->axis_align[1].index + 4], cfg); - icm42688_convert_gyro(&val[2], + icm4268x_convert_gyro(&val[2], cfg->axis_align[2].sign*readings[cfg->axis_align[2].index + 4], cfg); break; case SENSOR_CHAN_GYRO_X: - icm42688_convert_gyro(val, + icm4268x_convert_gyro(val, cfg->axis_align[0].sign*readings[cfg->axis_align[0].index + 4], cfg); break; case SENSOR_CHAN_GYRO_Y: - icm42688_convert_gyro(val, + icm4268x_convert_gyro(val, cfg->axis_align[1].sign*readings[cfg->axis_align[1].index + 4], cfg); break; case SENSOR_CHAN_GYRO_Z: - icm42688_convert_gyro(val, + icm4268x_convert_gyro(val, cfg->axis_align[2].sign*readings[cfg->axis_align[2].index + 4], cfg); break; case SENSOR_CHAN_DIE_TEMP: - icm42688_convert_temp(val, readings[0]); + icm4268x_convert_temp(val, readings[0]); break; default: return -ENOTSUP; @@ -94,21 +94,21 @@ int icm42688_channel_parse_readings(enum sensor_channel chan, int16_t readings[7 return 0; } -static int icm42688_channel_get(const struct device *dev, enum sensor_channel chan, +static int icm4268x_channel_get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) { - struct icm42688_dev_data *data = dev->data; + struct icm4268x_dev_data *data = dev->data; - return icm42688_channel_parse_readings(chan, data->readings, &data->cfg, val); + return icm4268x_channel_parse_readings(chan, data->readings, &data->cfg, val); } -static int icm42688_sample_fetch(const struct device *dev, enum sensor_channel chan) +static int icm4268x_sample_fetch(const struct device *dev, enum sensor_channel chan) { uint8_t status; - struct icm42688_dev_data *data = dev->data; - const struct icm42688_dev_cfg *cfg = dev->config; + struct icm4268x_dev_data *data = dev->data; + const struct icm4268x_dev_cfg *cfg = dev->config; - int res = icm42688_spi_read(&cfg->spi, REG_INT_STATUS, &status, 1); + int res = icm4268x_spi_read(&cfg->spi, REG_INT_STATUS, &status, 1); if (res) { return res; @@ -120,7 +120,7 @@ static int icm42688_sample_fetch(const struct device *dev, enum sensor_channel c uint8_t readings[14]; - res = icm42688_read_all(dev, readings); + res = icm4268x_read_all(dev, readings); if (res) { return res; @@ -133,11 +133,11 @@ static int icm42688_sample_fetch(const struct device *dev, enum sensor_channel c return 0; } -static int icm42688_attr_set(const struct device *dev, enum sensor_channel chan, +static int icm4268x_attr_set(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, const struct sensor_value *val) { - const struct icm42688_dev_data *data = dev->data; - struct icm42688_cfg new_config = data->cfg; + const struct icm4268x_dev_data *data = dev->data; + struct icm4268x_cfg new_config = data->cfg; int res = 0; __ASSERT_NO_MSG(val != NULL); @@ -148,9 +148,10 @@ static int icm42688_attr_set(const struct device *dev, enum sensor_channel chan, case SENSOR_CHAN_ACCEL_Z: case SENSOR_CHAN_ACCEL_XYZ: if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { - new_config.accel_odr = icm42688_accel_hz_to_reg(val->val1); + new_config.accel_odr = icm4268x_accel_hz_to_reg(val->val1); } else if (attr == SENSOR_ATTR_FULL_SCALE) { - new_config.accel_fs = icm42688_accel_fs_to_reg(sensor_ms2_to_g(val)); + new_config.accel_fs = icm4268x_accel_fs_to_reg(sensor_ms2_to_g(val), + data->cfg.variant); } else { LOG_ERR("Unsupported attribute"); res = -ENOTSUP; @@ -161,9 +162,10 @@ static int icm42688_attr_set(const struct device *dev, enum sensor_channel chan, case SENSOR_CHAN_GYRO_Z: case SENSOR_CHAN_GYRO_XYZ: if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { - new_config.gyro_odr = icm42688_gyro_odr_to_reg(val->val1); + new_config.gyro_odr = icm4268x_gyro_odr_to_reg(val->val1); } else if (attr == SENSOR_ATTR_FULL_SCALE) { - new_config.gyro_fs = icm42688_gyro_fs_to_reg(sensor_rad_to_degrees(val)); + new_config.gyro_fs = icm4268x_gyro_fs_to_reg(sensor_rad_to_degrees(val), + data->cfg.variant); } else { LOG_ERR("Unsupported attribute"); res = -EINVAL; @@ -175,11 +177,11 @@ static int icm42688_attr_set(const struct device *dev, enum sensor_channel chan, return -EINVAL; } new_config.batch_ticks = val->val1; - } else if ((enum sensor_attribute_icm42688)attr == - SENSOR_ATTR_ICM42688_PIN9_FUNCTION) { - if (val->val1 != ICM42688_PIN9_FUNCTION_INT2 && - val->val1 != ICM42688_PIN9_FUNCTION_FSYNC && - val->val1 != ICM42688_PIN9_FUNCTION_CLKIN) { + } else if ((enum sensor_attribute_icm4268x)attr == + SENSOR_ATTR_ICM4268X_PIN9_FUNCTION) { + if (val->val1 != ICM4268X_PIN9_FUNCTION_INT2 && + val->val1 != ICM4268X_PIN9_FUNCTION_FSYNC && + val->val1 != ICM4268X_PIN9_FUNCTION_CLKIN) { LOG_ERR("Unknown pin function"); return -EINVAL; } @@ -190,7 +192,7 @@ static int icm42688_attr_set(const struct device *dev, enum sensor_channel chan, } /* TODO: Allow this if FSYNC is configurable later. */ - if (val->val1 == ICM42688_PIN9_FUNCTION_FSYNC) { + if (val->val1 == ICM4268X_PIN9_FUNCTION_FSYNC) { LOG_ERR("FSYNC is disabled, PIN9_FUNCTION should not be set to " "FSYNC"); return -ENOTSUP; @@ -212,14 +214,14 @@ static int icm42688_attr_set(const struct device *dev, enum sensor_channel chan, if (res) { return res; } - return icm42688_safely_configure(dev, &new_config); + return icm4268x_safely_configure(dev, &new_config); } -static int icm42688_attr_get(const struct device *dev, enum sensor_channel chan, +static int icm4268x_attr_get(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, struct sensor_value *val) { - const struct icm42688_dev_data *data = dev->data; - const struct icm42688_cfg *cfg = &data->cfg; + const struct icm4268x_dev_data *data = dev->data; + const struct icm4268x_cfg *cfg = &data->cfg; int res = 0; __ASSERT_NO_MSG(val != NULL); @@ -230,9 +232,9 @@ static int icm42688_attr_get(const struct device *dev, enum sensor_channel chan, case SENSOR_CHAN_ACCEL_Z: case SENSOR_CHAN_ACCEL_XYZ: if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { - icm42688_accel_reg_to_hz(cfg->accel_odr, val); + icm4268x_accel_reg_to_hz(cfg->accel_odr, val); } else if (attr == SENSOR_ATTR_FULL_SCALE) { - icm42688_accel_reg_to_fs(cfg->accel_fs, val); + icm4268x_accel_reg_to_fs(cfg->accel_fs, data->cfg.variant, val); } else { LOG_ERR("Unsupported attribute"); res = -EINVAL; @@ -243,9 +245,9 @@ static int icm42688_attr_get(const struct device *dev, enum sensor_channel chan, case SENSOR_CHAN_GYRO_Z: case SENSOR_CHAN_GYRO_XYZ: if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) { - icm42688_gyro_reg_to_odr(cfg->gyro_odr, val); + icm4268x_gyro_reg_to_odr(cfg->gyro_odr, val); } else if (attr == SENSOR_ATTR_FULL_SCALE) { - icm42688_gyro_reg_to_fs(cfg->gyro_fs, val); + icm4268x_gyro_reg_to_fs(cfg->gyro_fs, data->cfg.variant, val); } else { LOG_ERR("Unsupported attribute"); res = -EINVAL; @@ -255,8 +257,8 @@ static int icm42688_attr_get(const struct device *dev, enum sensor_channel chan, if (attr == SENSOR_ATTR_BATCH_DURATION) { val->val1 = cfg->batch_ticks; val->val2 = 0; - } else if ((enum sensor_attribute_icm42688)attr == - SENSOR_ATTR_ICM42688_PIN9_FUNCTION) { + } else if ((enum sensor_attribute_icm4268x)attr == + SENSOR_ATTR_ICM4268X_PIN9_FUNCTION) { val->val1 = cfg->pin9_function; val->val2 = cfg->rtc_freq; } else { @@ -273,24 +275,24 @@ static int icm42688_attr_get(const struct device *dev, enum sensor_channel chan, return res; } -static DEVICE_API(sensor, icm42688_driver_api) = { - .sample_fetch = icm42688_sample_fetch, - .channel_get = icm42688_channel_get, - .attr_set = icm42688_attr_set, - .attr_get = icm42688_attr_get, -#ifdef CONFIG_ICM42688_TRIGGER - .trigger_set = icm42688_trigger_set, +static DEVICE_API(sensor, icm4268x_driver_api) = { + .sample_fetch = icm4268x_sample_fetch, + .channel_get = icm4268x_channel_get, + .attr_set = icm4268x_attr_set, + .attr_get = icm4268x_attr_get, +#ifdef CONFIG_ICM4268X_TRIGGER + .trigger_set = icm4268x_trigger_set, #endif - .get_decoder = icm42688_get_decoder, + .get_decoder = icm4268x_get_decoder, #ifdef CONFIG_SENSOR_ASYNC_API - .submit = icm42688_submit, + .submit = icm4268x_submit, #endif }; -int icm42688_init(const struct device *dev) +int icm4268x_init(const struct device *dev) { - struct icm42688_dev_data *data = dev->data; - const struct icm42688_dev_cfg *cfg = dev->config; + struct icm4268x_dev_data *data = dev->data; + const struct icm4268x_dev_cfg *cfg = dev->config; int res; if (!spi_is_ready_dt(&cfg->spi)) { @@ -298,20 +300,20 @@ int icm42688_init(const struct device *dev) return -ENODEV; } - if (icm42688_reset(dev)) { + if (icm4268x_reset(dev)) { LOG_ERR("could not initialize sensor"); return -EIO; } -#ifdef CONFIG_ICM42688_TRIGGER - res = icm42688_trigger_init(dev); +#ifdef CONFIG_ICM4268X_TRIGGER + res = icm4268x_trigger_init(dev); if (res != 0) { LOG_ERR("Failed to initialize triggers"); return res; } #endif - res = icm42688_configure(dev, &data->cfg); + res = icm4268x_configure(dev, &data->cfg); if (res != 0) { LOG_ERR("Failed to configure"); return res; @@ -320,27 +322,31 @@ int icm42688_init(const struct device *dev) return 0; } -#ifndef CONFIG_ICM42688_TRIGGER -void icm42688_lock(const struct device *dev) +#ifndef CONFIG_ICM4268X_TRIGGER +void icm4268x_lock(const struct device *dev) { ARG_UNUSED(dev); } -void icm42688_unlock(const struct device *dev) +void icm4268x_unlock(const struct device *dev) { ARG_UNUSED(dev); } #endif /* device defaults to spi mode 0/3 support */ -#define ICM42688_SPI_CFG \ +#define ICM4268X_SPI_CFG \ SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_TRANSFER_MSB -#define ICM42688_RTIO_DEFINE(inst) \ - SPI_DT_IODEV_DEFINE(icm42688_spi_iodev_##inst, DT_DRV_INST(inst), ICM42688_SPI_CFG, 0U); \ - RTIO_DEFINE(icm42688_rtio_##inst, 8, 4); +#define ICM4268X_RTIO_DEFINE(inst) \ + SPI_DT_IODEV_DEFINE(icm4268x_spi_iodev_##inst, DT_DRV_INST(inst), ICM4268X_SPI_CFG, 0U); \ + RTIO_DEFINE(icm4268x_rtio_##inst, 8, 4); #define ICM42688_DT_CONFIG_INIT(inst) \ { \ + COND_CODE_1(DT_INST_NODE_HAS_COMPAT(inst, invensense_icm42688), \ + (.variant = ICM4268X_VARIANT_ICM42688,), ( \ + COND_CODE_1(DT_INST_NODE_HAS_COMPAT(inst, invensense_icm42686), \ + (.variant = ICM4268X_VARIANT_ICM42686,), ()))) \ .accel_pwr_mode = DT_INST_PROP(inst, accel_pwr_mode), \ .accel_fs = DT_INST_PROP(inst, accel_fs), \ .accel_odr = DT_INST_PROP(inst, accel_odr), \ @@ -348,13 +354,13 @@ void icm42688_unlock(const struct device *dev) .gyro_fs = DT_INST_PROP(inst, gyro_fs), \ .gyro_odr = DT_INST_PROP(inst, gyro_odr), \ .temp_dis = false, \ - .fifo_en = IS_ENABLED(CONFIG_ICM42688_STREAM), \ + .fifo_en = IS_ENABLED(CONFIG_ICM4268X_STREAM), \ .batch_ticks = 0, \ .fifo_hires = DT_INST_PROP(inst, fifo_hires), \ .interrupt1_drdy = false, \ .interrupt1_fifo_ths = false, \ .interrupt1_fifo_full = false, \ - .pin9_function = ICM42688_PIN9_FUNCTION_INT2, \ + .pin9_function = ICM4268X_PIN9_FUNCTION_INT2, \ .rtc_freq = 32000, \ .axis_align[0].index = DT_INST_PROP(inst, axis_align_x), \ .axis_align[1].index = DT_INST_PROP(inst, axis_align_y), \ @@ -364,24 +370,43 @@ void icm42688_unlock(const struct device *dev) .axis_align[2].sign = DT_INST_PROP(inst, axis_align_z_sign)-1 \ } -#define ICM42688_DEFINE_DATA(inst) \ - IF_ENABLED(CONFIG_ICM42688_STREAM, (ICM42688_RTIO_DEFINE(inst))); \ - static struct icm42688_dev_data icm42688_driver_##inst = { \ +#define ICM4268X_DEFINE_DATA(inst) \ + IF_ENABLED(CONFIG_ICM4268X_STREAM, (ICM4268X_RTIO_DEFINE(inst))); \ + static struct icm4268x_dev_data icm4268x_driver_##inst = { \ .cfg = ICM42688_DT_CONFIG_INIT(inst), \ - IF_ENABLED(CONFIG_ICM42688_STREAM, (.r = &icm42688_rtio_##inst, \ - .spi_iodev = &icm42688_spi_iodev_##inst,)) \ + IF_ENABLED(CONFIG_ICM4268X_STREAM, (.r = &icm4268x_rtio_##inst, \ + .spi_iodev = &icm4268x_spi_iodev_##inst,)) \ }; -#define ICM42688_INIT(inst) \ - ICM42688_DEFINE_DATA(inst); \ +/** The rest of the Device-tree configuration is validated in the YAML + * file. This outlier comes from the fact we're sharing the dts-properties + * across variants, and ICM42686 has an extra enum for the accel-fs. + */ +#define ICM42688_BUILD_CONFIG_VALIDATION(inst) \ + BUILD_ASSERT((DT_INST_PROP(inst, accel_fs) >= ICM42688_DT_ACCEL_FS_16) && \ + (DT_INST_PROP(inst, accel_fs) <= ICM42688_DT_ACCEL_FS_2), \ + "Invalid accel-fs configured for ICM42688. Please revisit DTS config-set"); + +#define ICM4268X_INIT(inst) \ + \ + BUILD_ASSERT(DT_INST_NODE_HAS_COMPAT(inst, invensense_icm42688) || \ + DT_INST_NODE_HAS_COMPAT(inst, invensense_icm42686), \ + "Please define additional compatible property to dts node: " \ + " or "); \ + \ + \ + COND_CODE_1(DT_INST_NODE_HAS_COMPAT(inst, invensense_icm42688), \ + (ICM42688_BUILD_CONFIG_VALIDATION(inst)), ()); \ + \ + ICM4268X_DEFINE_DATA(inst); \ \ - static const struct icm42688_dev_cfg icm42688_cfg_##inst = { \ - .spi = SPI_DT_SPEC_INST_GET(inst, ICM42688_SPI_CFG, 0U), \ + static const struct icm4268x_dev_cfg icm4268x_cfg_##inst = { \ + .spi = SPI_DT_SPEC_INST_GET(inst, ICM4268X_SPI_CFG, 0U), \ .gpio_int1 = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \ }; \ \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, icm42688_init, NULL, &icm42688_driver_##inst, \ - &icm42688_cfg_##inst, POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, &icm42688_driver_api); + SENSOR_DEVICE_DT_INST_DEFINE(inst, icm4268x_init, NULL, &icm4268x_driver_##inst, \ + &icm4268x_cfg_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &icm4268x_driver_api); -DT_INST_FOREACH_STATUS_OKAY(ICM42688_INIT) +DT_INST_FOREACH_STATUS_OKAY(ICM4268X_INIT) diff --git a/drivers/sensor/tdk/icm4268x/icm4268x.h b/drivers/sensor/tdk/icm4268x/icm4268x.h new file mode 100644 index 000000000000..1f7be23e314f --- /dev/null +++ b/drivers/sensor/tdk/icm4268x/icm4268x.h @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2022 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ICM4268X_H_ +#define ZEPHYR_DRIVERS_SENSOR_ICM4268X_H_ + +#include +#include +#include +#include +#include +#include +#include + +struct alignment { + int8_t index; + int8_t sign; +}; + +enum icm4268x_variant { + ICM4268X_VARIANT_ICM42688 = 0, + ICM4268X_VARIANT_ICM42686 = 1, + ICM4268X_VARIANT_MAX, +}; + +/** Helper struct used to map between values and DT-options (e.g: DT_ACCEL_FS) */ +struct icm4268x_reg_val_pair { + uint8_t reg; + int32_t val; +}; + +static const uint8_t table_accel_fs_to_reg_array_size[ICM4268X_VARIANT_MAX] = { + [ICM4268X_VARIANT_ICM42688] = 4, /* FS16 to FS2 */ + [ICM4268X_VARIANT_ICM42686] = 5, /* FS32 to FS2 */ +}; + +static const struct icm4268x_reg_val_pair table_accel_fs_to_reg[][5] = { + [ICM4268X_VARIANT_ICM42688] = { + {.val = 16, .reg = ICM42688_DT_ACCEL_FS_16}, + {.val = 8, .reg = ICM42688_DT_ACCEL_FS_8}, + {.val = 4, .reg = ICM42688_DT_ACCEL_FS_4}, + {.val = 2, .reg = ICM42688_DT_ACCEL_FS_2}, + }, + [ICM4268X_VARIANT_ICM42686] = { + {.val = 32, .reg = ICM42686_DT_ACCEL_FS_32}, + {.val = 16, .reg = ICM42686_DT_ACCEL_FS_16}, + {.val = 8, .reg = ICM42686_DT_ACCEL_FS_8}, + {.val = 4, .reg = ICM42686_DT_ACCEL_FS_4}, + {.val = 2, .reg = ICM42686_DT_ACCEL_FS_2}, + }, +}; + +static inline uint8_t icm4268x_accel_fs_to_reg(uint8_t g, enum icm4268x_variant variant) +{ + for (uint8_t i = 0 ; i < table_accel_fs_to_reg_array_size[variant] ; i++) { + if (g >= table_accel_fs_to_reg[variant][i].val) { + return table_accel_fs_to_reg[variant][i].reg; + } + } + + /** Force values less than lower boundary */ + return table_accel_fs_to_reg[variant][table_accel_fs_to_reg_array_size[variant] - 1].reg; +} + +static inline void icm4268x_accel_reg_to_fs(uint8_t fs, enum icm4268x_variant variant, + struct sensor_value *out) +{ + for (uint8_t i = 0 ; i < table_accel_fs_to_reg_array_size[variant] ; i++) { + if (fs == table_accel_fs_to_reg[variant][i].reg) { + sensor_g_to_ms2(table_accel_fs_to_reg[variant][i].val, out); + return; + } + } + + CODE_UNREACHABLE; +} + +static const uint8_t table_gyro_fs_to_reg_array_size[ICM4268X_VARIANT_MAX] = { + [ICM4268X_VARIANT_ICM42688] = 8, /* FS2000 to FS15_625 */ + [ICM4268X_VARIANT_ICM42686] = 8, /* FS4000 to FS31_25 */ +}; + +static const struct icm4268x_reg_val_pair table_gyro_fs_to_reg[][8] = { + [ICM4268X_VARIANT_ICM42688] = { + {.val = 200000000, .reg = ICM42688_DT_GYRO_FS_2000}, + {.val = 100000000, .reg = ICM42688_DT_GYRO_FS_1000}, + {.val = 50000000, .reg = ICM42688_DT_GYRO_FS_500}, + {.val = 25000000, .reg = ICM42688_DT_GYRO_FS_250}, + {.val = 12500000, .reg = ICM42688_DT_GYRO_FS_125}, + {.val = 6250000, .reg = ICM42688_DT_GYRO_FS_62_5}, + {.val = 3125000, .reg = ICM42688_DT_GYRO_FS_31_25}, + {.val = 1562500, .reg = ICM42688_DT_GYRO_FS_15_625}, + }, + [ICM4268X_VARIANT_ICM42686] = { + {.val = 400000000, .reg = ICM42686_DT_GYRO_FS_4000}, + {.val = 200000000, .reg = ICM42686_DT_GYRO_FS_2000}, + {.val = 100000000, .reg = ICM42686_DT_GYRO_FS_1000}, + {.val = 50000000, .reg = ICM42686_DT_GYRO_FS_500}, + {.val = 25000000, .reg = ICM42686_DT_GYRO_FS_250}, + {.val = 12500000, .reg = ICM42686_DT_GYRO_FS_125}, + {.val = 6250000, .reg = ICM42686_DT_GYRO_FS_62_5}, + {.val = 3125000, .reg = ICM42686_DT_GYRO_FS_31_25}, + }, +}; + +static inline uint8_t icm4268x_gyro_fs_to_reg(uint16_t dps, enum icm4268x_variant variant) +{ + for (uint8_t i = 0 ; i < table_gyro_fs_to_reg_array_size[variant] ; i++) { + if (dps * 100000 >= table_gyro_fs_to_reg[variant][i].val) { + return table_gyro_fs_to_reg[variant][i].reg; + } + } + + /** Force values less than lower boundary */ + return table_gyro_fs_to_reg[variant][table_gyro_fs_to_reg_array_size[variant] - 1].reg; +} + +static inline void icm4268x_gyro_reg_to_fs(uint8_t fs, enum icm4268x_variant variant, + struct sensor_value *out) +{ + for (uint8_t i = 0 ; i < table_gyro_fs_to_reg_array_size[variant] ; i++) { + if (fs == table_gyro_fs_to_reg[variant][i].reg) { + sensor_10udegrees_to_rad(table_gyro_fs_to_reg[variant][i].val, out); + return; + } + } + + CODE_UNREACHABLE; +} + +static inline uint8_t icm4268x_accel_hz_to_reg(uint16_t hz) +{ + if (hz >= 32000) { + return ICM4268X_DT_ACCEL_ODR_32000; + } else if (hz >= 16000) { + return ICM4268X_DT_ACCEL_ODR_16000; + } else if (hz >= 8000) { + return ICM4268X_DT_ACCEL_ODR_8000; + } else if (hz >= 4000) { + return ICM4268X_DT_ACCEL_ODR_4000; + } else if (hz >= 2000) { + return ICM4268X_DT_ACCEL_ODR_2000; + } else if (hz >= 1000) { + return ICM4268X_DT_ACCEL_ODR_1000; + } else if (hz >= 500) { + return ICM4268X_DT_ACCEL_ODR_500; + } else if (hz >= 200) { + return ICM4268X_DT_ACCEL_ODR_200; + } else if (hz >= 100) { + return ICM4268X_DT_ACCEL_ODR_100; + } else if (hz >= 50) { + return ICM4268X_DT_ACCEL_ODR_50; + } else if (hz >= 25) { + return ICM4268X_DT_ACCEL_ODR_25; + } else if (hz >= 12) { + return ICM4268X_DT_ACCEL_ODR_12_5; + } else if (hz >= 6) { + return ICM4268X_DT_ACCEL_ODR_6_25; + } else if (hz >= 3) { + return ICM4268X_DT_ACCEL_ODR_3_125; + } else { + return ICM4268X_DT_ACCEL_ODR_1_5625; + } +} + +static inline void icm4268x_accel_reg_to_hz(uint8_t odr, struct sensor_value *out) +{ + switch (odr) { + case ICM4268X_DT_ACCEL_ODR_32000: + out->val1 = 32000; + out->val2 = 0; + return; + case ICM4268X_DT_ACCEL_ODR_16000: + out->val1 = 1600; + out->val2 = 0; + return; + case ICM4268X_DT_ACCEL_ODR_8000: + out->val1 = 8000; + out->val2 = 0; + return; + case ICM4268X_DT_ACCEL_ODR_4000: + out->val1 = 4000; + out->val2 = 0; + return; + case ICM4268X_DT_ACCEL_ODR_2000: + out->val1 = 2000; + out->val2 = 0; + return; + case ICM4268X_DT_ACCEL_ODR_1000: + out->val1 = 1000; + out->val2 = 0; + return; + case ICM4268X_DT_ACCEL_ODR_500: + out->val1 = 500; + out->val2 = 0; + return; + case ICM4268X_DT_ACCEL_ODR_200: + out->val1 = 200; + out->val2 = 0; + return; + case ICM4268X_DT_ACCEL_ODR_100: + out->val1 = 100; + out->val2 = 0; + return; + case ICM4268X_DT_ACCEL_ODR_50: + out->val1 = 50; + out->val2 = 0; + return; + case ICM4268X_DT_ACCEL_ODR_25: + out->val1 = 25; + out->val2 = 0; + return; + case ICM4268X_DT_ACCEL_ODR_12_5: + out->val1 = 12; + out->val2 = 500000; + return; + case ICM4268X_DT_ACCEL_ODR_6_25: + out->val1 = 6; + out->val2 = 250000; + return; + case ICM4268X_DT_ACCEL_ODR_3_125: + out->val1 = 3; + out->val2 = 125000; + return; + case ICM4268X_DT_ACCEL_ODR_1_5625: + out->val1 = 1; + out->val2 = 562500; + return; + default: + CODE_UNREACHABLE; + return; + } +} + +static inline uint8_t icm4268x_gyro_odr_to_reg(uint16_t hz) +{ + if (hz >= 32000) { + return ICM4268X_DT_GYRO_ODR_32000; + } else if (hz >= 16000) { + return ICM4268X_DT_GYRO_ODR_16000; + } else if (hz >= 8000) { + return ICM4268X_DT_GYRO_ODR_8000; + } else if (hz >= 4000) { + return ICM4268X_DT_GYRO_ODR_4000; + } else if (hz >= 2000) { + return ICM4268X_DT_GYRO_ODR_2000; + } else if (hz >= 1000) { + return ICM4268X_DT_GYRO_ODR_1000; + } else if (hz >= 500) { + return ICM4268X_DT_GYRO_ODR_500; + } else if (hz >= 200) { + return ICM4268X_DT_GYRO_ODR_200; + } else if (hz >= 100) { + return ICM4268X_DT_GYRO_ODR_100; + } else if (hz >= 50) { + return ICM4268X_DT_GYRO_ODR_50; + } else if (hz >= 25) { + return ICM4268X_DT_GYRO_ODR_25; + } else { + return ICM4268X_DT_GYRO_ODR_12_5; + } +} + +static inline void icm4268x_gyro_reg_to_odr(uint8_t odr, struct sensor_value *out) +{ + switch (odr) { + case ICM4268X_DT_GYRO_ODR_32000: + out->val1 = 32000; + out->val2 = 0; + return; + case ICM4268X_DT_GYRO_ODR_16000: + out->val1 = 16000; + out->val2 = 0; + return; + case ICM4268X_DT_GYRO_ODR_8000: + out->val1 = 8000; + out->val2 = 0; + return; + case ICM4268X_DT_GYRO_ODR_4000: + out->val1 = 4000; + out->val2 = 0; + return; + case ICM4268X_DT_GYRO_ODR_2000: + out->val1 = 2000; + out->val2 = 0; + return; + case ICM4268X_DT_GYRO_ODR_1000: + out->val1 = 1000; + out->val2 = 0; + return; + case ICM4268X_DT_GYRO_ODR_500: + out->val1 = 500; + out->val2 = 0; + return; + case ICM4268X_DT_GYRO_ODR_200: + out->val1 = 200; + out->val2 = 0; + return; + case ICM4268X_DT_GYRO_ODR_100: + out->val1 = 100; + out->val2 = 0; + return; + case ICM4268X_DT_GYRO_ODR_50: + out->val1 = 50; + out->val2 = 0; + return; + case ICM4268X_DT_GYRO_ODR_25: + out->val1 = 25; + out->val2 = 0; + return; + case ICM4268X_DT_GYRO_ODR_12_5: + out->val1 = 12; + out->val2 = 500000; + return; + default: + CODE_UNREACHABLE; + } +} + +/** + * @brief All sensor configuration options + */ +struct icm4268x_cfg { + enum icm4268x_variant variant; + uint8_t accel_pwr_mode; + uint8_t accel_fs; + uint8_t accel_odr; + /* TODO accel signal processing options */ + + uint8_t gyro_pwr_mode; + uint8_t gyro_fs; + uint8_t gyro_odr; + /* TODO gyro signal processing options */ + + bool temp_dis; + /* TODO temp signal processing options */ + + /* TODO timestamp options */ + + bool fifo_en; + int32_t batch_ticks; + bool fifo_hires; + /* TODO additional FIFO options */ + + /* TODO interrupt options */ + bool interrupt1_drdy; + bool interrupt1_fifo_ths; + bool interrupt1_fifo_full; + struct alignment axis_align[3]; + uint8_t pin9_function; + uint16_t rtc_freq; +}; + +struct icm4268x_trigger_entry { + struct sensor_trigger trigger; + sensor_trigger_handler_t handler; +}; + +/** + * @brief Device data (struct device) + */ +struct icm4268x_dev_data { + struct icm4268x_cfg cfg; +#ifdef CONFIG_ICM4268X_TRIGGER +#if defined(CONFIG_ICM4268X_TRIGGER_OWN_THREAD) + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ICM4268X_THREAD_STACK_SIZE); + struct k_thread thread; + struct k_sem gpio_sem; +#elif defined(CONFIG_ICM4268X_TRIGGER_GLOBAL_THREAD) + struct k_work work; +#endif +#ifdef CONFIG_ICM4268X_STREAM + struct rtio_iodev_sqe *streaming_sqe; + struct rtio *r; + struct rtio_iodev *spi_iodev; + uint8_t int_status; + uint16_t fifo_count; + uint64_t timestamp; + atomic_t reading_fifo; +#endif /* CONFIG_ICM4268X_STREAM */ + const struct device *dev; + struct gpio_callback gpio_cb; + sensor_trigger_handler_t data_ready_handler; + const struct sensor_trigger *data_ready_trigger; + struct k_mutex mutex; +#endif /* CONFIG_ICM4268X_TRIGGER */ + + int16_t readings[7]; +}; + +/** + * @brief Device config (struct device) + */ +struct icm4268x_dev_cfg { + struct spi_dt_spec spi; + struct gpio_dt_spec gpio_int1; + struct gpio_dt_spec gpio_int2; +}; + +/** + * @brief Reset the sensor + * + * @param dev icm4268x device pointer + * + * @retval 0 success + * @retval -EINVAL Reset status or whoami register returned unexpected value. + */ +int icm4268x_reset(const struct device *dev); + +/** + * @brief (Re)Configure the sensor with the given configuration + * + * @param dev icm4268x device pointer + * @param cfg icm4268x_cfg pointer + * + * @retval 0 success + * @retval -errno Error + */ +int icm4268x_configure(const struct device *dev, struct icm4268x_cfg *cfg); + + +/** + * @brief Safely (re)Configure the sensor with the given configuration + * + * Will rollback to prior configuration if new configuration is invalid + * + * @param dev icm4268x device pointer + * @param cfg icm4268x_cfg pointer + * + * @retval 0 success + * @retval -errno Error + */ +int icm4268x_safely_configure(const struct device *dev, struct icm4268x_cfg *cfg); + +/** + * @brief Reads all channels + * + * Regardless of what is enabled/disabled this reads all data registers + * as the time to read the 14 bytes at 1MHz is going to be 112 us which + * is less time than a SPI transaction takes to setup typically. + * + * @param dev icm4268x device pointer + * @param buf 14 byte buffer to store data values (7 channels, 2 bytes each) + * + * @retval 0 success + * @retval -errno Error + */ +int icm4268x_read_all(const struct device *dev, uint8_t data[14]); + +static const struct icm4268x_reg_val_pair table_accel_sensitivity_to_reg[][5] = { + [ICM4268X_VARIANT_ICM42688] = { + {.val = 2048, .reg = ICM42688_DT_ACCEL_FS_16}, + {.val = 4096, .reg = ICM42688_DT_ACCEL_FS_8}, + {.val = 8192, .reg = ICM42688_DT_ACCEL_FS_4}, + {.val = 16384, .reg = ICM42688_DT_ACCEL_FS_2}, + }, + [ICM4268X_VARIANT_ICM42686] = { + {.val = 1024, .reg = ICM42686_DT_ACCEL_FS_32}, + {.val = 2048, .reg = ICM42686_DT_ACCEL_FS_16}, + {.val = 4096, .reg = ICM42686_DT_ACCEL_FS_8}, + {.val = 8192, .reg = ICM42686_DT_ACCEL_FS_4}, + {.val = 16384, .reg = ICM42686_DT_ACCEL_FS_2}, + }, +}; + +/** + * @brief Convert icm4268x accelerometer value to useful m/s^2 values + * + * @param cfg icm4268x_cfg current device configuration + * @param in raw data value in int32_t format + * @param out_ms meters/s^2 (whole) output in int32_t + * @param out_ums micrometers/s^2 output as int32_t + */ +static inline void icm4268x_accel_ms(const struct icm4268x_cfg *cfg, int32_t in, int32_t *out_ms, + int32_t *out_ums) +{ + int64_t sensitivity = 0; + + for (uint8_t i = 0 ; i < table_accel_fs_to_reg_array_size[cfg->variant] ; i++) { + if (cfg->accel_fs == table_accel_sensitivity_to_reg[cfg->variant][i].reg) { + sensitivity = table_accel_sensitivity_to_reg[cfg->variant][i].val; + break; + } + } + + if (sensitivity != 0) { + /* Convert to micrometers/s^2 */ + int64_t in_ms = in * SENSOR_G; + + /* meters/s^2 whole values */ + *out_ms = in_ms / (sensitivity * 1000000LL); + + /* micrometers/s^2 */ + *out_ums = (in_ms - (*out_ms * sensitivity * 1000000LL)) / sensitivity; + } else { + CODE_UNREACHABLE; + } +} + +static const struct icm4268x_reg_val_pair table_gyro_sensitivity_to_reg[][8] = { + [ICM4268X_VARIANT_ICM42688] = { + {.val = 164, .reg = ICM42688_DT_GYRO_FS_2000}, + {.val = 328, .reg = ICM42688_DT_GYRO_FS_1000}, + {.val = 655, .reg = ICM42688_DT_GYRO_FS_500}, + {.val = 1310, .reg = ICM42688_DT_GYRO_FS_250}, + {.val = 2620, .reg = ICM42688_DT_GYRO_FS_125}, + {.val = 5243, .reg = ICM42688_DT_GYRO_FS_62_5}, + {.val = 10486, .reg = ICM42688_DT_GYRO_FS_31_25}, + {.val = 20972, .reg = ICM42688_DT_GYRO_FS_15_625}, + }, + [ICM4268X_VARIANT_ICM42686] = { + {.val = 82, .reg = ICM42686_DT_GYRO_FS_4000}, + {.val = 164, .reg = ICM42686_DT_GYRO_FS_2000}, + {.val = 328, .reg = ICM42686_DT_GYRO_FS_1000}, + {.val = 655, .reg = ICM42686_DT_GYRO_FS_500}, + {.val = 1310, .reg = ICM42686_DT_GYRO_FS_250}, + {.val = 2620, .reg = ICM42686_DT_GYRO_FS_125}, + {.val = 5243, .reg = ICM42686_DT_GYRO_FS_62_5}, + {.val = 10486, .reg = ICM42686_DT_GYRO_FS_31_25}, + }, +}; + +/** + * @brief Convert icm4268x gyroscope value to useful rad/s values + * + * @param cfg icm4268x_cfg current device configuration + * @param in raw data value in int32_t format + * @param out_rads whole rad/s output in int32_t + * @param out_urads microrad/s as int32_t + */ +static inline void icm4268x_gyro_rads(const struct icm4268x_cfg *cfg, int32_t in, int32_t *out_rads, + int32_t *out_urads) +{ + int64_t sensitivity = 0; + + for (uint8_t i = 0 ; i < table_gyro_fs_to_reg_array_size[cfg->variant] ; i++) { + if (cfg->gyro_fs == table_gyro_sensitivity_to_reg[cfg->variant][i].reg) { + sensitivity = table_gyro_sensitivity_to_reg[cfg->variant][i].val; + break; + } + } + + if (sensitivity != 0) { + int64_t in10_rads = (int64_t)in * SENSOR_PI * 10LL; + + /* Whole rad/s */ + *out_rads = in10_rads / (sensitivity * 180LL * 1000000LL); + + /* microrad/s */ + *out_urads = + (in10_rads - (*out_rads * sensitivity * 180LL * 1000000LL)) / + (sensitivity * 180LL); + } else { + CODE_UNREACHABLE; + } +} + +/** + * @brief Convert icm4268x temp value to useful celsius values + * + * @param cfg icm4268x_cfg current device configuration + * @param in raw data value in int32_t format + * @param out_c whole celsius output in int32_t + * @param out_uc micro (1/1000000) celsius as int32_t + */ +static inline void icm4268x_temp_c(int32_t in, int32_t *out_c, int32_t *out_uc) +{ + int64_t sensitivity = 13248; /* value equivalent for x100 1c */ + + /* Offset by 25 degrees Celsius */ + int64_t in100 = (in * 100) + (25 * sensitivity); + + /* Whole celsius */ + *out_c = in100 / sensitivity; + + /* Micro celsius */ + *out_uc = ((in100 - (*out_c) * sensitivity) * INT64_C(1000000)) / sensitivity; +} + +#endif /* ZEPHYR_DRIVERS_SENSOR_ICM4268X_H_ */ diff --git a/drivers/sensor/tdk/icm42688/icm42688_common.c b/drivers/sensor/tdk/icm4268x/icm4268x_common.c similarity index 70% rename from drivers/sensor/tdk/icm42688/icm42688_common.c rename to drivers/sensor/tdk/icm4268x/icm4268x_common.c index 58984a780d1f..634f78d68f98 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_common.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x_common.c @@ -7,28 +7,30 @@ */ #include -#include +#include #include #include -#include "icm42688.h" -#include "icm42688_reg.h" -#include "icm42688_spi.h" -#include "icm42688_trigger.h" +#include "icm4268x.h" +#include "icm4268x_reg.h" +#include "icm4268x_spi.h" +#include "icm4268x_trigger.h" #include -LOG_MODULE_REGISTER(ICM42688_LL, CONFIG_SENSOR_LOG_LEVEL); +LOG_MODULE_REGISTER(ICM4268X_LL, CONFIG_SENSOR_LOG_LEVEL); -int icm42688_reset(const struct device *dev) +int icm4268x_reset(const struct device *dev) { int res; uint8_t value; - const struct icm42688_dev_cfg *dev_cfg = dev->config; + const struct icm4268x_dev_cfg *dev_cfg = dev->config; + struct icm4268x_dev_data *dev_data = dev->data; + uint8_t expected_who_am_i; /* start up time for register read/write after POR is 1ms and supply ramp time is 3ms */ k_msleep(3); /* perform a soft reset to ensure a clean slate, reset bit will auto-clear */ - res = icm42688_spi_single_write(&dev_cfg->spi, REG_DEVICE_CONFIG, BIT_SOFT_RESET_CONFIG); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_DEVICE_CONFIG, BIT_SOFT_RESET_CONFIG); if (res) { LOG_ERR("write REG_SIGNAL_PATH_RESET failed"); @@ -39,7 +41,7 @@ int icm42688_reset(const struct device *dev) k_msleep(SOFT_RESET_TIME_MS); /* clear reset done int flag */ - res = icm42688_spi_read(&dev_cfg->spi, REG_INT_STATUS, &value, 1); + res = icm4268x_spi_read(&dev_cfg->spi, REG_INT_STATUS, &value, 1); if (res) { return res; @@ -50,20 +52,32 @@ int icm42688_reset(const struct device *dev) return -EINVAL; } - res = icm42688_spi_read(&dev_cfg->spi, REG_WHO_AM_I, &value, 1); + res = icm4268x_spi_read(&dev_cfg->spi, REG_WHO_AM_I, &value, 1); if (res) { return res; } - if (value != WHO_AM_I_ICM42688) { - LOG_ERR("invalid WHO_AM_I value, was %i but expected %i", value, WHO_AM_I_ICM42688); + switch (dev_data->cfg.variant) { + case ICM4268X_VARIANT_ICM42688: + expected_who_am_i = WHO_AM_I_ICM42688; + break; + case ICM4268X_VARIANT_ICM42686: + expected_who_am_i = WHO_AM_I_ICM42686; + break; + default: + LOG_ERR("Invalid variant: %d", dev_data->cfg.variant); + return -EINVAL; + } + + if (value != expected_who_am_i) { + LOG_ERR("invalid WHO_AM_I value, was %i but expected %i", value, expected_who_am_i); return -EINVAL; } return 0; } -static uint16_t icm42688_compute_fifo_wm(const struct icm42688_cfg *cfg) +static uint16_t icm4268x_compute_fifo_wm(const struct icm4268x_cfg *cfg) { const bool accel_enabled = cfg->accel_pwr_mode != ICM42688_DT_ACCEL_OFF; const bool gyro_enabled = cfg->gyro_pwr_mode != ICM42688_DT_GYRO_OFF; @@ -79,13 +93,13 @@ static uint16_t icm42688_compute_fifo_wm(const struct icm42688_cfg *cfg) if (accel_enabled) { struct sensor_value val = {0}; - icm42688_accel_reg_to_hz(cfg->accel_odr, &val); + icm4268x_accel_reg_to_hz(cfg->accel_odr, &val); accel_modr = sensor_value_to_micro(&val) / 1000; } if (gyro_enabled) { struct sensor_value val = {0}; - icm42688_gyro_reg_to_odr(cfg->gyro_odr, &val); + icm4268x_gyro_reg_to_odr(cfg->gyro_odr, &val); gyro_modr = sensor_value_to_micro(&val) / 1000; } @@ -119,18 +133,18 @@ static uint16_t icm42688_compute_fifo_wm(const struct icm42688_cfg *cfg) return (uint16_t)MIN(modr, 0x7ff); } -int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) +int icm4268x_configure(const struct device *dev, struct icm4268x_cfg *cfg) { - struct icm42688_dev_data *dev_data = dev->data; - const struct icm42688_dev_cfg *dev_cfg = dev->config; + struct icm4268x_dev_data *dev_data = dev->data; + const struct icm4268x_dev_cfg *dev_cfg = dev->config; int res; /* Disable interrupts, reconfigured at end */ - res = icm42688_spi_single_write(&dev_cfg->spi, REG_INT_SOURCE0, 0); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_INT_SOURCE0, 0); /* if fifo is enabled right now, disable and flush */ if (dev_data->cfg.fifo_en) { - res = icm42688_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG, + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG, FIELD_PREP(MASK_FIFO_MODE, BIT_FIFO_MODE_BYPASS)); if (res != 0) { @@ -138,7 +152,7 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) return -EINVAL; } - res = icm42688_spi_single_write(&dev_cfg->spi, REG_SIGNAL_PATH_RESET, + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_SIGNAL_PATH_RESET, FIELD_PREP(BIT_FIFO_FLUSH, 1)); if (res != 0) { @@ -150,7 +164,7 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) /* TODO maybe do the next few steps intelligently by checking current config */ /* Select register bank 1 */ - res = icm42688_spi_single_write(&dev_cfg->spi, REG_BANK_SEL, BIT_BANK1); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_BANK_SEL, BIT_BANK1); if (res != 0) { LOG_ERR("Error selecting register bank 1"); return -EINVAL; @@ -161,24 +175,24 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) LOG_DBG("INTF_CONFIG5 (0x%lx) 0x%x", FIELD_GET(REG_ADDRESS_MASK, REG_INTF_CONFIG5), intf_config5); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_INTF_CONFIG5, intf_config5); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_INTF_CONFIG5, intf_config5); if (res != 0) { LOG_ERR("Error writing INTF_CONFIG5"); return -EINVAL; } /* Select register bank 0 */ - res = icm42688_spi_single_write(&dev_cfg->spi, REG_BANK_SEL, BIT_BANK0); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_BANK_SEL, BIT_BANK0); if (res != 0) { LOG_ERR("Error selecting register bank 0"); return -EINVAL; } - bool is_pin9_clkin = cfg->pin9_function == ICM42688_PIN9_FUNCTION_CLKIN; + bool is_pin9_clkin = cfg->pin9_function == ICM4268X_PIN9_FUNCTION_CLKIN; uint8_t intf_config1 = 0x91 | FIELD_PREP(BIT_RTC_MODE, is_pin9_clkin); LOG_DBG("INTF_CONFIG1 (0x%x) 0x%x", REG_INTF_CONFIG1, intf_config1); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_INTF_CONFIG1, intf_config1); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_INTF_CONFIG1, intf_config1); if (res != 0) { LOG_ERR("Error writing INTF_CONFIG1"); return -EINVAL; @@ -190,7 +204,7 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) FIELD_PREP(BIT_TEMP_DIS, cfg->temp_dis); LOG_DBG("PWR_MGMT0 (0x%x) 0x%x", REG_PWR_MGMT0, pwr_mgmt0); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_PWR_MGMT0, pwr_mgmt0); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_PWR_MGMT0, pwr_mgmt0); if (res != 0) { LOG_ERR("Error writing PWR_MGMT0"); @@ -206,7 +220,7 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) FIELD_PREP(MASK_ACCEL_UI_FS_SEL, cfg->accel_fs); LOG_DBG("ACCEL_CONFIG0 (0x%x) 0x%x", REG_ACCEL_CONFIG0, accel_config0); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_ACCEL_CONFIG0, accel_config0); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_ACCEL_CONFIG0, accel_config0); if (res != 0) { LOG_ERR("Error writing ACCEL_CONFIG0"); return -EINVAL; @@ -216,7 +230,7 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) FIELD_PREP(MASK_GYRO_UI_FS_SEL, cfg->gyro_fs); LOG_DBG("GYRO_CONFIG0 (0x%x) 0x%x", REG_GYRO_CONFIG0, gyro_config0); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_GYRO_CONFIG0, gyro_config0); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_GYRO_CONFIG0, gyro_config0); if (res != 0) { LOG_ERR("Error writing GYRO_CONFIG0"); return -EINVAL; @@ -232,7 +246,7 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) uint8_t fifo_config_bypass = FIELD_PREP(MASK_FIFO_MODE, BIT_FIFO_MODE_BYPASS); LOG_DBG("FIFO_CONFIG (0x%x) 0x%x", REG_FIFO_CONFIG, fifo_config_bypass); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG, fifo_config_bypass); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG, fifo_config_bypass); if (res != 0) { LOG_ERR("Error writing FIFO_CONFIG"); return -EINVAL; @@ -241,27 +255,27 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) /* Disable FSYNC */ uint8_t tmst_config; - res = icm42688_spi_single_write(&dev_cfg->spi, REG_FSYNC_CONFIG, 0); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FSYNC_CONFIG, 0); if (res != 0) { LOG_ERR("Error writing FSYNC_CONFIG"); return -EINVAL; } - res = icm42688_spi_read(&dev_cfg->spi, REG_TMST_CONFIG, &tmst_config, 1); + res = icm4268x_spi_read(&dev_cfg->spi, REG_TMST_CONFIG, &tmst_config, 1); if (res != 0) { LOG_ERR("Error reading TMST_CONFIG"); return -EINVAL; } - res = icm42688_spi_single_write(&dev_cfg->spi, REG_TMST_CONFIG, tmst_config & ~BIT(1)); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_TMST_CONFIG, tmst_config & ~BIT(1)); if (res != 0) { LOG_ERR("Error writing TMST_CONFIG"); return -EINVAL; } /* Pulse mode with async reset (resets interrupt line on int status read) */ - if (IS_ENABLED(CONFIG_ICM42688_TRIGGER)) { - res = icm42688_trigger_enable_interrupt(dev, cfg); + if (IS_ENABLED(CONFIG_ICM4268X_TRIGGER)) { + res = icm4268x_trigger_enable_interrupt(dev, cfg); } else { - res = icm42688_spi_single_write(&dev_cfg->spi, REG_INT_CONFIG, + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_INT_CONFIG, BIT_INT1_DRIVE_CIRCUIT | BIT_INT1_POLARITY); } if (res) { @@ -277,7 +291,7 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) FIELD_PREP(BIT_INT_TDEASSERT_DISABLE, 1); } - res = icm42688_spi_single_write(&dev_cfg->spi, REG_INT_CONFIG1, int_config1); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_INT_CONFIG1, int_config1); if (res) { LOG_ERR("Error writing to INT_CONFIG1"); return res; @@ -300,18 +314,18 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) LOG_DBG("HIRES MODE ENABLED?: %d", cfg->fifo_hires); LOG_DBG("FIFO_CONFIG1 (0x%x) 0x%x", REG_FIFO_CONFIG1, fifo_cfg1); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG1, fifo_cfg1); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG1, fifo_cfg1); if (res != 0) { LOG_ERR("Error writing FIFO_CONFIG1"); return -EINVAL; } /* Set watermark and interrupt handling first */ - uint16_t fifo_wm = icm42688_compute_fifo_wm(cfg); + uint16_t fifo_wm = icm4268x_compute_fifo_wm(cfg); uint8_t fifo_wml = fifo_wm & 0xFF; LOG_DBG("FIFO_CONFIG2( (0x%x)) (WM Low) 0x%x", REG_FIFO_CONFIG2, fifo_wml); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG2, fifo_wml); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG2, fifo_wml); if (res != 0) { LOG_ERR("Error writing FIFO_CONFIG2"); return -EINVAL; @@ -320,7 +334,7 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) uint8_t fifo_wmh = (fifo_wm >> 8) & 0x0F; LOG_DBG("FIFO_CONFIG3 (0x%x) (WM High) 0x%x", REG_FIFO_CONFIG3, fifo_wmh); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG3, fifo_wmh); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG3, fifo_wmh); if (res != 0) { LOG_ERR("Error writing FIFO_CONFIG3"); return -EINVAL; @@ -330,13 +344,13 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) uint8_t fifo_config = FIELD_PREP(MASK_FIFO_MODE, BIT_FIFO_MODE_STREAM); LOG_DBG("FIFO_CONFIG (0x%x) 0x%x", REG_FIFO_CONFIG, 1 << 6); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG, fifo_config); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_FIFO_CONFIG, fifo_config); /* Config interrupt source to only be fifo wm/full */ uint8_t int_source0 = BIT_FIFO_FULL_INT1_EN | BIT_FIFO_THS_INT1_EN; LOG_DBG("INT_SOURCE0 (0x%x) 0x%x", REG_INT_SOURCE0, int_source0); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_INT_SOURCE0, int_source0); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_INT_SOURCE0, int_source0); if (res) { return res; } @@ -347,7 +361,7 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) uint8_t int_source0 = BIT_UI_DRDY_INT1_EN; LOG_DBG("INT_SOURCE0 (0x%x) 0x%x", REG_INT_SOURCE0, int_source0); - res = icm42688_spi_single_write(&dev_cfg->spi, REG_INT_SOURCE0, int_source0); + res = icm4268x_spi_single_write(&dev_cfg->spi, REG_INT_SOURCE0, int_source0); if (res) { return res; } @@ -356,26 +370,26 @@ int icm42688_configure(const struct device *dev, struct icm42688_cfg *cfg) return res; } -int icm42688_safely_configure(const struct device *dev, struct icm42688_cfg *cfg) +int icm4268x_safely_configure(const struct device *dev, struct icm4268x_cfg *cfg) { - struct icm42688_dev_data *drv_data = dev->data; - int ret = icm42688_configure(dev, cfg); + struct icm4268x_dev_data *drv_data = dev->data; + int ret = icm4268x_configure(dev, cfg); if (ret == 0) { drv_data->cfg = *cfg; } else { - ret = icm42688_configure(dev, &drv_data->cfg); + ret = icm4268x_configure(dev, &drv_data->cfg); } return ret; } -int icm42688_read_all(const struct device *dev, uint8_t data[14]) +int icm4268x_read_all(const struct device *dev, uint8_t data[14]) { - const struct icm42688_dev_cfg *dev_cfg = dev->config; + const struct icm4268x_dev_cfg *dev_cfg = dev->config; int res; - res = icm42688_spi_read(&dev_cfg->spi, REG_TEMP_DATA1, data, 14); + res = icm4268x_spi_read(&dev_cfg->spi, REG_TEMP_DATA1, data, 14); return res; } diff --git a/drivers/sensor/tdk/icm42688/icm42688_decoder.c b/drivers/sensor/tdk/icm4268x/icm4268x_decoder.c similarity index 69% rename from drivers/sensor/tdk/icm42688/icm42688_decoder.c rename to drivers/sensor/tdk/icm4268x/icm4268x_decoder.c index 61347994484c..9af166e33084 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_decoder.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x_decoder.c @@ -4,73 +4,83 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "icm42688_decoder.h" -#include "icm42688_reg.h" -#include "icm42688.h" +#include "icm4268x_decoder.h" +#include "icm4268x_reg.h" +#include "icm4268x.h" #include #include #include -LOG_MODULE_REGISTER(ICM42688_DECODER, CONFIG_SENSOR_LOG_LEVEL); +LOG_MODULE_REGISTER(ICM4268X_DECODER, CONFIG_SENSOR_LOG_LEVEL); + +#define DT_DRV_COMPAT invensense_icm4268x + +static const struct icm4268x_reg_val_pair table_accel_shift_to_reg[][5] = { + [ICM4268X_VARIANT_ICM42688] = { + {.val = 8, .reg = ICM42688_DT_ACCEL_FS_16}, + {.val = 7, .reg = ICM42688_DT_ACCEL_FS_8}, + {.val = 6, .reg = ICM42688_DT_ACCEL_FS_4}, + {.val = 5, .reg = ICM42688_DT_ACCEL_FS_2}, + }, + [ICM4268X_VARIANT_ICM42686] = { + {.val = 9, .reg = ICM42686_DT_ACCEL_FS_32}, + {.val = 8, .reg = ICM42686_DT_ACCEL_FS_16}, + {.val = 7, .reg = ICM42686_DT_ACCEL_FS_8}, + {.val = 6, .reg = ICM42686_DT_ACCEL_FS_4}, + {.val = 5, .reg = ICM42686_DT_ACCEL_FS_2}, + }, +}; -#define DT_DRV_COMPAT invensense_icm42688 +static const struct icm4268x_reg_val_pair table_gyro_shift_to_reg[][8] = { + [ICM4268X_VARIANT_ICM42688] = { + {.val = 6, .reg = ICM42688_DT_GYRO_FS_2000}, + {.val = 5, .reg = ICM42688_DT_GYRO_FS_1000}, + {.val = 4, .reg = ICM42688_DT_GYRO_FS_500}, + {.val = 3, .reg = ICM42688_DT_GYRO_FS_250}, + {.val = 2, .reg = ICM42688_DT_GYRO_FS_125}, + {.val = 1, .reg = ICM42688_DT_GYRO_FS_62_5}, + {.val = 0, .reg = ICM42688_DT_GYRO_FS_31_25}, + {.val = -1, .reg = ICM42688_DT_GYRO_FS_15_625}, + }, + [ICM4268X_VARIANT_ICM42686] = { + {.val = 7, .reg = ICM42686_DT_GYRO_FS_4000}, + {.val = 6, .reg = ICM42686_DT_GYRO_FS_2000}, + {.val = 5, .reg = ICM42686_DT_GYRO_FS_1000}, + {.val = 4, .reg = ICM42686_DT_GYRO_FS_500}, + {.val = 3, .reg = ICM42686_DT_GYRO_FS_250}, + {.val = 2, .reg = ICM42686_DT_GYRO_FS_125}, + {.val = 1, .reg = ICM42686_DT_GYRO_FS_62_5}, + {.val = 0, .reg = ICM42686_DT_GYRO_FS_31_25}, + }, +}; -static int icm42688_get_shift(enum sensor_channel channel, int accel_fs, int gyro_fs, int8_t *shift) +static int icm4268x_get_shift(enum sensor_channel channel, int accel_fs, int gyro_fs, + enum icm4268x_variant variant, int8_t *shift) { switch (channel) { case SENSOR_CHAN_ACCEL_XYZ: case SENSOR_CHAN_ACCEL_X: case SENSOR_CHAN_ACCEL_Y: case SENSOR_CHAN_ACCEL_Z: - switch (accel_fs) { - case ICM42688_DT_ACCEL_FS_2: - *shift = 5; - return 0; - case ICM42688_DT_ACCEL_FS_4: - *shift = 6; - return 0; - case ICM42688_DT_ACCEL_FS_8: - *shift = 7; - return 0; - case ICM42688_DT_ACCEL_FS_16: - *shift = 8; - return 0; - default: - return -EINVAL; + for (uint8_t i = 0 ; i < table_accel_fs_to_reg_array_size[variant] ; i++) { + if (accel_fs == table_accel_shift_to_reg[variant][i].reg) { + *shift = table_accel_shift_to_reg[variant][i].val; + return 0; + } } + return -EINVAL; case SENSOR_CHAN_GYRO_XYZ: case SENSOR_CHAN_GYRO_X: case SENSOR_CHAN_GYRO_Y: case SENSOR_CHAN_GYRO_Z: - switch (gyro_fs) { - case ICM42688_DT_GYRO_FS_15_625: - *shift = -1; - return 0; - case ICM42688_DT_GYRO_FS_31_25: - *shift = 0; - return 0; - case ICM42688_DT_GYRO_FS_62_5: - *shift = 1; - return 0; - case ICM42688_DT_GYRO_FS_125: - *shift = 2; - return 0; - case ICM42688_DT_GYRO_FS_250: - *shift = 3; - return 0; - case ICM42688_DT_GYRO_FS_500: - *shift = 4; - return 0; - case ICM42688_DT_GYRO_FS_1000: - *shift = 5; - return 0; - case ICM42688_DT_GYRO_FS_2000: - *shift = 6; - return 0; - default: - return -EINVAL; + for (uint8_t i = 0 ; i < table_gyro_fs_to_reg_array_size[variant] ; i++) { + if (gyro_fs == table_gyro_shift_to_reg[variant][i].reg) { + *shift = table_gyro_shift_to_reg[variant][i].val; + return 0; + } } + return -EINVAL; case SENSOR_CHAN_DIE_TEMP: *shift = 9; return 0; @@ -79,7 +89,7 @@ static int icm42688_get_shift(enum sensor_channel channel, int accel_fs, int gyr } } -int icm42688_convert_raw_to_q31(struct icm42688_cfg *cfg, enum sensor_channel chan, int32_t reading, +int icm4268x_convert_raw_to_q31(struct icm4268x_cfg *cfg, enum sensor_channel chan, int32_t reading, q31_t *out) { int32_t whole; @@ -88,7 +98,7 @@ int icm42688_convert_raw_to_q31(struct icm42688_cfg *cfg, enum sensor_channel ch int8_t shift; int rc; - rc = icm42688_get_shift(chan, cfg->accel_fs, cfg->gyro_fs, &shift); + rc = icm4268x_get_shift(chan, cfg->accel_fs, cfg->gyro_fs, cfg->variant, &shift); if (rc != 0) { return rc; } @@ -98,16 +108,16 @@ int icm42688_convert_raw_to_q31(struct icm42688_cfg *cfg, enum sensor_channel ch case SENSOR_CHAN_ACCEL_X: case SENSOR_CHAN_ACCEL_Y: case SENSOR_CHAN_ACCEL_Z: - icm42688_accel_ms(cfg, reading, &whole, &fraction); + icm4268x_accel_ms(cfg, reading, &whole, &fraction); break; case SENSOR_CHAN_GYRO_XYZ: case SENSOR_CHAN_GYRO_X: case SENSOR_CHAN_GYRO_Y: case SENSOR_CHAN_GYRO_Z: - icm42688_gyro_rads(cfg, reading, &whole, &fraction); + icm4268x_gyro_rads(cfg, reading, &whole, &fraction); break; case SENSOR_CHAN_DIE_TEMP: - icm42688_temp_c(reading, &whole, &fraction); + icm4268x_temp_c(reading, &whole, &fraction); break; default: return -ENOTSUP; @@ -116,7 +126,7 @@ int icm42688_convert_raw_to_q31(struct icm42688_cfg *cfg, enum sensor_channel ch if (shift < 0) { intermediate = intermediate * ((int64_t)INT32_MAX + 1) * (1 << -shift) / INT64_C(1000000); - } else if (shift > 0) { + } else if (shift >= 0) { intermediate = intermediate * ((int64_t)INT32_MAX + 1) / ((1 << shift) * INT64_C(1000000)); } @@ -125,7 +135,7 @@ int icm42688_convert_raw_to_q31(struct icm42688_cfg *cfg, enum sensor_channel ch return 0; } -static int icm42688_get_channel_position(enum sensor_channel chan) +static int icm4268x_get_channel_position(enum sensor_channel chan) { switch (chan) { case SENSOR_CHAN_DIE_TEMP: @@ -149,7 +159,7 @@ static int icm42688_get_channel_position(enum sensor_channel chan) } } -static uint8_t icm42688_encode_channel(enum sensor_channel chan) +static uint8_t icm4268x_encode_channel(enum sensor_channel chan) { uint8_t encode_bmask = 0; @@ -161,17 +171,17 @@ static uint8_t icm42688_encode_channel(enum sensor_channel chan) case SENSOR_CHAN_GYRO_X: case SENSOR_CHAN_GYRO_Y: case SENSOR_CHAN_GYRO_Z: - encode_bmask = BIT(icm42688_get_channel_position(chan)); + encode_bmask = BIT(icm4268x_get_channel_position(chan)); break; case SENSOR_CHAN_ACCEL_XYZ: - encode_bmask = BIT(icm42688_get_channel_position(SENSOR_CHAN_ACCEL_X)) | - BIT(icm42688_get_channel_position(SENSOR_CHAN_ACCEL_Y)) | - BIT(icm42688_get_channel_position(SENSOR_CHAN_ACCEL_Z)); + encode_bmask = BIT(icm4268x_get_channel_position(SENSOR_CHAN_ACCEL_X)) | + BIT(icm4268x_get_channel_position(SENSOR_CHAN_ACCEL_Y)) | + BIT(icm4268x_get_channel_position(SENSOR_CHAN_ACCEL_Z)); break; case SENSOR_CHAN_GYRO_XYZ: - encode_bmask = BIT(icm42688_get_channel_position(SENSOR_CHAN_GYRO_X)) | - BIT(icm42688_get_channel_position(SENSOR_CHAN_GYRO_Y)) | - BIT(icm42688_get_channel_position(SENSOR_CHAN_GYRO_Z)); + encode_bmask = BIT(icm4268x_get_channel_position(SENSOR_CHAN_GYRO_X)) | + BIT(icm4268x_get_channel_position(SENSOR_CHAN_GYRO_Y)) | + BIT(icm4268x_get_channel_position(SENSOR_CHAN_GYRO_Z)); break; default: break; @@ -180,18 +190,18 @@ static uint8_t icm42688_encode_channel(enum sensor_channel chan) return encode_bmask; } -int icm42688_encode(const struct device *dev, const struct sensor_chan_spec *const channels, +int icm4268x_encode(const struct device *dev, const struct sensor_chan_spec *const channels, const size_t num_channels, uint8_t *buf) { - struct icm42688_dev_data *data = dev->data; - struct icm42688_encoded_data *edata = (struct icm42688_encoded_data *)buf; + struct icm4268x_dev_data *data = dev->data; + struct icm4268x_encoded_data *edata = (struct icm4268x_encoded_data *)buf; uint64_t cycles; int rc; edata->channels = 0; for (int i = 0; i < num_channels; i++) { - edata->channels |= icm42688_encode_channel(channels[i].chan_type); + edata->channels |= icm4268x_encode_channel(channels[i].chan_type); } rc = sensor_clock_get_cycles(&cycles); @@ -200,6 +210,7 @@ int icm42688_encode(const struct device *dev, const struct sensor_chan_spec *con } edata->header.is_fifo = false; + edata->header.variant = data->cfg.variant; edata->header.accel_fs = data->cfg.accel_fs; edata->header.gyro_fs = data->cfg.gyro_fs; edata->header.axis_align[0] = data->cfg.axis_align[0]; @@ -213,7 +224,7 @@ int icm42688_encode(const struct device *dev, const struct sensor_chan_spec *con #define IS_ACCEL(chan) ((chan) >= SENSOR_CHAN_ACCEL_X && (chan) <= SENSOR_CHAN_ACCEL_XYZ) #define IS_GYRO(chan) ((chan) >= SENSOR_CHAN_GYRO_X && (chan) <= SENSOR_CHAN_GYRO_XYZ) -static inline q31_t icm42688_read_temperature_from_packet(const uint8_t *pkt) +static inline q31_t icm4268x_read_temperature_from_packet(const uint8_t *pkt) { int32_t temperature; int32_t whole; @@ -223,7 +234,7 @@ static inline q31_t icm42688_read_temperature_from_packet(const uint8_t *pkt) if (FIELD_GET(FIFO_HEADER_20, pkt[0]) == 1) { temperature = (pkt[0xd] << 8) | pkt[0xe]; - icm42688_temp_c(temperature, &whole, &fraction); + icm4268x_temp_c(temperature, &whole, &fraction); } else { if (FIELD_GET(FIFO_HEADER_ACCEL, pkt[0]) == 1 && FIELD_GET(FIFO_HEADER_GYRO, pkt[0]) == 1) { @@ -243,7 +254,7 @@ static inline q31_t icm42688_read_temperature_from_packet(const uint8_t *pkt) return FIELD_PREP(GENMASK(31, 22), whole) | (fraction * GENMASK64(21, 0) / 1000000); } -static int icm42688_read_imu_from_packet(const uint8_t *pkt, bool is_accel, int fs, +static int icm4268x_read_imu_from_packet(const uint8_t *pkt, bool is_accel, int fs, uint8_t axis_offset, q31_t *out) { uint32_t unsigned_value; @@ -322,7 +333,7 @@ static const uint32_t gyro_period_ns[] = { [ICM42688_DT_GYRO_ODR_32000] = UINT32_C(1000000) / 32, }; -static int icm42688_calc_timestamp_delta(int rtc_freq, int chan_type, int dt_odr, int frame_count, +static int icm4268x_calc_timestamp_delta(int rtc_freq, int chan_type, int dt_odr, int frame_count, uint64_t *out_delta) { uint32_t period; @@ -344,11 +355,11 @@ static int icm42688_calc_timestamp_delta(int rtc_freq, int chan_type, int dt_odr return 0; } -static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, +static int icm4268x_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, uint32_t *fit, uint16_t max_count, void *data_out) { - const struct icm42688_fifo_data *edata = (const struct icm42688_fifo_data *)buffer; - const uint8_t *buffer_end = buffer + sizeof(struct icm42688_fifo_data) + edata->fifo_count; + const struct icm4268x_fifo_data *edata = (const struct icm4268x_fifo_data *)buffer; + const uint8_t *buffer_end = buffer + sizeof(struct icm4268x_fifo_data) + edata->fifo_count; int accel_frame_count = 0; int gyro_frame_count = 0; int count = 0; @@ -360,7 +371,7 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c ((struct sensor_data_header *)data_out)->base_timestamp_ns = edata->header.timestamp; - buffer += sizeof(struct icm42688_fifo_data); + buffer += sizeof(struct icm4268x_fifo_data); while (count < max_count && buffer < buffer_end) { const bool is_20b = FIELD_GET(FIFO_HEADER_20, buffer[0]) == 1; const bool has_accel = FIELD_GET(FIFO_HEADER_ACCEL, buffer[0]) == 1; @@ -391,11 +402,11 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c uint64_t ts_delta; if (has_accel) { - rc = icm42688_calc_timestamp_delta( + rc = icm4268x_calc_timestamp_delta( edata->rtc_freq, SENSOR_CHAN_ACCEL_XYZ, edata->accel_odr, accel_frame_count - 1, &ts_delta); } else { - rc = icm42688_calc_timestamp_delta( + rc = icm4268x_calc_timestamp_delta( edata->rtc_freq, SENSOR_CHAN_GYRO_XYZ, edata->gyro_odr, gyro_frame_count - 1, &ts_delta); } @@ -418,17 +429,18 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c data->shift = 9; data->readings[count].temperature = - icm42688_read_temperature_from_packet(buffer); + icm4268x_read_temperature_from_packet(buffer); } else if (IS_ACCEL(chan_spec.chan_type) && has_accel) { /* Decode accel */ struct sensor_three_axis_data *data = (struct sensor_three_axis_data *)data_out; uint64_t ts_delta; - icm42688_get_shift(SENSOR_CHAN_ACCEL_XYZ, edata->header.accel_fs, - edata->header.gyro_fs, &data->shift); + icm4268x_get_shift(SENSOR_CHAN_ACCEL_XYZ, edata->header.accel_fs, + edata->header.gyro_fs, edata->header.variant, + &data->shift); - rc = icm42688_calc_timestamp_delta(edata->rtc_freq, SENSOR_CHAN_ACCEL_XYZ, + rc = icm4268x_calc_timestamp_delta(edata->rtc_freq, SENSOR_CHAN_ACCEL_XYZ, edata->accel_odr, accel_frame_count - 1, &ts_delta); if (rc < 0) { @@ -451,7 +463,7 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c q31_t reading[3]; for (int i = 0; i < 3; i++) { - rc |= icm42688_read_imu_from_packet( + rc |= icm4268x_read_imu_from_packet( buffer, true, edata->header.accel_fs, i, &reading[i]); } @@ -472,10 +484,11 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c (struct sensor_three_axis_data *)data_out; uint64_t ts_delta; - icm42688_get_shift(SENSOR_CHAN_GYRO_XYZ, edata->header.accel_fs, - edata->header.gyro_fs, &data->shift); + icm4268x_get_shift(SENSOR_CHAN_GYRO_XYZ, edata->header.accel_fs, + edata->header.gyro_fs, edata->header.variant, + &data->shift); - rc = icm42688_calc_timestamp_delta(edata->rtc_freq, SENSOR_CHAN_GYRO_XYZ, + rc = icm4268x_calc_timestamp_delta(edata->rtc_freq, SENSOR_CHAN_GYRO_XYZ, edata->gyro_odr, gyro_frame_count - 1, &ts_delta); if (rc < 0) { @@ -498,7 +511,7 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c q31_t reading[3]; for (int i = 0; i < 3; i++) { - rc |= icm42688_read_imu_from_packet( + rc |= icm4268x_read_imu_from_packet( buffer, false, edata->header.gyro_fs, i, &reading[i]); } @@ -513,6 +526,8 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c buffer = frame_end; continue; } + } else { + CODE_UNREACHABLE; } buffer = frame_end; *fit = (uintptr_t)frame_end; @@ -521,14 +536,15 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c return count; } -static int icm42688_one_shot_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, +static int icm4268x_one_shot_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, uint32_t *fit, uint16_t max_count, void *data_out) { - const struct icm42688_encoded_data *edata = (const struct icm42688_encoded_data *)buffer; - const struct icm42688_decoder_header *header = &edata->header; - struct icm42688_cfg cfg = { + const struct icm4268x_encoded_data *edata = (const struct icm4268x_encoded_data *)buffer; + const struct icm4268x_decoder_header *header = &edata->header; + struct icm4268x_cfg cfg = { .accel_fs = edata->header.accel_fs, .gyro_fs = edata->header.gyro_fs, + .variant = edata->header.variant, }; uint8_t channel_request; int rc; @@ -548,7 +564,7 @@ static int icm42688_one_shot_decode(const uint8_t *buffer, struct sensor_chan_sp case SENSOR_CHAN_GYRO_Y: case SENSOR_CHAN_GYRO_Z: case SENSOR_CHAN_DIE_TEMP: { - channel_request = icm42688_encode_channel(chan_spec.chan_type); + channel_request = icm4268x_encode_channel(chan_spec.chan_type); if ((channel_request & edata->channels) != channel_request) { return -ENODATA; } @@ -558,22 +574,22 @@ static int icm42688_one_shot_decode(const uint8_t *buffer, struct sensor_chan_sp out->header.base_timestamp_ns = edata->header.timestamp; out->header.reading_count = 1; - rc = icm42688_get_shift(chan_spec.chan_type, header->accel_fs, header->gyro_fs, - &out->shift); + rc = icm4268x_get_shift(chan_spec.chan_type, header->accel_fs, header->gyro_fs, + header->variant, &out->shift); if (rc != 0) { return -EINVAL; } - icm42688_convert_raw_to_q31( + icm4268x_convert_raw_to_q31( &cfg, chan_spec.chan_type, - edata->readings[icm42688_get_channel_position(chan_spec.chan_type)], + edata->readings[icm4268x_get_channel_position(chan_spec.chan_type)], &out->readings[0].value); *fit = 1; return 1; } case SENSOR_CHAN_ACCEL_XYZ: case SENSOR_CHAN_GYRO_XYZ: { - channel_request = icm42688_encode_channel(chan_spec.chan_type); + channel_request = icm4268x_encode_channel(chan_spec.chan_type); if ((channel_request & edata->channels) != channel_request) { return -ENODATA; } @@ -582,23 +598,23 @@ static int icm42688_one_shot_decode(const uint8_t *buffer, struct sensor_chan_sp out->header.base_timestamp_ns = edata->header.timestamp; out->header.reading_count = 1; - rc = icm42688_get_shift(chan_spec.chan_type, header->accel_fs, header->gyro_fs, - &out->shift); + rc = icm4268x_get_shift(chan_spec.chan_type, header->accel_fs, header->gyro_fs, + header->variant, &out->shift); if (rc != 0) { return -EINVAL; } - icm42688_convert_raw_to_q31( + icm4268x_convert_raw_to_q31( &cfg, chan_spec.chan_type - 3, - edata->readings[icm42688_get_channel_position(chan_spec.chan_type - 3)], + edata->readings[icm4268x_get_channel_position(chan_spec.chan_type - 3)], &out->readings[0].x); - icm42688_convert_raw_to_q31( + icm4268x_convert_raw_to_q31( &cfg, chan_spec.chan_type - 2, - edata->readings[icm42688_get_channel_position(chan_spec.chan_type - 2)], + edata->readings[icm4268x_get_channel_position(chan_spec.chan_type - 2)], &out->readings[0].y); - icm42688_convert_raw_to_q31( + icm4268x_convert_raw_to_q31( &cfg, chan_spec.chan_type - 1, - edata->readings[icm42688_get_channel_position(chan_spec.chan_type - 1)], + edata->readings[icm4268x_get_channel_position(chan_spec.chan_type - 1)], &out->readings[0].z); *fit = 1; return 1; @@ -608,31 +624,31 @@ static int icm42688_one_shot_decode(const uint8_t *buffer, struct sensor_chan_sp } } -static int icm42688_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, +static int icm4268x_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, uint32_t *fit, uint16_t max_count, void *data_out) { - const struct icm42688_decoder_header *header = - (const struct icm42688_decoder_header *)buffer; + const struct icm4268x_decoder_header *header = + (const struct icm4268x_decoder_header *)buffer; if (header->is_fifo) { - return icm42688_fifo_decode(buffer, chan_spec, fit, max_count, data_out); + return icm4268x_fifo_decode(buffer, chan_spec, fit, max_count, data_out); } - return icm42688_one_shot_decode(buffer, chan_spec, fit, max_count, data_out); + return icm4268x_one_shot_decode(buffer, chan_spec, fit, max_count, data_out); } -static int icm42688_decoder_get_frame_count(const uint8_t *buffer, +static int icm4268x_decoder_get_frame_count(const uint8_t *buffer, struct sensor_chan_spec chan_spec, uint16_t *frame_count) { - const struct icm42688_fifo_data *data = (const struct icm42688_fifo_data *)buffer; - const struct icm42688_encoded_data *enc_data = (const struct icm42688_encoded_data *)buffer; - const struct icm42688_decoder_header *header = &data->header; + const struct icm4268x_fifo_data *data = (const struct icm4268x_fifo_data *)buffer; + const struct icm4268x_encoded_data *enc_data = (const struct icm4268x_encoded_data *)buffer; + const struct icm4268x_decoder_header *header = &data->header; if (chan_spec.chan_idx != 0) { return -ENOTSUP; } - uint8_t channel_request = icm42688_encode_channel(chan_spec.chan_type); + uint8_t channel_request = icm4268x_encode_channel(chan_spec.chan_type); if ((!enc_data->header.is_fifo) && @@ -660,7 +676,7 @@ static int icm42688_decoder_get_frame_count(const uint8_t *buffer, } /* Skip the header */ - buffer += sizeof(struct icm42688_fifo_data); + buffer += sizeof(struct icm4268x_fifo_data); uint16_t count = 0; const uint8_t *end = buffer + data->fifo_count; @@ -690,7 +706,7 @@ static int icm42688_decoder_get_frame_count(const uint8_t *buffer, return 0; } -static int icm42688_decoder_get_size_info(struct sensor_chan_spec chan_spec, size_t *base_size, +static int icm4268x_decoder_get_size_info(struct sensor_chan_spec chan_spec, size_t *base_size, size_t *frame_size) { switch (chan_spec.chan_type) { @@ -716,7 +732,7 @@ static int icm42688_decoder_get_size_info(struct sensor_chan_spec chan_spec, siz static bool icm24688_decoder_has_trigger(const uint8_t *buffer, enum sensor_trigger_type trigger) { - const struct icm42688_fifo_data *edata = (const struct icm42688_fifo_data *)buffer; + const struct icm4268x_fifo_data *edata = (const struct icm4268x_fifo_data *)buffer; if (!edata->header.is_fifo) { return false; @@ -735,13 +751,13 @@ static bool icm24688_decoder_has_trigger(const uint8_t *buffer, enum sensor_trig } SENSOR_DECODER_API_DT_DEFINE() = { - .get_frame_count = icm42688_decoder_get_frame_count, - .get_size_info = icm42688_decoder_get_size_info, - .decode = icm42688_decoder_decode, + .get_frame_count = icm4268x_decoder_get_frame_count, + .get_size_info = icm4268x_decoder_get_size_info, + .decode = icm4268x_decoder_decode, .has_trigger = icm24688_decoder_has_trigger, }; -int icm42688_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) +int icm4268x_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) { ARG_UNUSED(dev); *decoder = &SENSOR_DECODER_NAME(); diff --git a/drivers/sensor/tdk/icm42688/icm42688_decoder.h b/drivers/sensor/tdk/icm4268x/icm4268x_decoder.h similarity index 55% rename from drivers/sensor/tdk/icm42688/icm42688_decoder.h rename to drivers/sensor/tdk/icm4268x/icm4268x_decoder.h index 460e89e74cbd..6d2cace1a5cb 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_decoder.h +++ b/drivers/sensor/tdk/icm4268x/icm4268x_decoder.h @@ -4,24 +4,24 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42688_DECODER_H_ -#define ZEPHYR_DRIVERS_SENSOR_ICM42688_DECODER_H_ +#ifndef ZEPHYR_DRIVERS_SENSOR_ICM4268X_DECODER_H_ +#define ZEPHYR_DRIVERS_SENSOR_ICM4268X_DECODER_H_ #include #include -#include "icm42688.h" +#include "icm4268x.h" -struct icm42688_decoder_header { +struct icm4268x_decoder_header { uint64_t timestamp; uint8_t is_fifo: 1; uint8_t gyro_fs: 3; - uint8_t accel_fs: 2; - uint8_t reserved: 2; + uint8_t accel_fs: 3; + uint8_t variant: 1; struct alignment axis_align[3]; } __attribute__((__packed__)); -struct icm42688_fifo_data { - struct icm42688_decoder_header header; +struct icm4268x_fifo_data { + struct icm4268x_decoder_header header; uint8_t int_status; uint8_t gyro_odr: 4; uint8_t accel_odr: 4; @@ -30,8 +30,8 @@ struct icm42688_fifo_data { uint16_t rtc_freq; } __attribute__((__packed__)); -struct icm42688_encoded_data { - struct icm42688_decoder_header header; +struct icm4268x_encoded_data { + struct icm4268x_decoder_header header; struct { uint8_t channels: 7; uint8_t reserved: 1; @@ -39,9 +39,9 @@ struct icm42688_encoded_data { int16_t readings[7]; }; -int icm42688_encode(const struct device *dev, const struct sensor_chan_spec *const channels, +int icm4268x_encode(const struct device *dev, const struct sensor_chan_spec *const channels, const size_t num_channels, uint8_t *buf); -int icm42688_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder); +int icm4268x_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder); -#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42688_DECODER_H_ */ +#endif /* ZEPHYR_DRIVERS_SENSOR_ICM4268X_DECODER_H_ */ diff --git a/drivers/sensor/tdk/icm42688/icm42688_emul.c b/drivers/sensor/tdk/icm4268x/icm4268x_emul.c similarity index 78% rename from drivers/sensor/tdk/icm42688/icm42688_emul.c rename to drivers/sensor/tdk/icm4268x/icm4268x_emul.c index 2055654ed5d8..0b3819b090f8 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_emul.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x_emul.c @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** This test is exclusive for icm42688 so let's restrict it for now. */ #define DT_DRV_COMPAT invensense_icm42688 #include @@ -12,39 +13,39 @@ #include #include -#include +#include -LOG_MODULE_DECLARE(ICM42688, CONFIG_SENSOR_LOG_LEVEL); +LOG_MODULE_DECLARE(ICM4268X, CONFIG_SENSOR_LOG_LEVEL); #define NUM_REGS (UINT8_MAX >> 1) -struct icm42688_emul_data { +struct icm4268x_emul_data { uint8_t reg[NUM_REGS]; }; -struct icm42688_emul_cfg { +struct icm4268x_emul_cfg { }; -void icm42688_emul_set_reg(const struct emul *target, uint8_t reg_addr, const uint8_t *val, +void icm4268x_emul_set_reg(const struct emul *target, uint8_t reg_addr, const uint8_t *val, size_t count) { - struct icm42688_emul_data *data = target->data; + struct icm4268x_emul_data *data = target->data; __ASSERT_NO_MSG(reg_addr + count < NUM_REGS); memcpy(data->reg + reg_addr, val, count); } -void icm42688_emul_get_reg(const struct emul *target, uint8_t reg_addr, uint8_t *val, size_t count) +void icm4268x_emul_get_reg(const struct emul *target, uint8_t reg_addr, uint8_t *val, size_t count) { - struct icm42688_emul_data *data = target->data; + struct icm4268x_emul_data *data = target->data; __ASSERT_NO_MSG(reg_addr + count < NUM_REGS); memcpy(val, data->reg + reg_addr, count); } -static void icm42688_emul_handle_write(const struct emul *target, uint8_t regn, uint8_t value) +static void icm4268x_emul_handle_write(const struct emul *target, uint8_t regn, uint8_t value) { - struct icm42688_emul_data *data = target->data; + struct icm4268x_emul_data *data = target->data; switch (regn) { case REG_DEVICE_CONFIG: @@ -57,14 +58,16 @@ static void icm42688_emul_handle_write(const struct emul *target, uint8_t regn, data->reg[REG_INT_STATUS] |= BIT_RESET_DONE_INT; } break; + default: + break; } } -static int icm42688_emul_io_spi(const struct emul *target, const struct spi_config *config, +static int icm4268x_emul_io_spi(const struct emul *target, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs) { - struct icm42688_emul_data *data = target->data; + struct icm4268x_emul_data *data = target->data; const struct spi_buf *tx, *rx; uint8_t regn; bool is_read; @@ -98,15 +101,15 @@ static int icm42688_emul_io_spi(const struct emul *target, const struct spi_conf __ASSERT_NO_MSG(tx->len > 0); value = ((uint8_t *)tx->buf)[0]; - icm42688_emul_handle_write(target, regn, value); + icm4268x_emul_handle_write(target, regn, value); } return 0; } -static int icm42688_emul_init(const struct emul *target, const struct device *parent) +static int icm4268x_emul_init(const struct emul *target, const struct device *parent) { - struct icm42688_emul_data *data = target->data; + struct icm4268x_emul_data *data = target->data; /* Initialized the who-am-i register */ data->reg[REG_WHO_AM_I] = WHO_AM_I_ICM42688; @@ -114,8 +117,8 @@ static int icm42688_emul_init(const struct emul *target, const struct device *pa return 0; } -static const struct spi_emul_api icm42688_emul_spi_api = { - .io = icm42688_emul_io_spi, +static const struct spi_emul_api icm4268x_emul_spi_api = { + .io = icm4268x_emul_io_spi, }; #define Q31_SCALE ((int64_t)INT32_MAX + 1) @@ -124,7 +127,7 @@ static const struct spi_emul_api icm42688_emul_spi_api = { * @brief Get current full-scale range in g's based on register config, along with corresponding * sensitivity and shift. See datasheet section 3.2, table 2. */ -static void icm42688_emul_get_accel_settings(const struct emul *target, int *fs_g, int *sensitivity, +static void icm4268x_emul_get_accel_settings(const struct emul *target, int *fs_g, int *sensitivity, int8_t *shift) { uint8_t reg; @@ -132,7 +135,7 @@ static void icm42688_emul_get_accel_settings(const struct emul *target, int *fs_ int sensitivity_out, fs_g_out; int8_t shift_out; - icm42688_emul_get_reg(target, REG_ACCEL_CONFIG0, ®, 1); + icm4268x_emul_get_reg(target, REG_ACCEL_CONFIG0, ®, 1); switch ((reg & MASK_ACCEL_UI_FS_SEL) >> 5) { case BIT_ACCEL_UI_FS_16: @@ -177,13 +180,13 @@ static void icm42688_emul_get_accel_settings(const struct emul *target, int *fs_ * @brief Helper function for calculating accelerometer ranges. Considers the current full-scale * register config (i.e. +/-2g, +/-4g, etc...) */ -static void icm42688_emul_get_accel_ranges(const struct emul *target, q31_t *lower, q31_t *upper, +static void icm4268x_emul_get_accel_ranges(const struct emul *target, q31_t *lower, q31_t *upper, q31_t *epsilon, int8_t *shift) { int fs_g; int sensitivity; - icm42688_emul_get_accel_settings(target, &fs_g, &sensitivity, shift); + icm4268x_emul_get_accel_settings(target, &fs_g, &sensitivity, shift); /* Epsilon is equal to 1.5 bit-counts worth of error. */ *epsilon = (3 * SENSOR_G * Q31_SCALE / sensitivity / 1000000LL / 2) >> *shift; @@ -195,7 +198,7 @@ static void icm42688_emul_get_accel_ranges(const struct emul *target, q31_t *low * @brief Get current full-scale gyro range in milli-degrees per second based on register config, * along with corresponding sensitivity and shift. See datasheet section 3.1, table 1. */ -static void icm42688_emul_get_gyro_settings(const struct emul *target, int *fs_mdps, +static void icm4268x_emul_get_gyro_settings(const struct emul *target, int *fs_mdps, int *sensitivity, int8_t *shift) { uint8_t reg; @@ -203,7 +206,7 @@ static void icm42688_emul_get_gyro_settings(const struct emul *target, int *fs_m int sensitivity_out, fs_mdps_out; int8_t shift_out; - icm42688_emul_get_reg(target, REG_GYRO_CONFIG0, ®, 1); + icm4268x_emul_get_reg(target, REG_GYRO_CONFIG0, ®, 1); switch ((reg & MASK_GYRO_UI_FS_SEL) >> 5) { case BIT_GYRO_UI_FS_2000: @@ -268,7 +271,7 @@ static void icm42688_emul_get_gyro_settings(const struct emul *target, int *fs_m * @brief Helper function for calculating gyroscope ranges. Considers the current full-scale * register config */ -static void icm42688_emul_get_gyro_ranges(const struct emul *target, q31_t *lower, q31_t *upper, +static void icm4268x_emul_get_gyro_ranges(const struct emul *target, q31_t *lower, q31_t *upper, q31_t *epsilon, int8_t *shift) { /* millidegrees/second */ @@ -276,7 +279,7 @@ static void icm42688_emul_get_gyro_ranges(const struct emul *target, q31_t *lowe /* 10x LSBs per degrees/second*/ int sensitivity; - icm42688_emul_get_gyro_settings(target, &fs_mdps, &sensitivity, shift); + icm4268x_emul_get_gyro_settings(target, &fs_mdps, &sensitivity, shift); /* Reduce the actual range of gyroscope values. Some full-scale ranges actually exceed the * size of an int16 by a small margin. For example, FS_SEL=0 has a +/-2000 deg/s range with @@ -295,7 +298,7 @@ static void icm42688_emul_get_gyro_ranges(const struct emul *target, q31_t *lowe *lower = -*upper; } -static int icm42688_emul_backend_get_sample_range(const struct emul *target, +static int icm4268x_emul_backend_get_sample_range(const struct emul *target, struct sensor_chan_spec ch, q31_t *lower, q31_t *upper, q31_t *epsilon, int8_t *shift) { @@ -314,12 +317,12 @@ static int icm42688_emul_backend_get_sample_range(const struct emul *target, case SENSOR_CHAN_ACCEL_X: case SENSOR_CHAN_ACCEL_Y: case SENSOR_CHAN_ACCEL_Z: - icm42688_emul_get_accel_ranges(target, lower, upper, epsilon, shift); + icm4268x_emul_get_accel_ranges(target, lower, upper, epsilon, shift); break; case SENSOR_CHAN_GYRO_X: case SENSOR_CHAN_GYRO_Y: case SENSOR_CHAN_GYRO_Z: - icm42688_emul_get_gyro_ranges(target, lower, upper, epsilon, shift); + icm4268x_emul_get_gyro_ranges(target, lower, upper, epsilon, shift); break; default: return -ENOTSUP; @@ -328,14 +331,14 @@ static int icm42688_emul_backend_get_sample_range(const struct emul *target, return 0; } -static int icm42688_emul_backend_set_channel(const struct emul *target, struct sensor_chan_spec ch, +static int icm4268x_emul_backend_set_channel(const struct emul *target, struct sensor_chan_spec ch, const q31_t *value, int8_t shift) { if (!target || !target->data) { return -EINVAL; } - struct icm42688_emul_data *data = target->data; + struct icm4268x_emul_data *data = target->data; int sensitivity; uint8_t reg_addr; @@ -364,7 +367,7 @@ static int icm42688_emul_backend_set_channel(const struct emul *target, struct s default: __ASSERT_UNREACHABLE; } - icm42688_emul_get_accel_settings(target, NULL, &sensitivity, NULL); + icm4268x_emul_get_accel_settings(target, NULL, &sensitivity, NULL); reg_val = ((value_unshifted * sensitivity / Q31_SCALE) * 1000000LL) / SENSOR_G; break; case SENSOR_CHAN_GYRO_X: @@ -383,7 +386,7 @@ static int icm42688_emul_backend_set_channel(const struct emul *target, struct s default: __ASSERT_UNREACHABLE; } - icm42688_emul_get_gyro_settings(target, NULL, &sensitivity, NULL); + icm4268x_emul_get_gyro_settings(target, NULL, &sensitivity, NULL); reg_val = CLAMP((((value_unshifted * sensitivity * 180LL) / Q31_SCALE) * 1000000LL) / SENSOR_PI / 10LL, @@ -402,18 +405,18 @@ static int icm42688_emul_backend_set_channel(const struct emul *target, struct s return 0; } -static const struct emul_sensor_driver_api icm42688_emul_sensor_driver_api = { - .set_channel = icm42688_emul_backend_set_channel, - .get_sample_range = icm42688_emul_backend_get_sample_range, +static const struct emul_sensor_driver_api icm4268x_emul_sensor_driver_api = { + .set_channel = icm4268x_emul_backend_set_channel, + .get_sample_range = icm4268x_emul_backend_get_sample_range, }; -#define ICM42688_EMUL_DEFINE(n, api) \ - EMUL_DT_INST_DEFINE(n, icm42688_emul_init, &icm42688_emul_data_##n, \ - &icm42688_emul_cfg_##n, &api, &icm42688_emul_sensor_driver_api) +#define ICM4268X_EMUL_DEFINE(n, api) \ + EMUL_DT_INST_DEFINE(n, icm4268x_emul_init, &icm4268x_emul_data_##n, \ + &icm4268x_emul_cfg_##n, &api, &icm4268x_emul_sensor_driver_api) -#define ICM42688_EMUL_SPI(n) \ - static struct icm42688_emul_data icm42688_emul_data_##n; \ - static const struct icm42688_emul_cfg icm42688_emul_cfg_##n; \ - ICM42688_EMUL_DEFINE(n, icm42688_emul_spi_api) +#define ICM4268X_EMUL_SPI(n) \ + static struct icm4268x_emul_data icm4268x_emul_data_##n; \ + static const struct icm4268x_emul_cfg icm4268x_emul_cfg_##n; \ + ICM4268X_EMUL_DEFINE(n, icm4268x_emul_spi_api) -DT_INST_FOREACH_STATUS_OKAY(ICM42688_EMUL_SPI) +DT_INST_FOREACH_STATUS_OKAY(ICM4268X_EMUL_SPI) diff --git a/drivers/sensor/tdk/icm42688/icm42688_emul.h b/drivers/sensor/tdk/icm4268x/icm4268x_emul.h similarity index 72% rename from drivers/sensor/tdk/icm42688/icm42688_emul.h rename to drivers/sensor/tdk/icm4268x/icm4268x_emul.h index 6c31fee8786c..5ba940a9b93a 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_emul.h +++ b/drivers/sensor/tdk/icm4268x/icm4268x_emul.h @@ -3,8 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef DRIVERS_SENSOR_ICM42688_ICM42688_EMUL_H -#define DRIVERS_SENSOR_ICM42688_ICM42688_EMUL_H +#ifndef DRIVERS_SENSOR_ICM4268X_ICM4268X_EMUL_H +#define DRIVERS_SENSOR_ICM4268X_ICM4268X_EMUL_H #include @@ -16,7 +16,7 @@ * @param in One or more bytes to write to the registers * @param count The number of bytes to write */ -void icm42688_emul_set_reg(const struct emul *target, uint8_t reg_addr, const uint8_t *in, +void icm4268x_emul_set_reg(const struct emul *target, uint8_t reg_addr, const uint8_t *in, size_t count); /** @@ -27,6 +27,6 @@ void icm42688_emul_set_reg(const struct emul *target, uint8_t reg_addr, const ui * @param out Buffer to write the register values into * @param count The number of bytes to read */ -void icm42688_emul_get_reg(const struct emul *target, uint8_t reg_addr, uint8_t *out, size_t count); +void icm4268x_emul_get_reg(const struct emul *target, uint8_t reg_addr, uint8_t *out, size_t count); -#endif /* DRIVERS_SENSOR_ICM42688_ICM42688_EMUL_H */ +#endif /* DRIVERS_SENSOR_ICM4268X_ICM4268X_EMUL_H */ diff --git a/drivers/sensor/tdk/icm42688/icm42688_reg.h b/drivers/sensor/tdk/icm4268x/icm4268x_reg.h similarity index 99% rename from drivers/sensor/tdk/icm42688/icm42688_reg.h rename to drivers/sensor/tdk/icm4268x/icm4268x_reg.h index 29e01e30f6fb..bbd79f88c801 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_reg.h +++ b/drivers/sensor/tdk/icm4268x/icm4268x_reg.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42688_REG_H_ -#define ZEPHYR_DRIVERS_SENSOR_ICM42688_REG_H_ +#ifndef ZEPHYR_DRIVERS_SENSOR_ICM4268X_REG_H_ +#define ZEPHYR_DRIVERS_SENSOR_ICM4268X_REG_H_ #include @@ -503,6 +503,7 @@ /* misc. defines */ #define WHO_AM_I_ICM42688 0x47 +#define WHO_AM_I_ICM42686 0x44 #define MIN_ACCEL_SENS_SHIFT 11 #define ACCEL_DATA_SIZE 6 #define GYRO_DATA_SIZE 6 @@ -519,4 +520,4 @@ #define FIFO_HEADER_ODR_ACCEL BIT(1) #define FIFO_HEADER_ODR_GYRO BIT(0) -#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42688_REG_H_ */ +#endif /* ZEPHYR_DRIVERS_SENSOR_ICM4268X_REG_H_ */ diff --git a/drivers/sensor/tdk/icm42688/icm42688_rtio.c b/drivers/sensor/tdk/icm4268x/icm4268x_rtio.c similarity index 61% rename from drivers/sensor/tdk/icm42688/icm42688_rtio.c rename to drivers/sensor/tdk/icm4268x/icm4268x_rtio.c index ad8476de13e4..c59aff475d4f 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_rtio.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x_rtio.c @@ -7,22 +7,22 @@ #include #include -#include "icm42688.h" -#include "icm42688_decoder.h" -#include "icm42688_reg.h" -#include "icm42688_rtio.h" -#include "icm42688_spi.h" +#include "icm4268x.h" +#include "icm4268x_decoder.h" +#include "icm4268x_reg.h" +#include "icm4268x_rtio.h" +#include "icm4268x_spi.h" #include -LOG_MODULE_REGISTER(ICM42688_RTIO, CONFIG_SENSOR_LOG_LEVEL); +LOG_MODULE_REGISTER(ICM4268X_RTIO, CONFIG_SENSOR_LOG_LEVEL); -static int icm42688_rtio_sample_fetch(const struct device *dev, int16_t readings[7]) +static int icm4268x_rtio_sample_fetch(const struct device *dev, int16_t readings[7]) { uint8_t status; - const struct icm42688_dev_cfg *cfg = dev->config; + const struct icm4268x_dev_cfg *cfg = dev->config; uint8_t *buffer = (uint8_t *)readings; - int res = icm42688_spi_read(&cfg->spi, REG_INT_STATUS, &status, 1); + int res = icm4268x_spi_read(&cfg->spi, REG_INT_STATUS, &status, 1); if (res) { return res; @@ -32,7 +32,7 @@ static int icm42688_rtio_sample_fetch(const struct device *dev, int16_t readings return -EBUSY; } - res = icm42688_read_all(dev, buffer); + res = icm4268x_read_all(dev, buffer); if (res) { return res; @@ -45,16 +45,16 @@ static int icm42688_rtio_sample_fetch(const struct device *dev, int16_t readings return 0; } -static void icm42688_submit_one_shot(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +static void icm4268x_submit_one_shot(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) { const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; const struct sensor_chan_spec *const channels = cfg->channels; const size_t num_channels = cfg->count; - uint32_t min_buf_len = sizeof(struct icm42688_encoded_data); + uint32_t min_buf_len = sizeof(struct icm4268x_encoded_data); int rc; uint8_t *buf; uint32_t buf_len; - struct icm42688_encoded_data *edata; + struct icm4268x_encoded_data *edata; /* Get the buffer for the frame, it may be allocated dynamically by the rtio context */ rc = rtio_sqe_rx_buf(iodev_sqe, min_buf_len, min_buf_len, &buf, &buf_len); @@ -64,16 +64,16 @@ static void icm42688_submit_one_shot(const struct device *dev, struct rtio_iodev return; } - edata = (struct icm42688_encoded_data *)buf; + edata = (struct icm4268x_encoded_data *)buf; - rc = icm42688_encode(dev, channels, num_channels, buf); + rc = icm4268x_encode(dev, channels, num_channels, buf); if (rc != 0) { LOG_ERR("Failed to encode sensor data"); rtio_iodev_sqe_err(iodev_sqe, rc); return; } - rc = icm42688_rtio_sample_fetch(dev, edata->readings); + rc = icm4268x_rtio_sample_fetch(dev, edata->readings); /* Check that the fetch succeeded */ if (rc != 0) { LOG_ERR("Failed to fetch samples"); @@ -84,21 +84,21 @@ static void icm42688_submit_one_shot(const struct device *dev, struct rtio_iodev rtio_iodev_sqe_ok(iodev_sqe, 0); } -void icm42688_submit_sync(struct rtio_iodev_sqe *iodev_sqe) +void icm4268x_submit_sync(struct rtio_iodev_sqe *iodev_sqe) { const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; const struct device *dev = cfg->sensor; if (!cfg->is_streaming) { - icm42688_submit_one_shot(dev, iodev_sqe); - } else if (IS_ENABLED(CONFIG_ICM42688_STREAM)) { - icm42688_submit_stream(dev, iodev_sqe); + icm4268x_submit_one_shot(dev, iodev_sqe); + } else if (IS_ENABLED(CONFIG_ICM4268X_STREAM)) { + icm4268x_submit_stream(dev, iodev_sqe); } else { rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); } } -void icm42688_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +void icm4268x_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) { struct rtio_work_req *req = rtio_work_req_alloc(); @@ -109,8 +109,8 @@ void icm42688_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) return; } - rtio_work_req_submit(req, iodev_sqe, icm42688_submit_sync); + rtio_work_req_submit(req, iodev_sqe, icm4268x_submit_sync); } -BUILD_ASSERT(sizeof(struct icm42688_decoder_header) == 15, - "icm42688_decoder_header size is not equal to 15"); +BUILD_ASSERT(sizeof(struct icm4268x_decoder_header) == 15, + "icm4268x_decoder_header size is not equal to 15"); diff --git a/drivers/sensor/tdk/icm4268x/icm4268x_rtio.h b/drivers/sensor/tdk/icm4268x/icm4268x_rtio.h new file mode 100644 index 000000000000..a764a7625093 --- /dev/null +++ b/drivers/sensor/tdk/icm4268x/icm4268x_rtio.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ICM4268X_RTIO_H_ +#define ZEPHYR_DRIVERS_SENSOR_ICM4268X_RTIO_H_ + +#include +#include + +void icm4268x_submit(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe); + +void icm4268x_submit_stream(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe); + +void icm4268x_fifo_event(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_SENSOR_ICM4268X_RTIO_H_ */ diff --git a/drivers/sensor/tdk/icm42688/icm42688_rtio_stream.c b/drivers/sensor/tdk/icm4268x/icm4268x_rtio_stream.c similarity index 79% rename from drivers/sensor/tdk/icm42688/icm42688_rtio_stream.c rename to drivers/sensor/tdk/icm4268x/icm4268x_rtio_stream.c index 901b16a6ee33..fe88dd86c61d 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_rtio_stream.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x_rtio_stream.c @@ -6,18 +6,18 @@ #include #include -#include "icm42688.h" -#include "icm42688_decoder.h" -#include "icm42688_reg.h" -#include "icm42688_rtio.h" +#include "icm4268x.h" +#include "icm4268x_decoder.h" +#include "icm4268x_reg.h" +#include "icm4268x_rtio.h" -LOG_MODULE_DECLARE(ICM42688_RTIO, CONFIG_SENSOR_LOG_LEVEL); +LOG_MODULE_DECLARE(ICM4268X_RTIO, CONFIG_SENSOR_LOG_LEVEL); -void icm42688_submit_stream(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe) +void icm4268x_submit_stream(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe) { const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; - struct icm42688_dev_data *data = sensor->data; - struct icm42688_cfg new_config = data->cfg; + struct icm4268x_dev_data *data = sensor->data; + struct icm4268x_cfg new_config = data->cfg; new_config.interrupt1_drdy = false; new_config.interrupt1_fifo_ths = false; @@ -43,7 +43,7 @@ void icm42688_submit_stream(const struct device *sensor, struct rtio_iodev_sqe * if (new_config.interrupt1_drdy != data->cfg.interrupt1_drdy || new_config.interrupt1_fifo_ths != data->cfg.interrupt1_fifo_ths || new_config.interrupt1_fifo_full != data->cfg.interrupt1_fifo_full) { - int rc = icm42688_safely_configure(sensor, &new_config); + int rc = icm4268x_safely_configure(sensor, &new_config); if (rc != 0) { LOG_ERR("Failed to configure sensor"); @@ -55,11 +55,11 @@ void icm42688_submit_stream(const struct device *sensor, struct rtio_iodev_sqe * data->streaming_sqe = iodev_sqe; } -static void icm42688_complete_cb(struct rtio *r, const struct rtio_sqe *sqe, void *arg) +static void icm4268x_complete_cb(struct rtio *r, const struct rtio_sqe *sqe, void *arg) { const struct device *dev = arg; - struct icm42688_dev_data *drv_data = dev->data; - const struct icm42688_dev_cfg *drv_cfg = dev->config; + struct icm4268x_dev_data *drv_data = dev->data; + const struct icm4268x_dev_cfg *drv_cfg = dev->config; struct rtio_iodev_sqe *iodev_sqe = sqe->userdata; rtio_iodev_sqe_ok(iodev_sqe, drv_data->fifo_count); @@ -67,11 +67,11 @@ static void icm42688_complete_cb(struct rtio *r, const struct rtio_sqe *sqe, voi gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); } -static void icm42688_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, void *arg) +static void icm4268x_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, void *arg) { const struct device *dev = arg; - struct icm42688_dev_data *drv_data = dev->data; - const struct icm42688_dev_cfg *drv_cfg = dev->config; + struct icm4268x_dev_data *drv_data = dev->data; + const struct icm4268x_dev_cfg *drv_cfg = dev->config; struct rtio_iodev *spi_iodev = drv_data->spi_iodev; uint8_t *fifo_count_buf = (uint8_t *)&drv_data->fifo_count; uint16_t fifo_count = ((fifo_count_buf[0] << 8) | fifo_count_buf[1]); @@ -91,8 +91,8 @@ static void icm42688_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, v } const size_t packet_size = drv_data->cfg.fifo_hires ? 20 : 16; - const size_t min_read_size = sizeof(struct icm42688_fifo_data) + packet_size; - const size_t ideal_read_size = sizeof(struct icm42688_fifo_data) + fifo_count; + const size_t min_read_size = sizeof(struct icm4268x_fifo_data) + packet_size; + const size_t ideal_read_size = sizeof(struct icm4268x_fifo_data) + fifo_count; uint8_t *buf; uint32_t buf_len; @@ -104,15 +104,34 @@ static void icm42688_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, v LOG_DBG("Requesting buffer [%u, %u] got %u", (unsigned int)min_read_size, (unsigned int)ideal_read_size, buf_len); + /** FSR are fixed for high-resolution, at which point we should + * override driver FS config. + */ + uint8_t accel_fs_hr, gyro_fs_hr; + + switch (drv_data->cfg.variant) { + case ICM4268X_VARIANT_ICM42688: + accel_fs_hr = ICM42688_DT_ACCEL_FS_16; + gyro_fs_hr = ICM42688_DT_GYRO_FS_2000; + break; + case ICM4268X_VARIANT_ICM42686: + accel_fs_hr = ICM42686_DT_ACCEL_FS_32; + gyro_fs_hr = ICM42686_DT_GYRO_FS_4000; + break; + default: + CODE_UNREACHABLE; + } + /* Read FIFO and call back to rtio with rtio_sqe completion */ /* TODO is packet format even needed? the fifo has a header per packet * already */ - struct icm42688_fifo_data hdr = { + struct icm4268x_fifo_data hdr = { .header = { .is_fifo = true, - .gyro_fs = drv_data->cfg.gyro_fs, - .accel_fs = drv_data->cfg.accel_fs, + .variant = drv_data->cfg.variant, + .gyro_fs = drv_data->cfg.fifo_hires ? gyro_fs_hr : drv_data->cfg.gyro_fs, + .accel_fs = drv_data->cfg.fifo_hires ? accel_fs_hr : drv_data->cfg.accel_fs, .timestamp = drv_data->timestamp, .axis_align[0] = drv_data->cfg.axis_align[0], .axis_align[1] = drv_data->cfg.axis_align[1], @@ -132,7 +151,7 @@ static void icm42688_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, v uint32_t pkts = read_len / packet_size; read_len = pkts * packet_size; - ((struct icm42688_fifo_data *)buf)->fifo_count = read_len; + ((struct icm4268x_fifo_data *)buf)->fifo_count = read_len; __ASSERT_NO_MSG(read_len % packet_size == 0); @@ -164,13 +183,13 @@ static void icm42688_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, v rtio_sqe_prep_read(read_fifo_data, spi_iodev, RTIO_PRIO_NORM, read_buf, read_len, iodev_sqe); read_fifo_data->flags = RTIO_SQE_CHAINED; - rtio_sqe_prep_callback(complete_op, icm42688_complete_cb, (void *)dev, iodev_sqe); + rtio_sqe_prep_callback(complete_op, icm4268x_complete_cb, (void *)dev, iodev_sqe); rtio_submit(r, 0); } static struct sensor_stream_trigger * -icm42688_get_read_config_trigger(const struct sensor_read_config *cfg, +icm4268x_get_read_config_trigger(const struct sensor_read_config *cfg, enum sensor_trigger_type trig) { for (int i = 0; i < cfg->count; ++i) { @@ -182,11 +201,11 @@ icm42688_get_read_config_trigger(const struct sensor_read_config *cfg, return NULL; } -static void icm42688_int_status_cb(struct rtio *r, const struct rtio_sqe *sqr, void *arg) +static void icm4268x_int_status_cb(struct rtio *r, const struct rtio_sqe *sqr, void *arg) { const struct device *dev = arg; - struct icm42688_dev_data *drv_data = dev->data; - const struct icm42688_dev_cfg *drv_cfg = dev->config; + struct icm4268x_dev_data *drv_data = dev->data; + const struct icm4268x_dev_cfg *drv_cfg = dev->config; struct rtio_iodev *spi_iodev = drv_data->spi_iodev; struct rtio_iodev_sqe *streaming_sqe = drv_data->streaming_sqe; struct sensor_read_config *read_config; @@ -204,12 +223,12 @@ static void icm42688_int_status_cb(struct rtio *r, const struct rtio_sqe *sqr, v } struct sensor_stream_trigger *fifo_ths_cfg = - icm42688_get_read_config_trigger(read_config, SENSOR_TRIG_FIFO_WATERMARK); + icm4268x_get_read_config_trigger(read_config, SENSOR_TRIG_FIFO_WATERMARK); bool has_fifo_ths_trig = fifo_ths_cfg != NULL && FIELD_GET(BIT_FIFO_THS_INT, drv_data->int_status) != 0; struct sensor_stream_trigger *fifo_full_cfg = - icm42688_get_read_config_trigger(read_config, SENSOR_TRIG_FIFO_FULL); + icm4268x_get_read_config_trigger(read_config, SENSOR_TRIG_FIFO_FULL); bool has_fifo_full_trig = fifo_full_cfg != NULL && FIELD_GET(BIT_FIFO_FULL_INT, drv_data->int_status) != 0; @@ -248,13 +267,13 @@ static void icm42688_int_status_cb(struct rtio *r, const struct rtio_sqe *sqr, v /* Clear streaming_sqe since we're done with the call */ drv_data->streaming_sqe = NULL; - if (rtio_sqe_rx_buf(streaming_sqe, sizeof(struct icm42688_fifo_data), - sizeof(struct icm42688_fifo_data), &buf, &buf_len) != 0) { + if (rtio_sqe_rx_buf(streaming_sqe, sizeof(struct icm4268x_fifo_data), + sizeof(struct icm4268x_fifo_data), &buf, &buf_len) != 0) { rtio_iodev_sqe_err(streaming_sqe, -ENOMEM); return; } - struct icm42688_fifo_data *data = (struct icm42688_fifo_data *)buf; + struct icm4268x_fifo_data *data = (struct icm4268x_fifo_data *)buf; memset(buf, 0, buf_len); data->header.timestamp = drv_data->timestamp; @@ -290,14 +309,14 @@ static void icm42688_int_status_cb(struct rtio *r, const struct rtio_sqe *sqr, v write_fifo_count_reg->flags = RTIO_SQE_TRANSACTION; rtio_sqe_prep_read(read_fifo_count, spi_iodev, RTIO_PRIO_NORM, read_buf, 2, NULL); read_fifo_count->flags = RTIO_SQE_CHAINED; - rtio_sqe_prep_callback(check_fifo_count, icm42688_fifo_count_cb, arg, NULL); + rtio_sqe_prep_callback(check_fifo_count, icm4268x_fifo_count_cb, arg, NULL); rtio_submit(r, 0); } -void icm42688_fifo_event(const struct device *dev) +void icm4268x_fifo_event(const struct device *dev) { - struct icm42688_dev_data *drv_data = dev->data; + struct icm4268x_dev_data *drv_data = dev->data; struct rtio_iodev *spi_iodev = drv_data->spi_iodev; struct rtio *r = drv_data->r; uint64_t cycles; @@ -334,6 +353,6 @@ void icm42688_fifo_event(const struct device *dev) write_int_reg->flags = RTIO_SQE_TRANSACTION; rtio_sqe_prep_read(read_int_reg, spi_iodev, RTIO_PRIO_NORM, &drv_data->int_status, 1, NULL); read_int_reg->flags = RTIO_SQE_CHAINED; - rtio_sqe_prep_callback(check_int_status, icm42688_int_status_cb, (void *)dev, NULL); + rtio_sqe_prep_callback(check_int_status, icm4268x_int_status_cb, (void *)dev, NULL); rtio_submit(r, 0); } diff --git a/drivers/sensor/tdk/icm42688/icm42688_spi.c b/drivers/sensor/tdk/icm4268x/icm4268x_spi.c similarity index 80% rename from drivers/sensor/tdk/icm42688/icm42688_spi.c rename to drivers/sensor/tdk/icm4268x/icm4268x_spi.c index dedaf56c034f..aed4f09d3875 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_spi.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x_spi.c @@ -5,8 +5,8 @@ */ #include -#include "icm42688_spi.h" -#include "icm42688_reg.h" +#include "icm4268x_spi.h" +#include "icm4268x_reg.h" static inline int spi_write_register(const struct spi_dt_spec *bus, uint8_t reg, uint8_t data) { @@ -63,7 +63,7 @@ static inline int spi_read_register(const struct spi_dt_spec *bus, uint8_t reg, return spi_transceive_dt(bus, &tx, &rx); } -int icm42688_spi_read(const struct spi_dt_spec *bus, uint16_t reg, uint8_t *data, size_t len) +int icm4268x_spi_read(const struct spi_dt_spec *bus, uint16_t reg, uint8_t *data, size_t len) { int res = 0; uint8_t address = FIELD_GET(REG_ADDRESS_MASK, reg); @@ -73,11 +73,11 @@ int icm42688_spi_read(const struct spi_dt_spec *bus, uint16_t reg, uint8_t *data return res; } -int icm42688_spi_update_register(const struct spi_dt_spec *bus, uint16_t reg, uint8_t mask, +int icm4268x_spi_update_register(const struct spi_dt_spec *bus, uint16_t reg, uint8_t mask, uint8_t data) { uint8_t temp = 0; - int res = icm42688_spi_read(bus, reg, &temp, 1); + int res = icm4268x_spi_read(bus, reg, &temp, 1); if (res) { return res; @@ -86,10 +86,10 @@ int icm42688_spi_update_register(const struct spi_dt_spec *bus, uint16_t reg, ui temp &= ~mask; temp |= FIELD_PREP(mask, data); - return icm42688_spi_single_write(bus, reg, temp); + return icm4268x_spi_single_write(bus, reg, temp); } -int icm42688_spi_single_write(const struct spi_dt_spec *bus, uint16_t reg, uint8_t data) +int icm4268x_spi_single_write(const struct spi_dt_spec *bus, uint16_t reg, uint8_t data) { int res = 0; uint8_t address = FIELD_GET(REG_ADDRESS_MASK, reg); diff --git a/drivers/sensor/tdk/icm42688/icm42688_spi.h b/drivers/sensor/tdk/icm4268x/icm4268x_spi.h similarity index 61% rename from drivers/sensor/tdk/icm42688/icm42688_spi.h rename to drivers/sensor/tdk/icm4268x/icm4268x_spi.h index ea0a0006dcbd..2985b9166b88 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_spi.h +++ b/drivers/sensor/tdk/icm4268x/icm4268x_spi.h @@ -4,52 +4,52 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_DRIVERS_SENSOR_ICM42688_SPI_H_ -#define ZEPHYR_DRIVERS_SENSOR_ICM42688_SPI_H_ +#ifndef ZEPHYR_DRIVERS_SENSOR_ICM4268X_SPI_H_ +#define ZEPHYR_DRIVERS_SENSOR_ICM4268X_SPI_H_ #include #include /** - * @brief perform a single SPI write to a ICM42688 register + * @brief perform a single SPI write to a ICM4268X register * - * this functions wraps all logic necessary to write to any of the ICM42688 registers, regardless + * this functions wraps all logic necessary to write to any of the ICM4268X registers, regardless * of which memory bank the register belongs to. * * @param bus SPI bus pointer - * @param reg address of ICM42688 register to write to + * @param reg address of ICM4268X register to write to * @param data data byte to write to register * @return int 0 on success, negative error code otherwise */ -int icm42688_spi_single_write(const struct spi_dt_spec *bus, uint16_t reg, uint8_t data); +int icm4268x_spi_single_write(const struct spi_dt_spec *bus, uint16_t reg, uint8_t data); /** - * @brief update a single ICM42688 register value + * @brief update a single ICM4268X register value * - * this functions wraps all logic necessary to update any of the ICM42688 registers, regardless + * this functions wraps all logic necessary to update any of the ICM4268X registers, regardless * of which memory bank the register belongs to. * * @param bus SPI bus pointer - * @param reg address of ICM42688 register to update + * @param reg address of ICM4268X register to update * @param mask bitmask defining which bits of the register to update * @param data new value to update register with, respecting the bitmask * @return int 0 on success, negative error code otherwise */ -int icm42688_spi_update_register(const struct spi_dt_spec *bus, uint16_t reg, uint8_t mask, +int icm4268x_spi_update_register(const struct spi_dt_spec *bus, uint16_t reg, uint8_t mask, uint8_t data); /** - * @brief read from one or more ICM42688 registers + * @brief read from one or more ICM4268X registers * - * this functions wraps all logic necessary to read from any of the ICM42688 registers, regardless + * this functions wraps all logic necessary to read from any of the ICM4268X registers, regardless * of which memory bank the register belongs to. * * @param bus SPI bus pointer - * @param reg start address of ICM42688 register(s) to read from + * @param reg start address of ICM4268X register(s) to read from * @param data pointer to byte array to read register values to * @param len number of bytes to read from the device * @return int 0 on success, negative error code otherwise */ -int icm42688_spi_read(const struct spi_dt_spec *bus, uint16_t reg, uint8_t *data, size_t len); +int icm4268x_spi_read(const struct spi_dt_spec *bus, uint16_t reg, uint8_t *data, size_t len); -#endif /* ZEPHYR_DRIVERS_SENSOR_ICM42688_SPI_H_ */ +#endif /* ZEPHYR_DRIVERS_SENSOR_ICM4268X_SPI_H_ */ diff --git a/drivers/sensor/tdk/icm42688/icm42688_trigger.c b/drivers/sensor/tdk/icm4268x/icm4268x_trigger.c similarity index 51% rename from drivers/sensor/tdk/icm42688/icm42688_trigger.c rename to drivers/sensor/tdk/icm4268x/icm4268x_trigger.c index 72ccd7e9059e..cbbd6b9205e1 100644 --- a/drivers/sensor/tdk/icm42688/icm42688_trigger.c +++ b/drivers/sensor/tdk/icm4268x/icm4268x_trigger.c @@ -10,78 +10,78 @@ #include #include -#include "icm42688.h" -#include "icm42688_reg.h" -#include "icm42688_rtio.h" -#include "icm42688_spi.h" -#include "icm42688_trigger.h" +#include "icm4268x.h" +#include "icm4268x_reg.h" +#include "icm4268x_rtio.h" +#include "icm4268x_spi.h" +#include "icm4268x_trigger.h" -LOG_MODULE_DECLARE(ICM42688, CONFIG_SENSOR_LOG_LEVEL); +LOG_MODULE_DECLARE(ICM4268X, CONFIG_SENSOR_LOG_LEVEL); -static void icm42688_gpio_callback(const struct device *dev, struct gpio_callback *cb, +static void icm4268x_gpio_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { - struct icm42688_dev_data *data = CONTAINER_OF(cb, struct icm42688_dev_data, gpio_cb); + struct icm4268x_dev_data *data = CONTAINER_OF(cb, struct icm4268x_dev_data, gpio_cb); ARG_UNUSED(dev); ARG_UNUSED(pins); -#if defined(CONFIG_ICM42688_TRIGGER_OWN_THREAD) +#if defined(CONFIG_ICM4268X_TRIGGER_OWN_THREAD) k_sem_give(&data->gpio_sem); -#elif defined(CONFIG_ICM42688_TRIGGER_GLOBAL_THREAD) +#elif defined(CONFIG_ICM4268X_TRIGGER_GLOBAL_THREAD) k_work_submit(&data->work); #endif - if (IS_ENABLED(CONFIG_ICM42688_STREAM)) { - icm42688_fifo_event(data->dev); + if (IS_ENABLED(CONFIG_ICM4268X_STREAM)) { + icm4268x_fifo_event(data->dev); } } -#if defined(CONFIG_ICM42688_TRIGGER_OWN_THREAD) || defined(CONFIG_ICM42688_TRIGGER_GLOBAL_THREAD) -static void icm42688_thread_cb(const struct device *dev) +#if defined(CONFIG_ICM4268X_TRIGGER_OWN_THREAD) || defined(CONFIG_ICM4268X_TRIGGER_GLOBAL_THREAD) +static void icm4268x_thread_cb(const struct device *dev) { - struct icm42688_dev_data *data = dev->data; + struct icm4268x_dev_data *data = dev->data; - icm42688_lock(dev); + icm4268x_lock(dev); if (data->data_ready_handler != NULL) { data->data_ready_handler(dev, data->data_ready_trigger); } - icm42688_unlock(dev); + icm4268x_unlock(dev); } #endif -#ifdef CONFIG_ICM42688_TRIGGER_OWN_THREAD +#ifdef CONFIG_ICM4268X_TRIGGER_OWN_THREAD -static void icm42688_thread(void *p1, void *p2, void *p3) +static void icm4268x_thread(void *p1, void *p2, void *p3) { ARG_UNUSED(p2); ARG_UNUSED(p3); - struct icm42688_dev_data *data = p1; + struct icm4268x_dev_data *data = p1; while (1) { k_sem_take(&data->gpio_sem, K_FOREVER); - icm42688_thread_cb(data->dev); + icm4268x_thread_cb(data->dev); } } -#elif defined(CONFIG_ICM42688_TRIGGER_GLOBAL_THREAD) +#elif defined(CONFIG_ICM4268X_TRIGGER_GLOBAL_THREAD) -static void icm42688_work_handler(struct k_work *work) +static void icm4268x_work_handler(struct k_work *work) { - struct icm42688_dev_data *data = CONTAINER_OF(work, struct icm42688_dev_data, work); + struct icm4268x_dev_data *data = CONTAINER_OF(work, struct icm4268x_dev_data, work); - icm42688_thread_cb(data->dev); + icm4268x_thread_cb(data->dev); } #endif -int icm42688_trigger_set(const struct device *dev, const struct sensor_trigger *trig, +int icm4268x_trigger_set(const struct device *dev, const struct sensor_trigger *trig, sensor_trigger_handler_t handler) { - struct icm42688_dev_data *data = dev->data; - const struct icm42688_dev_cfg *cfg = dev->config; + struct icm4268x_dev_data *data = dev->data; + const struct icm4268x_dev_cfg *cfg = dev->config; uint8_t status; int res = 0; @@ -89,7 +89,7 @@ int icm42688_trigger_set(const struct device *dev, const struct sensor_trigger * return -EINVAL; } - icm42688_lock(dev); + icm4268x_lock(dev); gpio_pin_interrupt_configure_dt(&cfg->gpio_int1, GPIO_INT_DISABLE); switch (trig->type) { @@ -99,23 +99,23 @@ int icm42688_trigger_set(const struct device *dev, const struct sensor_trigger * data->data_ready_handler = handler; data->data_ready_trigger = trig; - res = icm42688_spi_read(&cfg->spi, REG_INT_STATUS, &status, 1); + res = icm4268x_spi_read(&cfg->spi, REG_INT_STATUS, &status, 1); break; default: res = -ENOTSUP; break; } - icm42688_unlock(dev); + icm4268x_unlock(dev); gpio_pin_interrupt_configure_dt(&cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); return res; } -int icm42688_trigger_init(const struct device *dev) +int icm4268x_trigger_init(const struct device *dev) { - struct icm42688_dev_data *data = dev->data; - const struct icm42688_dev_cfg *cfg = dev->config; + struct icm4268x_dev_data *data = dev->data; + const struct icm4268x_dev_cfg *cfg = dev->config; int res = 0; if (!cfg->gpio_int1.port) { @@ -130,7 +130,7 @@ int icm42688_trigger_init(const struct device *dev) data->dev = dev; gpio_pin_configure_dt(&cfg->gpio_int1, GPIO_INPUT); - gpio_init_callback(&data->gpio_cb, icm42688_gpio_callback, BIT(cfg->gpio_int1.pin)); + gpio_init_callback(&data->gpio_cb, icm4268x_gpio_callback, BIT(cfg->gpio_int1.pin)); res = gpio_add_callback(cfg->gpio_int1.port, &data->gpio_cb); if (res < 0) { @@ -139,31 +139,31 @@ int icm42688_trigger_init(const struct device *dev) } k_mutex_init(&data->mutex); -#if defined(CONFIG_ICM42688_TRIGGER_OWN_THREAD) +#if defined(CONFIG_ICM4268X_TRIGGER_OWN_THREAD) k_sem_init(&data->gpio_sem, 0, K_SEM_MAX_LIMIT); - k_thread_create(&data->thread, data->thread_stack, CONFIG_ICM42688_THREAD_STACK_SIZE, - icm42688_thread, data, NULL, NULL, - K_PRIO_COOP(CONFIG_ICM42688_THREAD_PRIORITY), 0, K_NO_WAIT); -#elif defined(CONFIG_ICM42688_TRIGGER_GLOBAL_THREAD) - data->work.handler = icm42688_work_handler; + k_thread_create(&data->thread, data->thread_stack, CONFIG_ICM4268X_THREAD_STACK_SIZE, + icm4268x_thread, data, NULL, NULL, + K_PRIO_COOP(CONFIG_ICM4268X_THREAD_PRIORITY), 0, K_NO_WAIT); +#elif defined(CONFIG_ICM4268X_TRIGGER_GLOBAL_THREAD) + data->work.handler = icm4268x_work_handler; #endif return gpio_pin_interrupt_configure_dt(&cfg->gpio_int1, GPIO_INT_EDGE_TO_ACTIVE); } -int icm42688_trigger_enable_interrupt(const struct device *dev, struct icm42688_cfg *new_cfg) +int icm4268x_trigger_enable_interrupt(const struct device *dev, struct icm4268x_cfg *new_cfg) { int res; - const struct icm42688_dev_cfg *cfg = dev->config; + const struct icm4268x_dev_cfg *cfg = dev->config; /* pulse-mode (auto clearing), push-pull and active-high */ - res = icm42688_spi_single_write(&cfg->spi, REG_INT_CONFIG, + res = icm4268x_spi_single_write(&cfg->spi, REG_INT_CONFIG, BIT_INT1_DRIVE_CIRCUIT | BIT_INT1_POLARITY); if (res != 0) { return res; } /* Deassert async reset for proper INT pin operation, see datasheet 14.50 */ - res = icm42688_spi_single_write(&cfg->spi, REG_INT_CONFIG1, 0); + res = icm4268x_spi_single_write(&cfg->spi, REG_INT_CONFIG1, 0); if (res != 0) { return res; } @@ -180,19 +180,19 @@ int icm42688_trigger_enable_interrupt(const struct device *dev, struct icm42688_ if (new_cfg->interrupt1_fifo_full) { value |= FIELD_PREP(BIT_FIFO_FULL_INT1_EN, 1); } - return icm42688_spi_single_write(&cfg->spi, REG_INT_SOURCE0, value); + return icm4268x_spi_single_write(&cfg->spi, REG_INT_SOURCE0, value); } -void icm42688_lock(const struct device *dev) +void icm4268x_lock(const struct device *dev) { - struct icm42688_dev_data *data = dev->data; + struct icm4268x_dev_data *data = dev->data; k_mutex_lock(&data->mutex, K_FOREVER); } -void icm42688_unlock(const struct device *dev) +void icm4268x_unlock(const struct device *dev) { - struct icm42688_dev_data *data = dev->data; + struct icm4268x_dev_data *data = dev->data; k_mutex_unlock(&data->mutex); } diff --git a/drivers/sensor/tdk/icm4268x/icm4268x_trigger.h b/drivers/sensor/tdk/icm4268x/icm4268x_trigger.h new file mode 100644 index 000000000000..894fae4f3e14 --- /dev/null +++ b/drivers/sensor/tdk/icm4268x/icm4268x_trigger.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 Intel Corporation + * Copyright (c) 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_ICM4268X_TRIGGER_H_ +#define ZEPHYR_DRIVERS_SENSOR_ICM4268X_TRIGGER_H_ + +#include + +/** implement the trigger_set sensor api function */ +int icm4268x_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler); + +/** + * @brief initialize the icm4268x trigger system + * + * @param dev icm4268x device pointer + * @return int 0 on success, negative error code otherwise + */ +int icm4268x_trigger_init(const struct device *dev); + +/** + * @brief enable the trigger gpio interrupt + * + * @param dev icm4268x device pointer + * @param new_cfg New configuration to use for the device + * @return int 0 on success, negative error code otherwise + */ +int icm4268x_trigger_enable_interrupt(const struct device *dev, struct icm4268x_cfg *new_cfg); + +/** + * @brief lock access to the icm4268x device driver + * + * @param dev icm4268x device pointer + */ +void icm4268x_lock(const struct device *dev); + +/** + * @brief lock access to the icm4268x device driver + * + * @param dev icm4268x device pointer + */ +void icm4268x_unlock(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_SENSOR_ICM4268X_TRIGGER_H_ */ diff --git a/dts/bindings/sensor/invensense,icm42686.yaml b/dts/bindings/sensor/invensense,icm42686.yaml new file mode 100644 index 000000000000..422d4a09a1e8 --- /dev/null +++ b/dts/bindings/sensor/invensense,icm42686.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Intel Corporation +# Copyright (c) 2022 Esco Medical ApS +# Copyright (c) 2020 TDK Invensense +# Copyright (c) 2025 Croxel, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + ICM-42686 motion tracking device. + + When setting the accel-pm, accel-range, accel-odr, gyro-pm, gyro-range, + gyro-odr properties in a .dts or .dtsi file you may include icm42686.h + and use the macros defined there. + + Example: + #include + + icm42686: icm42686@0 { + compatible = "invensense,icm42686", "invensense,icm4268x" + ... + + accel-pwr-mode = ; + accel-fs = ; + accel-odr = ; + gyro-pwr-mode= ; + gyro-fs = ; + gyro-odr = ; + }; +compatible: "invensense,icm42686" +include: ["invensense,icm4268x.yaml"] diff --git a/dts/bindings/sensor/invensense,icm42688.yaml b/dts/bindings/sensor/invensense,icm42688.yaml index eb1410bd4ee1..50e56bf103bb 100644 --- a/dts/bindings/sensor/invensense,icm42688.yaml +++ b/dts/bindings/sensor/invensense,icm42688.yaml @@ -1,6 +1,7 @@ # Copyright (c) 2024 Intel Corporation # Copyright (c) 2022 Esco Medical ApS # Copyright (c) 2020 TDK Invensense +# Copyright (c) 2025 Croxel, Inc. # SPDX-License-Identifier: Apache-2.0 description: | @@ -14,6 +15,7 @@ description: | #include icm42688: icm42688@0 { + compatible = "invensense,icm42688", "invensense,icm4268x" ... accel-pwr-mode = ; @@ -24,110 +26,4 @@ description: | gyro-odr = ; }; compatible: "invensense,icm42688" -include: [sensor-axis-align.yaml, sensor-device.yaml, spi-device.yaml] - -properties: - int-gpios: - type: phandle-array - description: | - The INT signal default configuration is active-high. The - property value should ensure the flags properly describe the - signal that is presented to the driver. - - accel-pwr-mode: - type: int - default: 0 - description: | - Specify the default accelerometer power mode. - Default is power-up configuration. - enum: - - 0 # ICM42688_DT_ACCEL_OFF - - 2 # ICM42688_DT_ACCEL_LP - - 3 # ICM42688_DT_ACCEL_LN - - accel-odr: - type: int - default: 6 - description: | - Specify the default accelerometer output data rate expressed in samples per second (Hz). - Default is power-up configuration. - enum: - - 1 # ICM42688_DT_ACCEL_ODR_32000 - - 2 # ICM42688_DT_ACCEL_ODR_16000 - - 3 # ICM42688_DT_ACCEL_ODR_8000 - - 4 # ICM42688_DT_ACCEL_ODR_4000 - - 5 # ICM42688_DT_ACCEL_ODR_2000 - - 6 # ICM42688_DT_ACCEL_ODR_1000 - - 7 # ICM42688_DT_ACCEL_ODR_200 - - 8 # ICM42688_DT_ACCEL_ODR_100 - - 9 # ICM42688_DT_ACCEL_ODR_50 - - 10 # ICM42688_DT_ACCEL_ODR_25 - - 11 # ICM42688_DT_ACCEL_ODR_12_5 - - 12 # ICM42688_DT_ACCEL_ODR_6_25 - - 13 # ICM42688_DT_ACCEL_ODR_3_125 - - 14 # ICM42688_DT_ACCEL_ODR_1_5625 - - 15 # ICM42688_DT_ACCEL_ODR_500 - - accel-fs: - type: int - default: 0 - description: | - Specify the accelerometer range in g. - Default is power-up configuration. - enum: - - 0 # ICM42688_DT_ACCEL_FS_16 - - 1 # ICM42688_DT_ACCEL_FS_8 - - 2 # ICM42688_DT_ACCEL_FS_4 - - 3 # ICM42688_DT_ACCEL_FS_2 - - gyro-pwr-mode: - type: int - default: 0 - description: | - Specify the default gyro power mode. - Default is power-up configuration. - enum: - - 0 # ICM42688_DT_GYRO_OFF - - 1 # ICM42688_DT_GYRO_STANDBY - - 3 # ICM42688_DT_GYRO_LN - - gyro-odr: - type: int - default: 6 - description: | - Specify the default gyro output data rate expressed in samples per second (Hz). - Default is power-up configuration. - enum: - - 1 # ICM42688_DT_GYRO_ODR_32000 - - 2 # ICM42688_DT_GYRO_ODR_16000 - - 3 # ICM42688_DT_GYRO_ODR_8000 - - 4 # ICM42688_DT_GYRO_ODR_4000 - - 5 # ICM42688_DT_GYRO_ODR_2000 - - 6 # ICM42688_DT_GYRO_ODR_1000 - - 7 # ICM42688_DT_GYRO_ODR_200 - - 8 # ICM42688_DT_GYRO_ODR_100 - - 9 # ICM42688_DT_GYRO_ODR_50 - - 10 # ICM42688_DT_GYRO_ODR_25 - - 11 # ICM42688_DT_GYRO_ODR_12_5 - - 15 # ICM42688_DT_GYRO_ODR_500 - - gyro-fs: - type: int - default: 0 - description: | - Specify the gyro range in degrees per second. - Default is power-up configuration. - enum: - - 0 # ICM42688_DT_GYRO_FS_2000 - - 1 # ICM42688_DT_GYRO_FS_1000 - - 2 # ICM42688_DT_GYRO_FS_500 - - 3 # ICM42688_DT_GYRO_FS_250 - - 4 # ICM42688_DT_GYRO_FS_125 - - 5 # ICM42688_DT_GYRO_FS_62_5 - - 6 # ICM42688_DT_GYRO_FS_31_25 - - 7 # ICM42688_DT_GYRO_FS_15_625 - - fifo-hires: - type: boolean - description: | - Enables hires for fifo +include: ["invensense,icm4268x.yaml"] diff --git a/dts/bindings/sensor/invensense,icm4268x.yaml b/dts/bindings/sensor/invensense,icm4268x.yaml new file mode 100644 index 000000000000..20a109fbc3c0 --- /dev/null +++ b/dts/bindings/sensor/invensense,icm4268x.yaml @@ -0,0 +1,112 @@ +# Copyright (c) 2025 Croxel, Inc. +# SPDX-License-Identifier: Apache-2.0 + +compatible: "invensense,icm4268x" +include: [sensor-axis-align.yaml, sensor-device.yaml, spi-device.yaml] + +properties: + int-gpios: + type: phandle-array + description: | + The INT signal default configuration is active-high. The + property value should ensure the flags properly describe the + signal that is presented to the driver. + + accel-pwr-mode: + type: int + default: 0 + description: | + Specify the default accelerometer power mode. + Default is power-up configuration. + enum: + - 0 # ICM4268X_DT_ACCEL_OFF + - 2 # ICM4268X_DT_ACCEL_LP + - 3 # ICM4268X_DT_ACCEL_LN + + accel-odr: + type: int + default: 6 + description: | + Specify the default accelerometer output data rate expressed in samples per second (Hz). + Default is power-up configuration. + enum: + - 1 # ICM4268X_DT_ACCEL_ODR_32000 + - 2 # ICM4268X_DT_ACCEL_ODR_16000 + - 3 # ICM4268X_DT_ACCEL_ODR_8000 + - 4 # ICM4268X_DT_ACCEL_ODR_4000 + - 5 # ICM4268X_DT_ACCEL_ODR_2000 + - 6 # ICM4268X_DT_ACCEL_ODR_1000 + - 7 # ICM4268X_DT_ACCEL_ODR_200 + - 8 # ICM4268X_DT_ACCEL_ODR_100 + - 9 # ICM4268X_DT_ACCEL_ODR_50 + - 10 # ICM4268X_DT_ACCEL_ODR_25 + - 11 # ICM4268X_DT_ACCEL_ODR_12_5 + - 12 # ICM4268X_DT_ACCEL_ODR_6_25 + - 13 # ICM4268X_DT_ACCEL_ODR_3_125 + - 14 # ICM4268X_DT_ACCEL_ODR_1_5625 + - 15 # ICM4268X_DT_ACCEL_ODR_500 + + accel-fs: + type: int + default: 0 + description: | + Specify the accelerometer range in g. + Default is power-up configuration. + enum: + - 0 # ICM42686_DT_ACCEL_FS_32 | ICM42688_DT_ACCEL_FS_16 + - 1 # ICM42686_DT_ACCEL_FS_16 | ICM42688_DT_ACCEL_FS_8 + - 2 # ICM42686_DT_ACCEL_FS_8 | ICM42688_DT_ACCEL_FS_4 + - 3 # ICM42686_DT_ACCEL_FS_4 | ICM42688_DT_ACCEL_FS_2 + - 4 # ICM42686_DT_ACCEL_FS_2 + + gyro-pwr-mode: + type: int + default: 0 + description: | + Specify the default gyro power mode. + Default is power-up configuration. + enum: + - 0 # ICM4268X_DT_GYRO_OFF + - 1 # ICM4268X_DT_GYRO_STANDBY + - 3 # ICM4268X_DT_GYRO_LN + + gyro-odr: + type: int + default: 6 + description: | + Specify the default gyro output data rate expressed in samples per second (Hz). + Default is power-up configuration. + enum: + - 1 # ICM4268X_DT_GYRO_ODR_32000 + - 2 # ICM4268X_DT_GYRO_ODR_16000 + - 3 # ICM4268X_DT_GYRO_ODR_8000 + - 4 # ICM4268X_DT_GYRO_ODR_4000 + - 5 # ICM4268X_DT_GYRO_ODR_2000 + - 6 # ICM4268X_DT_GYRO_ODR_1000 + - 7 # ICM4268X_DT_GYRO_ODR_200 + - 8 # ICM4268X_DT_GYRO_ODR_100 + - 9 # ICM4268X_DT_GYRO_ODR_50 + - 10 # ICM4268X_DT_GYRO_ODR_25 + - 11 # ICM4268X_DT_GYRO_ODR_12_5 + - 15 # ICM4268X_DT_GYRO_ODR_500 + + gyro-fs: + type: int + default: 0 + description: | + Specify the gyro range in degrees per second. + Default is power-up configuration. + enum: + - 0 # ICM42686_DT_GYRO_FS_4000 | ICM42688_DT_GYRO_FS_2000 + - 1 # ICM42686_DT_GYRO_FS_2000 | ICM42688_DT_GYRO_FS_1000 + - 2 # ICM42686_DT_GYRO_FS_1000 | ICM42688_DT_GYRO_FS_500 + - 3 # ICM42686_DT_GYRO_FS_500 | ICM42688_DT_GYRO_FS_250 + - 4 # ICM42686_DT_GYRO_FS_250 | ICM42688_DT_GYRO_FS_125 + - 5 # ICM42686_DT_GYRO_FS_125 | ICM42688_DT_GYRO_FS_62_5 + - 6 # ICM42686_DT_GYRO_FS_62_5 | ICM42688_DT_GYRO_FS_31_25 + - 7 # ICM42686_DT_GYRO_FS_31_25 | ICM42688_DT_GYRO_FS_15_625 + + fifo-hires: + type: boolean + description: | + Enables hires for fifo diff --git a/include/zephyr/drivers/sensor/icm42688.h b/include/zephyr/drivers/sensor/icm42688.h deleted file mode 100644 index da9c00528fe4..000000000000 --- a/include/zephyr/drivers/sensor/icm42688.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright The Zephyr Project Contributors - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_ICM42688_H_ -#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_ICM42688_H_ - -#include - -/** - * @file - * @brief Extended public API for ICM42688 - * - * Pin function configuration via attributes under the current sensor driver abstraction. - */ - -#define ICM42688_PIN9_FUNCTION_INT2 0 -#define ICM42688_PIN9_FUNCTION_FSYNC 1 -#define ICM42688_PIN9_FUNCTION_CLKIN 2 - -/** - * @brief Extended sensor attributes for ICM42688 - * - * Attributes for setting pin function. - */ -enum sensor_attribute_icm42688 { - SENSOR_ATTR_ICM42688_PIN9_FUNCTION = SENSOR_ATTR_PRIV_START -}; - -#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_ICM42688_H_ */ diff --git a/include/zephyr/drivers/sensor/icm4268x.h b/include/zephyr/drivers/sensor/icm4268x.h new file mode 100644 index 000000000000..427a64d941b8 --- /dev/null +++ b/include/zephyr/drivers/sensor/icm4268x.h @@ -0,0 +1,32 @@ +/* + * Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_ICM4268X_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_ICM4268X_H_ + +#include + +/** + * @file + * @brief Extended public API for ICM4268X + * + * Pin function configuration via attributes under the current sensor driver abstraction. + */ + +#define ICM4268X_PIN9_FUNCTION_INT2 0 +#define ICM4268X_PIN9_FUNCTION_FSYNC 1 +#define ICM4268X_PIN9_FUNCTION_CLKIN 2 + +/** + * @brief Extended sensor attributes for ICM4268X + * + * Attributes for setting pin function. + */ +enum sensor_attribute_icm4268x { + SENSOR_ATTR_ICM4268X_PIN9_FUNCTION = SENSOR_ATTR_PRIV_START +}; + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_ICM4268X_H_ */ diff --git a/include/zephyr/dt-bindings/sensor/icm42686.h b/include/zephyr/dt-bindings/sensor/icm42686.h new file mode 100644 index 000000000000..62994cf0cb43 --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/icm42686.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2024 Intel Corporation + * Copyright (c) 2025 Croxel, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_TDK_ICM42686P_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_TDK_ICM42686P_H_ + +#include "icm4268x.h" + +/** + * @defgroup ICM42686 Invensense (TDK) ICM42686 DT Options + * @ingroup sensor_interface + * @{ + */ + +/** + * @defgroup ICM42686_ACCEL_POWER_MODES Accelerometer power modes + * @{ + */ +#define ICM42686_DT_ACCEL_OFF ICM4268X_DT_ACCEL_OFF +#define ICM42686_DT_ACCEL_LP ICM4268X_DT_ACCEL_LP +#define ICM42686_DT_ACCEL_LN ICM4268X_DT_ACCEL_LN +/** @} */ + +/** + * @defgroup ICM42686_GYRO_POWER_MODES Gyroscope power modes + * @{ + */ +#define ICM42686_DT_GYRO_OFF ICM4268X_DT_GYRO_OFF +#define ICM42686_DT_GYRO_STANDBY ICM4268X_DT_GYRO_STANDBY +#define ICM42686_DT_GYRO_LN ICM4268X_DT_GYRO_LN +/** @} */ + +/** + * @defgroup ICM42686_ACCEL_SCALE Accelerometer scale options + * @{ + */ +#define ICM42686_DT_ACCEL_FS_32 0 +#define ICM42686_DT_ACCEL_FS_16 1 +#define ICM42686_DT_ACCEL_FS_8 2 +#define ICM42686_DT_ACCEL_FS_4 3 +#define ICM42686_DT_ACCEL_FS_2 4 +/** @} */ + +/** + * @defgroup ICM42686_GYRO_SCALE Gyroscope scale options + * @{ + */ +#define ICM42686_DT_GYRO_FS_4000 0 +#define ICM42686_DT_GYRO_FS_2000 1 +#define ICM42686_DT_GYRO_FS_1000 2 +#define ICM42686_DT_GYRO_FS_500 3 +#define ICM42686_DT_GYRO_FS_250 4 +#define ICM42686_DT_GYRO_FS_125 5 +#define ICM42686_DT_GYRO_FS_62_5 6 +#define ICM42686_DT_GYRO_FS_31_25 7 +/** @} */ + +/** + * @defgroup ICM42686_ACCEL_DATA_RATE Accelerometer data rate options + * @{ + */ +#define ICM42686_DT_ACCEL_ODR_32000 ICM4268X_DT_ACCEL_ODR_32000 +#define ICM42686_DT_ACCEL_ODR_16000 ICM4268X_DT_ACCEL_ODR_16000 +#define ICM42686_DT_ACCEL_ODR_8000 ICM4268X_DT_ACCEL_ODR_8000 +#define ICM42686_DT_ACCEL_ODR_4000 ICM4268X_DT_ACCEL_ODR_4000 +#define ICM42686_DT_ACCEL_ODR_2000 ICM4268X_DT_ACCEL_ODR_2000 +#define ICM42686_DT_ACCEL_ODR_1000 ICM4268X_DT_ACCEL_ODR_1000 +#define ICM42686_DT_ACCEL_ODR_200 ICM4268X_DT_ACCEL_ODR_200 +#define ICM42686_DT_ACCEL_ODR_100 ICM4268X_DT_ACCEL_ODR_100 +#define ICM42686_DT_ACCEL_ODR_50 ICM4268X_DT_ACCEL_ODR_50 +#define ICM42686_DT_ACCEL_ODR_25 ICM4268X_DT_ACCEL_ODR_25 +#define ICM42686_DT_ACCEL_ODR_12_5 ICM4268X_DT_ACCEL_ODR_12_5 +#define ICM42686_DT_ACCEL_ODR_6_25 ICM4268X_DT_ACCEL_ODR_6_25 +#define ICM42686_DT_ACCEL_ODR_3_125 ICM4268X_DT_ACCEL_ODR_3_125 +#define ICM42686_DT_ACCEL_ODR_1_5625 ICM4268X_DT_ACCEL_ODR_1_5625 +#define ICM42686_DT_ACCEL_ODR_500 ICM4268X_DT_ACCEL_ODR_500 +/** @} */ + +/** + * @defgroup ICM42686_GYRO_DATA_RATE Gyroscope data rate options + * @{ + */ +#define ICM42686_DT_GYRO_ODR_32000 ICM4268X_DT_GYRO_ODR_32000 +#define ICM42686_DT_GYRO_ODR_16000 ICM4268X_DT_GYRO_ODR_16000 +#define ICM42686_DT_GYRO_ODR_8000 ICM4268X_DT_GYRO_ODR_8000 +#define ICM42686_DT_GYRO_ODR_4000 ICM4268X_DT_GYRO_ODR_4000 +#define ICM42686_DT_GYRO_ODR_2000 ICM4268X_DT_GYRO_ODR_2000 +#define ICM42686_DT_GYRO_ODR_1000 ICM4268X_DT_GYRO_ODR_1000 +#define ICM42686_DT_GYRO_ODR_200 ICM4268X_DT_GYRO_ODR_200 +#define ICM42686_DT_GYRO_ODR_100 ICM4268X_DT_GYRO_ODR_100 +#define ICM42686_DT_GYRO_ODR_50 ICM4268X_DT_GYRO_ODR_50 +#define ICM42686_DT_GYRO_ODR_25 ICM4268X_DT_GYRO_ODR_25 +#define ICM42686_DT_GYRO_ODR_12_5 ICM4268X_DT_GYRO_ODR_12_5 +#define ICM42686_DT_GYRO_ODR_500 ICM4268X_DT_GYRO_ODR_500 +/** @} */ + +/** @} */ + +#endif /*ZEPHYR_INCLUDE_DT_BINDINGS_TDK_ICM42686P_H_ */ diff --git a/include/zephyr/dt-bindings/sensor/icm42688.h b/include/zephyr/dt-bindings/sensor/icm42688.h index 6f84fecd7e06..ea1d60c21d8e 100644 --- a/include/zephyr/dt-bindings/sensor/icm42688.h +++ b/include/zephyr/dt-bindings/sensor/icm42688.h @@ -1,11 +1,13 @@ /* * Copyright (c) 2024 Intel Corporation + * Copyright (c) 2025 Croxel, Inc. * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_TDK_ICM42688P_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_TDK_ICM42688P_H_ -#include "sensor_axis_align.h" + +#include "icm4268x.h" /** * @defgroup ICM42688 Invensense (TDK) ICM42688 DT Options @@ -17,18 +19,18 @@ * @defgroup ICM42688_ACCEL_POWER_MODES Accelerometer power modes * @{ */ -#define ICM42688_DT_ACCEL_OFF 0 -#define ICM42688_DT_ACCEL_LP 2 -#define ICM42688_DT_ACCEL_LN 3 +#define ICM42688_DT_ACCEL_OFF ICM4268X_DT_ACCEL_OFF +#define ICM42688_DT_ACCEL_LP ICM4268X_DT_ACCEL_LP +#define ICM42688_DT_ACCEL_LN ICM4268X_DT_ACCEL_LN /** @} */ /** * @defgroup ICM42688_GYRO_POWER_MODES Gyroscope power modes * @{ */ -#define ICM42688_DT_GYRO_OFF 0 -#define ICM42688_DT_GYRO_STANDBY 1 -#define ICM42688_DT_GYRO_LN 3 +#define ICM42688_DT_GYRO_OFF ICM4268X_DT_GYRO_OFF +#define ICM42688_DT_GYRO_STANDBY ICM4268X_DT_GYRO_STANDBY +#define ICM42688_DT_GYRO_LN ICM4268X_DT_GYRO_LN /** @} */ /** @@ -59,39 +61,39 @@ * @defgroup ICM42688_ACCEL_DATA_RATE Accelerometer data rate options * @{ */ -#define ICM42688_DT_ACCEL_ODR_32000 1 -#define ICM42688_DT_ACCEL_ODR_16000 2 -#define ICM42688_DT_ACCEL_ODR_8000 3 -#define ICM42688_DT_ACCEL_ODR_4000 4 -#define ICM42688_DT_ACCEL_ODR_2000 5 -#define ICM42688_DT_ACCEL_ODR_1000 6 -#define ICM42688_DT_ACCEL_ODR_200 7 -#define ICM42688_DT_ACCEL_ODR_100 8 -#define ICM42688_DT_ACCEL_ODR_50 9 -#define ICM42688_DT_ACCEL_ODR_25 10 -#define ICM42688_DT_ACCEL_ODR_12_5 11 -#define ICM42688_DT_ACCEL_ODR_6_25 12 -#define ICM42688_DT_ACCEL_ODR_3_125 13 -#define ICM42688_DT_ACCEL_ODR_1_5625 14 -#define ICM42688_DT_ACCEL_ODR_500 15 +#define ICM42688_DT_ACCEL_ODR_32000 ICM4268X_DT_ACCEL_ODR_32000 +#define ICM42688_DT_ACCEL_ODR_16000 ICM4268X_DT_ACCEL_ODR_16000 +#define ICM42688_DT_ACCEL_ODR_8000 ICM4268X_DT_ACCEL_ODR_8000 +#define ICM42688_DT_ACCEL_ODR_4000 ICM4268X_DT_ACCEL_ODR_4000 +#define ICM42688_DT_ACCEL_ODR_2000 ICM4268X_DT_ACCEL_ODR_2000 +#define ICM42688_DT_ACCEL_ODR_1000 ICM4268X_DT_ACCEL_ODR_1000 +#define ICM42688_DT_ACCEL_ODR_200 ICM4268X_DT_ACCEL_ODR_200 +#define ICM42688_DT_ACCEL_ODR_100 ICM4268X_DT_ACCEL_ODR_100 +#define ICM42688_DT_ACCEL_ODR_50 ICM4268X_DT_ACCEL_ODR_50 +#define ICM42688_DT_ACCEL_ODR_25 ICM4268X_DT_ACCEL_ODR_25 +#define ICM42688_DT_ACCEL_ODR_12_5 ICM4268X_DT_ACCEL_ODR_12_5 +#define ICM42688_DT_ACCEL_ODR_6_25 ICM4268X_DT_ACCEL_ODR_6_25 +#define ICM42688_DT_ACCEL_ODR_3_125 ICM4268X_DT_ACCEL_ODR_3_125 +#define ICM42688_DT_ACCEL_ODR_1_5625 ICM4268X_DT_ACCEL_ODR_1_5625 +#define ICM42688_DT_ACCEL_ODR_500 ICM4268X_DT_ACCEL_ODR_500 /** @} */ /** * @defgroup ICM42688_GYRO_DATA_RATE Gyroscope data rate options * @{ */ -#define ICM42688_DT_GYRO_ODR_32000 1 -#define ICM42688_DT_GYRO_ODR_16000 2 -#define ICM42688_DT_GYRO_ODR_8000 3 -#define ICM42688_DT_GYRO_ODR_4000 4 -#define ICM42688_DT_GYRO_ODR_2000 5 -#define ICM42688_DT_GYRO_ODR_1000 6 -#define ICM42688_DT_GYRO_ODR_200 7 -#define ICM42688_DT_GYRO_ODR_100 8 -#define ICM42688_DT_GYRO_ODR_50 9 -#define ICM42688_DT_GYRO_ODR_25 10 -#define ICM42688_DT_GYRO_ODR_12_5 11 -#define ICM42688_DT_GYRO_ODR_500 15 +#define ICM42688_DT_GYRO_ODR_32000 ICM4268X_DT_GYRO_ODR_32000 +#define ICM42688_DT_GYRO_ODR_16000 ICM4268X_DT_GYRO_ODR_16000 +#define ICM42688_DT_GYRO_ODR_8000 ICM4268X_DT_GYRO_ODR_8000 +#define ICM42688_DT_GYRO_ODR_4000 ICM4268X_DT_GYRO_ODR_4000 +#define ICM42688_DT_GYRO_ODR_2000 ICM4268X_DT_GYRO_ODR_2000 +#define ICM42688_DT_GYRO_ODR_1000 ICM4268X_DT_GYRO_ODR_1000 +#define ICM42688_DT_GYRO_ODR_200 ICM4268X_DT_GYRO_ODR_200 +#define ICM42688_DT_GYRO_ODR_100 ICM4268X_DT_GYRO_ODR_100 +#define ICM42688_DT_GYRO_ODR_50 ICM4268X_DT_GYRO_ODR_50 +#define ICM42688_DT_GYRO_ODR_25 ICM4268X_DT_GYRO_ODR_25 +#define ICM42688_DT_GYRO_ODR_12_5 ICM4268X_DT_GYRO_ODR_12_5 +#define ICM42688_DT_GYRO_ODR_500 ICM4268X_DT_GYRO_ODR_500 /** @} */ /** @} */ diff --git a/include/zephyr/dt-bindings/sensor/icm4268x.h b/include/zephyr/dt-bindings/sensor/icm4268x.h new file mode 100644 index 000000000000..6d61dafa0e18 --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/icm4268x.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024 Intel Corporation + * Copyright (c) 2025 Croxel, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_TDK_ICM4268X_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_TDK_ICM4268X_H_ + +#include "sensor_axis_align.h" + +/** + * @defgroup ICM4268X Invensense (TDK) ICM4268X DT Options + * @ingroup sensor_interface + * @{ + */ + +/** + * @defgroup ICM4268X_ACCEL_POWER_MODES Accelerometer power modes + * @{ + */ +#define ICM4268X_DT_ACCEL_OFF 0 +#define ICM4268X_DT_ACCEL_LP 2 +#define ICM4268X_DT_ACCEL_LN 3 +/** @} */ + +/** + * @defgroup ICM4268X_GYRO_POWER_MODES Gyroscope power modes + * @{ + */ +#define ICM4268X_DT_GYRO_OFF 0 +#define ICM4268X_DT_GYRO_STANDBY 1 +#define ICM4268X_DT_GYRO_LN 3 +/** @} */ + +/** + * @defgroup ICM4268X_ACCEL_DATA_RATE Accelerometer data rate options + * @{ + */ +#define ICM4268X_DT_ACCEL_ODR_32000 1 +#define ICM4268X_DT_ACCEL_ODR_16000 2 +#define ICM4268X_DT_ACCEL_ODR_8000 3 +#define ICM4268X_DT_ACCEL_ODR_4000 4 +#define ICM4268X_DT_ACCEL_ODR_2000 5 +#define ICM4268X_DT_ACCEL_ODR_1000 6 +#define ICM4268X_DT_ACCEL_ODR_200 7 +#define ICM4268X_DT_ACCEL_ODR_100 8 +#define ICM4268X_DT_ACCEL_ODR_50 9 +#define ICM4268X_DT_ACCEL_ODR_25 10 +#define ICM4268X_DT_ACCEL_ODR_12_5 11 +#define ICM4268X_DT_ACCEL_ODR_6_25 12 +#define ICM4268X_DT_ACCEL_ODR_3_125 13 +#define ICM4268X_DT_ACCEL_ODR_1_5625 14 +#define ICM4268X_DT_ACCEL_ODR_500 15 +/** @} */ + +/** + * @defgroup ICM4268X_GYRO_DATA_RATE Gyroscope data rate options + * @{ + */ +#define ICM4268X_DT_GYRO_ODR_32000 1 +#define ICM4268X_DT_GYRO_ODR_16000 2 +#define ICM4268X_DT_GYRO_ODR_8000 3 +#define ICM4268X_DT_GYRO_ODR_4000 4 +#define ICM4268X_DT_GYRO_ODR_2000 5 +#define ICM4268X_DT_GYRO_ODR_1000 6 +#define ICM4268X_DT_GYRO_ODR_200 7 +#define ICM4268X_DT_GYRO_ODR_100 8 +#define ICM4268X_DT_GYRO_ODR_50 9 +#define ICM4268X_DT_GYRO_ODR_25 10 +#define ICM4268X_DT_GYRO_ODR_12_5 11 +#define ICM4268X_DT_GYRO_ODR_500 15 +/** @} */ + +/** @} */ + +#endif /*ZEPHYR_INCLUDE_DT_BINDINGS_TDK_ICM4268X_H_ */ diff --git a/samples/sensor/sensor_shell/boards/vmu_rt1170_mimxrt1176_cm7.overlay b/samples/sensor/sensor_shell/boards/vmu_rt1170_mimxrt1176_cm7.overlay deleted file mode 100644 index e4aa29a1d8ef..000000000000 --- a/samples/sensor/sensor_shell/boards/vmu_rt1170_mimxrt1176_cm7.overlay +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2025 CogniPilot Foundation */ -/* SPDX-License-Identifier: Apache-2.0 */ - -&lpspi1 { - /delete-node/ icm42688p0@0; - /delete-property/ dmas; - /delete-property/ dma-names; -}; - -&lpspi2 { - status = "okay"; - cs-gpios =<&gpio3 24 GPIO_ACTIVE_LOW>; - - icm42688_1: icm42688p1@0 { - compatible = "invensense,icm42688"; - reg = <0>; - int-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>; - spi-max-frequency = <24000000>; - accel-pwr-mode = ; - accel-odr = ; - accel-fs = ; - gyro-pwr-mode = ; - gyro-odr = ; - gyro-fs = ; - axis-align-x = ; - axis-align-y = ; - axis-align-z = ; - }; -}; diff --git a/tests/boards/vmu_rt1170/icm42688/src/main.c b/tests/boards/vmu_rt1170/icm42688/src/main.c index d936df5a8e5b..00b5830bb758 100644 --- a/tests/boards/vmu_rt1170/icm42688/src/main.c +++ b/tests/boards/vmu_rt1170/icm42688/src/main.c @@ -27,7 +27,7 @@ static struct sensor_stream_trigger stream_trigger = { }; static struct sensor_read_config stream_config = { - .sensor = DEVICE_DT_GET(DT_NODELABEL(icm42688_1)), + .sensor = DEVICE_DT_GET(DT_NODELABEL(icm42688_0)), .is_streaming = true, .triggers = &stream_trigger, .count = 0, diff --git a/tests/drivers/build_all/sensor/sensors_trigger_global.conf b/tests/drivers/build_all/sensor/sensors_trigger_global.conf index a9134740db76..4681bb2397fc 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_global.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_global.conf @@ -25,7 +25,7 @@ CONFIG_GROW_R502A_TRIGGER_GLOBAL_THREAD=y CONFIG_HMC5883L_TRIGGER_GLOBAL_THREAD=y CONFIG_HTS221_TRIGGER_GLOBAL_THREAD=y CONFIG_ICM42605_TRIGGER_GLOBAL_THREAD=y -CONFIG_ICM42688_TRIGGER_GLOBAL_THREAD=y +CONFIG_ICM4268X_TRIGGER_GLOBAL_THREAD=y CONFIG_ICM42X70_TRIGGER_GLOBAL_THREAD=y CONFIG_ICM45686_TRIGGER_GLOBAL_THREAD=y CONFIG_ICP201XX_TRIGGER_GLOBAL_THREAD=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_none.conf b/tests/drivers/build_all/sensor/sensors_trigger_none.conf index 7c196b9e422c..9ddd5d1f7fd3 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_none.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_none.conf @@ -26,7 +26,7 @@ CONFIG_GROW_R502A_TRIGGER_NONE=y CONFIG_HMC5883L_TRIGGER_NONE=y CONFIG_HTS221_TRIGGER_NONE=y CONFIG_ICM42605_TRIGGER_NONE=y -CONFIG_ICM42688_TRIGGER_NONE=y +CONFIG_ICM4268X_TRIGGER_NONE=y CONFIG_ICM42X70_TRIGGER_NONE=y CONFIG_ICM45686_TRIGGER_NONE=y CONFIG_ICP201XX_TRIGGER_NONE=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_own.conf b/tests/drivers/build_all/sensor/sensors_trigger_own.conf index bbee6eb03824..2d501a82568f 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_own.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_own.conf @@ -24,7 +24,7 @@ CONFIG_FXOS8700_TRIGGER_OWN_THREAD=y CONFIG_GROW_R502A_TRIGGER_OWN_THREAD=y CONFIG_HMC5883L_TRIGGER_OWN_THREAD=y CONFIG_HTS221_TRIGGER_OWN_THREAD=y -CONFIG_ICM42688_TRIGGER_OWN_THREAD=y +CONFIG_ICM4268X_TRIGGER_OWN_THREAD=y CONFIG_ICM42X70_TRIGGER_OWN_THREAD=y CONFIG_ICM45686_TRIGGER_OWN_THREAD=y CONFIG_ICP201XX_TRIGGER_OWN_THREAD=y diff --git a/tests/drivers/build_all/sensor/spi.dtsi b/tests/drivers/build_all/sensor/spi.dtsi index 29e7e6901bf2..efa60f5e5090 100644 --- a/tests/drivers/build_all/sensor/spi.dtsi +++ b/tests/drivers/build_all/sensor/spi.dtsi @@ -198,7 +198,7 @@ test_spi_bme680: bme680@19 { }; test_spi_icm426888: icm42688@1a { - compatible = "invensense,icm42688"; + compatible = "invensense,icm42688", "invensense,icm4268x"; reg = <0x1a>; spi-max-frequency = <24000000>; int-gpios = <&test_gpio 0 0>; @@ -459,3 +459,10 @@ test_spi_adxl366: adxl366@37 { odr = <4>; fifo-mode = <0>; }; + +test_spi_icm42686: icm42686@38 { + compatible = "invensense,icm42686", "invensense,icm4268x"; + reg = <0x1a>; + spi-max-frequency = <24000000>; + int-gpios = <&test_gpio 0 0>; +}; diff --git a/tests/drivers/sensor/icm42688/boards/native_sim.overlay b/tests/drivers/sensor/icm42688/boards/native_sim.overlay index 9247b6365bb2..5f84b35e29a5 100644 --- a/tests/drivers/sensor/icm42688/boards/native_sim.overlay +++ b/tests/drivers/sensor/icm42688/boards/native_sim.overlay @@ -4,7 +4,7 @@ &spi0 { icm42688: icm42688@3 { - compatible = "invensense,icm42688"; + compatible = "invensense,icm42688", "invensense,icm4268x"; int-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; spi-max-frequency = <50000000>; reg = <3>; diff --git a/tests/drivers/sensor/icm42688/src/main.c b/tests/drivers/sensor/icm42688/src/main.c index 5426f1b0c1ea..bc945cb2db70 100644 --- a/tests/drivers/sensor/icm42688/src/main.c +++ b/tests/drivers/sensor/icm42688/src/main.c @@ -12,8 +12,8 @@ #include #include -#include "icm42688_emul.h" -#include "icm42688_reg.h" +#include "icm4268x_emul.h" +#include "icm4268x_reg.h" #define NODE DT_NODELABEL(icm42688) @@ -42,7 +42,7 @@ ZTEST_F(icm42688, test_fetch_fail_no_ready_data) { uint8_t status = 0; - icm42688_emul_set_reg(fixture->target, REG_INT_STATUS, &status, 1); + icm4268x_emul_set_reg(fixture->target, REG_INT_STATUS, &status, 1); zassert_equal(-EBUSY, sensor_sample_fetch(fixture->dev)); } @@ -56,7 +56,7 @@ static void test_fetch_temp_mc(const struct icm42688_fixture *fixture, int16_t t /* Set the INT_STATUS register to show we have data */ buffer[0] = BIT_DATA_RDY_INT; - icm42688_emul_set_reg(fixture->target, REG_INT_STATUS, buffer, 1); + icm4268x_emul_set_reg(fixture->target, REG_INT_STATUS, buffer, 1); /* * Set the temperature data to 22.5C via: @@ -65,7 +65,7 @@ static void test_fetch_temp_mc(const struct icm42688_fixture *fixture, int16_t t temperature_reg = ((temperature_mc - 25000) * 13248) / 100000; buffer[0] = (temperature_reg >> 8) & GENMASK(7, 0); buffer[1] = temperature_reg & GENMASK(7, 0); - icm42688_emul_set_reg(fixture->target, REG_TEMP_DATA1, buffer, 2); + icm4268x_emul_set_reg(fixture->target, REG_TEMP_DATA1, buffer, 2); /* Fetch the data */ zassert_ok(sensor_sample_fetch(fixture->dev)); @@ -96,7 +96,7 @@ static void test_fetch_accel_with_range(const struct icm42688_fixture *fixture, /* Se the INT_STATUS register to show we have data */ register_buffer[0] = BIT_DATA_RDY_INT; - icm42688_emul_set_reg(fixture->target, REG_INT_STATUS, register_buffer, 1); + icm4268x_emul_set_reg(fixture->target, REG_INT_STATUS, register_buffer, 1); /* Set accel range */ sensor_g_to_ms2(accel_range_g, &values[0]); @@ -108,7 +108,7 @@ static void test_fetch_accel_with_range(const struct icm42688_fixture *fixture, register_buffer[i * 2] = (accel_percent[i] >> 8) & GENMASK(7, 0); register_buffer[i * 2 + 1] = accel_percent[i] & GENMASK(7, 0); } - icm42688_emul_set_reg(fixture->target, REG_ACCEL_DATA_X1, register_buffer, 6); + icm4268x_emul_set_reg(fixture->target, REG_ACCEL_DATA_X1, register_buffer, 6); /* Fetch the data */ zassert_ok(sensor_sample_fetch(fixture->dev)); @@ -158,7 +158,7 @@ static void test_fetch_gyro_with_range(const struct icm42688_fixture *fixture, i /* Se the INT_STATUS register to show we have data */ register_buffer[0] = BIT_DATA_RDY_INT; - icm42688_emul_set_reg(fixture->target, REG_INT_STATUS, register_buffer, 1); + icm4268x_emul_set_reg(fixture->target, REG_INT_STATUS, register_buffer, 1); /* Set gyro range */ sensor_degrees_to_rad((scale_mdps / 1000) + (scale_mdps % 1000 == 0 ? 0 : 1), &values[0]); @@ -170,7 +170,7 @@ static void test_fetch_gyro_with_range(const struct icm42688_fixture *fixture, i register_buffer[i * 2] = (gyro_percent[i] >> 8) & GENMASK(7, 0); register_buffer[i * 2 + 1] = gyro_percent[i] & GENMASK(7, 0); } - icm42688_emul_set_reg(fixture->target, REG_GYRO_DATA_X1, register_buffer, 6); + icm4268x_emul_set_reg(fixture->target, REG_GYRO_DATA_X1, register_buffer, 6); /* Fetch the data */ zassert_ok(sensor_sample_fetch(fixture->dev));