sensor: icm45686: Add I2C bus support
Validated for read/decode APIs, as well as Streaming mode (FIFO). Signed-off-by: Luis Ubieda <luisf@croxel.com>
This commit is contained in:
parent
b22299d262
commit
0a4d86c557
6 changed files with 94 additions and 7 deletions
|
@ -6,8 +6,10 @@ menuconfig ICM45686
|
|||
bool "ICM45686 High-precision 6-Axis Motion Tracking Device"
|
||||
default y
|
||||
depends on DT_HAS_INVENSENSE_ICM45686_ENABLED
|
||||
select SPI
|
||||
select SPI_RTIO
|
||||
select SPI if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM45686),spi)
|
||||
select SPI_RTIO if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM45686),spi)
|
||||
select I2C if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM45686),i2c)
|
||||
select I2C_RTIO if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM45686),i2c)
|
||||
help
|
||||
Enable driver for ICM45686 High-precision 6-axis motion
|
||||
tracking device.
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/rtio/rtio.h>
|
||||
|
||||
|
@ -199,6 +200,9 @@ static inline void icm45686_submit_one_shot(const struct device *dev,
|
|||
edata->payload.buf,
|
||||
sizeof(edata->payload.buf),
|
||||
NULL);
|
||||
if (data->rtio.type == ICM45686_BUS_I2C) {
|
||||
read_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
|
||||
}
|
||||
read_sqe->flags |= RTIO_SQE_CHAINED;
|
||||
|
||||
rtio_sqe_prep_callback_no_cqe(complete_sqe,
|
||||
|
@ -245,10 +249,18 @@ static int icm45686_init(const struct device *dev)
|
|||
uint8_t val;
|
||||
int err;
|
||||
|
||||
if (!spi_is_ready_iodev(data->rtio.iodev)) {
|
||||
#if CONFIG_SPI_RTIO
|
||||
if ((data->rtio.type == ICM45686_BUS_SPI) && !spi_is_ready_iodev(data->rtio.iodev)) {
|
||||
LOG_ERR("Bus is not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_I2C_RTIO
|
||||
if ((data->rtio.type == ICM45686_BUS_I2C) && !i2c_is_ready_iodev(data->rtio.iodev)) {
|
||||
LOG_ERR("Bus is not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Soft-reset sensor to restore config to defaults */
|
||||
|
||||
|
@ -383,10 +395,18 @@ static int icm45686_init(const struct device *dev)
|
|||
#define ICM45686_INIT(inst) \
|
||||
\
|
||||
RTIO_DEFINE(icm45686_rtio_ctx_##inst, 8, 8); \
|
||||
SPI_DT_IODEV_DEFINE(icm45686_bus_##inst, \
|
||||
DT_DRV_INST(inst), \
|
||||
SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB, \
|
||||
0U); \
|
||||
\
|
||||
COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
|
||||
(SPI_DT_IODEV_DEFINE(icm45686_bus_##inst, \
|
||||
DT_DRV_INST(inst), \
|
||||
SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB, \
|
||||
0U)), \
|
||||
()); \
|
||||
\
|
||||
COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \
|
||||
(I2C_DT_IODEV_DEFINE(icm45686_bus_##inst, \
|
||||
DT_DRV_INST(inst))), \
|
||||
()); \
|
||||
\
|
||||
static const struct icm45686_config icm45686_cfg_##inst = { \
|
||||
.settings = { \
|
||||
|
@ -414,6 +434,10 @@ static int icm45686_init(const struct device *dev)
|
|||
.rtio = { \
|
||||
.iodev = &icm45686_bus_##inst, \
|
||||
.ctx = &icm45686_rtio_ctx_##inst, \
|
||||
COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \
|
||||
(.type = ICM45686_BUS_I2C), ()) \
|
||||
COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
|
||||
(.type = ICM45686_BUS_SPI), ()) \
|
||||
}, \
|
||||
}; \
|
||||
\
|
||||
|
|
|
@ -130,10 +130,16 @@ struct icm45686_stream {
|
|||
} data;
|
||||
};
|
||||
|
||||
enum icm45686_bus_type {
|
||||
ICM45686_BUS_SPI,
|
||||
ICM45686_BUS_I2C,
|
||||
};
|
||||
|
||||
struct icm45686_data {
|
||||
struct {
|
||||
struct rtio_iodev *iodev;
|
||||
struct rtio *ctx;
|
||||
enum icm45686_bus_type type;
|
||||
} rtio;
|
||||
/** Single-shot encoded data instance to support fetch/get API */
|
||||
struct icm45686_encoded_data edata;
|
||||
|
|
|
@ -36,6 +36,9 @@ static inline int icm45686_bus_read(const struct device *dev,
|
|||
rtio_sqe_prep_write(write_sqe, iodev, RTIO_PRIO_HIGH, ®, 1, NULL);
|
||||
write_sqe->flags |= RTIO_SQE_TRANSACTION;
|
||||
rtio_sqe_prep_read(read_sqe, iodev, RTIO_PRIO_HIGH, buf, len, NULL);
|
||||
if (data->rtio.type == ICM45686_BUS_I2C) {
|
||||
read_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
|
||||
}
|
||||
|
||||
err = rtio_submit(ctx, 2);
|
||||
if (err) {
|
||||
|
@ -73,6 +76,9 @@ static inline int icm45686_bus_write(const struct device *dev,
|
|||
rtio_sqe_prep_write(write_reg_sqe, iodev, RTIO_PRIO_HIGH, ®, 1, NULL);
|
||||
write_reg_sqe->flags |= RTIO_SQE_TRANSACTION;
|
||||
rtio_sqe_prep_write(write_buf_sqe, iodev, RTIO_PRIO_HIGH, buf, len, NULL);
|
||||
if (data->rtio.type == ICM45686_BUS_I2C) {
|
||||
write_buf_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP;
|
||||
}
|
||||
|
||||
err = rtio_submit(ctx, 2);
|
||||
if (err) {
|
||||
|
|
|
@ -204,6 +204,9 @@ static void icm45686_handle_event_actions(struct rtio *ctx,
|
|||
(buf->header.fifo_count *
|
||||
sizeof(struct icm45686_encoded_fifo_payload)),
|
||||
NULL);
|
||||
if (data->rtio.type == ICM45686_BUS_I2C) {
|
||||
data_rd_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
|
||||
}
|
||||
data_rd_sqe->flags |= RTIO_SQE_CHAINED;
|
||||
|
||||
} else if (should_flush_fifo(read_cfg, int_status)) {
|
||||
|
@ -232,6 +235,9 @@ static void icm45686_handle_event_actions(struct rtio *ctx,
|
|||
write_reg,
|
||||
sizeof(write_reg),
|
||||
NULL);
|
||||
if (data->rtio.type == ICM45686_BUS_I2C) {
|
||||
write_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP;
|
||||
}
|
||||
write_sqe->flags |= RTIO_SQE_CHAINED;
|
||||
|
||||
} else if (should_read_data(read_cfg, int_status)) {
|
||||
|
@ -269,6 +275,9 @@ static void icm45686_handle_event_actions(struct rtio *ctx,
|
|||
buf->payload.buf,
|
||||
sizeof(buf->payload.buf),
|
||||
NULL);
|
||||
if (data->rtio.type == ICM45686_BUS_I2C) {
|
||||
read_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
|
||||
}
|
||||
read_sqe->flags |= RTIO_SQE_CHAINED;
|
||||
}
|
||||
|
||||
|
@ -318,6 +327,9 @@ static void icm45686_event_handler(const struct device *dev)
|
|||
wr_data,
|
||||
sizeof(wr_data),
|
||||
NULL);
|
||||
if (data->rtio.type == ICM45686_BUS_I2C) {
|
||||
write_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP;
|
||||
}
|
||||
rtio_submit(data->rtio.ctx, 0);
|
||||
|
||||
data->stream.settings.enabled.drdy = false;
|
||||
|
@ -375,8 +387,12 @@ static void icm45686_event_handler(const struct device *dev)
|
|||
&data->stream.data.int_status,
|
||||
1,
|
||||
NULL);
|
||||
if (data->rtio.type == ICM45686_BUS_I2C) {
|
||||
read_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
|
||||
}
|
||||
read_sqe->flags |= RTIO_SQE_CHAINED;
|
||||
|
||||
|
||||
/** Preemptively read FIFO count so we can decide on the next callback
|
||||
* how much FIFO data we'd read (if needed).
|
||||
*/
|
||||
|
@ -395,6 +411,9 @@ static void icm45686_event_handler(const struct device *dev)
|
|||
(uint8_t *)&data->stream.data.fifo_count,
|
||||
2,
|
||||
NULL);
|
||||
if (data->rtio.type == ICM45686_BUS_I2C) {
|
||||
read_fifo_ct_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
|
||||
}
|
||||
read_fifo_ct_sqe->flags |= RTIO_SQE_CHAINED;
|
||||
|
||||
rtio_sqe_prep_callback_no_cqe(complete_sqe,
|
||||
|
|
30
dts/bindings/sensor/invensense,icm45686-i2c.yaml
Normal file
30
dts/bindings/sensor/invensense,icm45686-i2c.yaml
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Copyright (c) 2025 Croxel Inc.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
ICM45686 High-precision 6-axis 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 icm45686.h
|
||||
and use the macros defined there.
|
||||
|
||||
Example:
|
||||
#include <zephyr/dt-bindings/sensor/icm45686.h>
|
||||
|
||||
&i2c0 {
|
||||
...
|
||||
|
||||
icm42688: icm45686@68 {
|
||||
...
|
||||
|
||||
accel-pwr-mode = <ICM45686_DT_ACCEL_LN>;
|
||||
accel-fs = <ICM45686_DT_ACCEL_FS_32>;
|
||||
accel-odr = <ICM45686_DT_ACCEL_ODR_800>;
|
||||
gyro-pwr-mode= <ICM45686_DT_GYRO_LN>;
|
||||
gyro-fs = <ICM45686_DT_GYRO_FS_4000>;
|
||||
gyro-odr = <ICM45686_DT_GYRO_ODR_800>;
|
||||
};
|
||||
};
|
||||
|
||||
compatible: "invensense,icm45686"
|
||||
|
||||
include: ["i2c-device.yaml", "invensense,icm45686-common.yaml"]
|
Loading…
Add table
Add a link
Reference in a new issue