Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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