drivers: sensors: bmi08x: add initial support for bmi08x
This adds support for the bosch bmi085 and bmi088. This also includes support for data sync mode. Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
This commit is contained in:
parent
f9773859c4
commit
f1a992c87a
22 changed files with 3029 additions and 0 deletions
|
@ -18,6 +18,7 @@ add_subdirectory_ifdef(CONFIG_BMC150_MAGN bmc150_magn)
|
||||||
add_subdirectory_ifdef(CONFIG_BME280 bme280)
|
add_subdirectory_ifdef(CONFIG_BME280 bme280)
|
||||||
add_subdirectory_ifdef(CONFIG_BME680 bme680)
|
add_subdirectory_ifdef(CONFIG_BME680 bme680)
|
||||||
add_subdirectory_ifdef(CONFIG_BMG160 bmg160)
|
add_subdirectory_ifdef(CONFIG_BMG160 bmg160)
|
||||||
|
add_subdirectory_ifdef(CONFIG_BMI08X bmi08x)
|
||||||
add_subdirectory_ifdef(CONFIG_BMI160 bmi160)
|
add_subdirectory_ifdef(CONFIG_BMI160 bmi160)
|
||||||
add_subdirectory_ifdef(CONFIG_BMI270 bmi270)
|
add_subdirectory_ifdef(CONFIG_BMI270 bmi270)
|
||||||
add_subdirectory_ifdef(CONFIG_BMI323 bmi323)
|
add_subdirectory_ifdef(CONFIG_BMI323 bmi323)
|
||||||
|
|
|
@ -74,6 +74,7 @@ source "drivers/sensor/bmc150_magn/Kconfig"
|
||||||
source "drivers/sensor/bme280/Kconfig"
|
source "drivers/sensor/bme280/Kconfig"
|
||||||
source "drivers/sensor/bme680/Kconfig"
|
source "drivers/sensor/bme680/Kconfig"
|
||||||
source "drivers/sensor/bmg160/Kconfig"
|
source "drivers/sensor/bmg160/Kconfig"
|
||||||
|
source "drivers/sensor/bmi08x/Kconfig"
|
||||||
source "drivers/sensor/bmi160/Kconfig"
|
source "drivers/sensor/bmi160/Kconfig"
|
||||||
source "drivers/sensor/bmi270/Kconfig"
|
source "drivers/sensor/bmi270/Kconfig"
|
||||||
source "drivers/sensor/bmi323/Kconfig"
|
source "drivers/sensor/bmi323/Kconfig"
|
||||||
|
|
9
drivers/sensor/bmi08x/CMakeLists.txt
Normal file
9
drivers/sensor/bmi08x/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
zephyr_library()
|
||||||
|
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_BMI08X bmi08x_accel.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_BMI08X bmi08x_gyro.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_BMI08X 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)
|
95
drivers/sensor/bmi08x/Kconfig
Normal file
95
drivers/sensor/bmi08x/Kconfig
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
# Bosch BMI08X inertial measurement configuration options
|
||||||
|
|
||||||
|
# Copyright (c) 2022 Meta Platforms, Inc. and its affiliates
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
menuconfig BMI08X
|
||||||
|
bool "Bosch BMI08X inertial measurement unit"
|
||||||
|
default y
|
||||||
|
depends on DT_HAS_BOSCH_BMI08X_ACCEL_ENABLED || DT_HAS_BOSCH_BMI08X_GYRO_ENABLED
|
||||||
|
select I2C if $(dt_compat_on_bus,$(DT_COMPAT_BOSCH_BMI08X_ACCEL),i2c) \
|
||||||
|
|| $(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)
|
||||||
|
help
|
||||||
|
Enable Bosch BMI08X inertial measurement unit that provides acceleration
|
||||||
|
and angular rate measurements.
|
||||||
|
|
||||||
|
if BMI08X
|
||||||
|
|
||||||
|
choice BMI08X_ACCEL_TRIGGER_MODE
|
||||||
|
prompt "Accelerometer trigger mode"
|
||||||
|
default BMI08X_ACCEL_TRIGGER_GLOBAL_THREAD
|
||||||
|
help
|
||||||
|
Specify the type of triggering to be used by the driver.
|
||||||
|
|
||||||
|
config BMI08X_ACCEL_TRIGGER_NONE
|
||||||
|
bool "No trigger"
|
||||||
|
|
||||||
|
config BMI08X_ACCEL_TRIGGER_GLOBAL_THREAD
|
||||||
|
bool "Use global thread"
|
||||||
|
select BMI08X_ACCEL_TRIGGER
|
||||||
|
|
||||||
|
config BMI08X_ACCEL_TRIGGER_OWN_THREAD
|
||||||
|
bool "Use own thread"
|
||||||
|
select BMI08X_ACCEL_TRIGGER
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config BMI08X_ACCEL_TRIGGER
|
||||||
|
bool
|
||||||
|
|
||||||
|
config BMI08X_ACCEL_THREAD_PRIORITY
|
||||||
|
int "Accelerometer own thread priority"
|
||||||
|
depends on BMI08X_ACCEL_TRIGGER_OWN_THREAD
|
||||||
|
default 10
|
||||||
|
help
|
||||||
|
The priority of the thread used for handling interrupts.
|
||||||
|
|
||||||
|
config BMI08X_ACCEL_THREAD_STACK_SIZE
|
||||||
|
int "Accelerometer own thread stack size"
|
||||||
|
depends on BMI08X_ACCEL_TRIGGER_OWN_THREAD
|
||||||
|
default 1536
|
||||||
|
help
|
||||||
|
The thread stack size.
|
||||||
|
|
||||||
|
choice BMI08X_GYRO_TRIGGER_MODE
|
||||||
|
prompt "Gyroscope trigger mode"
|
||||||
|
default BMI08X_GYRO_TRIGGER_NONE
|
||||||
|
default BMI08X_GYRO_TRIGGER_GLOBAL_THREAD
|
||||||
|
help
|
||||||
|
Specify the type of triggering to be used by the driver.
|
||||||
|
|
||||||
|
config BMI08X_GYRO_TRIGGER_NONE
|
||||||
|
bool "No trigger"
|
||||||
|
|
||||||
|
config BMI08X_GYRO_TRIGGER_GLOBAL_THREAD
|
||||||
|
bool "Use global thread"
|
||||||
|
select BMI08X_GYRO_TRIGGER
|
||||||
|
|
||||||
|
config BMI08X_GYRO_TRIGGER_OWN_THREAD
|
||||||
|
bool "Use own thread"
|
||||||
|
select BMI08X_GYRO_TRIGGER
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config BMI08X_GYRO_TRIGGER
|
||||||
|
bool
|
||||||
|
|
||||||
|
config BMI08X_GYRO_THREAD_PRIORITY
|
||||||
|
int "Own thread priority"
|
||||||
|
depends on BMI08X_GYRO_TRIGGER_OWN_THREAD
|
||||||
|
default 10
|
||||||
|
help
|
||||||
|
The priority of the thread used for handling interrupts.
|
||||||
|
|
||||||
|
config BMI08X_GYRO_THREAD_STACK_SIZE
|
||||||
|
int "Own thread stack size"
|
||||||
|
depends on BMI08X_GYRO_TRIGGER_OWN_THREAD
|
||||||
|
default 1536
|
||||||
|
help
|
||||||
|
The thread stack size.
|
||||||
|
|
||||||
|
config BMI08X_I2C_WRITE_BURST_SIZE
|
||||||
|
int "Maximum length of single i2c write"
|
||||||
|
default 16
|
||||||
|
|
||||||
|
endif # BMI08X
|
74
drivers/sensor/bmi08x/bmi08x.c
Normal file
74
drivers/sensor/bmi08x/bmi08x.c
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/* Bosch BMI08X inertial measurement unit driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Meta Platforms, Inc. and its affiliates
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include "bmi08x.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Output data rate map with allowed frequencies:
|
||||||
|
* freq = freq_int + freq_milli / 1000
|
||||||
|
*
|
||||||
|
* Since we don't need a finer frequency resolution than milliHz, use uint16_t
|
||||||
|
* to save some flash.
|
||||||
|
*/
|
||||||
|
static const struct {
|
||||||
|
uint16_t freq_int;
|
||||||
|
uint16_t freq_milli; /* User should convert to uHz before setting the
|
||||||
|
* SENSOR_ATTR_SAMPLING_FREQUENCY attribute.
|
||||||
|
*/
|
||||||
|
} bmi08x_odr_map[] = {
|
||||||
|
{0, 0}, {0, 780}, {1, 562}, {3, 120}, {6, 250}, {12, 500}, {25, 0},
|
||||||
|
{50, 0}, {100, 0}, {200, 0}, {400, 0}, {800, 0}, {1600, 0}, {3200, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
int bmi08x_freq_to_odr_val(uint16_t freq_int, uint16_t freq_milli)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* An ODR of 0 Hz is not allowed */
|
||||||
|
if (freq_int == 0U && freq_milli == 0U) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(bmi08x_odr_map); i++) {
|
||||||
|
if (freq_int < bmi08x_odr_map[i].freq_int ||
|
||||||
|
(freq_int == bmi08x_odr_map[i].freq_int &&
|
||||||
|
freq_milli <= bmi08x_odr_map[i].freq_milli)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t bmi08x_range_to_reg_val(uint16_t range, const struct bmi08x_range *range_map,
|
||||||
|
uint16_t range_map_size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < range_map_size; i++) {
|
||||||
|
if (range <= range_map[i].range) {
|
||||||
|
return range_map[i].reg_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t bmi08x_reg_val_to_range(uint8_t reg_val, const struct bmi08x_range *range_map,
|
||||||
|
uint16_t range_map_size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < range_map_size; i++) {
|
||||||
|
if (reg_val == range_map[i].reg_val) {
|
||||||
|
return range_map[i].range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
593
drivers/sensor/bmi08x/bmi08x.h
Normal file
593
drivers/sensor/bmi08x/bmi08x.h
Normal file
|
@ -0,0 +1,593 @@
|
||||||
|
/* Bosch BMI08X inertial measurement unit header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Meta Platforms, Inc. and its affiliates
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_DRIVERS_SENSOR_BMI08X_H_
|
||||||
|
#define ZEPHYR_DRIVERS_SENSOR_BMI08X_H_
|
||||||
|
|
||||||
|
#include <zephyr/drivers/gpio.h>
|
||||||
|
#include <zephyr/drivers/i2c.h>
|
||||||
|
#include <zephyr/drivers/sensor.h>
|
||||||
|
#include <zephyr/drivers/spi.h>
|
||||||
|
#include <zephyr/sys/util.h>
|
||||||
|
|
||||||
|
/* Accel Chip Id register */
|
||||||
|
#define BMI08X_REG_ACCEL_CHIP_ID 0x00
|
||||||
|
|
||||||
|
/* Accel Error condition register */
|
||||||
|
#define BMI08X_REG_ACCEL_ERR 0x02
|
||||||
|
|
||||||
|
/* Accel Status flag register */
|
||||||
|
#define BMI08X_REG_ACCEL_STATUS 0x03
|
||||||
|
|
||||||
|
/* Accel X LSB data register */
|
||||||
|
#define BMI08X_REG_ACCEL_X_LSB 0x12
|
||||||
|
|
||||||
|
/* Accel X MSB data register */
|
||||||
|
#define BMI08X_REG_ACCEL_X_MSB 0x13
|
||||||
|
|
||||||
|
/* Accel Y LSB data register */
|
||||||
|
#define BMI08X_REG_ACCEL_Y_LSB 0x14
|
||||||
|
|
||||||
|
/* Accel Y MSB data register */
|
||||||
|
#define BMI08X_REG_ACCEL_Y_MSB 0x15
|
||||||
|
|
||||||
|
/* Accel Z LSB data register */
|
||||||
|
#define BMI08X_REG_ACCEL_Z_LSB 0x16
|
||||||
|
|
||||||
|
/* Accel Z MSB data register */
|
||||||
|
#define BMI08X_REG_ACCEL_Z_MSB 0x17
|
||||||
|
|
||||||
|
/* Sensor time byte 0 register */
|
||||||
|
#define BMI08X_REG_ACCEL_SENSORTIME_0 0x18
|
||||||
|
|
||||||
|
/* Sensor time byte 1 register */
|
||||||
|
#define BMI08X_REG_ACCEL_SENSORTIME_1 0x19
|
||||||
|
|
||||||
|
/* Sensor time byte 2 register */
|
||||||
|
#define BMI08X_REG_ACCEL_SENSORTIME_2 0x1A
|
||||||
|
|
||||||
|
/* Accel Interrupt status0 register */
|
||||||
|
#define BMI08X_REG_ACCEL_INT_STAT_0 0x1C
|
||||||
|
|
||||||
|
/* Accel Interrupt status1 register */
|
||||||
|
#define BMI08X_REG_ACCEL_INT_STAT_1 0x1D
|
||||||
|
|
||||||
|
/* Accel general purpose register 0*/
|
||||||
|
#define BMI08X_REG_ACCEL_GP_0 0x1E
|
||||||
|
|
||||||
|
/* Sensor temperature MSB data register */
|
||||||
|
#define BMI08X_REG_TEMP_MSB 0x22
|
||||||
|
|
||||||
|
/* Sensor temperature LSB data register */
|
||||||
|
#define BMI08X_REG_TEMP_LSB 0x23
|
||||||
|
|
||||||
|
/* Accel general purpose register 4*/
|
||||||
|
#define BMI08X_REG_ACCEL_GP_4 0x27
|
||||||
|
|
||||||
|
/* Accel Internal status register */
|
||||||
|
#define BMI08X_REG_ACCEL_INTERNAL_STAT 0x2A
|
||||||
|
|
||||||
|
/* Accel configuration register */
|
||||||
|
#define BMI08X_REG_ACCEL_CONF 0x40
|
||||||
|
|
||||||
|
/* Accel range setting register */
|
||||||
|
#define BMI08X_REG_ACCEL_RANGE 0x41
|
||||||
|
|
||||||
|
/* Accel Interrupt pin 1 configuration register */
|
||||||
|
#define BMI08X_REG_ACCEL_INT1_IO_CONF 0x53
|
||||||
|
|
||||||
|
/* Accel Interrupt pin 2 configuration register */
|
||||||
|
#define BMI08X_REG_ACCEL_INT2_IO_CONF 0x54
|
||||||
|
|
||||||
|
/* Accel Interrupt latch configuration register */
|
||||||
|
#define BMI08X_REG_ACCEL_INT_LATCH_CONF 0x55
|
||||||
|
|
||||||
|
/* Accel Interrupt pin1 mapping register */
|
||||||
|
#define BMI08X_REG_ACCEL_INT1_MAP 0x56
|
||||||
|
|
||||||
|
/* Accel Interrupt pin2 mapping register */
|
||||||
|
#define BMI08X_REG_ACCEL_INT2_MAP 0x57
|
||||||
|
|
||||||
|
/* Accel Interrupt map register */
|
||||||
|
#define BMI08X_REG_ACCEL_INT1_INT2_MAP_DATA 0x58
|
||||||
|
|
||||||
|
/* Accel Init control register */
|
||||||
|
#define BMI08X_REG_ACCEL_INIT_CTRL 0x59
|
||||||
|
|
||||||
|
/* Accel Self test register */
|
||||||
|
#define BMI08X_REG_ACCEL_SELF_TEST 0x6D
|
||||||
|
|
||||||
|
/* Accel Power mode configuration register */
|
||||||
|
#define BMI08X_REG_ACCEL_PWR_CONF 0x7C
|
||||||
|
|
||||||
|
/* Accel Power control (switch on or off register */
|
||||||
|
#define BMI08X_REG_ACCEL_PWR_CTRL 0x7D
|
||||||
|
|
||||||
|
/* Accel Soft reset register */
|
||||||
|
#define BMI08X_REG_ACCEL_SOFTRESET 0x7E
|
||||||
|
|
||||||
|
/* BMI085 Accel unique chip identifier */
|
||||||
|
#define BMI085_ACCEL_CHIP_ID 0x1F
|
||||||
|
|
||||||
|
/* BMI088 Accel unique chip identifier */
|
||||||
|
#define BMI088_ACCEL_CHIP_ID 0x1E
|
||||||
|
|
||||||
|
/* Feature Config related Registers */
|
||||||
|
#define BMI08X_ACCEL_RESERVED_5B_REG 0x5B
|
||||||
|
#define BMI08X_ACCEL_RESERVED_5C_REG 0x5C
|
||||||
|
#define BMI08X_ACCEL_FEATURE_CFG_REG 0x5E
|
||||||
|
|
||||||
|
/* Interrupt masks */
|
||||||
|
#define BMI08X_ACCEL_DATA_READY_INT 0x80
|
||||||
|
|
||||||
|
/* Accel Bandwidth */
|
||||||
|
#define BMI08X_ACCEL_BW_OSR4 0x00
|
||||||
|
#define BMI08X_ACCEL_BW_OSR2 0x01
|
||||||
|
#define BMI08X_ACCEL_BW_NORMAL 0x02
|
||||||
|
|
||||||
|
/* BMI085 Accel Range */
|
||||||
|
#define BMI085_ACCEL_RANGE_2G 0x00
|
||||||
|
#define BMI085_ACCEL_RANGE_4G 0x01
|
||||||
|
#define BMI085_ACCEL_RANGE_8G 0x02
|
||||||
|
#define BMI085_ACCEL_RANGE_16G 0x03
|
||||||
|
|
||||||
|
/**\name BMI088 Accel Range */
|
||||||
|
#define BMI088_ACCEL_RANGE_3G 0x00
|
||||||
|
#define BMI088_ACCEL_RANGE_6G 0x01
|
||||||
|
#define BMI088_ACCEL_RANGE_12G 0x02
|
||||||
|
#define BMI088_ACCEL_RANGE_24G 0x03
|
||||||
|
|
||||||
|
/* Accel Output data rate */
|
||||||
|
#define BMI08X_ACCEL_ODR_12_5_HZ 0x05
|
||||||
|
#define BMI08X_ACCEL_ODR_25_HZ 0x06
|
||||||
|
#define BMI08X_ACCEL_ODR_50_HZ 0x07
|
||||||
|
#define BMI08X_ACCEL_ODR_100_HZ 0x08
|
||||||
|
#define BMI08X_ACCEL_ODR_200_HZ 0x09
|
||||||
|
#define BMI08X_ACCEL_ODR_400_HZ 0x0A
|
||||||
|
#define BMI08X_ACCEL_ODR_800_HZ 0x0B
|
||||||
|
#define BMI08X_ACCEL_ODR_1600_HZ 0x0C
|
||||||
|
|
||||||
|
/* Accel Init Ctrl */
|
||||||
|
#define BMI08X_ACCEL_INIT_CTRL_DISABLE 0x00
|
||||||
|
#define BMI08X_ACCEL_INIT_CTRL_ENABLE 0x01
|
||||||
|
|
||||||
|
/* Accel Self test */
|
||||||
|
#define BMI08X_ACCEL_SWITCH_OFF_SELF_TEST 0x00
|
||||||
|
#define BMI08X_ACCEL_POSITIVE_SELF_TEST 0x0D
|
||||||
|
#define BMI08X_ACCEL_NEGATIVE_SELF_TEST 0x09
|
||||||
|
|
||||||
|
/* Accel Power mode */
|
||||||
|
#define BMI08X_ACCEL_PM_ACTIVE 0x00
|
||||||
|
#define BMI08X_ACCEL_PM_SUSPEND 0x03
|
||||||
|
|
||||||
|
/* Accel Power control settings */
|
||||||
|
#define BMI08X_ACCEL_POWER_DISABLE 0x00
|
||||||
|
#define BMI08X_ACCEL_POWER_ENABLE 0x04
|
||||||
|
|
||||||
|
/* Accel internal interrupt pin mapping */
|
||||||
|
#define BMI08X_ACCEL_INTA_DISABLE 0x00
|
||||||
|
#define BMI08X_ACCEL_INTA_ENABLE 0x01
|
||||||
|
#define BMI08X_ACCEL_INTB_DISABLE 0x00
|
||||||
|
#define BMI08X_ACCEL_INTB_ENABLE 0x02
|
||||||
|
#define BMI08X_ACCEL_INTC_DISABLE 0x00
|
||||||
|
#define BMI08X_ACCEL_INTC_ENABLE 0x04
|
||||||
|
|
||||||
|
/* Accel Soft reset delay */
|
||||||
|
#define BMI08X_ACCEL_SOFTRESET_DELAY_MS 1
|
||||||
|
|
||||||
|
/* Mask definitions for ACCEL_ERR_REG register */
|
||||||
|
#define BMI08X_FATAL_ERR_MASK 0x01
|
||||||
|
#define BMI08X_ERR_CODE_MASK 0x1C
|
||||||
|
|
||||||
|
/* Position definitions for ACCEL_ERR_REG register */
|
||||||
|
#define BMI08X_CMD_ERR_POS 1
|
||||||
|
#define BMI08X_ERR_CODE_POS 2
|
||||||
|
|
||||||
|
/* Mask definition for ACCEL_STATUS_REG register */
|
||||||
|
#define BMI08X_ACCEL_STATUS_MASK 0x80
|
||||||
|
|
||||||
|
/* Position definitions for ACCEL_STATUS_REG */
|
||||||
|
#define BMI08X_ACCEL_STATUS_POS 7
|
||||||
|
|
||||||
|
/* Mask definitions for odr, bandwidth and range */
|
||||||
|
#define BMI08X_ACCEL_ODR_MASK 0x0F
|
||||||
|
#define BMI08X_ACCEL_BW_MASK 0x70
|
||||||
|
#define BMI08X_ACCEL_RANGE_MASK 0x03
|
||||||
|
|
||||||
|
/* Position definitions for odr, bandwidth and range */
|
||||||
|
#define BMI08X_ACCEL_BW_POS 4
|
||||||
|
|
||||||
|
/* Mask definitions for INT1_IO_CONF register */
|
||||||
|
#define BMI08X_ACCEL_INT_EDGE_MASK 0x01
|
||||||
|
#define BMI08X_ACCEL_INT_LVL_MASK 0x02
|
||||||
|
#define BMI08X_ACCEL_INT_OD_MASK 0x04
|
||||||
|
#define BMI08X_ACCEL_INT_IO_MASK 0x08
|
||||||
|
#define BMI08X_ACCEL_INT_IN_MASK 0x10
|
||||||
|
|
||||||
|
/* Position definitions for INT1_IO_CONF register */
|
||||||
|
#define BMI08X_ACCEL_INT_EDGE_POS 0
|
||||||
|
#define BMI08X_ACCEL_INT_LVL_POS 1
|
||||||
|
#define BMI08X_ACCEL_INT_OD_POS 2
|
||||||
|
#define BMI08X_ACCEL_INT_IO_POS 3
|
||||||
|
#define BMI08X_ACCEL_INT_IN_POS 4
|
||||||
|
|
||||||
|
/* Mask definitions for INT1/INT2 mapping register */
|
||||||
|
#define BMI08X_ACCEL_MAP_INTA_MASK 0x01
|
||||||
|
|
||||||
|
/* Mask definitions for INT1/INT2 mapping register */
|
||||||
|
#define BMI08X_ACCEL_MAP_INTA_POS 0x00
|
||||||
|
|
||||||
|
/* Mask definitions for INT1_INT2_MAP_DATA register */
|
||||||
|
#define BMI08X_ACCEL_INT1_DRDY_MASK 0x04
|
||||||
|
#define BMI08X_ACCEL_INT2_DRDY_MASK 0x40
|
||||||
|
|
||||||
|
/* Position definitions for INT1_INT2_MAP_DATA register */
|
||||||
|
#define BMI08X_ACCEL_INT1_DRDY_POS 2
|
||||||
|
#define BMI08X_ACCEL_INT2_DRDY_POS 6
|
||||||
|
|
||||||
|
/* Asic Initialization value */
|
||||||
|
#define BMI08X_ASIC_INITIALIZED 0x01
|
||||||
|
|
||||||
|
#define BMI08X_TEMP_OFFSET 32
|
||||||
|
|
||||||
|
/*************************** BMI08 Gyroscope Macros *****************************/
|
||||||
|
/** Register map */
|
||||||
|
/* Gyro registers */
|
||||||
|
|
||||||
|
/* Gyro Chip Id register */
|
||||||
|
#define BMI08X_REG_GYRO_CHIP_ID 0x00
|
||||||
|
|
||||||
|
/* Gyro X LSB data register */
|
||||||
|
#define BMI08X_REG_GYRO_X_LSB 0x02
|
||||||
|
|
||||||
|
/* Gyro X MSB data register */
|
||||||
|
#define BMI08X_REG_GYRO_X_MSB 0x03
|
||||||
|
|
||||||
|
/* Gyro Y LSB data register */
|
||||||
|
#define BMI08X_REG_GYRO_Y_LSB 0x04
|
||||||
|
|
||||||
|
/* Gyro Y MSB data register */
|
||||||
|
#define BMI08X_REG_GYRO_Y_MSB 0x05
|
||||||
|
|
||||||
|
/* Gyro Z LSB data register */
|
||||||
|
#define BMI08X_REG_GYRO_Z_LSB 0x06
|
||||||
|
|
||||||
|
/* Gyro Z MSB data register */
|
||||||
|
#define BMI08X_REG_GYRO_Z_MSB 0x07
|
||||||
|
|
||||||
|
/* Gyro Interrupt status register */
|
||||||
|
#define BMI08X_REG_GYRO_INT_STAT_1 0x0A
|
||||||
|
|
||||||
|
/* Gyro Range register */
|
||||||
|
#define BMI08X_REG_GYRO_RANGE 0x0F
|
||||||
|
|
||||||
|
/* Gyro Bandwidth register */
|
||||||
|
#define BMI08X_REG_GYRO_BANDWIDTH 0x10
|
||||||
|
|
||||||
|
/* Gyro Power register */
|
||||||
|
#define BMI08X_REG_GYRO_LPM1 0x11
|
||||||
|
|
||||||
|
/* Gyro Soft reset register */
|
||||||
|
#define BMI08X_REG_GYRO_SOFTRESET 0x14
|
||||||
|
|
||||||
|
/* Gyro Interrupt control register */
|
||||||
|
#define BMI08X_REG_GYRO_INT_CTRL 0x15
|
||||||
|
|
||||||
|
/* Gyro Interrupt Pin configuration register */
|
||||||
|
#define BMI08X_REG_GYRO_INT3_INT4_IO_CONF 0x16
|
||||||
|
|
||||||
|
/* Gyro Interrupt Map register */
|
||||||
|
#define BMI08X_REG_GYRO_INT3_INT4_IO_MAP 0x18
|
||||||
|
|
||||||
|
/* Gyro Self test register */
|
||||||
|
#define BMI08X_REG_GYRO_SELF_TEST 0x3C
|
||||||
|
|
||||||
|
/* Gyro unique chip identifier */
|
||||||
|
#define BMI08X_GYRO_CHIP_ID 0x0F
|
||||||
|
|
||||||
|
/* Gyro Range */
|
||||||
|
#define BMI08X_GYRO_RANGE_2000_DPS 0x00
|
||||||
|
#define BMI08X_GYRO_RANGE_1000_DPS 0x01
|
||||||
|
#define BMI08X_GYRO_RANGE_500_DPS 0x02
|
||||||
|
#define BMI08X_GYRO_RANGE_250_DPS 0x03
|
||||||
|
#define BMI08X_GYRO_RANGE_125_DPS 0x04
|
||||||
|
|
||||||
|
/* Gyro Output data rate and bandwidth */
|
||||||
|
#define BMI08X_GYRO_BW_532_ODR_2000_HZ 0x00
|
||||||
|
#define BMI08X_GYRO_BW_230_ODR_2000_HZ 0x01
|
||||||
|
#define BMI08X_GYRO_BW_116_ODR_1000_HZ 0x02
|
||||||
|
#define BMI08X_GYRO_BW_47_ODR_400_HZ 0x03
|
||||||
|
#define BMI08X_GYRO_BW_23_ODR_200_HZ 0x04
|
||||||
|
#define BMI08X_GYRO_BW_12_ODR_100_HZ 0x05
|
||||||
|
#define BMI08X_GYRO_BW_64_ODR_200_HZ 0x06
|
||||||
|
#define BMI08X_GYRO_BW_32_ODR_100_HZ 0x07
|
||||||
|
#define BMI08X_GYRO_ODR_RESET_VAL 0x80
|
||||||
|
|
||||||
|
/* Gyro Power mode */
|
||||||
|
#define BMI08X_GYRO_PM_NORMAL 0x00
|
||||||
|
#define BMI08X_GYRO_PM_DEEP_SUSPEND 0x20
|
||||||
|
#define BMI08X_GYRO_PM_SUSPEND 0x80
|
||||||
|
|
||||||
|
/* Gyro data ready interrupt enable value */
|
||||||
|
#define BMI08X_GYRO_DRDY_INT_DISABLE_VAL 0x00
|
||||||
|
#define BMI08X_GYRO_DRDY_INT_ENABLE_VAL 0x80
|
||||||
|
|
||||||
|
/* Gyro data ready map values */
|
||||||
|
#define BMI08X_GYRO_MAP_DRDY_TO_INT3 0x01
|
||||||
|
#define BMI08X_GYRO_MAP_DRDY_TO_INT4 0x80
|
||||||
|
#define BMI08X_GYRO_MAP_DRDY_TO_BOTH_INT3_INT4 0x81
|
||||||
|
|
||||||
|
/* Gyro Soft reset delay */
|
||||||
|
#define BMI08X_GYRO_SOFTRESET_DELAY 30
|
||||||
|
|
||||||
|
/* Gyro power mode config delay */
|
||||||
|
#define BMI08X_GYRO_POWER_MODE_CONFIG_DELAY 30
|
||||||
|
|
||||||
|
/** Mask definitions for range, bandwidth and power */
|
||||||
|
#define BMI08X_GYRO_RANGE_MASK 0x07
|
||||||
|
#define BMI08X_GYRO_BW_MASK 0x0F
|
||||||
|
#define BMI08X_GYRO_POWER_MASK 0xA0
|
||||||
|
|
||||||
|
/** Position definitions for range, bandwidth and power */
|
||||||
|
#define BMI08X_GYRO_POWER_POS 5
|
||||||
|
|
||||||
|
/* Mask definitions for BMI08X_GYRO_INT_CTRL_REG register */
|
||||||
|
#define BMI08X_GYRO_DATA_EN_MASK 0x80
|
||||||
|
|
||||||
|
/* Position definitions for BMI08X_GYRO_INT_CTRL_REG register */
|
||||||
|
#define BMI08X_GYRO_DATA_EN_POS 7
|
||||||
|
|
||||||
|
/* Mask definitions for BMI08X_GYRO_INT3_INT4_IO_CONF_REG register */
|
||||||
|
#define BMI08X_GYRO_INT3_LVL_MASK 0x01
|
||||||
|
#define BMI08X_GYRO_INT3_OD_MASK 0x02
|
||||||
|
#define BMI08X_GYRO_INT4_LVL_MASK 0x04
|
||||||
|
#define BMI08X_GYRO_INT4_OD_MASK 0x08
|
||||||
|
|
||||||
|
/* Position definitions for BMI08X_GYRO_INT3_INT4_IO_CONF_REG register */
|
||||||
|
#define BMI08X_GYRO_INT3_OD_POS 1
|
||||||
|
#define BMI08X_GYRO_INT4_LVL_POS 2
|
||||||
|
#define BMI08X_GYRO_INT4_OD_POS 3
|
||||||
|
|
||||||
|
/* Mask definitions for BMI08X_GYRO_INT_EN_REG register */
|
||||||
|
#define BMI08X_GYRO_INT_EN_MASK 0x80
|
||||||
|
|
||||||
|
/* Position definitions for BMI08X_GYRO_INT_EN_REG register */
|
||||||
|
#define BMI08X_GYRO_INT_EN_POS 7
|
||||||
|
|
||||||
|
/* Mask definitions for BMI088_GYRO_INT_MAP_REG register */
|
||||||
|
#define BMI08X_GYRO_INT3_MAP_MASK 0x01
|
||||||
|
#define BMI08X_GYRO_INT4_MAP_MASK 0x80
|
||||||
|
|
||||||
|
/* Position definitions for BMI088_GYRO_INT_MAP_REG register */
|
||||||
|
#define BMI08X_GYRO_INT3_MAP_POS 0
|
||||||
|
#define BMI08X_GYRO_INT4_MAP_POS 7
|
||||||
|
|
||||||
|
/* Mask definitions for BMI088_GYRO_INT_MAP_REG register */
|
||||||
|
#define BMI088_GYRO_INT3_MAP_MASK 0x01
|
||||||
|
#define BMI088_GYRO_INT4_MAP_MASK 0x80
|
||||||
|
|
||||||
|
/* Position definitions for BMI088_GYRO_INT_MAP_REG register */
|
||||||
|
#define BMI088_GYRO_INT3_MAP_POS 0
|
||||||
|
#define BMI088_GYRO_INT4_MAP_POS 7
|
||||||
|
|
||||||
|
/* Mask definitions for GYRO_SELF_TEST register */
|
||||||
|
#define BMI08X_GYRO_SELF_TEST_EN_MASK 0x01
|
||||||
|
#define BMI08X_GYRO_SELF_TEST_RDY_MASK 0x02
|
||||||
|
#define BMI08X_GYRO_SELF_TEST_RESULT_MASK 0x04
|
||||||
|
#define BMI08X_GYRO_SELF_TEST_FUNCTION_MASK 0x08
|
||||||
|
|
||||||
|
/* Position definitions for GYRO_SELF_TEST register */
|
||||||
|
#define BMI08X_GYRO_SELF_TEST_RDY_POS 1
|
||||||
|
#define BMI08X_GYRO_SELF_TEST_RESULT_POS 2
|
||||||
|
#define BMI08X_GYRO_SELF_TEST_FUNCTION_POS 3
|
||||||
|
|
||||||
|
/*************************** Common Macros for both Accel and Gyro *****************************/
|
||||||
|
/** Soft reset Value */
|
||||||
|
#define BMI08X_SOFT_RESET_CMD 0xB6
|
||||||
|
|
||||||
|
/* Constant values macros */
|
||||||
|
#define BMI08X_SENSOR_DATA_SYNC_TIME_MS 1
|
||||||
|
#define BMI08X_DELAY_BETWEEN_WRITES_MS 1
|
||||||
|
#define BMI08X_SELF_TEST_DELAY_MS 3
|
||||||
|
#define BMI08X_POWER_CONFIG_DELAY 5
|
||||||
|
#define BMI08X_SENSOR_SETTLE_TIME_MS 30
|
||||||
|
#define BMI08X_SELF_TEST_DATA_READ_MS 50
|
||||||
|
#define BMI08X_ASIC_INIT_TIME_MS 150
|
||||||
|
|
||||||
|
/* allowed ODR values */
|
||||||
|
enum bmi08x_odr {
|
||||||
|
BMI08X_ODR_25_2,
|
||||||
|
BMI08X_ODR_25,
|
||||||
|
BMI08X_ODR_50,
|
||||||
|
BMI08X_ODR_100,
|
||||||
|
BMI08X_ODR_200,
|
||||||
|
BMI08X_ODR_400,
|
||||||
|
BMI08X_ODR_800,
|
||||||
|
BMI08X_ODR_1600,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Range values for accelerometer */
|
||||||
|
#define BMI08X_ACC_RANGE_2G_3G 0x0
|
||||||
|
#define BMI08X_ACC_RANGE_4G_6G 0x1
|
||||||
|
#define BMI08X_ACC_RANGE_8G_12G 0x2
|
||||||
|
#define BMI08X_ACC_RANGE_16G_24G 0x3
|
||||||
|
|
||||||
|
/* Range values for gyro */
|
||||||
|
#define BMI08X_GYR_RANGE_2000DPS 0
|
||||||
|
#define BMI08X_GYR_RANGE_1000DPS 1
|
||||||
|
#define BMI08X_GYR_RANGE_500DPS 2
|
||||||
|
#define BMI08X_GYR_RANGE_250DPS 3
|
||||||
|
#define BMI08X_GYR_RANGE_125DPS 4
|
||||||
|
|
||||||
|
#define BMI08X_ACC_SCALE(range_g) ((2 * range_g * SENSOR_G) / 65536LL)
|
||||||
|
#define BMI08X_GYR_SCALE(range_dps) ((2 * range_dps * SENSOR_PI) / 180LL / 65536LL)
|
||||||
|
|
||||||
|
/* report of data sync is selected */
|
||||||
|
#define BMI08X_ACCEL_DATA_SYNC_EN(inst) DT_NODE_HAS_STATUS(DT_INST_PHANDLE(inst, data_sync), okay)
|
||||||
|
/* Macro used for compile time optimization to compile in/out code used for data-sync
|
||||||
|
* if at least 1 bmi08x has data-sync enabled
|
||||||
|
*/
|
||||||
|
#define ACCEL_HELPER(inst) BMI08X_ACCEL_DATA_SYNC_EN(inst) ||
|
||||||
|
#define BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC DT_INST_FOREACH_STATUS_OKAY(ACCEL_HELPER) 0
|
||||||
|
#define GYRO_HELPER(inst) DT_INST_PROP(inst, data_sync) ||
|
||||||
|
#define BMI08X_GYRO_ANY_INST_HAS_DATA_SYNC DT_INST_FOREACH_STATUS_OKAY(GYRO_HELPER) 0
|
||||||
|
|
||||||
|
struct bmi08x_range {
|
||||||
|
uint16_t range;
|
||||||
|
uint8_t reg_val;
|
||||||
|
};
|
||||||
|
|
||||||
|
union bmi08x_bus {
|
||||||
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||||
|
struct spi_dt_spec spi;
|
||||||
|
#endif
|
||||||
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||||
|
struct i2c_dt_spec i2c;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bmi08x_accel_bus_io {
|
||||||
|
int (*check)(const union bmi08x_bus *bus);
|
||||||
|
int (*bus_init)(const struct device *dev);
|
||||||
|
int (*transceive)(const struct device *dev, uint8_t reg, bool write, void *data,
|
||||||
|
size_t length);
|
||||||
|
#if BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
|
||||||
|
int (*write_config_file)(const struct device *dev);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bmi08x_gyro_bus_io {
|
||||||
|
int (*check)(const union bmi08x_bus *bus);
|
||||||
|
int (*transceive)(const struct device *dev, uint8_t reg, bool write, void *data,
|
||||||
|
size_t length);
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_BMI08X_ACCEL_TRIGGER) || BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
|
||||||
|
uint8_t int1_map;
|
||||||
|
uint8_t int2_map;
|
||||||
|
uint8_t int1_conf_io;
|
||||||
|
uint8_t int2_conf_io;
|
||||||
|
#endif
|
||||||
|
uint8_t accel_hz;
|
||||||
|
uint8_t accel_fs;
|
||||||
|
#if BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
|
||||||
|
uint8_t data_sync;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_BMI08X_GYRO_TRIGGER) || BMI08X_GYRO_ANY_INST_HAS_DATA_SYNC
|
||||||
|
uint8_t int3_4_map;
|
||||||
|
uint8_t int3_4_conf_io;
|
||||||
|
#endif
|
||||||
|
uint8_t gyro_hz;
|
||||||
|
uint8_t gyro_fs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bmi08x_accel_data {
|
||||||
|
#if defined(CONFIG_BMI08X_ACCEL_TRIGGER)
|
||||||
|
struct gpio_callback gpio_cb;
|
||||||
|
#endif
|
||||||
|
uint16_t acc_sample[3];
|
||||||
|
uint16_t scale; /* micro m/s^2/lsb */
|
||||||
|
|
||||||
|
#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
|
||||||
|
sensor_trigger_handler_t handler_drdy_acc;
|
||||||
|
const struct sensor_trigger *drdy_trig_acc;
|
||||||
|
#endif /* CONFIG_BMI08X_ACCEL_TRIGGER */
|
||||||
|
uint8_t accel_chip_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bmi08x_gyro_data {
|
||||||
|
#if defined(CONFIG_BMI08X_GYRO_TRIGGER)
|
||||||
|
struct gpio_callback gpio_cb;
|
||||||
|
#endif
|
||||||
|
uint16_t gyr_sample[3];
|
||||||
|
uint16_t scale; /* micro radians/s/lsb */
|
||||||
|
|
||||||
|
#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
|
||||||
|
sensor_trigger_handler_t handler_drdy_gyr;
|
||||||
|
const struct sensor_trigger *drdy_trig_gyr;
|
||||||
|
#endif /* CONFIG_BMI08X_GYRO_TRIGGER */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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,
|
||||||
|
uint16_t range_map_size);
|
||||||
|
int32_t bmi08x_reg_val_to_range(uint8_t reg_val, const struct bmi08x_range *range_map,
|
||||||
|
uint16_t range_map_size);
|
||||||
|
|
||||||
|
int bmi08x_accel_read(const struct device *dev, uint8_t reg_addr, uint8_t *data, uint8_t len);
|
||||||
|
int bmi08x_accel_write(const struct device *dev, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
||||||
|
int bmi08x_accel_byte_read(const struct device *dev, uint8_t reg_addr, uint8_t *byte);
|
||||||
|
int bmi08x_accel_byte_write(const struct device *dev, uint8_t reg_addr, uint8_t byte);
|
||||||
|
int bmi08x_accel_word_write(const struct device *dev, uint8_t reg_addr, uint16_t word);
|
||||||
|
int bmi08x_accel_reg_field_update(const struct device *dev, uint8_t reg_addr, uint8_t pos,
|
||||||
|
uint8_t mask, uint8_t val);
|
||||||
|
static inline int bmi08x_accel_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t mask,
|
||||||
|
uint8_t val)
|
||||||
|
{
|
||||||
|
return bmi08x_accel_reg_field_update(dev, reg_addr, 0, mask, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_gyro_read(const struct device *dev, uint8_t reg_addr, uint8_t *data, uint8_t len);
|
||||||
|
int bmi08x_gyro_byte_read(const struct device *dev, uint8_t reg_addr, uint8_t *byte);
|
||||||
|
int bmi08x_gyro_byte_write(const struct device *dev, uint8_t reg_addr, uint8_t byte);
|
||||||
|
int bmi08x_gyro_word_write(const struct device *dev, uint8_t reg_addr, uint16_t word);
|
||||||
|
int bmi08x_gyro_reg_field_update(const struct device *dev, uint8_t reg_addr, uint8_t pos,
|
||||||
|
uint8_t mask, uint8_t val);
|
||||||
|
static inline int bmi08x_gyro_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t mask,
|
||||||
|
uint8_t val)
|
||||||
|
{
|
||||||
|
return bmi08x_gyro_reg_field_update(dev, reg_addr, 0, mask, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_acc_trigger_mode_init(const struct device *dev);
|
||||||
|
int bmi08x_trigger_set_acc(const struct device *dev, const struct sensor_trigger *trig,
|
||||||
|
sensor_trigger_handler_t handler);
|
||||||
|
int bmi08x_acc_slope_config(const struct device *dev, enum sensor_attribute attr,
|
||||||
|
const struct sensor_value *val);
|
||||||
|
int32_t bmi08x_acc_reg_val_to_range(uint8_t reg_val);
|
||||||
|
|
||||||
|
int bmi08x_gyr_trigger_mode_init(const struct device *dev);
|
||||||
|
int bmi08x_trigger_set_gyr(const struct device *dev, const struct sensor_trigger *trig,
|
||||||
|
sensor_trigger_handler_t handler);
|
||||||
|
int bmi08x_gyr_slope_config(const struct device *dev, enum sensor_attribute attr,
|
||||||
|
const struct sensor_value *val);
|
||||||
|
int32_t bmi08x_gyr_reg_val_to_range(uint8_t reg_val);
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_DRIVERS_SENSOR_BMI08X_H_ */
|
812
drivers/sensor/bmi08x/bmi08x_accel.c
Normal file
812
drivers/sensor/bmi08x/bmi08x_accel.c
Normal file
|
@ -0,0 +1,812 @@
|
||||||
|
/* Bosch BMI08X inertial measurement unit driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Meta Platforms, Inc. and its affiliates
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/drivers/sensor.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>
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT bosch_bmi08x_accel
|
||||||
|
#include "bmi08x.h"
|
||||||
|
#include "bmi08x_config_file.h"
|
||||||
|
|
||||||
|
LOG_MODULE_REGISTER(BMI08X_ACCEL, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
|
|
||||||
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||||
|
|
||||||
|
static int bmi08x_accel_transceive_i2c(const struct device *dev, uint8_t reg, bool write,
|
||||||
|
void *data, size_t length)
|
||||||
|
{
|
||||||
|
const struct bmi08x_accel_config *bmi08x = dev->config;
|
||||||
|
|
||||||
|
if (!write) {
|
||||||
|
return i2c_write_read_dt(&bmi08x->bus.i2c, ®, 1, data, length);
|
||||||
|
}
|
||||||
|
if (length > CONFIG_BMI08X_I2C_WRITE_BURST_SIZE) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
uint8_t buf[1 + CONFIG_BMI08X_I2C_WRITE_BURST_SIZE];
|
||||||
|
|
||||||
|
buf[0] = reg;
|
||||||
|
memcpy(&buf[1], data, length);
|
||||||
|
return i2c_write_dt(&bmi08x->bus.i2c, buf, 1 + length);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
|
||||||
|
static int bmi08x_stream_transfer_write_i2c(const struct device *dev, uint16_t index,
|
||||||
|
const uint8_t *stream_data, uint16_t stream_length)
|
||||||
|
{
|
||||||
|
uint8_t asic_msb = (uint8_t)((index / 2) >> 4);
|
||||||
|
uint8_t asic_lsb = ((index / 2) & 0x0F);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_ACCEL_RESERVED_5B_REG, asic_lsb);
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_ERR("Cannot write index");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_ACCEL_RESERVED_5C_REG, asic_msb);
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_ERR("Cannot write index");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = bmi08x_accel_write(dev, BMI08X_ACCEL_FEATURE_CFG_REG, (uint8_t *)stream_data,
|
||||||
|
stream_length);
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_ERR("Cannot write configuration for accelerometer.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_write_config_file_i2c(const struct device *dev)
|
||||||
|
{
|
||||||
|
const uint8_t *data = bmi08x_config_file;
|
||||||
|
uint16_t length = sizeof(bmi08x_config_file);
|
||||||
|
uint16_t index = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
while (length != 0) {
|
||||||
|
uint16_t len1 = length;
|
||||||
|
|
||||||
|
if (len1 > CONFIG_BMI08X_I2C_WRITE_BURST_SIZE) {
|
||||||
|
len1 = CONFIG_BMI08X_I2C_WRITE_BURST_SIZE;
|
||||||
|
}
|
||||||
|
ret = bmi08x_stream_transfer_write_i2c(dev, index, data, len1);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
index += len1;
|
||||||
|
data += len1;
|
||||||
|
length -= len1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int bmi08x_bus_check_i2c(const union bmi08x_bus *bus)
|
||||||
|
{
|
||||||
|
return i2c_is_ready_dt(&bus->i2c) ? 0 : -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bmi08x_accel_bus_io bmi08x_i2c_api = {.check = bmi08x_bus_check_i2c,
|
||||||
|
.transceive = bmi08x_accel_transceive_i2c,
|
||||||
|
#if BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
|
||||||
|
.write_config_file =
|
||||||
|
bmi08x_write_config_file_i2c
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */
|
||||||
|
|
||||||
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||||
|
|
||||||
|
static int bmi08x_accel_transceive_spi(const struct device *dev, uint8_t reg, bool write,
|
||||||
|
void *data, size_t length)
|
||||||
|
{
|
||||||
|
const struct bmi08x_accel_config *bmi08x = dev->config;
|
||||||
|
const struct spi_buf tx_buf[2] = {{.buf = ®, .len = 1}, {.buf = data, .len = length}};
|
||||||
|
const struct spi_buf_set tx = {.buffers = tx_buf, .count = write ? 2 : 1};
|
||||||
|
|
||||||
|
if (!write) {
|
||||||
|
uint16_t dummy;
|
||||||
|
const struct spi_buf rx_buf[2] = {{.buf = &dummy, .len = 2},
|
||||||
|
{.buf = data, .len = length}};
|
||||||
|
const struct spi_buf_set rx = {.buffers = rx_buf, .count = 2};
|
||||||
|
|
||||||
|
return spi_transceive_dt(&bmi08x->bus.spi, &tx, &rx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return spi_write_dt(&bmi08x->bus.spi, &tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
|
||||||
|
static int bmi08x_write_config_file_spi(const struct device *dev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_ACCEL_RESERVED_5B_REG, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot write index");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_ACCEL_RESERVED_5C_REG, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot write index");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* write config file */
|
||||||
|
ret = bmi08x_accel_write(dev, BMI08X_ACCEL_FEATURE_CFG_REG, (uint8_t *)bmi08x_config_file,
|
||||||
|
sizeof(bmi08x_config_file));
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot write configuration for accelerometer.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int bmi08x_bus_check_spi(const union bmi08x_bus *bus)
|
||||||
|
{
|
||||||
|
return spi_is_ready_dt(&bus->spi) ? 0 : -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_bus_init_spi(const struct device *dev)
|
||||||
|
{
|
||||||
|
uint8_t val;
|
||||||
|
int ret;
|
||||||
|
/* do a dummy read from 0x7F to activate SPI */
|
||||||
|
ret = bmi08x_accel_byte_read(dev, 0x7F, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot read from 0x7F..");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_usleep(100);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bmi08x_accel_bus_io bmi08x_spi_api = {.check = bmi08x_bus_check_spi,
|
||||||
|
.bus_init = bmi08x_bus_init_spi,
|
||||||
|
.transceive = bmi08x_accel_transceive_spi,
|
||||||
|
#if BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
|
||||||
|
.write_config_file =
|
||||||
|
bmi08x_write_config_file_spi
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
|
||||||
|
|
||||||
|
static inline int bmi08x_bus_check(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct bmi08x_accel_config *config = dev->config;
|
||||||
|
|
||||||
|
return config->api->check(&config->bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int bmi08x_bus_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct bmi08x_accel_config *config = dev->config;
|
||||||
|
|
||||||
|
/* optional, only needed to initialize SPI according to datasheet */
|
||||||
|
if (config->api->bus_init) {
|
||||||
|
return config->api->bus_init(dev);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_accel_transceive(const struct device *dev, uint8_t reg, bool write, void *data,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
const struct bmi08x_accel_config *config = dev->config;
|
||||||
|
|
||||||
|
return config->api->transceive(dev, reg, write, data, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_accel_read(const struct device *dev, uint8_t reg_addr, uint8_t *data, uint8_t len)
|
||||||
|
{
|
||||||
|
return bmi08x_accel_transceive(dev, reg_addr | BIT(7), false, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_accel_write(const struct device *dev, uint8_t reg_addr, uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
return bmi08x_accel_transceive(dev, reg_addr, true, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_accel_byte_read(const struct device *dev, uint8_t reg_addr, uint8_t *byte)
|
||||||
|
{
|
||||||
|
return bmi08x_accel_transceive(dev, reg_addr | BIT(7), false, byte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_accel_word_read(const struct device *dev, uint8_t reg_addr, uint16_t *word)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bmi08x_accel_transceive(dev, reg_addr | BIT(7), false, word, 2);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
*word = sys_le16_to_cpu(*word);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_accel_byte_write(const struct device *dev, uint8_t reg_addr, uint8_t byte)
|
||||||
|
{
|
||||||
|
return bmi08x_accel_transceive(dev, reg_addr & 0x7F, true, &byte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_accel_word_write(const struct device *dev, uint8_t reg_addr, uint16_t word)
|
||||||
|
{
|
||||||
|
uint8_t tx_word[2] = {(uint8_t)(word & 0xff), (uint8_t)(word >> 8)};
|
||||||
|
|
||||||
|
return bmi08x_accel_transceive(dev, reg_addr & 0x7F, true, tx_word, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_accel_reg_field_update(const struct device *dev, uint8_t reg_addr, uint8_t pos,
|
||||||
|
uint8_t mask, uint8_t val)
|
||||||
|
{
|
||||||
|
uint8_t old_val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bmi08x_accel_byte_read(dev, reg_addr, &old_val);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bmi08x_accel_byte_write(dev, reg_addr, (old_val & ~mask) | ((val << pos) & mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_acc_odr_set(const struct device *dev, uint16_t freq_int, uint16_t freq_milli)
|
||||||
|
{
|
||||||
|
int odr = bmi08x_freq_to_odr_val(freq_int, freq_milli);
|
||||||
|
|
||||||
|
if (odr < BMI08X_ACCEL_ODR_12_5_HZ) {
|
||||||
|
return odr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bmi08x_accel_reg_field_update(dev, BMI08X_REG_ACCEL_CONF, 0, BMI08X_ACCEL_ODR_MASK,
|
||||||
|
(uint8_t)odr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bmi08x_range bmi085_acc_range_map[] = {
|
||||||
|
{2, BMI085_ACCEL_RANGE_2G},
|
||||||
|
{4, BMI085_ACCEL_RANGE_4G},
|
||||||
|
{8, BMI085_ACCEL_RANGE_8G},
|
||||||
|
{16, BMI085_ACCEL_RANGE_16G},
|
||||||
|
};
|
||||||
|
#define BMI085_ACC_RANGE_MAP_SIZE ARRAY_SIZE(bmi085_acc_range_map)
|
||||||
|
|
||||||
|
static const struct bmi08x_range bmi088_acc_range_map[] = {
|
||||||
|
{3, BMI088_ACCEL_RANGE_3G},
|
||||||
|
{6, BMI088_ACCEL_RANGE_6G},
|
||||||
|
{12, BMI088_ACCEL_RANGE_12G},
|
||||||
|
{24, BMI088_ACCEL_RANGE_24G},
|
||||||
|
};
|
||||||
|
#define BMI088_ACC_RANGE_MAP_SIZE ARRAY_SIZE(bmi088_acc_range_map)
|
||||||
|
|
||||||
|
static int bmi08x_acc_range_set(const struct device *dev, int32_t range)
|
||||||
|
{
|
||||||
|
struct bmi08x_accel_data *data = dev->data;
|
||||||
|
int32_t reg_val = -1;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (data->accel_chip_id == BMI085_ACCEL_CHIP_ID) {
|
||||||
|
reg_val = bmi08x_range_to_reg_val(range, bmi085_acc_range_map,
|
||||||
|
BMI085_ACC_RANGE_MAP_SIZE);
|
||||||
|
} else if (data->accel_chip_id == BMI088_ACCEL_CHIP_ID) {
|
||||||
|
reg_val = bmi08x_range_to_reg_val(range, bmi088_acc_range_map,
|
||||||
|
BMI088_ACC_RANGE_MAP_SIZE);
|
||||||
|
} else {
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg_val < 0) {
|
||||||
|
return reg_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_RANGE, reg_val & 0xff);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->scale = BMI08X_ACC_SCALE(range);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_acc_config(const struct device *dev, enum sensor_channel chan,
|
||||||
|
enum sensor_attribute attr, const struct sensor_value *val)
|
||||||
|
{
|
||||||
|
switch (attr) {
|
||||||
|
case SENSOR_ATTR_FULL_SCALE:
|
||||||
|
return bmi08x_acc_range_set(dev, sensor_ms2_to_g(val));
|
||||||
|
case SENSOR_ATTR_SAMPLING_FREQUENCY:
|
||||||
|
return bmi08x_acc_odr_set(dev, val->val1, val->val2 / 1000);
|
||||||
|
default:
|
||||||
|
LOG_ERR("Accel attribute not supported.");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_attr_set(const struct device *dev, enum sensor_channel chan,
|
||||||
|
enum sensor_attribute attr, const struct sensor_value *val)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_PM_DEVICE
|
||||||
|
enum pm_device_state state;
|
||||||
|
|
||||||
|
(void)pm_device_state_get(dev, &state);
|
||||||
|
if (state != PM_DEVICE_STATE_ACTIVE) {
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (chan) {
|
||||||
|
case SENSOR_CHAN_ACCEL_X:
|
||||||
|
case SENSOR_CHAN_ACCEL_Y:
|
||||||
|
case SENSOR_CHAN_ACCEL_Z:
|
||||||
|
case SENSOR_CHAN_ACCEL_XYZ:
|
||||||
|
return bmi08x_acc_config(dev, chan, attr, val);
|
||||||
|
default:
|
||||||
|
LOG_ERR("attr_set() not supported on this channel.");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
||||||
|
{
|
||||||
|
struct bmi08x_accel_data *data = dev->data;
|
||||||
|
size_t i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_ACCEL_XYZ) {
|
||||||
|
LOG_ERR("Unsupported sensor channel");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_DEVICE
|
||||||
|
enum pm_device_state state;
|
||||||
|
|
||||||
|
(void)pm_device_state_get(dev, &state);
|
||||||
|
if (state != PM_DEVICE_STATE_ACTIVE) {
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pm_device_busy_set(dev);
|
||||||
|
|
||||||
|
ret = bmi08x_accel_read(dev, BMI08X_REG_ACCEL_X_LSB, (uint8_t *)data->acc_sample,
|
||||||
|
sizeof(data->acc_sample));
|
||||||
|
if (ret < 0) {
|
||||||
|
pm_device_busy_clear(dev);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert samples to cpu endianness */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(data->acc_sample); i++) {
|
||||||
|
data->acc_sample[i] = sys_le16_to_cpu(data->acc_sample[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pm_device_busy_clear(dev);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bmi08x_to_fixed_point(int16_t raw_val, uint16_t scale, struct sensor_value *val)
|
||||||
|
{
|
||||||
|
int32_t converted_val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* maximum converted value we can get is: max(raw_val) * max(scale)
|
||||||
|
* max(raw_val) = +/- 2^15
|
||||||
|
* max(scale) = 4785
|
||||||
|
* max(converted_val) = 156794880 which is less than 2^31
|
||||||
|
*/
|
||||||
|
converted_val = raw_val * scale;
|
||||||
|
val->val1 = converted_val / 1000000;
|
||||||
|
val->val2 = converted_val % 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bmi08x_channel_convert(enum sensor_channel chan, uint16_t scale, uint16_t *raw_xyz,
|
||||||
|
struct sensor_value *val)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint8_t ofs_start, ofs_stop;
|
||||||
|
|
||||||
|
switch (chan) {
|
||||||
|
case SENSOR_CHAN_ACCEL_X:
|
||||||
|
ofs_start = ofs_stop = 0U;
|
||||||
|
break;
|
||||||
|
case SENSOR_CHAN_ACCEL_Y:
|
||||||
|
ofs_start = ofs_stop = 1U;
|
||||||
|
break;
|
||||||
|
case SENSOR_CHAN_ACCEL_Z:
|
||||||
|
ofs_start = ofs_stop = 2U;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ofs_start = 0U;
|
||||||
|
ofs_stop = 2U;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = ofs_start; i <= ofs_stop; i++, val++) {
|
||||||
|
bmi08x_to_fixed_point(raw_xyz[i], scale, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void bmi08x_acc_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||||
|
struct sensor_value *val)
|
||||||
|
{
|
||||||
|
struct bmi08x_accel_data *data = dev->data;
|
||||||
|
|
||||||
|
bmi08x_channel_convert(chan, data->scale, data->acc_sample, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_temp_channel_get(const struct device *dev, struct sensor_value *val)
|
||||||
|
{
|
||||||
|
uint16_t temp_raw = 0U;
|
||||||
|
int32_t temp_micro = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bmi08x_accel_word_read(dev, BMI08X_REG_TEMP_MSB, &temp_raw);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the scale is 1/2^5/LSB = 31250 micro degrees */
|
||||||
|
temp_micro = BMI08X_TEMP_OFFSET * 1000000ULL + temp_raw * 31250ULL;
|
||||||
|
|
||||||
|
val->val1 = temp_micro / 1000000ULL;
|
||||||
|
val->val2 = temp_micro % 1000000ULL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||||
|
struct sensor_value *val)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_PM_DEVICE
|
||||||
|
enum pm_device_state state;
|
||||||
|
|
||||||
|
(void)pm_device_state_get(dev, &state);
|
||||||
|
if (state != PM_DEVICE_STATE_ACTIVE) {
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch ((int16_t)chan) {
|
||||||
|
case SENSOR_CHAN_ACCEL_X:
|
||||||
|
case SENSOR_CHAN_ACCEL_Y:
|
||||||
|
case SENSOR_CHAN_ACCEL_Z:
|
||||||
|
case SENSOR_CHAN_ACCEL_XYZ:
|
||||||
|
bmi08x_acc_channel_get(dev, chan, val);
|
||||||
|
return 0;
|
||||||
|
case SENSOR_CHAN_DIE_TEMP:
|
||||||
|
return bmi08x_temp_channel_get(dev, val);
|
||||||
|
default:
|
||||||
|
LOG_ERR("Channel not supported.");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_DEVICE
|
||||||
|
static int bmi08x_accel_pm_action(const struct device *dev, enum pm_device_action action)
|
||||||
|
{
|
||||||
|
uint8_t conf_reg_val;
|
||||||
|
uint8_t ctrl_reg_val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case PM_DEVICE_ACTION_RESUME:
|
||||||
|
conf_reg_val = BMI08X_ACCEL_PM_ACTIVE;
|
||||||
|
ctrl_reg_val = BMI08X_ACCEL_POWER_ENABLE;
|
||||||
|
break;
|
||||||
|
case PM_DEVICE_ACTION_SUSPEND:
|
||||||
|
conf_reg_val = BMI08X_ACCEL_PM_SUSPEND;
|
||||||
|
ctrl_reg_val = BMI08X_ACCEL_POWER_DISABLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_PWR_CONF, conf_reg_val);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to set conf power mode");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
k_msleep(BMI08X_POWER_CONFIG_DELAY);
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_PWR_CTRL, ctrl_reg_val);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to set ctrl power mode");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
k_msleep(BMI08X_POWER_CONFIG_DELAY);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PM_DEVICE */
|
||||||
|
|
||||||
|
static const struct sensor_driver_api bmi08x_api = {
|
||||||
|
.attr_set = bmi08x_attr_set,
|
||||||
|
#ifdef CONFIG_BMI08X_ACCEL_TRIGGER
|
||||||
|
.trigger_set = bmi08x_trigger_set_acc,
|
||||||
|
#endif
|
||||||
|
.sample_fetch = bmi08x_sample_fetch,
|
||||||
|
.channel_get = bmi08x_channel_get,
|
||||||
|
};
|
||||||
|
|
||||||
|
#if BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
|
||||||
|
static int bmi08x_apply_sync_binary_config(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct bmi08x_accel_config *config = dev->config;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_PWR_CONF, BMI08X_ACCEL_PM_ACTIVE);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot deactivate advanced power save mode.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* required when switching power modes */
|
||||||
|
k_msleep(BMI08X_POWER_CONFIG_DELAY);
|
||||||
|
|
||||||
|
/* deactivate accel, otherwise post processing can not be enabled safely */
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_PWR_CTRL, BMI08X_ACCEL_POWER_DISABLE);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot deactivate accel.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* required when switching power modes */
|
||||||
|
k_msleep(BMI08X_POWER_CONFIG_DELAY);
|
||||||
|
/* disable config loading */
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_INIT_CTRL,
|
||||||
|
BMI08X_ACCEL_INIT_CTRL_DISABLE);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot disable config loading.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config->api->write_config_file(dev) != 0) {
|
||||||
|
LOG_ERR("Cannot write configuration for accelerometer.");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
k_msleep(5U);
|
||||||
|
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_INIT_CTRL,
|
||||||
|
BMI08X_ACCEL_INIT_CTRL_ENABLE);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot write configuration for accelerometer.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
k_msleep(BMI08X_ASIC_INIT_TIME_MS);
|
||||||
|
|
||||||
|
/* check config initialization status */
|
||||||
|
uint8_t val;
|
||||||
|
|
||||||
|
ret = bmi08x_accel_byte_read(dev, BMI08X_REG_ACCEL_INTERNAL_STAT, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot write configuration for accelerometer.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (val != 1) {
|
||||||
|
LOG_ERR("Configuration stream error.");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write feature configuration */
|
||||||
|
uint8_t fdata[8];
|
||||||
|
|
||||||
|
ret = bmi08x_accel_read(dev, BMI08X_ACCEL_FEATURE_CFG_REG, fdata, 6);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot read configuration for accelerometer.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
fdata[4] = config->data_sync;
|
||||||
|
fdata[5] = 0x00;
|
||||||
|
ret = bmi08x_accel_write(dev, BMI08X_ACCEL_FEATURE_CFG_REG, fdata, 6);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot write configuration for accelerometer.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
k_msleep(100U);
|
||||||
|
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_PWR_CTRL, BMI08X_ACCEL_POWER_ENABLE);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot activate accel.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* required when switching power modes */
|
||||||
|
k_msleep(BMI08X_POWER_CONFIG_DELAY);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int bmi08x_accel_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct bmi08x_accel_config *config = dev->config;
|
||||||
|
struct bmi08x_accel_data *data = dev->data;
|
||||||
|
uint8_t val = 0U;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bmi08x_bus_check(dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Bus not ready for '%s'", dev->name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reboot the chip */
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_SOFTRESET, BMI08X_SOFT_RESET_CMD);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot reboot chip.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_msleep(BMI08X_ACCEL_SOFTRESET_DELAY_MS);
|
||||||
|
|
||||||
|
ret = bmi08x_bus_init(dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Can't initialize bus for %s", dev->name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = bmi08x_accel_byte_read(dev, BMI08X_REG_ACCEL_CHIP_ID, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to read chip id.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((val != BMI085_ACCEL_CHIP_ID) && (val != BMI088_ACCEL_CHIP_ID)) {
|
||||||
|
LOG_ERR("Unsupported chip detected (0x%02x)!", val);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
data->accel_chip_id = val;
|
||||||
|
|
||||||
|
/* enable power */
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_PWR_CONF, BMI08X_ACCEL_PM_ACTIVE);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to set conf power mode");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
k_msleep(BMI08X_POWER_CONFIG_DELAY);
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_PWR_CTRL, BMI08X_ACCEL_POWER_ENABLE);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to set ctrl power mode");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
k_msleep(BMI08X_POWER_CONFIG_DELAY);
|
||||||
|
|
||||||
|
#if BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
|
||||||
|
if (config->data_sync != 0) {
|
||||||
|
ret = bmi08x_apply_sync_binary_config(dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* set accelerometer default range, divide by two because the dts contains both bmi085 and
|
||||||
|
* bmi088 valid values even values in the enum are for the bmi085 and odd values are for the
|
||||||
|
* bmi088
|
||||||
|
*/
|
||||||
|
ret = bmi08x_acc_range_set(dev, config->accel_fs);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot set default range for accelerometer.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set accelerometer default odr */
|
||||||
|
/* add 5 to offset from the dts enum */
|
||||||
|
ret = bmi08x_accel_reg_field_update(dev, BMI08X_REG_ACCEL_CONF, 0, BMI08X_ACCEL_ODR_MASK,
|
||||||
|
config->accel_hz);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to set accel's default ODR.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_BMI08X_ACCEL_TRIGGER
|
||||||
|
ret = bmi08x_acc_trigger_mode_init(dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot set up trigger mode.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BMI08X_CONFIG_SPI(inst) \
|
||||||
|
.bus.spi = SPI_DT_SPEC_INST_GET( \
|
||||||
|
inst, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), 2),
|
||||||
|
|
||||||
|
#define BMI08X_CONFIG_I2C(inst) .bus.i2c = I2C_DT_SPEC_INST_GET(inst),
|
||||||
|
|
||||||
|
#define BMI08X_ACCEL_TRIG(inst) \
|
||||||
|
.int1_map = DT_INST_PROP(inst, int1_map_io), .int2_map = DT_INST_PROP(inst, int2_map_io), \
|
||||||
|
.int1_conf_io = DT_INST_PROP(inst, int1_conf_io), \
|
||||||
|
.int2_conf_io = DT_INST_PROP(inst, int2_conf_io),
|
||||||
|
|
||||||
|
/* verify the bmi08x-accel is paired with a bmi08x-gyro */
|
||||||
|
#define BMI08X_VERIFY_DATA_SYNC(inst) \
|
||||||
|
BUILD_ASSERT(DT_NODE_HAS_COMPAT(DT_INST_PHANDLE(inst, data_sync), bosch_bmi08x_gyro) != 0, \
|
||||||
|
"bmi08x-accel data sync not paired with a bmi08x-gyro")
|
||||||
|
/*
|
||||||
|
* verify data sync odr, the only valid odr combinitions with the gyro are
|
||||||
|
* (gyro-hz == "400_47" and accel-hz == "400") or (gyro-hz == "1000_116" and accel-hz == "800")
|
||||||
|
* or ((gyro-hz == "2000_230" or gyro-hz == "2000_532") and accel-hz == "1600")
|
||||||
|
*/
|
||||||
|
#define BMI08X_GYRO_ODR(inst) DT_ENUM_IDX(DT_INST_PHANDLE(inst, data_sync), gyro_hz)
|
||||||
|
#define BMI08X_ACCEL_ODR(inst) DT_INST_ENUM_IDX(inst, accel_hz)
|
||||||
|
/* As the dts uses strings to define the definition, ints must be used for comparision */
|
||||||
|
#define BMI08X_VERIFY_DATA_SYNC_ODR(inst) \
|
||||||
|
BUILD_ASSERT((BMI08X_GYRO_ODR(inst) == 3 && BMI08X_ACCEL_ODR(inst) == 5) || \
|
||||||
|
(BMI08X_GYRO_ODR(inst) == 2 && BMI08X_ACCEL_ODR(inst) == 6) || \
|
||||||
|
((BMI08X_GYRO_ODR(inst) == 1 || BMI08X_GYRO_ODR(inst) == 0) && \
|
||||||
|
BMI08X_ACCEL_ODR(inst) == 7), \
|
||||||
|
"Invalid gyro and accel odr for data-sync")
|
||||||
|
/* Assert if the gyro does not have data-sync enabled */
|
||||||
|
#define BMI08X_VERIFY_GYRO_DATA_SYNC_EN(inst) \
|
||||||
|
BUILD_ASSERT(DT_PROP(DT_INST_PHANDLE(inst, data_sync), data_sync), \
|
||||||
|
"paired bmi08x-gyro does not have data-sync enabled")
|
||||||
|
|
||||||
|
/* infer the data-sync value from the gyro and accel odr 2000=1, 1000=2, 400=3, otherwise it is 0 if
|
||||||
|
* it is not enabled. the build_assert should prevent any invalid values when it is enabled
|
||||||
|
*/
|
||||||
|
#define BMI08X_DATA_SYNC_REG_VAL(inst) \
|
||||||
|
(BMI08X_GYRO_ODR(inst) == 3 && BMI08X_ACCEL_ODR(inst) == 5) ? 3 \
|
||||||
|
: (BMI08X_GYRO_ODR(inst) == 2 && BMI08X_ACCEL_ODR(inst) == 6) ? 2 \
|
||||||
|
: ((BMI08X_GYRO_ODR(inst) == 1 || BMI08X_GYRO_ODR(inst) == 0) && \
|
||||||
|
BMI08X_ACCEL_ODR(inst) == 7) \
|
||||||
|
? 1 \
|
||||||
|
: 0
|
||||||
|
|
||||||
|
/* define the .data_sync in the driver config */
|
||||||
|
#if BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
|
||||||
|
/* if another bmi08x as the data sync enabled, and one doesn't, it will get the value of 0 and won't
|
||||||
|
* have the config file sent over
|
||||||
|
*/
|
||||||
|
#define BMI08X_DATA_SYNC_REG(inst) \
|
||||||
|
.data_sync = COND_CODE_1(BMI08X_ACCEL_DATA_SYNC_EN(inst), \
|
||||||
|
(BMI08X_DATA_SYNC_REG_VAL(inst)), (0)),
|
||||||
|
#define BMI08X_ACCEL_TRIGGER_PINS(inst) BMI08X_ACCEL_TRIG(inst)
|
||||||
|
#else
|
||||||
|
#define BMI08X_DATA_SYNC_REG(inst)
|
||||||
|
#define BMI08X_ACCEL_TRIGGER_PINS(inst) \
|
||||||
|
IF_ENABLED(CONFIG_BMI08X_ACCEL_TRIGGER, (BMI08X_ACCEL_TRIG(inst)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BMI08X_CREATE_INST(inst) \
|
||||||
|
\
|
||||||
|
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 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),)) \
|
||||||
|
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)}; \
|
||||||
|
\
|
||||||
|
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), \
|
||||||
|
&bmi08x_drv_##inst, &bmi08x_config_##inst, POST_KERNEL, \
|
||||||
|
CONFIG_SENSOR_INIT_PRIORITY, &bmi08x_api);
|
||||||
|
|
||||||
|
/* Create the struct device for every status "okay" node in the devicetree. */
|
||||||
|
DT_INST_FOREACH_STATUS_OKAY(BMI08X_CREATE_INST)
|
171
drivers/sensor/bmi08x/bmi08x_accel_trigger.c
Normal file
171
drivers/sensor/bmi08x/bmi08x_accel_trigger.c
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
/* Bosch BMI08X inertial measurement unit driver, trigger implementation
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Meta Platforms, Inc. and its affiliates
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/drivers/gpio.h>
|
||||||
|
#include <zephyr/drivers/sensor.h>
|
||||||
|
#include <zephyr/pm/device.h>
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT bosch_bmi08x_accel
|
||||||
|
#include "bmi08x.h"
|
||||||
|
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
LOG_MODULE_DECLARE(BMI08X_ACCEL, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
|
|
||||||
|
static void bmi08x_handle_drdy_acc(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct bmi08x_accel_data *data = dev->data;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_DEVICE
|
||||||
|
enum pm_device_state state;
|
||||||
|
|
||||||
|
(void)pm_device_state_get(dev, &state);
|
||||||
|
if (state != PM_DEVICE_STATE_ACTIVE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (data->handler_drdy_acc) {
|
||||||
|
data->handler_drdy_acc(dev, data->drdy_trig_acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bmi08x_handle_interrupts_acc(void *arg)
|
||||||
|
{
|
||||||
|
const struct device *dev = (const struct device *)arg;
|
||||||
|
|
||||||
|
bmi08x_handle_drdy_acc(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_BMI08X_ACCEL_TRIGGER_OWN_THREAD
|
||||||
|
static void bmi08x_acc_thread_main(void *arg1, void *unused1, void *unused2)
|
||||||
|
{
|
||||||
|
k_thread_name_set(NULL, "bmi08x_acc_trig");
|
||||||
|
|
||||||
|
ARG_UNUSED(unused1);
|
||||||
|
ARG_UNUSED(unused2);
|
||||||
|
|
||||||
|
const struct device *dev = (const struct device *)arg1;
|
||||||
|
struct bmi08x_accel_data *data = dev->data;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
k_sem_take(&data->sem, K_FOREVER);
|
||||||
|
bmi08x_handle_interrupts_acc((void *)dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BMI08X_ACCEL_TRIGGER_GLOBAL_THREAD
|
||||||
|
static void bmi08x_acc_work_handler(struct k_work *work)
|
||||||
|
{
|
||||||
|
struct bmi08x_accel_data *data = CONTAINER_OF(work, struct bmi08x_accel_data, work);
|
||||||
|
|
||||||
|
bmi08x_handle_interrupts_acc((void *)data->dev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void bmi08x_acc_gpio_callback(const struct device *port, struct gpio_callback *cb,
|
||||||
|
uint32_t pin)
|
||||||
|
{
|
||||||
|
struct bmi08x_accel_data *data = CONTAINER_OF(cb, struct bmi08x_accel_data, gpio_cb);
|
||||||
|
|
||||||
|
ARG_UNUSED(port);
|
||||||
|
ARG_UNUSED(pin);
|
||||||
|
|
||||||
|
#if defined(CONFIG_BMI08X_ACCEL_TRIGGER_OWN_THREAD)
|
||||||
|
k_sem_give(&data->sem);
|
||||||
|
#elif defined(CONFIG_BMI08X_ACCEL_TRIGGER_GLOBAL_THREAD)
|
||||||
|
k_work_submit(&data->work);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_trigger_set_acc(const struct device *dev, const struct sensor_trigger *trig,
|
||||||
|
sensor_trigger_handler_t handler)
|
||||||
|
{
|
||||||
|
struct bmi08x_accel_data *data = dev->data;
|
||||||
|
|
||||||
|
if ((trig->chan == SENSOR_CHAN_ACCEL_XYZ) && (trig->type == SENSOR_TRIG_DATA_READY)) {
|
||||||
|
data->handler_drdy_acc = handler;
|
||||||
|
data->drdy_trig_acc = trig;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_acc_trigger_mode_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct bmi08x_accel_data *data = dev->data;
|
||||||
|
const struct bmi08x_accel_config *cfg = dev->config;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!gpio_is_ready_dt(&cfg->int_gpio)) {
|
||||||
|
LOG_ERR("GPIO device not ready");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BMI08X_ACCEL_TRIGGER_OWN_THREAD)
|
||||||
|
k_sem_init(&data->sem, 0, K_SEM_MAX_LIMIT);
|
||||||
|
|
||||||
|
k_thread_create(&data->thread, data->thread_stack,
|
||||||
|
CONFIG_BMI08X_ACCEL_THREAD_STACK_SIZE, bmi08x_acc_thread_main, (void *)dev,
|
||||||
|
NULL, NULL, K_PRIO_COOP(CONFIG_BMI08X_ACCEL_THREAD_PRIORITY), 0, K_NO_WAIT);
|
||||||
|
#elif defined(CONFIG_BMI08X_ACCEL_TRIGGER_GLOBAL_THREAD)
|
||||||
|
data->work.handler = bmi08x_acc_work_handler;
|
||||||
|
data->dev = dev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BMI08X_ACCEL_ANY_INST_HAS_DATA_SYNC
|
||||||
|
if (config->data_sync != 0) {
|
||||||
|
/* set accel ints */
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_INT1_MAP, cfg->int1_map);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to map interrupts.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_INT2_MAP, cfg->int2_map);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to map interrupts.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
uint8_t map_data = ((cfg->int2_map << BMI08X_ACCEL_INT2_DRDY_POS) |
|
||||||
|
(cfg->int1_map << BMI08X_ACCEL_INT1_DRDY_POS));
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_INT1_INT2_MAP_DATA, map_data);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to map interrupts.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_INT1_IO_CONF, cfg->int1_conf_io);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to map interrupts.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = bmi08x_accel_byte_write(dev, BMI08X_REG_ACCEL_INT2_IO_CONF, cfg->int2_conf_io);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to map interrupts.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_pin_configure_dt(&cfg->int_gpio, GPIO_INPUT);
|
||||||
|
|
||||||
|
gpio_init_callback(&data->gpio_cb, bmi08x_acc_gpio_callback, BIT(cfg->int_gpio.pin));
|
||||||
|
|
||||||
|
ret = gpio_add_callback(cfg->int_gpio.port, &data->gpio_cb);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to set gpio callback.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_EDGE_TO_ACTIVE);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
424
drivers/sensor/bmi08x/bmi08x_config_file.h
Normal file
424
drivers/sensor/bmi08x/bmi08x_config_file.h
Normal file
|
@ -0,0 +1,424 @@
|
||||||
|
/* Bosch BMI08X inertial measurement unit header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Bosch Sensortec GmbH.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BMI08X_BMI08X_CONFIG_FILE_H_
|
||||||
|
#define BMI08X_BMI08X_CONFIG_FILE_H_
|
||||||
|
|
||||||
|
/* Source : https://github.com/BoschSensortec/BMI08x-Sensor-API/blob/bmi08x_v1.5.8/bmi08a.c#L69 */
|
||||||
|
const uint8_t bmi08x_config_file[] = {
|
||||||
|
0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x48, 0xb4, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x6d,
|
||||||
|
0xb4, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0xd4, 0xb3, 0x80, 0x2e, 0xb0, 0xb3, 0x80, 0x2e,
|
||||||
|
0x12, 0xb4, 0x50, 0x39, 0x21, 0x2e, 0xb0, 0xf0, 0x10, 0x30, 0x21, 0x2e, 0x16, 0xf0, 0x80,
|
||||||
|
0x2e, 0xfe, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
|
||||||
|
0x79, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x40, 0x50, 0xfb, 0x7f, 0x98, 0x2e, 0x03, 0xb1, 0x12, 0x24, 0x67, 0x00, 0x90, 0x42,
|
||||||
|
0x81, 0x42, 0xba, 0x82, 0xd1, 0x7f, 0xe2, 0x7f, 0x98, 0x2e, 0x3c, 0xb0, 0xd1, 0x6f, 0x00,
|
||||||
|
0x2e, 0x41, 0x40, 0x40, 0xb2, 0x4c, 0x2f, 0xe1, 0x6f, 0x44, 0x86, 0x03, 0x2e, 0x67, 0x00,
|
||||||
|
0xc2, 0x40, 0xf7, 0x86, 0x4a, 0x04, 0xc1, 0x42, 0x00, 0x2e, 0xc2, 0x40, 0x80, 0xac, 0x01,
|
||||||
|
0x2f, 0x23, 0x2e, 0x63, 0x00, 0xd1, 0x40, 0xd2, 0x40, 0x0a, 0x0f, 0x01, 0x2f, 0x40, 0xac,
|
||||||
|
0x02, 0x2f, 0x01, 0x30, 0x23, 0x2e, 0x63, 0x00, 0xfe, 0x82, 0xc2, 0x40, 0x43, 0x40, 0xd3,
|
||||||
|
0x04, 0x46, 0x84, 0xc3, 0x7f, 0x85, 0x86, 0xc5, 0x82, 0x45, 0x80, 0x44, 0x40, 0xc1, 0x6f,
|
||||||
|
0xc3, 0x40, 0xe0, 0x7f, 0xd1, 0x7f, 0x00, 0x2e, 0x82, 0x40, 0x98, 0x2e, 0x00, 0xb0, 0xe1,
|
||||||
|
0x6f, 0x72, 0x84, 0x40, 0x42, 0x85, 0x86, 0xc5, 0x82, 0x45, 0x80, 0x44, 0x40, 0xc3, 0x40,
|
||||||
|
0xd1, 0x6f, 0xe0, 0x7f, 0x00, 0x2e, 0x82, 0x40, 0x98, 0x2e, 0x00, 0xb0, 0xe1, 0x6f, 0x72,
|
||||||
|
0x84, 0x40, 0x42, 0x85, 0x86, 0xc5, 0x82, 0x45, 0x80, 0x44, 0x40, 0xc3, 0x40, 0xd1, 0x6f,
|
||||||
|
0xe0, 0x7f, 0x00, 0x2e, 0x82, 0x40, 0x98, 0x2e, 0x00, 0xb0, 0xe1, 0x6f, 0x00, 0x2e, 0x40,
|
||||||
|
0x42, 0x98, 0x2e, 0xa5, 0xb0, 0x11, 0x30, 0x23, 0x2e, 0x5e, 0xf0, 0xfb, 0x6f, 0xc0, 0x5f,
|
||||||
|
0xb8, 0x2e, 0xaa, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0xed,
|
||||||
|
0x8f, 0xd9, 0x31, 0x00, 0x00, 0xc6, 0x01, 0x8c, 0x03, 0xc6, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xb0, 0x50, 0xf0, 0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x01, 0x01, 0x02, 0xbc,
|
||||||
|
0x0f, 0xb8, 0xe0, 0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x01, 0x01, 0x01, 0xbc, 0x0f, 0xb8, 0xd0,
|
||||||
|
0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x01, 0x01, 0x0f, 0xb8, 0xc0, 0x7f, 0x02, 0x30, 0xe6, 0x6f,
|
||||||
|
0xd4, 0x6f, 0xc3, 0x6f, 0x80, 0x91, 0x04, 0x2f, 0x00, 0x91, 0x02, 0x2f, 0xc0, 0xb2, 0x90,
|
||||||
|
0x2e, 0xf6, 0x01, 0xf0, 0x6f, 0x0b, 0x2e, 0x24, 0x00, 0x01, 0x82, 0x40, 0x91, 0x14, 0x2f,
|
||||||
|
0x41, 0x87, 0x27, 0x2e, 0x24, 0x00, 0x00, 0x40, 0x21, 0x2e, 0x1b, 0x00, 0x53, 0x40, 0x10,
|
||||||
|
0x24, 0x1c, 0x00, 0x13, 0x42, 0x00, 0x2e, 0x41, 0x40, 0x01, 0x42, 0x25, 0x2e, 0x18, 0x00,
|
||||||
|
0x25, 0x2e, 0x19, 0x00, 0x25, 0x2e, 0x1e, 0x00, 0x50, 0x5f, 0xb8, 0x2e, 0x0b, 0x2e, 0x00,
|
||||||
|
0x01, 0xd5, 0xbe, 0xd5, 0xba, 0xb5, 0x7f, 0x00, 0x2e, 0x0b, 0x2e, 0x01, 0x01, 0xd3, 0xbe,
|
||||||
|
0xd3, 0xba, 0xa5, 0x7f, 0x00, 0x2e, 0x0b, 0x2e, 0x00, 0x01, 0xd4, 0xbe, 0xdf, 0xba, 0x95,
|
||||||
|
0x7f, 0x00, 0x2e, 0x95, 0x6f, 0x0f, 0x2e, 0x1a, 0x00, 0x3d, 0x1a, 0x05, 0x2f, 0x25, 0x2e,
|
||||||
|
0x18, 0x00, 0x25, 0x2e, 0x19, 0x00, 0x2b, 0x2e, 0x1a, 0x00, 0x80, 0x91, 0x01, 0x2f, 0x06,
|
||||||
|
0x30, 0x07, 0x2d, 0x06, 0x40, 0x0f, 0x2e, 0x1b, 0x00, 0xb7, 0x05, 0x80, 0xa9, 0xd6, 0x05,
|
||||||
|
0xb7, 0x23, 0x86, 0x7f, 0x00, 0x91, 0x01, 0x2f, 0x04, 0x30, 0x07, 0x2d, 0x44, 0x40, 0x0d,
|
||||||
|
0x2e, 0x1c, 0x00, 0x26, 0x05, 0x00, 0xa9, 0x94, 0x05, 0x26, 0x23, 0x74, 0x7f, 0xc0, 0x90,
|
||||||
|
0x01, 0x2f, 0x00, 0x2e, 0x09, 0x2d, 0x02, 0x86, 0x00, 0x2e, 0xc3, 0x40, 0x09, 0x2e, 0x1d,
|
||||||
|
0x00, 0xdc, 0x04, 0xc0, 0xa8, 0x93, 0x04, 0x9a, 0x22, 0x62, 0x7f, 0x12, 0x30, 0x84, 0x6f,
|
||||||
|
0xb3, 0x6f, 0x63, 0x0f, 0x14, 0x30, 0x08, 0x2f, 0x74, 0x6f, 0x63, 0x0f, 0x14, 0x30, 0x04,
|
||||||
|
0x2f, 0x64, 0x6f, 0x63, 0x0f, 0x14, 0x30, 0x00, 0x2f, 0x04, 0x30, 0x54, 0x7f, 0x40, 0x91,
|
||||||
|
0x0b, 0x2e, 0x18, 0x00, 0x54, 0x6f, 0xa3, 0x6f, 0x6a, 0x29, 0x1d, 0x2f, 0x00, 0x91, 0x06,
|
||||||
|
0x30, 0x14, 0x24, 0x1c, 0x00, 0x0d, 0x2f, 0x2d, 0x2e, 0x18, 0x00, 0x05, 0x2e, 0x19, 0x00,
|
||||||
|
0x81, 0x84, 0x25, 0x2e, 0x19, 0x00, 0x05, 0x2e, 0x19, 0x00, 0x53, 0x0e, 0x2b, 0x2f, 0x2d,
|
||||||
|
0x2e, 0x1e, 0x00, 0x29, 0x2d, 0x2b, 0x2e, 0x18, 0x00, 0x2d, 0x2e, 0x19, 0x00, 0x0b, 0x2e,
|
||||||
|
0x18, 0x00, 0x6b, 0x0e, 0x20, 0x2f, 0x25, 0x2e, 0x1e, 0x00, 0x1e, 0x2d, 0x00, 0xb3, 0x05,
|
||||||
|
0x2f, 0x02, 0x30, 0x25, 0x2e, 0x18, 0x00, 0x25, 0x2e, 0x1e, 0x00, 0x08, 0x2d, 0x2b, 0x2e,
|
||||||
|
0x18, 0x00, 0x09, 0x2e, 0x18, 0x00, 0x63, 0x0e, 0x01, 0x2f, 0x25, 0x2e, 0x1e, 0x00, 0x02,
|
||||||
|
0x40, 0x25, 0x2e, 0x1b, 0x00, 0x31, 0x25, 0x00, 0x2e, 0xd5, 0x40, 0x12, 0x24, 0x1c, 0x00,
|
||||||
|
0x42, 0x25, 0x95, 0x42, 0x00, 0x2e, 0xc3, 0x40, 0x83, 0x42, 0x00, 0x2e, 0x05, 0x2e, 0x1e,
|
||||||
|
0x00, 0x80, 0xb2, 0x0d, 0x2f, 0x00, 0x40, 0x21, 0x2e, 0x1b, 0x00, 0x50, 0x40, 0x10, 0x43,
|
||||||
|
0x00, 0x2e, 0x40, 0x40, 0x00, 0x43, 0x20, 0x30, 0x21, 0x2e, 0x5e, 0xf0, 0x02, 0x2d, 0x25,
|
||||||
|
0x2e, 0x24, 0x00, 0x50, 0x5f, 0xb8, 0x2e, 0x40, 0x30, 0x21, 0x2e, 0xba, 0xf0, 0xb8, 0x2e,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x70, 0x50, 0xf4, 0x7f, 0xe3, 0x7f, 0xd2, 0x7f, 0xc1, 0x7f, 0x12,
|
||||||
|
0x30, 0x03, 0x2e, 0x66, 0x00, 0x91, 0x14, 0x92, 0x7f, 0x00, 0x31, 0xc4, 0x6f, 0x95, 0x6f,
|
||||||
|
0xe3, 0x6f, 0xa5, 0x0f, 0x70, 0x84, 0x01, 0x04, 0x14, 0x2f, 0xd5, 0x6f, 0x00, 0xa9, 0x01,
|
||||||
|
0x2f, 0xa5, 0x7f, 0x21, 0x2d, 0xdd, 0x04, 0xb3, 0x7f, 0x40, 0xb2, 0xb3, 0x6f, 0x1c, 0x18,
|
||||||
|
0x06, 0x2f, 0x50, 0xa0, 0x01, 0x2f, 0xba, 0x11, 0x03, 0x2d, 0x71, 0x12, 0xb8, 0x14, 0x8a,
|
||||||
|
0x0b, 0x6e, 0x00, 0xa1, 0x7f, 0x11, 0x2d, 0xf7, 0x6f, 0xfb, 0x05, 0xb7, 0x7f, 0x25, 0x05,
|
||||||
|
0xb5, 0x6f, 0x2c, 0x18, 0x40, 0xb2, 0x06, 0x2f, 0x50, 0xa0, 0x01, 0x2f, 0xba, 0x11, 0x03,
|
||||||
|
0x2d, 0x71, 0x12, 0xb8, 0x14, 0x8a, 0x0b, 0x5e, 0x00, 0xa1, 0x7f, 0x00, 0x2e, 0xa0, 0x6f,
|
||||||
|
0x90, 0x5f, 0xb8, 0x2e, 0x01, 0x2e, 0x02, 0x01, 0x8e, 0xbc, 0x01, 0x2e, 0x62, 0x00, 0x9e,
|
||||||
|
0xb8, 0x01, 0x1a, 0x5f, 0x2f, 0x01, 0x2e, 0x02, 0x01, 0x0e, 0xbc, 0x0e, 0xb8, 0x21, 0x2e,
|
||||||
|
0x62, 0x00, 0x03, 0x2e, 0x62, 0x00, 0x43, 0xb2, 0x10, 0x24, 0x65, 0x00, 0x3c, 0x2f, 0x42,
|
||||||
|
0xb2, 0x22, 0x2f, 0x41, 0xb2, 0x06, 0x2f, 0x01, 0x30, 0x11, 0x42, 0x01, 0x42, 0x3e, 0x80,
|
||||||
|
0x00, 0x2e, 0x01, 0x42, 0xb8, 0x2e, 0x03, 0x2e, 0x9d, 0x00, 0x5f, 0x90, 0x62, 0x30, 0x11,
|
||||||
|
0x24, 0x81, 0x00, 0x07, 0x2f, 0x30, 0x25, 0x34, 0x37, 0xd4, 0x42, 0xc2, 0x42, 0xfe, 0x86,
|
||||||
|
0x00, 0x2e, 0xc1, 0x42, 0x00, 0x2e, 0x07, 0x2e, 0x9d, 0x00, 0xde, 0x90, 0x35, 0x2f, 0x63,
|
||||||
|
0x36, 0x13, 0x42, 0x02, 0x42, 0x3e, 0x80, 0x00, 0x2e, 0x01, 0x42, 0xb8, 0x2e, 0x03, 0x2e,
|
||||||
|
0x9d, 0x00, 0x5f, 0xb2, 0x52, 0x30, 0x21, 0x32, 0x0a, 0x2f, 0x07, 0x2e, 0x9d, 0x00, 0xde,
|
||||||
|
0x90, 0x24, 0x2f, 0x23, 0x31, 0x13, 0x42, 0x02, 0x42, 0x3e, 0x80, 0x00, 0x2e, 0x01, 0x42,
|
||||||
|
0xb8, 0x2e, 0x03, 0x32, 0x13, 0x42, 0x02, 0x42, 0x3e, 0x80, 0x00, 0x2e, 0x01, 0x42, 0xb8,
|
||||||
|
0x2e, 0x03, 0x2e, 0x9d, 0x00, 0x5f, 0xb2, 0x42, 0x30, 0x11, 0x31, 0x0a, 0x2f, 0x07, 0x2e,
|
||||||
|
0x9d, 0x00, 0xde, 0x90, 0x0c, 0x2f, 0xa3, 0x30, 0x13, 0x42, 0x02, 0x42, 0x3e, 0x80, 0x00,
|
||||||
|
0x2e, 0x01, 0x42, 0xb8, 0x2e, 0x63, 0x31, 0x13, 0x42, 0x02, 0x42, 0x3e, 0x80, 0x00, 0x2e,
|
||||||
|
0x01, 0x42, 0xb8, 0x2e, 0x10, 0x24, 0x78, 0x00, 0x11, 0x24, 0x52, 0xf0, 0x12, 0x40, 0x52,
|
||||||
|
0x42, 0x28, 0xb5, 0x52, 0x42, 0x00, 0x2e, 0x12, 0x40, 0x42, 0x42, 0x42, 0x82, 0x00, 0x40,
|
||||||
|
0x50, 0x42, 0x08, 0xb4, 0x40, 0x42, 0x7e, 0x80, 0xa8, 0xb4, 0x01, 0x42, 0xb8, 0x2e, 0x12,
|
||||||
|
0x24, 0x71, 0x00, 0x90, 0x40, 0x84, 0x82, 0x20, 0x50, 0x50, 0x42, 0x77, 0x80, 0x82, 0x40,
|
||||||
|
0x42, 0x42, 0xfb, 0x7f, 0x05, 0x82, 0x00, 0x40, 0x40, 0x42, 0x7c, 0x80, 0x05, 0x82, 0x00,
|
||||||
|
0x40, 0x40, 0x42, 0x7c, 0x80, 0x05, 0x82, 0x00, 0x40, 0x40, 0x42, 0x77, 0x84, 0x00, 0x2e,
|
||||||
|
0x90, 0x40, 0x84, 0x82, 0x82, 0x40, 0x50, 0x42, 0x77, 0x80, 0x42, 0x42, 0x05, 0x82, 0x00,
|
||||||
|
0x40, 0x40, 0x42, 0x7c, 0x80, 0x05, 0x82, 0x00, 0x40, 0x40, 0x42, 0x7c, 0x80, 0x05, 0x82,
|
||||||
|
0x00, 0x40, 0x40, 0x42, 0x7c, 0x82, 0xe1, 0x7f, 0x98, 0x2e, 0x03, 0xb1, 0xe2, 0x6f, 0x00,
|
||||||
|
0x2e, 0x90, 0x42, 0x81, 0x42, 0xbc, 0x82, 0x10, 0x24, 0x33, 0xf0, 0x23, 0x40, 0x02, 0x40,
|
||||||
|
0xb8, 0xbd, 0x9a, 0x0a, 0x03, 0x80, 0x52, 0x42, 0x00, 0x2e, 0x23, 0x40, 0x02, 0x40, 0xb8,
|
||||||
|
0xbd, 0x9a, 0x0a, 0x03, 0x80, 0x52, 0x42, 0x00, 0x2e, 0x22, 0x40, 0x00, 0x40, 0x28, 0xbd,
|
||||||
|
0x10, 0x0a, 0x40, 0x42, 0x00, 0x2e, 0xfb, 0x6f, 0xe0, 0x5f, 0xb8, 0x2e, 0x11, 0x24, 0x28,
|
||||||
|
0xf0, 0x50, 0x50, 0x60, 0x40, 0xf0, 0x7f, 0x51, 0x25, 0x60, 0x40, 0xe0, 0x7f, 0x00, 0x2e,
|
||||||
|
0x41, 0x40, 0xd1, 0x7f, 0x00, 0x2e, 0xe2, 0x6f, 0xd0, 0x6f, 0x00, 0xb2, 0xf3, 0x6f, 0xa8,
|
||||||
|
0xb8, 0x28, 0xbe, 0x59, 0x0a, 0x20, 0x0a, 0x01, 0x2f, 0xb0, 0x5f, 0xb8, 0x2e, 0x45, 0x41,
|
||||||
|
0xc5, 0x7f, 0x00, 0x2e, 0xc5, 0x6f, 0x40, 0x91, 0x09, 0x2f, 0x05, 0x2e, 0x28, 0xf0, 0xb2,
|
||||||
|
0x7f, 0x00, 0x2e, 0xb2, 0x6f, 0x1a, 0x1a, 0x07, 0x2f, 0xf0, 0x3f, 0x13, 0x25, 0x05, 0x2d,
|
||||||
|
0x15, 0x1a, 0x02, 0x2f, 0x10, 0x24, 0xff, 0x00, 0x20, 0x0a, 0xb0, 0x5f, 0xb8, 0x2e, 0x01,
|
||||||
|
0x2e, 0x03, 0x01, 0x8f, 0xbc, 0x01, 0x2e, 0x1f, 0x00, 0x9f, 0xb8, 0x01, 0x1a, 0x12, 0x2f,
|
||||||
|
0x01, 0x2e, 0x03, 0x01, 0x0f, 0xbc, 0x0f, 0xb8, 0x21, 0x2e, 0x1f, 0x00, 0x11, 0x30, 0x05,
|
||||||
|
0x2e, 0x1f, 0x00, 0x51, 0x08, 0xd2, 0x3f, 0x01, 0x2e, 0x07, 0xf0, 0x02, 0x08, 0x91, 0xbc,
|
||||||
|
0x01, 0x0a, 0x21, 0x2e, 0x07, 0xf0, 0xb8, 0x2e, 0xb8, 0x2e, 0x50, 0x50, 0xf2, 0x7f, 0xe1,
|
||||||
|
0x7f, 0x01, 0x30, 0xd1, 0x7f, 0xc1, 0x7f, 0x10, 0x24, 0x91, 0x04, 0xf2, 0x6f, 0xe3, 0x6f,
|
||||||
|
0x1c, 0x2d, 0xc4, 0x6f, 0x9c, 0x01, 0xd5, 0x6f, 0x86, 0x41, 0x6e, 0x0d, 0xd5, 0x7f, 0xb1,
|
||||||
|
0x7f, 0x0e, 0x2d, 0xd6, 0x6f, 0xef, 0xba, 0x61, 0xbf, 0x40, 0x91, 0x01, 0x2f, 0xd6, 0x7f,
|
||||||
|
0x03, 0x2d, 0x70, 0x0d, 0xd5, 0x7f, 0x00, 0x2e, 0xb5, 0x6f, 0x41, 0x8b, 0xb5, 0x7f, 0x00,
|
||||||
|
0x2e, 0xb5, 0x6f, 0x50, 0xa3, 0xee, 0x2f, 0x01, 0x89, 0xc4, 0x7f, 0x00, 0x2e, 0xc4, 0x6f,
|
||||||
|
0x62, 0x0e, 0xe0, 0x2f, 0xd0, 0x6f, 0xb0, 0x5f, 0xb8, 0x2e, 0x90, 0x50, 0xd3, 0x7f, 0xfb,
|
||||||
|
0x7f, 0xc2, 0x7f, 0xb1, 0x7f, 0x11, 0x30, 0xa1, 0x7f, 0x1a, 0x25, 0xc2, 0x6f, 0x72, 0x7f,
|
||||||
|
0x77, 0x82, 0xb2, 0x6f, 0x82, 0x7f, 0xe2, 0x7f, 0x22, 0x30, 0x98, 0x2e, 0x4d, 0xb1, 0x90,
|
||||||
|
0x7f, 0x00, 0x2e, 0xe1, 0x6f, 0xd0, 0x6f, 0x41, 0x16, 0x92, 0x6f, 0x01, 0x08, 0x51, 0x08,
|
||||||
|
0x48, 0x1a, 0x01, 0x2f, 0x01, 0x30, 0xa1, 0x7f, 0x00, 0x2e, 0xfb, 0x6f, 0xa0, 0x6f, 0x70,
|
||||||
|
0x5f, 0xb8, 0x2e, 0x70, 0x50, 0xe3, 0x7f, 0xfb, 0x7f, 0xc1, 0x7f, 0xd2, 0x7f, 0x1a, 0x25,
|
||||||
|
0xc0, 0x6f, 0xd2, 0x6f, 0x90, 0x7f, 0xa2, 0x7f, 0x79, 0x82, 0xe2, 0x6f, 0xb2, 0x7f, 0x32,
|
||||||
|
0x30, 0x98, 0x2e, 0x4d, 0xb1, 0xfb, 0x6f, 0x90, 0x5f, 0xb8, 0x2e, 0xb0, 0x50, 0xa4, 0x7f,
|
||||||
|
0xfb, 0x7f, 0x93, 0x7f, 0x82, 0x7f, 0x71, 0x7f, 0x00, 0x30, 0xa1, 0x6f, 0xe1, 0x7f, 0x40,
|
||||||
|
0x42, 0x00, 0x2e, 0x92, 0x6f, 0x83, 0x6f, 0x71, 0x6f, 0xd3, 0x7f, 0xc2, 0x7f, 0xb1, 0x7f,
|
||||||
|
0x98, 0x2e, 0x7a, 0xb1, 0x60, 0x7f, 0x00, 0x2e, 0x60, 0x6f, 0x01, 0xb2, 0x1e, 0x2f, 0xb1,
|
||||||
|
0x6f, 0xf2, 0x30, 0x8a, 0x08, 0x13, 0x24, 0xf0, 0x00, 0x4b, 0x08, 0x24, 0xbd, 0x94, 0xb8,
|
||||||
|
0x51, 0x0a, 0x51, 0x7f, 0x00, 0x2e, 0x51, 0x6f, 0x81, 0x16, 0xd3, 0x6f, 0x9a, 0x08, 0xc4,
|
||||||
|
0x6f, 0xe1, 0x08, 0xe1, 0x6f, 0x93, 0x0a, 0x42, 0x42, 0x12, 0x24, 0x00, 0xff, 0x43, 0x40,
|
||||||
|
0x9a, 0x08, 0x14, 0x24, 0xff, 0x00, 0xdc, 0x08, 0xb8, 0xbd, 0x28, 0xb9, 0x9a, 0x0a, 0x42,
|
||||||
|
0x42, 0x00, 0x2e, 0xfb, 0x6f, 0x50, 0x5f, 0xb8, 0x2e, 0x70, 0x50, 0xd4, 0x7f, 0xfb, 0x7f,
|
||||||
|
0xc3, 0x7f, 0xa1, 0x7f, 0xb2, 0x7f, 0x02, 0x30, 0x92, 0x7f, 0x00, 0x2e, 0x05, 0x2e, 0x20,
|
||||||
|
0x00, 0xc4, 0x6f, 0x80, 0xb2, 0x0c, 0x2f, 0x81, 0x90, 0x1a, 0x2f, 0xd2, 0x6f, 0x07, 0x2e,
|
||||||
|
0x21, 0x00, 0xa1, 0x32, 0x98, 0x2e, 0xaf, 0xb1, 0x02, 0x30, 0x25, 0x2e, 0x20, 0x00, 0x92,
|
||||||
|
0x7f, 0x10, 0x2d, 0xa1, 0x6f, 0xb2, 0x6f, 0xe4, 0x7f, 0xa3, 0x32, 0x98, 0x2e, 0x9c, 0xb1,
|
||||||
|
0x21, 0x2e, 0x21, 0x00, 0xe2, 0x6f, 0x03, 0x2e, 0x21, 0x00, 0x81, 0x42, 0x12, 0x30, 0x25,
|
||||||
|
0x2e, 0x20, 0x00, 0x92, 0x7f, 0x00, 0x2e, 0xfb, 0x6f, 0x90, 0x6f, 0x90, 0x5f, 0xb8, 0x2e,
|
||||||
|
0x10, 0x50, 0x00, 0x30, 0xf0, 0x7f, 0x12, 0x24, 0x86, 0x00, 0x1b, 0x2d, 0xf1, 0x6f, 0xd1,
|
||||||
|
0x00, 0x00, 0x2e, 0xc0, 0x42, 0xbc, 0x84, 0xd1, 0x00, 0x00, 0x2e, 0xc0, 0x42, 0x8c, 0x84,
|
||||||
|
0xd1, 0x00, 0x00, 0x2e, 0xc0, 0x42, 0xbc, 0x84, 0xd1, 0x00, 0x00, 0x2e, 0xc0, 0x42, 0x8c,
|
||||||
|
0x84, 0xd1, 0x00, 0x00, 0x2e, 0xc0, 0x42, 0xbc, 0x84, 0xd1, 0x00, 0x00, 0x2e, 0xc0, 0x42,
|
||||||
|
0x41, 0x82, 0xf1, 0x7f, 0xb4, 0x84, 0xf1, 0x6f, 0x43, 0xa2, 0xe1, 0x2f, 0xf0, 0x5f, 0xb8,
|
||||||
|
0x2e, 0xc0, 0x50, 0x92, 0x7f, 0xfb, 0x7f, 0x81, 0x7f, 0x00, 0x30, 0x60, 0x7f, 0x70, 0x7f,
|
||||||
|
0x50, 0x7f, 0x00, 0x2e, 0x03, 0x2e, 0x04, 0x01, 0x9d, 0xbc, 0x9e, 0xb8, 0x41, 0x7f, 0x00,
|
||||||
|
0x2e, 0x42, 0x6f, 0x52, 0x7f, 0xe2, 0x7f, 0x00, 0x2e, 0x83, 0x6f, 0xc4, 0x82, 0xd3, 0x7f,
|
||||||
|
0x0c, 0x2d, 0x55, 0x6f, 0x7f, 0x89, 0xdc, 0x01, 0x9d, 0x01, 0xcb, 0x41, 0x8b, 0x43, 0xcc,
|
||||||
|
0x01, 0x4d, 0x01, 0xc7, 0x41, 0x47, 0x43, 0x54, 0x7f, 0x00, 0x2e, 0x54, 0x6f, 0x00, 0xab,
|
||||||
|
0xf0, 0x2f, 0x9b, 0x6f, 0x8a, 0x00, 0x4b, 0x42, 0xc2, 0x7f, 0xb1, 0x7f, 0x50, 0x7f, 0x7c,
|
||||||
|
0x80, 0xa0, 0x7f, 0x13, 0x24, 0x09, 0x01, 0x3f, 0x2d, 0x50, 0x6f, 0x18, 0x01, 0xc8, 0x84,
|
||||||
|
0xc8, 0x00, 0x50, 0x00, 0x05, 0x41, 0xc7, 0x40, 0x44, 0x40, 0x61, 0x6f, 0x73, 0x6f, 0x2f,
|
||||||
|
0x18, 0x00, 0xb3, 0x0b, 0x2f, 0x10, 0xa1, 0x03, 0x2f, 0x30, 0x89, 0xbc, 0x11, 0xce, 0x17,
|
||||||
|
0x06, 0x2d, 0x74, 0x13, 0x06, 0x31, 0xb4, 0x05, 0xbe, 0x15, 0xfc, 0x11, 0xae, 0x0b, 0x4e,
|
||||||
|
0x00, 0xdf, 0x02, 0x61, 0x7f, 0x73, 0x7f, 0xb4, 0x84, 0x01, 0x82, 0xd1, 0x00, 0x88, 0x80,
|
||||||
|
0xa2, 0x6f, 0x11, 0x01, 0x81, 0x00, 0xc3, 0x40, 0x05, 0x41, 0x84, 0x40, 0x1d, 0x18, 0x72,
|
||||||
|
0x6f, 0x00, 0xb3, 0x63, 0x6f, 0x0b, 0x2f, 0x10, 0xa1, 0x03, 0x2f, 0x30, 0x89, 0xbc, 0x11,
|
||||||
|
0xce, 0x17, 0x06, 0x2d, 0x74, 0x13, 0x06, 0x31, 0xb4, 0x05, 0xbe, 0x15, 0xfc, 0x11, 0xae,
|
||||||
|
0x0b, 0xde, 0x04, 0x97, 0x06, 0x63, 0x7f, 0x72, 0x7f, 0x51, 0x7f, 0x3c, 0x86, 0xb1, 0x6f,
|
||||||
|
0xe2, 0x6f, 0x50, 0x6f, 0x42, 0x0e, 0xbc, 0x2f, 0xe0, 0x6f, 0xc8, 0x82, 0x98, 0x00, 0x48,
|
||||||
|
0x00, 0xc0, 0x6f, 0x83, 0x40, 0x04, 0x40, 0x42, 0x40, 0x61, 0x6f, 0x70, 0x6f, 0x80, 0xb2,
|
||||||
|
0x1c, 0x18, 0x0b, 0x2f, 0x90, 0xa0, 0x03, 0x2f, 0xb0, 0x84, 0xba, 0x11, 0xce, 0x17, 0x06,
|
||||||
|
0x2d, 0x03, 0x31, 0xda, 0x04, 0xfb, 0x14, 0x32, 0x13, 0xfa, 0x11, 0xa3, 0x0b, 0x4e, 0x00,
|
||||||
|
0x07, 0x02, 0x61, 0x7f, 0x70, 0x7f, 0x00, 0x2e, 0x72, 0x6f, 0x80, 0xa8, 0x60, 0x6f, 0xd1,
|
||||||
|
0x6f, 0x13, 0x2f, 0x80, 0x90, 0x03, 0x2f, 0x13, 0x24, 0xff, 0x7f, 0x43, 0x0f, 0x0d, 0x2f,
|
||||||
|
0xbf, 0xa0, 0x07, 0x2f, 0xbf, 0x90, 0x03, 0x2f, 0x12, 0x24, 0x00, 0x80, 0x42, 0x0e, 0x01,
|
||||||
|
0x2f, 0x40, 0x42, 0x07, 0x2d, 0x10, 0x24, 0x00, 0x80, 0x40, 0x42, 0x03, 0x2d, 0x10, 0x24,
|
||||||
|
0xff, 0x7f, 0x40, 0x42, 0x00, 0x2e, 0xfb, 0x6f, 0x40, 0x5f, 0x40, 0x40, 0xb8, 0x2e, 0x11,
|
||||||
|
0x24, 0x7b, 0x00, 0x30, 0x50, 0x10, 0x30, 0x50, 0x42, 0xfb, 0x7f, 0x10, 0x24, 0x33, 0xf0,
|
||||||
|
0x23, 0x40, 0x02, 0x40, 0xb8, 0xbd, 0x9a, 0x0a, 0x03, 0x80, 0x52, 0x42, 0x00, 0x2e, 0x23,
|
||||||
|
0x40, 0x02, 0x40, 0xb8, 0xbd, 0x9a, 0x0a, 0x03, 0x80, 0x52, 0x42, 0x00, 0x2e, 0x23, 0x40,
|
||||||
|
0x02, 0x40, 0xb8, 0xbd, 0x9a, 0x0a, 0x3c, 0x80, 0x42, 0x42, 0x7e, 0x84, 0xe0, 0x7f, 0x86,
|
||||||
|
0x82, 0xd1, 0x7f, 0x00, 0x2e, 0x82, 0x40, 0x98, 0x2e, 0x40, 0xb2, 0xd1, 0x6f, 0x7d, 0x82,
|
||||||
|
0x00, 0x2e, 0x40, 0x42, 0x7e, 0x80, 0x0d, 0x82, 0x02, 0x40, 0xd1, 0x7f, 0x98, 0x2e, 0x40,
|
||||||
|
0xb2, 0xd1, 0x6f, 0x76, 0x82, 0x00, 0x2e, 0x40, 0x42, 0x7e, 0x80, 0x14, 0x82, 0x02, 0x40,
|
||||||
|
0xd1, 0x7f, 0x98, 0x2e, 0x40, 0xb2, 0xd1, 0x6f, 0x6f, 0x82, 0x00, 0x2e, 0x40, 0x42, 0x7e,
|
||||||
|
0x80, 0xe1, 0x6f, 0x12, 0x40, 0x52, 0x42, 0x28, 0xb5, 0x52, 0x42, 0x00, 0x2e, 0x12, 0x40,
|
||||||
|
0x52, 0x42, 0x28, 0xb5, 0x52, 0x42, 0x00, 0x2e, 0x00, 0x40, 0x50, 0x42, 0x08, 0xb4, 0x40,
|
||||||
|
0x42, 0x00, 0x2e, 0xfb, 0x6f, 0xd0, 0x5f, 0xb8, 0x2e, 0x10, 0x50, 0x01, 0x2e, 0x55, 0xf0,
|
||||||
|
0xf0, 0x7f, 0x00, 0x2e, 0xf0, 0x6f, 0x21, 0x2e, 0x55, 0xf0, 0xf0, 0x5f, 0xb8, 0x2e, 0x20,
|
||||||
|
0x50, 0x00, 0x30, 0xe0, 0x7f, 0xfb, 0x7f, 0x11, 0x24, 0xb1, 0xf0, 0x42, 0x40, 0x43, 0x30,
|
||||||
|
0x93, 0x0a, 0x42, 0x42, 0x58, 0x82, 0x12, 0x24, 0xaf, 0x00, 0x62, 0x42, 0x12, 0x24, 0xff,
|
||||||
|
0x00, 0x42, 0x42, 0x69, 0x82, 0x72, 0x3c, 0x43, 0x40, 0x9a, 0x08, 0x83, 0x32, 0x93, 0x0a,
|
||||||
|
0x42, 0x42, 0x42, 0x82, 0x02, 0x3f, 0x43, 0x40, 0x9a, 0x08, 0x52, 0x42, 0x0b, 0x31, 0x4b,
|
||||||
|
0x42, 0x7e, 0x82, 0x72, 0x31, 0x42, 0x42, 0x00, 0x2e, 0x03, 0x2e, 0x40, 0xf0, 0x5f, 0xb2,
|
||||||
|
0x03, 0x2f, 0x03, 0x2e, 0x40, 0xf0, 0x5e, 0x90, 0x27, 0x2f, 0x11, 0x24, 0x00, 0x02, 0x12,
|
||||||
|
0x24, 0x05, 0x80, 0x13, 0x24, 0xff, 0xb7, 0x1b, 0x24, 0x00, 0xb0, 0x04, 0x30, 0x05, 0x30,
|
||||||
|
0x56, 0x32, 0x6e, 0x1a, 0x00, 0x2f, 0x25, 0x36, 0x69, 0x1a, 0x01, 0x2f, 0x5b, 0x25, 0x00,
|
||||||
|
0x2e, 0x56, 0x41, 0x26, 0x0d, 0x06, 0x30, 0xcf, 0xbb, 0x41, 0xbe, 0xc0, 0x91, 0x01, 0x2f,
|
||||||
|
0x00, 0x2e, 0x01, 0x2d, 0x22, 0x0d, 0x81, 0x8d, 0x90, 0xa1, 0xf5, 0x2f, 0xeb, 0x0e, 0xe8,
|
||||||
|
0x2f, 0x01, 0x2e, 0x25, 0x00, 0x20, 0x1a, 0x05, 0x2f, 0x20, 0x30, 0xe0, 0x7f, 0x03, 0x2d,
|
||||||
|
0x30, 0x30, 0xe0, 0x7f, 0x00, 0x2e, 0xe0, 0x6f, 0x00, 0xb2, 0x06, 0x2f, 0x21, 0x2e, 0x59,
|
||||||
|
0xf0, 0x98, 0x2e, 0x43, 0xb3, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0xfb, 0x6f, 0xe0, 0x5f,
|
||||||
|
0xb8, 0x2e, 0xa0, 0x50, 0x80, 0x7f, 0xe7, 0x7f, 0xd5, 0x7f, 0xc4, 0x7f, 0xb3, 0x7f, 0xa2,
|
||||||
|
0x7f, 0x91, 0x7f, 0xf6, 0x7f, 0x7b, 0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x43, 0xf0, 0x08, 0xbc,
|
||||||
|
0x0f, 0xb8, 0x60, 0x7f, 0x00, 0x2e, 0x60, 0x6f, 0x00, 0xb2, 0x01, 0x2f, 0x98, 0x2e, 0xb9,
|
||||||
|
0xb0, 0x40, 0x30, 0x21, 0x2e, 0xb8, 0xf0, 0xf6, 0x6f, 0x91, 0x6f, 0xa2, 0x6f, 0xb3, 0x6f,
|
||||||
|
0xc4, 0x6f, 0xd5, 0x6f, 0xe7, 0x6f, 0x7b, 0x6f, 0x80, 0x6f, 0x60, 0x5f, 0xc8, 0x2e, 0xa0,
|
||||||
|
0x50, 0x80, 0x7f, 0xe7, 0x7f, 0xd5, 0x7f, 0xc4, 0x7f, 0xb3, 0x7f, 0xa2, 0x7f, 0x91, 0x7f,
|
||||||
|
0xf6, 0x7f, 0x7b, 0x7f, 0x00, 0x2e, 0x01, 0x2e, 0x29, 0xf0, 0x08, 0xbc, 0x0f, 0xb8, 0x60,
|
||||||
|
0x7f, 0x00, 0x2e, 0x60, 0x6f, 0x01, 0x90, 0x1b, 0x2f, 0x01, 0x2e, 0x02, 0x01, 0x0e, 0xbc,
|
||||||
|
0x0e, 0xb8, 0x00, 0x90, 0x05, 0x2f, 0x01, 0x2e, 0x04, 0x01, 0x0f, 0xbc, 0x0f, 0xb8, 0x01,
|
||||||
|
0xb2, 0x0d, 0x2f, 0x01, 0x2e, 0x7b, 0x00, 0x01, 0x90, 0x04, 0x2f, 0x98, 0x2e, 0x1a, 0xb2,
|
||||||
|
0x00, 0x30, 0x21, 0x2e, 0x7b, 0x00, 0x01, 0x2e, 0x37, 0xf0, 0x21, 0x2e, 0x37, 0xf0, 0x02,
|
||||||
|
0x2d, 0x98, 0x2e, 0xf3, 0xb2, 0x80, 0x30, 0x21, 0x2e, 0xb8, 0xf0, 0xf6, 0x6f, 0x91, 0x6f,
|
||||||
|
0xa2, 0x6f, 0xb3, 0x6f, 0xc4, 0x6f, 0xd5, 0x6f, 0xe7, 0x6f, 0x7b, 0x6f, 0x80, 0x6f, 0x60,
|
||||||
|
0x5f, 0xc8, 0x2e, 0x60, 0x50, 0xe7, 0x7f, 0xf6, 0x7f, 0x36, 0x30, 0x0f, 0x2e, 0x01, 0xf0,
|
||||||
|
0xfe, 0xbf, 0xfe, 0xbb, 0xb7, 0x05, 0xa6, 0x7f, 0xd3, 0x7f, 0xc4, 0x7f, 0xb5, 0x7f, 0x14,
|
||||||
|
0x24, 0x89, 0xf0, 0x3f, 0x8b, 0x03, 0x41, 0x44, 0x41, 0xb8, 0xbd, 0x9c, 0x0b, 0xa3, 0x6f,
|
||||||
|
0x14, 0x24, 0x9a, 0x00, 0xb3, 0x11, 0x43, 0x8b, 0x16, 0x43, 0x00, 0x2e, 0x67, 0x41, 0x46,
|
||||||
|
0x41, 0xf8, 0xbf, 0xbe, 0x0b, 0xb3, 0x11, 0x16, 0x43, 0x43, 0x8d, 0x00, 0x2e, 0xa5, 0x41,
|
||||||
|
0x86, 0x41, 0xd8, 0xbe, 0x6e, 0x0b, 0xeb, 0x10, 0x03, 0x43, 0x13, 0x30, 0x27, 0x2e, 0x22,
|
||||||
|
0x00, 0x03, 0x31, 0x27, 0x2e, 0xb8, 0xf0, 0xf6, 0x6f, 0xe7, 0x6f, 0xc4, 0x6f, 0xb5, 0x6f,
|
||||||
|
0xd3, 0x6f, 0xa0, 0x5f, 0xc8, 0x2e, 0xa0, 0x50, 0x80, 0x7f, 0x91, 0x7f, 0xe7, 0x7f, 0xd5,
|
||||||
|
0x7f, 0xc4, 0x7f, 0xb3, 0x7f, 0xa2, 0x7f, 0xf6, 0x7f, 0x7b, 0x7f, 0x00, 0x2e, 0x01, 0x2e,
|
||||||
|
0xb9, 0xf0, 0x60, 0x7f, 0x10, 0x30, 0x61, 0x6f, 0x08, 0x08, 0x00, 0xb2, 0x01, 0x2f, 0x98,
|
||||||
|
0x2e, 0x9e, 0x00, 0x10, 0x30, 0x21, 0x2e, 0xb9, 0xf0, 0x21, 0x2e, 0x5f, 0xf0, 0xf6, 0x6f,
|
||||||
|
0x91, 0x6f, 0xa2, 0x6f, 0xb3, 0x6f, 0xc4, 0x6f, 0xd5, 0x6f, 0xe7, 0x6f, 0x7b, 0x6f, 0x80,
|
||||||
|
0x6f, 0x60, 0x5f, 0xc8, 0x2e, 0x20, 0x50, 0xe7, 0x7f, 0xf6, 0x7f, 0x56, 0x32, 0x0f, 0x2e,
|
||||||
|
0x58, 0xf0, 0x7e, 0x1a, 0x02, 0x2f, 0x16, 0x30, 0x2d, 0x2e, 0x23, 0x00, 0x16, 0x24, 0x80,
|
||||||
|
0x00, 0x2d, 0x2e, 0xb9, 0xf0, 0xe7, 0x6f, 0xf6, 0x6f, 0xe0, 0x5f, 0xc8, 0x2e, 0x30, 0x50,
|
||||||
|
0x04, 0x30, 0xd4, 0x7f, 0xe4, 0x7f, 0xfb, 0x7f, 0x13, 0x24, 0x26, 0xf0, 0xc2, 0x40, 0xc1,
|
||||||
|
0x86, 0xe4, 0x7f, 0xd2, 0x7f, 0x00, 0x2e, 0xd1, 0x40, 0x18, 0xbc, 0x18, 0xba, 0xd2, 0x6f,
|
||||||
|
0xe1, 0x6f, 0x90, 0x0a, 0x0c, 0x0b, 0xd2, 0x7f, 0xe4, 0x7f, 0x00, 0x2e, 0xe4, 0x6f, 0xc3,
|
||||||
|
0x40, 0xe3, 0x0a, 0xdb, 0x6f, 0xdb, 0x7f, 0xe3, 0x7f, 0x13, 0x24, 0x15, 0x01, 0xe2, 0x6f,
|
||||||
|
0x09, 0x2e, 0x16, 0x01, 0xd1, 0x6f, 0x98, 0x2e, 0xea, 0xb1, 0x21, 0x2e, 0x58, 0xf0, 0x98,
|
||||||
|
0x2e, 0x43, 0xb3, 0xfb, 0x6f, 0xd0, 0x5f, 0xb8, 0x2e, 0x98, 0x2e, 0x4d, 0xb3, 0x20, 0x26,
|
||||||
|
0x98, 0x2e, 0xfa, 0x01, 0x98, 0x2e, 0xf5, 0xb4, 0x98, 0x2e, 0xf1, 0xb4, 0x98, 0x2e, 0xde,
|
||||||
|
0xb4, 0x98, 0x2e, 0xf9, 0xb4, 0x01, 0x2e, 0x40, 0xf0, 0x21, 0x2e, 0x9d, 0x00, 0x10, 0x30,
|
||||||
|
0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0x43, 0xb3, 0x21, 0x30, 0x10, 0x24, 0x9a, 0x00, 0x00,
|
||||||
|
0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x05, 0x2e, 0x22, 0x00, 0x80, 0xb2, 0x02, 0x30, 0x05, 0x2f,
|
||||||
|
0x23, 0x2e, 0x5f, 0xf0, 0x25, 0x2e, 0x22, 0x00, 0x98, 0x2e, 0x17, 0x01, 0x98, 0x2e, 0x31,
|
||||||
|
0xb1, 0x01, 0x2e, 0x23, 0x00, 0x01, 0x90, 0x00, 0x30, 0xe7, 0x2f, 0x21, 0x2e, 0x23, 0x00,
|
||||||
|
0x98, 0x2e, 0x80, 0xb4, 0xe3, 0x2d, 0x80, 0x30, 0x21, 0x2e, 0xba, 0xf0, 0x10, 0x24, 0x80,
|
||||||
|
0x00, 0x03, 0x2e, 0x06, 0xf0, 0x08, 0x0a, 0x21, 0x2e, 0x06, 0xf0, 0x00, 0x3e, 0x03, 0x2e,
|
||||||
|
0x06, 0xf0, 0x08, 0x08, 0x51, 0x30, 0x01, 0x0a, 0x21, 0x2e, 0x06, 0xf0, 0xb8, 0x2e, 0x00,
|
||||||
|
0x31, 0x21, 0x2e, 0xba, 0xf0, 0xb8, 0x2e, 0x10, 0x30, 0x21, 0x2e, 0xbb, 0xf0, 0xb8, 0x2e,
|
||||||
|
0x10, 0x24, 0x80, 0x00, 0x21, 0x2e, 0xbb, 0xf0, 0xb8, 0x2e, 0x1a, 0x24, 0x26, 0x00, 0x80,
|
||||||
|
0x2e, 0xab, 0xb4, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
|
||||||
|
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80,
|
||||||
|
0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00,
|
||||||
|
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
|
||||||
|
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00};
|
||||||
|
|
||||||
|
#endif /* BMI08X_BMI08X_CONFIG_FILE_H_ */
|
484
drivers/sensor/bmi08x/bmi08x_gyro.c
Normal file
484
drivers/sensor/bmi08x/bmi08x_gyro.c
Normal file
|
@ -0,0 +1,484 @@
|
||||||
|
/* Bosch BMI08X inertial measurement unit driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Meta Platforms, Inc. and its affiliates
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/drivers/sensor.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>
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT bosch_bmi08x_gyro
|
||||||
|
#include "bmi08x.h"
|
||||||
|
|
||||||
|
LOG_MODULE_REGISTER(BMI08X_GYRO, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
|
|
||||||
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||||
|
|
||||||
|
static int bmi08x_gyro_transceive_i2c(const struct device *dev, uint8_t reg, bool write, void *data,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
const struct bmi08x_gyro_config *bmi08x = dev->config;
|
||||||
|
|
||||||
|
if (!write) {
|
||||||
|
return i2c_write_read_dt(&bmi08x->bus.i2c, ®, 1, data, length);
|
||||||
|
}
|
||||||
|
if (length > CONFIG_BMI08X_I2C_WRITE_BURST_SIZE) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
uint8_t buf[1 + CONFIG_BMI08X_I2C_WRITE_BURST_SIZE];
|
||||||
|
|
||||||
|
buf[0] = reg;
|
||||||
|
memcpy(&buf[1], data, length);
|
||||||
|
return i2c_write_dt(&bmi08x->bus.i2c, buf, 1 + length);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_bus_check_i2c(const union bmi08x_bus *bus)
|
||||||
|
{
|
||||||
|
return i2c_is_ready_dt(&bus->i2c) ? 0 : -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bmi08x_gyro_bus_io bmi08x_i2c_api = {
|
||||||
|
.check = bmi08x_bus_check_i2c,
|
||||||
|
.transceive = bmi08x_gyro_transceive_i2c,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */
|
||||||
|
|
||||||
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||||
|
|
||||||
|
static int bmi08x_gyro_transceive_spi(const struct device *dev, uint8_t reg, bool write, void *data,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
const struct bmi08x_gyro_config *bmi08x = dev->config;
|
||||||
|
const struct spi_buf tx_buf[2] = {{.buf = ®, .len = 1}, {.buf = data, .len = length}};
|
||||||
|
const struct spi_buf_set tx = {.buffers = tx_buf, .count = write ? 2 : 1};
|
||||||
|
|
||||||
|
if (!write) {
|
||||||
|
uint16_t dummy;
|
||||||
|
const struct spi_buf rx_buf[2] = {{.buf = &dummy, .len = 1},
|
||||||
|
{.buf = data, .len = length}};
|
||||||
|
const struct spi_buf_set rx = {.buffers = rx_buf, .count = 2};
|
||||||
|
|
||||||
|
return spi_transceive_dt(&bmi08x->bus.spi, &tx, &rx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return spi_write_dt(&bmi08x->bus.spi, &tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_bus_check_spi(const union bmi08x_bus *bus)
|
||||||
|
{
|
||||||
|
return spi_is_ready_dt(&bus->spi) ? 0 : -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bmi08x_gyro_bus_io bmi08x_spi_api = {
|
||||||
|
.check = bmi08x_bus_check_spi,
|
||||||
|
.transceive = bmi08x_gyro_transceive_spi,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
|
||||||
|
|
||||||
|
static inline int bmi08x_bus_check(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct bmi08x_gyro_config *config = dev->config;
|
||||||
|
|
||||||
|
return config->api->check(&config->bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_gyro_transceive(const struct device *dev, uint8_t reg, bool write, void *data,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
const struct bmi08x_gyro_config *cfg = dev->config;
|
||||||
|
|
||||||
|
return cfg->api->transceive(dev, reg, write, data, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_gyro_read(const struct device *dev, uint8_t reg_addr, uint8_t *data, uint8_t len)
|
||||||
|
{
|
||||||
|
return bmi08x_gyro_transceive(dev, reg_addr | BIT(7), false, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_gyro_byte_read(const struct device *dev, uint8_t reg_addr, uint8_t *byte)
|
||||||
|
{
|
||||||
|
return bmi08x_gyro_transceive(dev, reg_addr | BIT(7), false, byte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_gyro_byte_write(const struct device *dev, uint8_t reg_addr, uint8_t byte)
|
||||||
|
{
|
||||||
|
return bmi08x_gyro_transceive(dev, reg_addr & 0x7F, true, &byte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_gyro_word_write(const struct device *dev, uint8_t reg_addr, uint16_t word)
|
||||||
|
{
|
||||||
|
uint8_t tx_word[2] = {(uint8_t)(word & 0xff), (uint8_t)(word >> 8)};
|
||||||
|
|
||||||
|
return bmi08x_gyro_transceive(dev, reg_addr & 0x7F, true, tx_word, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_gyro_reg_field_update(const struct device *dev, uint8_t reg_addr, uint8_t pos,
|
||||||
|
uint8_t mask, uint8_t val)
|
||||||
|
{
|
||||||
|
uint8_t old_val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bmi08x_gyro_byte_read(dev, reg_addr, &old_val);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bmi08x_gyro_byte_write(dev, reg_addr, (old_val & ~mask) | ((val << pos) & mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bmi08x_range bmi08x_gyr_range_map[] = {
|
||||||
|
{125, BMI08X_GYR_RANGE_125DPS}, {250, BMI08X_GYR_RANGE_250DPS},
|
||||||
|
{500, BMI08X_GYR_RANGE_500DPS}, {1000, BMI08X_GYR_RANGE_1000DPS},
|
||||||
|
{2000, BMI08X_GYR_RANGE_2000DPS},
|
||||||
|
};
|
||||||
|
#define BMI08X_GYR_RANGE_MAP_SIZE ARRAY_SIZE(bmi08x_gyr_range_map)
|
||||||
|
|
||||||
|
int32_t bmi08x_gyr_reg_val_to_range(uint8_t reg_val)
|
||||||
|
{
|
||||||
|
return bmi08x_reg_val_to_range(reg_val, bmi08x_gyr_range_map, BMI08X_GYR_RANGE_MAP_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_gyr_odr_set(const struct device *dev, uint16_t freq_int, uint16_t freq_milli)
|
||||||
|
{
|
||||||
|
int odr = bmi08x_freq_to_odr_val(freq_int, freq_milli);
|
||||||
|
|
||||||
|
if (odr < 0) {
|
||||||
|
return odr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (odr < BMI08X_GYRO_BW_532_ODR_2000_HZ || odr > BMI08X_GYRO_BW_32_ODR_100_HZ) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bmi08x_gyro_byte_write(dev, BMI08X_REG_GYRO_BANDWIDTH, (uint8_t)odr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_gyr_range_set(const struct device *dev, uint16_t range)
|
||||||
|
{
|
||||||
|
struct bmi08x_gyro_data *bmi08x = dev->data;
|
||||||
|
int32_t reg_val =
|
||||||
|
bmi08x_range_to_reg_val(range, bmi08x_gyr_range_map, BMI08X_GYR_RANGE_MAP_SIZE);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (reg_val < 0) {
|
||||||
|
return reg_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = bmi08x_gyro_byte_write(dev, BMI08X_REG_GYRO_RANGE, reg_val);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bmi08x->scale = BMI08X_GYR_SCALE(range);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_gyr_config(const struct device *dev, enum sensor_channel chan,
|
||||||
|
enum sensor_attribute attr, const struct sensor_value *val)
|
||||||
|
{
|
||||||
|
switch (attr) {
|
||||||
|
case SENSOR_ATTR_FULL_SCALE:
|
||||||
|
return bmi08x_gyr_range_set(dev, sensor_rad_to_degrees(val));
|
||||||
|
case SENSOR_ATTR_SAMPLING_FREQUENCY:
|
||||||
|
return bmi08x_gyr_odr_set(dev, val->val1, val->val2 / 1000);
|
||||||
|
default:
|
||||||
|
LOG_ERR("Gyro attribute not supported.");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_attr_set(const struct device *dev, enum sensor_channel chan,
|
||||||
|
enum sensor_attribute attr, const struct sensor_value *val)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_PM_DEVICE
|
||||||
|
enum pm_device_state state;
|
||||||
|
|
||||||
|
(void)pm_device_state_get(dev, &state);
|
||||||
|
if (state != PM_DEVICE_STATE_ACTIVE) {
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (chan) {
|
||||||
|
case SENSOR_CHAN_GYRO_X:
|
||||||
|
case SENSOR_CHAN_GYRO_Y:
|
||||||
|
case SENSOR_CHAN_GYRO_Z:
|
||||||
|
case SENSOR_CHAN_GYRO_XYZ:
|
||||||
|
return bmi08x_gyr_config(dev, chan, attr, val);
|
||||||
|
default:
|
||||||
|
LOG_ERR("attr_set() not supported on this channel.");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
||||||
|
{
|
||||||
|
struct bmi08x_gyro_data *bmi08x = dev->data;
|
||||||
|
size_t i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_GYRO_XYZ) {
|
||||||
|
LOG_ERR("Unsupported sensor channel");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = bmi08x_gyro_read(dev, BMI08X_REG_GYRO_X_LSB, (uint8_t *)bmi08x->gyr_sample,
|
||||||
|
sizeof(bmi08x->gyr_sample));
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert samples to cpu endianness */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(bmi08x->gyr_sample); i++) {
|
||||||
|
bmi08x->gyr_sample[i] = sys_le16_to_cpu(bmi08x->gyr_sample[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bmi08x_to_fixed_point(int16_t raw_val, uint16_t scale, struct sensor_value *val)
|
||||||
|
{
|
||||||
|
int32_t converted_val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* maximum converted value we can get is: max(raw_val) * max(scale)
|
||||||
|
* max(raw_val) = +/- 2^15
|
||||||
|
* max(scale) = 4785
|
||||||
|
* max(converted_val) = 156794880 which is less than 2^31
|
||||||
|
*/
|
||||||
|
converted_val = raw_val * scale;
|
||||||
|
val->val1 = converted_val / 1000000;
|
||||||
|
val->val2 = converted_val % 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bmi08x_channel_convert(enum sensor_channel chan, uint16_t scale, uint16_t *raw_xyz,
|
||||||
|
struct sensor_value *val)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint8_t ofs_start, ofs_stop;
|
||||||
|
|
||||||
|
switch (chan) {
|
||||||
|
case SENSOR_CHAN_GYRO_X:
|
||||||
|
ofs_start = ofs_stop = 0U;
|
||||||
|
break;
|
||||||
|
case SENSOR_CHAN_GYRO_Y:
|
||||||
|
ofs_start = ofs_stop = 1U;
|
||||||
|
break;
|
||||||
|
case SENSOR_CHAN_GYRO_Z:
|
||||||
|
ofs_start = ofs_stop = 2U;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ofs_start = 0U;
|
||||||
|
ofs_stop = 2U;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = ofs_start; i <= ofs_stop; i++, val++) {
|
||||||
|
bmi08x_to_fixed_point(raw_xyz[i], scale, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void bmi08x_gyr_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||||
|
struct sensor_value *val)
|
||||||
|
{
|
||||||
|
struct bmi08x_gyro_data *bmi08x = dev->data;
|
||||||
|
|
||||||
|
bmi08x_channel_convert(chan, bmi08x->scale, bmi08x->gyr_sample, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmi08x_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||||
|
struct sensor_value *val)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_PM_DEVICE
|
||||||
|
enum pm_device_state state;
|
||||||
|
|
||||||
|
(void)pm_device_state_get(dev, &state);
|
||||||
|
if (state != PM_DEVICE_STATE_ACTIVE) {
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch ((int16_t)chan) {
|
||||||
|
case SENSOR_CHAN_GYRO_X:
|
||||||
|
case SENSOR_CHAN_GYRO_Y:
|
||||||
|
case SENSOR_CHAN_GYRO_Z:
|
||||||
|
case SENSOR_CHAN_GYRO_XYZ:
|
||||||
|
bmi08x_gyr_channel_get(dev, chan, val);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
LOG_ERR("Channel not supported.");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_DEVICE
|
||||||
|
static int bmi08x_gyro_pm_action(const struct device *dev, enum pm_device_action action)
|
||||||
|
{
|
||||||
|
uint8_t reg_val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case PM_DEVICE_ACTION_RESUME:
|
||||||
|
reg_val = BMI08X_GYRO_PM_NORMAL;
|
||||||
|
break;
|
||||||
|
case PM_DEVICE_ACTION_SUSPEND:
|
||||||
|
reg_val = BMI08X_GYRO_PM_SUSPEND;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = bmi08x_gyro_byte_write(dev, BMI08X_REG_GYRO_LPM1, reg_val);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to set power mode");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
k_msleep(BMI08X_GYRO_POWER_MODE_CONFIG_DELAY);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PM_DEVICE */
|
||||||
|
|
||||||
|
static const struct sensor_driver_api bmi08x_api = {
|
||||||
|
.attr_set = bmi08x_attr_set,
|
||||||
|
#ifdef CONFIG_BMI08X_GYRO_TRIGGER
|
||||||
|
.trigger_set = bmi08x_trigger_set_gyr,
|
||||||
|
#endif
|
||||||
|
.sample_fetch = bmi08x_sample_fetch,
|
||||||
|
.channel_get = bmi08x_channel_get,
|
||||||
|
};
|
||||||
|
|
||||||
|
int bmi08x_gyro_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct bmi08x_gyro_config *config = dev->config;
|
||||||
|
uint8_t val = 0U;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bmi08x_bus_check(dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Bus not ready for '%s'", dev->name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reboot the chip */
|
||||||
|
ret = bmi08x_gyro_byte_write(dev, BMI08X_REG_GYRO_SOFTRESET, BMI08X_SOFT_RESET_CMD);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot reboot chip.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_msleep(BMI08X_GYRO_SOFTRESET_DELAY);
|
||||||
|
|
||||||
|
ret = bmi08x_gyro_byte_read(dev, BMI08X_REG_GYRO_CHIP_ID, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to read chip id.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val != BMI08X_GYRO_CHIP_ID) {
|
||||||
|
LOG_ERR("Unsupported chip detected (0x%02x)!", val);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set gyro default range */
|
||||||
|
ret = bmi08x_gyr_range_set(dev, config->gyro_fs);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot set default range for gyroscope.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set gyro default bandwidth */
|
||||||
|
ret = bmi08x_gyro_byte_write(dev, BMI08X_REG_GYRO_BANDWIDTH, config->gyro_hz);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to set gyro's default ODR.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_BMI08X_GYRO_TRIGGER
|
||||||
|
ret = bmi08x_gyr_trigger_mode_init(dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Cannot set up trigger mode.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* with BMI08X_DATA_SYNC set, it is expected that the INT3 or INT4 is wired to either INT1
|
||||||
|
* or INT2
|
||||||
|
*/
|
||||||
|
#if defined(CONFIG_BMI08X_GYRO_TRIGGER) || BMI08X_GYRO_ANY_INST_HAS_DATA_SYNC
|
||||||
|
/* set gyro ints */
|
||||||
|
/* set ints */
|
||||||
|
ret = bmi08x_gyro_byte_write(dev, BMI08X_REG_GYRO_INT_CTRL, 0x80);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to map interrupts.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = bmi08x_gyro_byte_write(dev, BMI08X_REG_GYRO_INT3_INT4_IO_CONF,
|
||||||
|
config->int3_4_conf_io);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to map interrupts.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = bmi08x_gyro_byte_write(dev, BMI08X_REG_GYRO_INT3_INT4_IO_MAP, config->int3_4_map);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to map interrupts.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BMI08X_CONFIG_SPI(inst) \
|
||||||
|
.bus.spi = SPI_DT_SPEC_INST_GET( \
|
||||||
|
inst, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), 2),
|
||||||
|
|
||||||
|
#define BMI08X_CONFIG_I2C(inst) .bus.i2c = I2C_DT_SPEC_INST_GET(inst),
|
||||||
|
|
||||||
|
#define BMI08X_GYRO_TRIG(inst) \
|
||||||
|
.int3_4_map = DT_INST_PROP(inst, int3_4_map_io), \
|
||||||
|
.int3_4_conf_io = DT_INST_PROP(inst, int3_4_conf_io),
|
||||||
|
|
||||||
|
#if BMI08X_GYRO_ANY_INST_HAS_DATA_SYNC
|
||||||
|
/* the bmi08x-gyro should not have trigger mode with data-sync enabled */
|
||||||
|
BUILD_ASSERT(CONFIG_BMI08X_GYRO_TRIGGER_NONE,
|
||||||
|
"Only none trigger type allowed for bmi08x-gyro with data-sync enabled");
|
||||||
|
/* with data-sync, one of the int pins should be wired directory to the accel's int pins, their
|
||||||
|
* config should be defined
|
||||||
|
*/
|
||||||
|
#define BMI08X_GYRO_TRIGGER_PINS(inst) BMI08X_GYRO_TRIG(inst)
|
||||||
|
#else
|
||||||
|
#define BMI08X_GYRO_TRIGGER_PINS(inst) \
|
||||||
|
IF_ENABLED(CONFIG_BMI08X_GYRO_TRIGGER, (BMI08X_GYRO_TRIG(inst)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BMI08X_CREATE_INST(inst) \
|
||||||
|
\
|
||||||
|
static struct bmi08x_gyro_data bmi08x_drv_##inst; \
|
||||||
|
\
|
||||||
|
static const struct bmi08x_gyro_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_GYRO_TRIGGER, \
|
||||||
|
(.int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios),)) \
|
||||||
|
.gyro_hz = DT_INST_ENUM_IDX(inst, gyro_hz), \
|
||||||
|
BMI08X_GYRO_TRIGGER_PINS(inst).gyro_fs = DT_INST_ENUM_IDX(inst, gyro_fs), \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
PM_DEVICE_DT_INST_DEFINE(inst, bmi08x_gyro_pm_action); \
|
||||||
|
SENSOR_DEVICE_DT_INST_DEFINE(inst, bmi08x_gyro_init, PM_DEVICE_DT_INST_GET(inst), \
|
||||||
|
&bmi08x_drv_##inst, &bmi08x_config_##inst, POST_KERNEL, \
|
||||||
|
CONFIG_SENSOR_INIT_PRIORITY, &bmi08x_api);
|
||||||
|
|
||||||
|
/* Create the struct device for every status "okay" node in the devicetree. */
|
||||||
|
DT_INST_FOREACH_STATUS_OKAY(BMI08X_CREATE_INST)
|
135
drivers/sensor/bmi08x/bmi08x_gyro_trigger.c
Normal file
135
drivers/sensor/bmi08x/bmi08x_gyro_trigger.c
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
/* Bosch BMI08X inertial measurement unit driver, trigger implementation
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Meta Platforms, Inc. and its affiliates
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/drivers/gpio.h>
|
||||||
|
#include <zephyr/drivers/sensor.h>
|
||||||
|
#include <zephyr/pm/device.h>
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT bosch_bmi08x_gyro
|
||||||
|
#include "bmi08x.h"
|
||||||
|
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
LOG_MODULE_DECLARE(BMI08X_GYRO, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
|
|
||||||
|
static void bmi08x_handle_drdy_gyr(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct bmi08x_gyro_data *data = dev->data;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_DEVICE
|
||||||
|
enum pm_device_state state;
|
||||||
|
|
||||||
|
(void)pm_device_state_get(dev, &state);
|
||||||
|
if (state != PM_DEVICE_STATE_ACTIVE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (data->handler_drdy_gyr) {
|
||||||
|
data->handler_drdy_gyr(dev, data->drdy_trig_gyr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bmi08x_handle_interrupts_gyr(void *arg)
|
||||||
|
{
|
||||||
|
const struct device *dev = (const struct device *)arg;
|
||||||
|
|
||||||
|
bmi08x_handle_drdy_gyr(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_BMI08X_GYRO_TRIGGER_OWN_THREAD
|
||||||
|
static void bmi08x_gyr_thread_main(void *arg1, void *unused1, void *unused2)
|
||||||
|
{
|
||||||
|
k_thread_name_set(NULL, "bmi08x_gyr_trig");
|
||||||
|
|
||||||
|
ARG_UNUSED(unused1);
|
||||||
|
ARG_UNUSED(unused2);
|
||||||
|
|
||||||
|
const struct device *dev = (const struct device *)arg1;
|
||||||
|
struct bmi08x_gyro_data *data = dev->data;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
k_sem_take(&data->sem, K_FOREVER);
|
||||||
|
bmi08x_handle_interrupts_gyr((void *)dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BMI08X_GYRO_TRIGGER_GLOBAL_THREAD
|
||||||
|
static void bmi08x_gyr_work_handler(struct k_work *work)
|
||||||
|
{
|
||||||
|
struct bmi08x_gyro_data *data = CONTAINER_OF(work, struct bmi08x_gyro_data, work);
|
||||||
|
|
||||||
|
bmi08x_handle_interrupts_gyr((void *)data->dev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void bmi08x_gyr_gpio_callback(const struct device *port, struct gpio_callback *cb,
|
||||||
|
uint32_t pin)
|
||||||
|
{
|
||||||
|
struct bmi08x_gyro_data *data = CONTAINER_OF(cb, struct bmi08x_gyro_data, gpio_cb);
|
||||||
|
|
||||||
|
ARG_UNUSED(port);
|
||||||
|
ARG_UNUSED(pin);
|
||||||
|
|
||||||
|
#if defined(CONFIG_BMI08X_GYRO_TRIGGER_OWN_THREAD)
|
||||||
|
k_sem_give(&data->sem);
|
||||||
|
#elif defined(CONFIG_BMI08X_GYRO_TRIGGER_GLOBAL_THREAD)
|
||||||
|
k_work_submit(&data->work);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_trigger_set_gyr(const struct device *dev, const struct sensor_trigger *trig,
|
||||||
|
sensor_trigger_handler_t handler)
|
||||||
|
{
|
||||||
|
struct bmi08x_gyro_data *data = dev->data;
|
||||||
|
|
||||||
|
if ((trig->chan == SENSOR_CHAN_GYRO_XYZ) && (trig->type == SENSOR_TRIG_DATA_READY)) {
|
||||||
|
data->handler_drdy_gyr = handler;
|
||||||
|
data->drdy_trig_gyr = trig;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmi08x_gyr_trigger_mode_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
struct bmi08x_gyro_data *data = dev->data;
|
||||||
|
const struct bmi08x_gyro_config *cfg = dev->config;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!gpio_is_ready_dt(&cfg->int_gpio)) {
|
||||||
|
LOG_ERR("GPIO device not ready");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BMI08X_GYRO_TRIGGER_OWN_THREAD)
|
||||||
|
k_sem_init(&data->sem, 0, K_SEM_MAX_LIMIT);
|
||||||
|
|
||||||
|
k_thread_create(&data->thread, data->thread_stack,
|
||||||
|
CONFIG_BMI08X_GYRO_THREAD_STACK_SIZE, bmi08x_gyr_thread_main, (void *)dev,
|
||||||
|
NULL, NULL, K_PRIO_COOP(CONFIG_BMI08X_GYRO_THREAD_PRIORITY), 0, K_NO_WAIT);
|
||||||
|
#elif defined(CONFIG_BMI08X_GYRO_TRIGGER_GLOBAL_THREAD)
|
||||||
|
data->work.handler = bmi08x_gyr_work_handler;
|
||||||
|
data->dev = dev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gpio_pin_configure_dt(&cfg->int_gpio, GPIO_INPUT);
|
||||||
|
|
||||||
|
gpio_init_callback(&data->gpio_cb, bmi08x_gyr_gpio_callback, BIT(cfg->int_gpio.pin));
|
||||||
|
|
||||||
|
ret = gpio_add_callback(cfg->int_gpio.port, &data->gpio_cb);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Failed to set gpio callback.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
gpio_pin_interrupt_configure_dt(&cfg->int_gpio, GPIO_INT_EDGE_TO_ACTIVE);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
8
dts/bindings/sensor/bosch,bmi08x-accel-i2c.yaml
Normal file
8
dts/bindings/sensor/bosch,bmi08x-accel-i2c.yaml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Copyright (c) 2022 Meta Platforms, Inc. and its affiliates.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: BMI08X Accel inertial measurement unit
|
||||||
|
|
||||||
|
compatible: "bosch,bmi08x-accel"
|
||||||
|
|
||||||
|
include: [i2c-device.yaml, "bosch,bmi08x-accel.yaml"]
|
8
dts/bindings/sensor/bosch,bmi08x-accel-spi.yaml
Normal file
8
dts/bindings/sensor/bosch,bmi08x-accel-spi.yaml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Copyright (c) 2022 Meta Platforms, Inc. and its affiliates.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: BMI08X Accel inertial measurement unit
|
||||||
|
|
||||||
|
compatible: "bosch,bmi08x-accel"
|
||||||
|
|
||||||
|
include: [spi-device.yaml, "bosch,bmi08x-accel.yaml"]
|
84
dts/bindings/sensor/bosch,bmi08x-accel.yaml
Normal file
84
dts/bindings/sensor/bosch,bmi08x-accel.yaml
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
# Copyright (c) 2022 Meta Platforms, Inc. and its affiliates.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: BMI08X Accel inertial measurement unit
|
||||||
|
|
||||||
|
include: sensor-device.yaml
|
||||||
|
|
||||||
|
properties:
|
||||||
|
int-gpios:
|
||||||
|
type: phandle-array
|
||||||
|
description: |
|
||||||
|
This property specifies the connection for INT, because the
|
||||||
|
Zephyr driver maps all interrupts to INT. The signal defaults
|
||||||
|
to output low when produced by the sensor.
|
||||||
|
|
||||||
|
int1-map-io:
|
||||||
|
type: int
|
||||||
|
description: |
|
||||||
|
Bit[0]: Map Interrupt A to INT1, Accel Data Ready
|
||||||
|
Bit[1]: Map Interrupt B to INT1
|
||||||
|
Bit[2]: Map Interrupt C to INT1
|
||||||
|
|
||||||
|
int2-map-io:
|
||||||
|
type: int
|
||||||
|
description: |
|
||||||
|
Bit[0]: Map Interrupt A to INT2, Accel Data Ready
|
||||||
|
Bit[1]: Map Interrupt B to INT2
|
||||||
|
Bit[2]: Map Interrupt C to INT2
|
||||||
|
|
||||||
|
int1-conf-io:
|
||||||
|
type: int
|
||||||
|
description: |
|
||||||
|
Bit[0]: reserved
|
||||||
|
Bit[1]: if set to 1, INT1 is active high, otherwise it's active low
|
||||||
|
Bit[2]: if set to 1, INT1 is open-drain, otherwise it's push-pull
|
||||||
|
Bit[3]: if set to 1, enable INT1 as an output pin
|
||||||
|
Bit[4]: if set to 1, enable INT1 as an input pin
|
||||||
|
Bit[7:5] : reserved
|
||||||
|
|
||||||
|
int2-conf-io:
|
||||||
|
type: int
|
||||||
|
description: |
|
||||||
|
Bit[0]: reserved
|
||||||
|
Bit[1]: if set to 1, INT2 is active high, otherwise it's active low
|
||||||
|
Bit[2]: if set to 1, INT2 is open-drain, otherwise it's push-pull
|
||||||
|
Bit[3]: if set to 1, enable INT2 as an output pin
|
||||||
|
Bit[4]: if set to 1, enable INT2 as an input pin
|
||||||
|
Bit[7:5] : reserved
|
||||||
|
|
||||||
|
accel-hz:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: |
|
||||||
|
Default frequency of accelerometer. (Unit - Hz)
|
||||||
|
enum:
|
||||||
|
- "12.5"
|
||||||
|
- "25"
|
||||||
|
- "50"
|
||||||
|
- "100"
|
||||||
|
- "200"
|
||||||
|
- "400"
|
||||||
|
- "800"
|
||||||
|
- "1600"
|
||||||
|
|
||||||
|
accel-fs:
|
||||||
|
type: int
|
||||||
|
required: true
|
||||||
|
description: |
|
||||||
|
Default full scale of accelerometer. (Unit - g)
|
||||||
|
enum:
|
||||||
|
- 2
|
||||||
|
- 3
|
||||||
|
- 4
|
||||||
|
- 6
|
||||||
|
- 8
|
||||||
|
- 12
|
||||||
|
- 16
|
||||||
|
- 24
|
||||||
|
|
||||||
|
data-sync:
|
||||||
|
type: phandle
|
||||||
|
description: |
|
||||||
|
Enables data sync if defined. This is to point to the bmi08x-gyro definition
|
||||||
|
that is within the same IC as the bmi08x-accel.
|
8
dts/bindings/sensor/bosch,bmi08x-gyro-i2c.yaml
Normal file
8
dts/bindings/sensor/bosch,bmi08x-gyro-i2c.yaml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Copyright (c) 2022 Meta Platforms, Inc. and its affiliates.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: BMI08X Gyro inertial measurement unit
|
||||||
|
|
||||||
|
compatible: "bosch,bmi08x-gyro"
|
||||||
|
|
||||||
|
include: [i2c-device.yaml, "bosch,bmi08x-gyro.yaml"]
|
8
dts/bindings/sensor/bosch,bmi08x-gyro-spi.yaml
Normal file
8
dts/bindings/sensor/bosch,bmi08x-gyro-spi.yaml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Copyright (c) 2022 Meta Platforms, Inc. and its affiliates.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: BMI08X Gyro inertial measurement unit
|
||||||
|
|
||||||
|
compatible: "bosch,bmi08x-gyro"
|
||||||
|
|
||||||
|
include: [spi-device.yaml, "bosch,bmi08x-gyro.yaml"]
|
62
dts/bindings/sensor/bosch,bmi08x-gyro.yaml
Normal file
62
dts/bindings/sensor/bosch,bmi08x-gyro.yaml
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# Copyright (c) 2022 Meta Platforms, Inc. and its affiliates.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: BMI08X Gyro inertial measurement unit
|
||||||
|
|
||||||
|
include: sensor-device.yaml
|
||||||
|
|
||||||
|
properties:
|
||||||
|
int-gpios:
|
||||||
|
type: phandle-array
|
||||||
|
description: |
|
||||||
|
This property specifies the connection for INT, because the
|
||||||
|
Zephyr driver maps all interrupts to INT. The signal defaults
|
||||||
|
to output low when produced by the sensor.
|
||||||
|
|
||||||
|
int3-4-map-io:
|
||||||
|
type: int
|
||||||
|
description: |
|
||||||
|
Bit[0] will map the data ready interrupt on INT3
|
||||||
|
Bit[2] will map the fifo interrupt on INT3
|
||||||
|
Bit[5] will map the fifo interrupt on INT4
|
||||||
|
Bit[7] will enable the data ready interrupt on INT4
|
||||||
|
|
||||||
|
int3-4-conf-io:
|
||||||
|
type: int
|
||||||
|
description: |
|
||||||
|
Bit[0]: if set to 1, INT3 is active high, otherwise it's active low
|
||||||
|
Bit[1]: if set to 1, INT3 is open-drain, otherwise it's push-pull
|
||||||
|
Bit[2]: if set to 1, INT4 is active high, otherwise it's active low
|
||||||
|
Bit[3]: if set to 1, INT4 is open-drain, otherwise it's push-pull
|
||||||
|
|
||||||
|
gyro-hz:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: |
|
||||||
|
Default frequency of accelerometer. (Unit - Hz)
|
||||||
|
enum:
|
||||||
|
- "2000_532"
|
||||||
|
- "2000_230"
|
||||||
|
- "1000_116"
|
||||||
|
- "400_47"
|
||||||
|
- "200_23"
|
||||||
|
- "100_12"
|
||||||
|
- "200_64"
|
||||||
|
- "100_32"
|
||||||
|
|
||||||
|
gyro-fs:
|
||||||
|
type: int
|
||||||
|
required: true
|
||||||
|
description: |
|
||||||
|
Default full scale of accelerometer. (Unit - g)
|
||||||
|
enum:
|
||||||
|
- 2000
|
||||||
|
- 1000
|
||||||
|
- 500
|
||||||
|
- 250
|
||||||
|
- 125
|
||||||
|
|
||||||
|
data-sync:
|
||||||
|
type: boolean
|
||||||
|
description: |
|
||||||
|
Enables data sync if defined. Must be set if bmi08x-accel data-sync is set as well.
|
|
@ -745,3 +745,25 @@ test_tcn75a: tcn75a@73 {
|
||||||
reg = <0x73>;
|
reg = <0x73>;
|
||||||
alert-gpios = <&test_gpio 0 0>;
|
alert-gpios = <&test_gpio 0 0>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test_i2c_bmi08x_accel: bmi08x@74 {
|
||||||
|
compatible = "bosch,bmi08x-accel";
|
||||||
|
reg = <0x74>;
|
||||||
|
int-gpios = <&test_gpio 0 0>;
|
||||||
|
int1-map-io = <0x01>;
|
||||||
|
int2-map-io = <0x00>;
|
||||||
|
int1-conf-io = <0x0A>;
|
||||||
|
int2-conf-io = <0x17>;
|
||||||
|
accel-hz = "800";
|
||||||
|
accel-fs = <4>;
|
||||||
|
};
|
||||||
|
|
||||||
|
test_i2c_bmi08x_gyro: bmi08x@75 {
|
||||||
|
compatible = "bosch,bmi08x-gyro";
|
||||||
|
reg = <0x75>;
|
||||||
|
int-gpios = <&test_gpio 0 0>;
|
||||||
|
int3-4-map-io = <0x01>;
|
||||||
|
int3-4-conf-io = <0x01>;
|
||||||
|
gyro-hz = "1000_116";
|
||||||
|
gyro-fs = <1000>;
|
||||||
|
};
|
||||||
|
|
|
@ -6,6 +6,8 @@ CONFIG_AMG88XX_TRIGGER_GLOBAL_THREAD=y
|
||||||
CONFIG_APDS9960_TRIGGER_GLOBAL_THREAD=y
|
CONFIG_APDS9960_TRIGGER_GLOBAL_THREAD=y
|
||||||
CONFIG_BMA280_TRIGGER_GLOBAL_THREAD=y
|
CONFIG_BMA280_TRIGGER_GLOBAL_THREAD=y
|
||||||
CONFIG_BMG160_TRIGGER_GLOBAL_THREAD=y
|
CONFIG_BMG160_TRIGGER_GLOBAL_THREAD=y
|
||||||
|
CONFIG_BMI08X_ACCEL_TRIGGER_GLOBAL_THREAD=y
|
||||||
|
CONFIG_BMI08X_GYRO_TRIGGER_GLOBAL_THREAD=y
|
||||||
CONFIG_BMI160_TRIGGER_GLOBAL_THREAD=y
|
CONFIG_BMI160_TRIGGER_GLOBAL_THREAD=y
|
||||||
CONFIG_BMI270_TRIGGER_GLOBAL_THREAD=y
|
CONFIG_BMI270_TRIGGER_GLOBAL_THREAD=y
|
||||||
CONFIG_BMP388_TRIGGER_GLOBAL_THREAD=y
|
CONFIG_BMP388_TRIGGER_GLOBAL_THREAD=y
|
||||||
|
|
|
@ -6,6 +6,8 @@ CONFIG_AMG88XX_TRIGGER_NONE=y
|
||||||
CONFIG_APDS9960_TRIGGER_NONE=y
|
CONFIG_APDS9960_TRIGGER_NONE=y
|
||||||
CONFIG_BMA280_TRIGGER_NONE=y
|
CONFIG_BMA280_TRIGGER_NONE=y
|
||||||
CONFIG_BMG160_TRIGGER_NONE=y
|
CONFIG_BMG160_TRIGGER_NONE=y
|
||||||
|
CONFIG_BMI08X_ACCEL_TRIGGER_NONE=y
|
||||||
|
CONFIG_BMI08X_GYRO_TRIGGER_NONE=y
|
||||||
CONFIG_BMI160_TRIGGER_NONE=y
|
CONFIG_BMI160_TRIGGER_NONE=y
|
||||||
CONFIG_BMI270_TRIGGER_NONE=y
|
CONFIG_BMI270_TRIGGER_NONE=y
|
||||||
CONFIG_BMP388_TRIGGER_NONE=y
|
CONFIG_BMP388_TRIGGER_NONE=y
|
||||||
|
|
|
@ -5,6 +5,8 @@ CONFIG_ADXL372_TRIGGER_OWN_THREAD=y
|
||||||
CONFIG_AMG88XX_TRIGGER_OWN_THREAD=y
|
CONFIG_AMG88XX_TRIGGER_OWN_THREAD=y
|
||||||
CONFIG_BMA280_TRIGGER_OWN_THREAD=y
|
CONFIG_BMA280_TRIGGER_OWN_THREAD=y
|
||||||
CONFIG_BMG160_TRIGGER_OWN_THREAD=y
|
CONFIG_BMG160_TRIGGER_OWN_THREAD=y
|
||||||
|
CONFIG_BMI08X_ACCEL_TRIGGER_OWN_THREAD=y
|
||||||
|
CONFIG_BMI08X_GYRO_TRIGGER_OWN_THREAD=y
|
||||||
CONFIG_BMI160_TRIGGER_OWN_THREAD=y
|
CONFIG_BMI160_TRIGGER_OWN_THREAD=y
|
||||||
CONFIG_BMI270_TRIGGER_OWN_THREAD=y
|
CONFIG_BMI270_TRIGGER_OWN_THREAD=y
|
||||||
CONFIG_BMP388_TRIGGER_OWN_THREAD=y
|
CONFIG_BMP388_TRIGGER_OWN_THREAD=y
|
||||||
|
|
|
@ -395,3 +395,27 @@ test_spi_lsm6dsv16x: lsm6dsv16x@30 {
|
||||||
spi-max-frequency = <0>;
|
spi-max-frequency = <0>;
|
||||||
irq-gpios = <&test_gpio 0 0>;
|
irq-gpios = <&test_gpio 0 0>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test_spi_bmi08x_accel: bmi08x@31 {
|
||||||
|
compatible = "bosch,bmi08x-accel";
|
||||||
|
reg = <0x31>;
|
||||||
|
spi-max-frequency = <0>;
|
||||||
|
int-gpios = <&test_gpio 0 0>;
|
||||||
|
int1-map-io = <0x01>;
|
||||||
|
int2-map-io = <0x00>;
|
||||||
|
int1-conf-io = <0x0A>;
|
||||||
|
int2-conf-io = <0x17>;
|
||||||
|
accel-hz = "800";
|
||||||
|
accel-fs = <4>;
|
||||||
|
};
|
||||||
|
|
||||||
|
test_spi_bmi08x_gyro: bmi08x@32 {
|
||||||
|
compatible = "bosch,bmi08x-gyro";
|
||||||
|
reg = <0x32>;
|
||||||
|
spi-max-frequency = <0>;
|
||||||
|
int-gpios = <&test_gpio 0 0>;
|
||||||
|
int3-4-map-io = <0x01>;
|
||||||
|
int3-4-conf-io = <0x01>;
|
||||||
|
gyro-hz = "1000_116";
|
||||||
|
gyro-fs = <1000>;
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue