Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions drivers/sensor/bosch/bmi08x/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@ zephyr_library_sources(bmi08x_gyro.c)
zephyr_library_sources(bmi08x.c)
zephyr_library_sources_ifdef(CONFIG_BMI08X_ACCEL_TRIGGER bmi08x_accel_trigger.c)
zephyr_library_sources_ifdef(CONFIG_BMI08X_GYRO_TRIGGER bmi08x_gyro_trigger.c)
zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API
bmi08x_bus.c
bmi08x_gyro_async.c
bmi08x_gyro_decoder.c
bmi08x_accel_async.c
bmi08x_accel_decoder.c
)
zephyr_library_sources_ifdef(CONFIG_BMI08X_GYRO_STREAM bmi08x_gyro_stream.c)
zephyr_library_sources_ifdef(CONFIG_BMI08X_ACCEL_STREAM bmi08x_accel_stream.c)
16 changes: 16 additions & 0 deletions drivers/sensor/bosch/bmi08x/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ menuconfig BMI08X
|| $(dt_compat_on_bus,$(DT_COMPAT_BOSCH_BMI08X_GYRO),i2c)
select SPI if $(dt_compat_on_bus,$(DT_COMPAT_BOSCH_BMI08X_ACCEL),spi) \
|| $(dt_compat_on_bus,$(DT_COMPAT_BOSCH_BMI08X_GYRO),spi)
select SPI_RTIO if SPI
select I2C_RTIO if I2C
help
Enable Bosch BMI08X inertial measurement unit that provides acceleration
and angular rate measurements.
Expand All @@ -19,6 +21,7 @@ if BMI08X

choice BMI08X_ACCEL_TRIGGER_MODE
prompt "Accelerometer trigger mode"
default BMI08X_ACCEL_TRIGGER_NONE
default BMI08X_ACCEL_TRIGGER_GLOBAL_THREAD
help
Specify the type of triggering to be used by the driver.
Expand All @@ -39,6 +42,13 @@ config BMI08X_ACCEL_TRIGGER_OWN_THREAD
select BMI08X_ACCEL_TRIGGER
endchoice

config BMI08X_ACCEL_STREAM
bool "Accelerometer Streaming Mode (FIFO)"
depends on !BMI08X_ACCEL_TRIGGER
depends on GPIO
depends on $(dt_compat_any_has_prop,$(DT_COMPAT_BOSCH_BMI08X_ACCEL),int-gpios)


config BMI08X_ACCEL_TRIGGER
bool

Expand Down Expand Up @@ -75,6 +85,12 @@ config BMI08X_GYRO_TRIGGER_OWN_THREAD
select BMI08X_GYRO_TRIGGER
endchoice

config BMI08X_GYRO_STREAM
bool "Gyroscope Streaming Mode (FIFO)"
depends on !BMI08X_GYRO_TRIGGER
depends on GPIO
depends on $(dt_compat_any_has_prop,$(DT_COMPAT_BOSCH_BMI08X_GYRO),int-gpios)

config BMI08X_GYRO_TRIGGER
bool

Expand Down
124 changes: 118 additions & 6 deletions drivers/sensor/bosch/bmi08x/bmi08x.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <zephyr/drivers/spi.h>
#include <zephyr/sys/util.h>

#include "bmi08x_bus.h"

/* Accel Chip Id register */
#define BMI08X_REG_ACCEL_CHIP_ID 0x00

Expand Down Expand Up @@ -65,6 +67,15 @@
/* Sensor temperature LSB data register */
#define BMI08X_REG_TEMP_LSB 0x23

/* Accel FIFO Length (low byte) */
#define BMI08X_REG_ACCEL_FIFO_LEN_0 0x24

/* Accel FIFO Length (high byte) */
#define BMI08X_REG_ACCEL_FIFO_LEN_1 0x25

/* Accel FIFO Data register */
#define BMI08X_REG_ACCEL_FIFO_DATA 0x26

/* Accel general purpose register 4*/
#define BMI08X_REG_ACCEL_GP_4 0x27

Expand All @@ -77,6 +88,18 @@
/* Accel range setting register */
#define BMI08X_REG_ACCEL_RANGE 0x41

/* Accel FIFO Watermark (low byte) */
#define BMI08X_REG_ACCEL_FIFO_WTM_0 0x46

/* Accel FIFO Watermark (high byte) */
#define BMI08X_REG_ACCEL_FIFO_WTM_1 0x47

/* Accel FIFO Config (FIFO mode) */
#define BMI08X_REG_ACCEL_FIFO_CONFIG_0 0x48

/* Accel FIFO Config (Interrupt enabling) */
#define BMI08X_REG_ACCEL_FIFO_CONFIG_1 0x49

/* Accel Interrupt pin 1 configuration register */
#define BMI08X_REG_ACCEL_INT1_IO_CONF 0x53

Expand Down Expand Up @@ -262,6 +285,9 @@
/* Gyro Interrupt status register */
#define BMI08X_REG_GYRO_INT_STAT_1 0x0A

/* FIFO Status register (Overrun and Frame counter) */
#define BMI08X_REG_FIFO_STATUS 0x0E

/* Gyro Range register */
#define BMI08X_REG_GYRO_RANGE 0x0F

Expand All @@ -283,9 +309,21 @@
/* Gyro Interrupt Map register */
#define BMI08X_REG_GYRO_INT3_INT4_IO_MAP 0x18

/* FIFO Watermark enable */
#define BMI08X_REG_GYRO_FIFO_WM_EN 0x1E

/* Gyro Self test register */
#define BMI08X_REG_GYRO_SELF_TEST 0x3C

/* FIFO Config register (FIFO Watermark) */
#define BMI08X_REG_GYRO_FIFO_CONFIG_0 0x3D

/* FIFO Config register (FIFO Mode) */
#define BMI08X_REG_GYRO_FIFO_CONFIG_1 0x3E

/* FIFO Data register */
#define BMI08X_REG_GYRO_FIFO_DATA 0x3F

/* Gyro unique chip identifier */
#define BMI08X_GYRO_CHIP_ID 0x0F

Expand Down Expand Up @@ -469,8 +507,9 @@ struct bmi08x_gyro_bus_io {
struct bmi08x_accel_config {
union bmi08x_bus bus;
const struct bmi08x_accel_bus_io *api;
#if defined(CONFIG_BMI08X_ACCEL_TRIGGER)
struct gpio_dt_spec int_gpio;
#if defined(CONFIG_SENSOR_ASYNC_API)
struct bmi08x_rtio_bus rtio_bus;
#endif
#if defined(CONFIG_BMI08X_ACCEL_TRIGGER) || BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
uint8_t int1_map;
Expand All @@ -488,8 +527,9 @@ struct bmi08x_accel_config {
struct bmi08x_gyro_config {
union bmi08x_bus bus;
const struct bmi08x_gyro_bus_io *api;
#if defined(CONFIG_BMI08X_GYRO_TRIGGER)
struct gpio_dt_spec int_gpio;
#if defined(CONFIG_SENSOR_ASYNC_API)
struct bmi08x_rtio_bus rtio_bus;
#endif
#if defined(CONFIG_BMI08X_GYRO_TRIGGER) || BMI08X_GYRO_ANY_INST_HAS_DATA_SYNC
uint8_t int3_4_map;
Expand All @@ -500,19 +540,27 @@ struct bmi08x_gyro_config {
};

struct bmi08x_accel_data {
#if defined(CONFIG_BMI08X_ACCEL_TRIGGER)
const struct device *dev;
#if defined(CONFIG_BMI08X_ACCEL_TRIGGER) || defined(CONFIG_SENSOR_ASYNC_API)
struct gpio_callback gpio_cb;
#endif
uint16_t acc_sample[3];
uint16_t scale; /* micro m/s^2/lsb */
uint16_t range;
#if defined(CONFIG_SENSOR_ASYNC_API)
struct {
struct rtio_iodev_sqe *iodev_sqe;
atomic_t state;
uint8_t fifo_wm;
} stream;
#endif

#if defined(CONFIG_BMI08X_ACCEL_TRIGGER_OWN_THREAD)
K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_BMI08X_ACCEL_THREAD_STACK_SIZE);
struct k_thread thread;
struct k_sem sem;
#elif defined(CONFIG_BMI08X_ACCEL_TRIGGER_GLOBAL_THREAD)
struct k_work work;
const struct device *dev;
#endif

#ifdef CONFIG_BMI08X_ACCEL_TRIGGER
Expand All @@ -523,19 +571,27 @@ struct bmi08x_accel_data {
};

struct bmi08x_gyro_data {
#if defined(CONFIG_BMI08X_GYRO_TRIGGER)
const struct device *dev;
#if defined(CONFIG_BMI08X_GYRO_TRIGGER) || defined(CONFIG_SENSOR_ASYNC_API)
struct gpio_callback gpio_cb;
#endif
uint16_t gyr_sample[3];
uint16_t scale; /* micro radians/s/lsb */
uint16_t range;
#if defined(CONFIG_SENSOR_ASYNC_API)
struct {
struct rtio_iodev_sqe *iodev_sqe;
atomic_t state;
uint8_t fifo_wm;
} stream;
#endif

#if defined(CONFIG_BMI08X_GYRO_TRIGGER_OWN_THREAD)
K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_BMI08X_GYRO_THREAD_STACK_SIZE);
struct k_thread thread;
struct k_sem sem;
#elif defined(CONFIG_BMI08X_GYRO_TRIGGER_GLOBAL_THREAD)
struct k_work work;
const struct device *dev;
#endif

#ifdef CONFIG_BMI08X_GYRO_TRIGGER
Expand All @@ -544,6 +600,62 @@ struct bmi08x_gyro_data {
#endif /* CONFIG_BMI08X_GYRO_TRIGGER */
};

struct bmi08x_accel_frame {
uint8_t header;
union {
struct {
uint16_t payload[3];
} accel;
struct {
uint8_t skipped_frames;
} skip;
struct {
uint8_t time[3];
} sensortime;
struct {
uint8_t change;
} fifo_config;
};
} __packed;

struct bmi08x_gyro_frame {
uint16_t payload[3];
} __packed;

struct bmi08x_accel_encoded_data {
struct {
uint64_t timestamp;
uint16_t range;
uint8_t chip_id;
bool has_accel;
bool is_streaming;
uint16_t fifo_len;
uint8_t sample_count;
uint16_t buf_len;
} header;
union {
uint16_t payload[3];
uint8_t fifo[0]; /* Left as bytes since it can contain multiple frames */
};
};

struct bmi08x_gyro_encoded_data {
struct {
uint64_t timestamp;
uint16_t range;
bool has_gyro;
bool is_streaming;
uint8_t int_status;
uint8_t fifo_status;
uint8_t sample_count;
} header;
union {
struct bmi08x_gyro_frame frame;
struct bmi08x_gyro_frame fifo[0];
} __packed;
};


/* common functions for accel and gyro */
int bmi08x_freq_to_odr_val(uint16_t freq_int, uint16_t freq_milli);
int32_t bmi08x_range_to_reg_val(uint16_t range, const struct bmi08x_range *range_map,
Expand Down
48 changes: 44 additions & 4 deletions drivers/sensor/bosch/bmi08x/bmi08x_accel.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@
*/

#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/sensor_clock.h>
#include <zephyr/pm/device.h>
#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/check.h>

#define DT_DRV_COMPAT bosch_bmi08x_accel
#include "bmi08x.h"
#include "bmi08x_config_file.h"
#include "bmi08x_accel_async.h"
#include "bmi08x_accel_stream.h"
#include "bmi08x_accel_decoder.h"

LOG_MODULE_REGISTER(BMI08X_ACCEL, CONFIG_SENSOR_LOG_LEVEL);

Expand Down Expand Up @@ -320,6 +325,7 @@ static int bmi08x_acc_range_set(const struct device *dev, int32_t range)
}

data->scale = BMI08X_ACC_SCALE(range);
data->range = reg_val;

return ret;
}
Expand Down Expand Up @@ -538,6 +544,10 @@ static DEVICE_API(sensor, bmi08x_api) = {
.attr_set = bmi08x_attr_set,
#ifdef CONFIG_BMI08X_ACCEL_TRIGGER
.trigger_set = bmi08x_trigger_set_acc,
#endif
#ifdef CONFIG_SENSOR_ASYNC_API
.submit = bmi08x_accel_async_submit,
.get_decoder = bmi08x_accel_decoder_get,
#endif
.sample_fetch = bmi08x_sample_fetch,
.channel_get = bmi08x_channel_get,
Expand Down Expand Up @@ -719,6 +729,14 @@ int bmi08x_accel_init(const struct device *dev)
}
#endif

#if defined(CONFIG_BMI08X_ACCEL_STREAM)
ret = bmi08x_accel_stream_init(dev);
if (ret < 0) {
LOG_ERR("Failed to init stream: %d", ret);
return ret;
}
#endif

return ret;
}

Expand Down Expand Up @@ -784,22 +802,44 @@ int bmi08x_accel_init(const struct device *dev)

#define BMI08X_CREATE_INST(inst) \
\
RTIO_DEFINE(bmi08x_accel_rtio_ctx_##inst, 16, 16); \
\
COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \
(I2C_DT_IODEV_DEFINE(bmi08x_accel_rtio_bus_##inst, \
DT_DRV_INST(inst))), \
(COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
(SPI_DT_IODEV_DEFINE(bmi08x_accel_rtio_bus_##inst, \
DT_DRV_INST(inst), \
SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB)),\
()))); \
\
IF_ENABLED(BMI08X_ACCEL_DATA_SYNC_EN(inst), (BMI08X_VERIFY_DATA_SYNC(inst);)) \
IF_ENABLED(BMI08X_ACCEL_DATA_SYNC_EN(inst), (BMI08X_VERIFY_DATA_SYNC_ODR(inst);)) \
IF_ENABLED(BMI08X_ACCEL_DATA_SYNC_EN(inst), (BMI08X_VERIFY_GYRO_DATA_SYNC_EN(inst);)) \
\
static struct bmi08x_accel_data bmi08x_drv_##inst; \
static struct bmi08x_accel_data bmi08x_drv_##inst = { \
IF_ENABLED(CONFIG_BMI08X_ACCEL_STREAM, \
(.stream.fifo_wm = DT_INST_PROP_OR(inst, fifo_watermark, 0),)) \
}; \
\
\
static const struct bmi08x_accel_config bmi08x_config_##inst = { \
COND_CODE_1(DT_INST_ON_BUS(inst, spi), (BMI08X_CONFIG_SPI(inst)), \
(BMI08X_CONFIG_I2C(inst))) \
.api = COND_CODE_1(DT_INST_ON_BUS(inst, spi), (&bmi08x_spi_api), \
(&bmi08x_i2c_api)), \
IF_ENABLED(CONFIG_BMI08X_ACCEL_TRIGGER, \
(.int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios),)) \
.int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \
BMI08X_ACCEL_TRIGGER_PINS(inst) \
.accel_hz = DT_INST_ENUM_IDX(inst, accel_hz) + 5, \
.accel_fs = DT_INST_PROP(inst, accel_fs), BMI08X_DATA_SYNC_REG(inst)}; \
.rtio_bus = { \
.ctx = &bmi08x_accel_rtio_ctx_##inst, \
.iodev = &bmi08x_accel_rtio_bus_##inst, \
.type = COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \
(BMI08X_RTIO_BUS_TYPE_I2C), \
(BMI08X_RTIO_BUS_TYPE_SPI)), \
}, \
.accel_fs = DT_INST_PROP(inst, accel_fs), BMI08X_DATA_SYNC_REG(inst) \
}; \
\
PM_DEVICE_DT_INST_DEFINE(inst, bmi08x_accel_pm_action); \
SENSOR_DEVICE_DT_INST_DEFINE(inst, bmi08x_accel_init, PM_DEVICE_DT_INST_GET(inst), \
Expand Down
Loading
Loading