652 lines
16 KiB
C
652 lines
16 KiB
C
/*
|
|
* Copyright (c) 2024 Bootlin
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#define DT_DRV_COMPAT st_lsm9ds1
|
|
|
|
#include <zephyr/drivers/sensor.h>
|
|
#include <zephyr/logging/log.h>
|
|
|
|
#include "lsm9ds1.h"
|
|
#include <stmemsc.h>
|
|
|
|
LOG_MODULE_REGISTER(LSM9DS1, CONFIG_SENSOR_LOG_LEVEL);
|
|
|
|
/* Sensitivity of the accelerometer, indexed by the raw full scale value. Unit is µg/ LSB */
|
|
static const uint16_t lsm9ds1_accel_fs_sens[] = {61, 732, 122, 244};
|
|
|
|
/*
|
|
* Sensitivity of the gyroscope, indexed by the raw full scale value.
|
|
* The value here is just a factor applied to GAIN_UNIT_G, as the sensitivity is
|
|
* proportional to the full scale size.
|
|
* The index 2 is never used : the value `0` is just a placeholder.
|
|
*/
|
|
static const uint16_t lsm9ds1_gyro_fs_sens[] = {1, 2, 0, 8};
|
|
|
|
/*
|
|
* Values of the different sampling frequencies of the accelerometer, indexed by the raw odr
|
|
* value that the sensor understands.
|
|
*/
|
|
static const uint16_t lsm9ds1_odr_map[] = {0, 10, 50, 119, 238, 476, 952};
|
|
|
|
/*
|
|
* Value of the different sampling frequencies of the gyroscope, indexed by the raw odr value
|
|
* that the sensor understands.
|
|
*/
|
|
static const uint16_t lsm9ds1_gyro_odr_map[] = {0, 15, 59, 119, 238, 476, 952};
|
|
|
|
static int lsm9ds1_reboot(const struct device *dev)
|
|
{
|
|
const struct lsm9ds1_config *cfg = dev->config;
|
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
|
lsm9ds1_ctrl_reg8_t ctrl8_reg;
|
|
int ret;
|
|
|
|
ret = lsm9ds1_read_reg(ctx, LSM9DS1_CTRL_REG8, (uint8_t *)&ctrl8_reg, 1);
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
ctrl8_reg.boot = 1;
|
|
|
|
ret = lsm9ds1_write_reg(ctx, LSM9DS1_CTRL_REG8, (uint8_t *)&ctrl8_reg, 1);
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
k_msleep(50);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_accel_range_to_fs_val(int32_t range)
|
|
{
|
|
switch (range) {
|
|
case 2:
|
|
return LSM9DS1_2g;
|
|
case 4:
|
|
return LSM9DS1_4g;
|
|
case 8:
|
|
return LSM9DS1_8g;
|
|
case 16:
|
|
return LSM9DS1_16g;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
static int lsm9ds1_gyro_range_to_fs_val(int32_t range)
|
|
{
|
|
switch (range) {
|
|
case 245:
|
|
return LSM9DS1_245dps;
|
|
case 500:
|
|
return LSM9DS1_500dps;
|
|
case 2000:
|
|
return LSM9DS1_2000dps;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
static int lsm9ds1_accel_fs_val_to_gain(int fs)
|
|
{
|
|
return lsm9ds1_accel_fs_sens[fs];
|
|
}
|
|
|
|
static int lsm9ds1_accel_freq_to_odr_val(uint16_t freq)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(lsm9ds1_odr_map); i++) {
|
|
if (freq <= lsm9ds1_odr_map[i]) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -EINVAL;
|
|
}
|
|
|
|
static int lsm9ds1_gyro_freq_to_odr_val(uint16_t freq)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(lsm9ds1_gyro_odr_map); i++) {
|
|
if (freq <= lsm9ds1_gyro_odr_map[i]) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -EINVAL;
|
|
}
|
|
|
|
static int lsm9ds1_accel_set_odr_raw(const struct device *dev, uint8_t odr)
|
|
{
|
|
const struct lsm9ds1_config *cfg = dev->config;
|
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
|
struct lsm9ds1_data *data = dev->data;
|
|
int ret;
|
|
|
|
lsm9ds1_ctrl_reg6_xl_t ctrl_reg6_xl;
|
|
|
|
ret = lsm9ds1_read_reg(ctx, LSM9DS1_CTRL_REG6_XL, (uint8_t *)&ctrl_reg6_xl, 1);
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
ctrl_reg6_xl.odr_xl = odr;
|
|
|
|
ret = lsm9ds1_write_reg(ctx, LSM9DS1_CTRL_REG6_XL, (uint8_t *)&ctrl_reg6_xl, 1);
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
data->accel_odr = odr;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_gyro_set_odr_raw(const struct device *dev, uint8_t odr)
|
|
{
|
|
const struct lsm9ds1_config *cfg = dev->config;
|
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
|
struct lsm9ds1_data *data = dev->data;
|
|
int ret;
|
|
|
|
lsm9ds1_ctrl_reg1_g_t ctrl_reg1;
|
|
|
|
ret = lsm9ds1_read_reg(ctx, LSM9DS1_CTRL_REG1_G, (uint8_t *)&ctrl_reg1, 1);
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
ctrl_reg1.odr_g = odr;
|
|
|
|
ret = lsm9ds1_write_reg(ctx, LSM9DS1_CTRL_REG1_G, (uint8_t *)&ctrl_reg1, 1);
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
data->gyro_odr = odr;
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_gyro_odr_set(const struct device *dev, uint16_t freq)
|
|
{
|
|
struct lsm9ds1_data *data = dev->data;
|
|
int odr;
|
|
int ret;
|
|
|
|
odr = lsm9ds1_gyro_freq_to_odr_val(freq);
|
|
|
|
if (odr == data->gyro_odr) {
|
|
return 0;
|
|
}
|
|
|
|
LOG_INF("You are also changing the odr of the accelerometer");
|
|
|
|
ret = lsm9ds1_gyro_set_odr_raw(dev, odr);
|
|
if (ret < 0) {
|
|
LOG_DBG("failed to set gyroscope sampling rate");
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* When the gyroscope is on, the value of the accelerometer odr must be
|
|
* the same as the value of the gyroscope.
|
|
*/
|
|
|
|
ret = lsm9ds1_accel_set_odr_raw(dev, odr);
|
|
if (ret < 0) {
|
|
LOG_ERR("failed to set accelerometer sampling rate");
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_accel_odr_set(const struct device *dev, uint16_t freq)
|
|
{
|
|
const struct lsm9ds1_config *cfg = dev->config;
|
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
|
struct lsm9ds1_data *data = dev->data;
|
|
int odr, ret;
|
|
lsm9ds1_imu_odr_t old_odr;
|
|
|
|
ret = lsm9ds1_imu_data_rate_get(ctx, &old_odr);
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* The gyroscope is on :
|
|
* we have to change the odr on both the accelerometer and the gyroscope
|
|
*/
|
|
if (old_odr & GYRO_ODR_MASK) {
|
|
|
|
odr = lsm9ds1_gyro_freq_to_odr_val(freq);
|
|
|
|
if (odr == data->gyro_odr) {
|
|
return 0;
|
|
}
|
|
|
|
LOG_INF("You are also changing the odr of the gyroscope");
|
|
|
|
ret = lsm9ds1_accel_set_odr_raw(dev, odr);
|
|
if (ret < 0) {
|
|
LOG_DBG("failed to set accelerometer sampling rate");
|
|
return ret;
|
|
}
|
|
|
|
ret = lsm9ds1_gyro_set_odr_raw(dev, odr);
|
|
if (ret < 0) {
|
|
LOG_ERR("failed to set gyroscope sampling rate");
|
|
return ret;
|
|
}
|
|
|
|
/* The gyroscope is off, we have to change the odr of just the accelerometer */
|
|
} else {
|
|
|
|
odr = lsm9ds1_accel_freq_to_odr_val(freq);
|
|
|
|
if (odr == data->accel_odr) {
|
|
return 0;
|
|
}
|
|
|
|
if (odr < 0) {
|
|
return odr;
|
|
}
|
|
|
|
ret = lsm9ds1_accel_set_odr_raw(dev, odr);
|
|
if (ret < 0) {
|
|
LOG_DBG("failed to set accelerometer sampling rate");
|
|
return ret;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_accel_range_set(const struct device *dev, int32_t range)
|
|
{
|
|
int fs;
|
|
struct lsm9ds1_data *data = dev->data;
|
|
const struct lsm9ds1_config *cfg = dev->config;
|
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
|
int ret;
|
|
|
|
fs = lsm9ds1_accel_range_to_fs_val(range);
|
|
if (fs < 0) {
|
|
LOG_DBG("full scale value not supported");
|
|
return fs;
|
|
}
|
|
|
|
ret = lsm9ds1_xl_full_scale_set(ctx, fs);
|
|
if (ret < 0) {
|
|
LOG_DBG("failed to set accelerometer full-scale");
|
|
return ret;
|
|
}
|
|
|
|
data->acc_gain = lsm9ds1_accel_fs_val_to_gain(fs);
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_gyro_range_set(const struct device *dev, int32_t range)
|
|
{
|
|
int fs;
|
|
struct lsm9ds1_data *data = dev->data;
|
|
const struct lsm9ds1_config *cfg = dev->config;
|
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
|
int ret;
|
|
|
|
fs = lsm9ds1_gyro_range_to_fs_val(range);
|
|
if (fs < 0) {
|
|
return fs;
|
|
}
|
|
|
|
ret = lsm9ds1_gy_full_scale_set(ctx, fs);
|
|
if (ret < 0) {
|
|
LOG_DBG("failed to set gyroscope full-scale");
|
|
return ret;
|
|
}
|
|
|
|
data->gyro_gain = (lsm9ds1_gyro_fs_sens[fs] * GAIN_UNIT_G);
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_accel_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 lsm9ds1_accel_range_set(dev, sensor_ms2_to_g(val));
|
|
case SENSOR_ATTR_SAMPLING_FREQUENCY:
|
|
return lsm9ds1_accel_odr_set(dev, val->val1);
|
|
default:
|
|
LOG_DBG("Accel attribute not supported.");
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_gyro_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 lsm9ds1_gyro_range_set(dev, sensor_rad_to_degrees(val));
|
|
case SENSOR_ATTR_SAMPLING_FREQUENCY:
|
|
return lsm9ds1_gyro_odr_set(dev, val->val1);
|
|
default:
|
|
LOG_DBG("Gyro attribute not supported.");
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_attr_set(const struct device *dev, enum sensor_channel chan,
|
|
enum sensor_attribute attr, const struct sensor_value *val)
|
|
{
|
|
switch (chan) {
|
|
case SENSOR_CHAN_ACCEL_XYZ:
|
|
return lsm9ds1_accel_config(dev, chan, attr, val);
|
|
case SENSOR_CHAN_GYRO_XYZ:
|
|
return lsm9ds1_gyro_config(dev, chan, attr, val);
|
|
default:
|
|
LOG_WRN("attr_set() not supported on this channel.");
|
|
return -ENOTSUP;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_sample_fetch_accel(const struct device *dev)
|
|
{
|
|
const struct lsm9ds1_config *cfg = dev->config;
|
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
|
struct lsm9ds1_data *data = dev->data;
|
|
int ret;
|
|
|
|
ret = lsm9ds1_acceleration_raw_get(ctx, data->acc);
|
|
if (ret < 0) {
|
|
LOG_DBG("Failed to read sample");
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_sample_fetch_gyro(const struct device *dev)
|
|
{
|
|
const struct lsm9ds1_config *cfg = dev->config;
|
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
|
struct lsm9ds1_data *data = dev->data;
|
|
int ret;
|
|
|
|
ret = lsm9ds1_angular_rate_raw_get(ctx, data->gyro);
|
|
if (ret < 0) {
|
|
LOG_DBG("Failed to read sample");
|
|
return ret;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#if IS_ENABLED(CONFIG_LSM9DS1_ENABLE_TEMP)
|
|
static int lsm9ds1_sample_fetch_temp(const struct device *dev)
|
|
{
|
|
const struct lsm9ds1_config *cfg = dev->config;
|
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
|
struct lsm9ds1_data *data = dev->data;
|
|
int ret;
|
|
|
|
ret = lsm9ds1_temperature_raw_get(ctx, &data->temp_sample);
|
|
if (ret < 0) {
|
|
LOG_DBG("Failed to read sample");
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
static int lsm9ds1_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
|
{
|
|
switch (chan) {
|
|
case SENSOR_CHAN_ACCEL_XYZ:
|
|
lsm9ds1_sample_fetch_accel(dev);
|
|
break;
|
|
case SENSOR_CHAN_GYRO_XYZ:
|
|
lsm9ds1_sample_fetch_gyro(dev);
|
|
break;
|
|
#if IS_ENABLED(CONFIG_LSM9DS1_ENABLE_TEMP)
|
|
case SENSOR_CHAN_DIE_TEMP:
|
|
lsm9ds1_sample_fetch_temp(dev);
|
|
break;
|
|
#endif
|
|
case SENSOR_CHAN_ALL:
|
|
lsm9ds1_sample_fetch_accel(dev);
|
|
lsm9ds1_sample_fetch_gyro(dev);
|
|
#if IS_ENABLED(CONFIG_LSM9DS1_ENABLE_TEMP)
|
|
lsm9ds1_sample_fetch_temp(dev);
|
|
#endif
|
|
break;
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static inline void lsm9ds1_accel_convert(struct sensor_value *val, int raw_val,
|
|
uint32_t sensitivity)
|
|
{
|
|
/* Sensitivity is exposed in ug/LSB */
|
|
/* Convert to m/s^2 */
|
|
sensor_ug_to_ms2(raw_val * sensitivity, val);
|
|
}
|
|
|
|
static inline int lsm9ds1_accel_get_channel(enum sensor_channel chan, struct sensor_value *val,
|
|
struct lsm9ds1_data *data, uint32_t sensitivity)
|
|
{
|
|
uint8_t i;
|
|
|
|
switch (chan) {
|
|
case SENSOR_CHAN_ACCEL_X:
|
|
lsm9ds1_accel_convert(val, data->acc[0], sensitivity);
|
|
break;
|
|
case SENSOR_CHAN_ACCEL_Y:
|
|
lsm9ds1_accel_convert(val, data->acc[1], sensitivity);
|
|
break;
|
|
case SENSOR_CHAN_ACCEL_Z:
|
|
lsm9ds1_accel_convert(val, data->acc[2], sensitivity);
|
|
break;
|
|
case SENSOR_CHAN_ACCEL_XYZ:
|
|
for (i = 0; i < 3; i++) {
|
|
lsm9ds1_accel_convert(val++, data->acc[i], sensitivity);
|
|
}
|
|
break;
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_accel_channel_get(enum sensor_channel chan, struct sensor_value *val,
|
|
struct lsm9ds1_data *data)
|
|
{
|
|
return lsm9ds1_accel_get_channel(chan, val, data, data->acc_gain);
|
|
}
|
|
|
|
static inline void lsm9ds1_gyro_convert(struct sensor_value *val, int raw_val, uint32_t sensitivity)
|
|
{
|
|
/* Sensitivity is exposed in udps/LSB */
|
|
/* Convert to rad/s */
|
|
sensor_10udegrees_to_rad((raw_val * (int32_t)sensitivity) / 10, val);
|
|
}
|
|
|
|
static inline int lsm9ds1_gyro_get_channel(enum sensor_channel chan, struct sensor_value *val,
|
|
struct lsm9ds1_data *data, uint32_t sensitivity)
|
|
{
|
|
uint8_t i;
|
|
|
|
switch (chan) {
|
|
case SENSOR_CHAN_GYRO_X:
|
|
lsm9ds1_gyro_convert(val, data->gyro[0], sensitivity);
|
|
break;
|
|
case SENSOR_CHAN_GYRO_Y:
|
|
lsm9ds1_gyro_convert(val, data->gyro[1], sensitivity);
|
|
break;
|
|
case SENSOR_CHAN_GYRO_Z:
|
|
lsm9ds1_gyro_convert(val, data->gyro[2], sensitivity);
|
|
break;
|
|
case SENSOR_CHAN_GYRO_XYZ:
|
|
for (i = 0; i < 3; i++) {
|
|
lsm9ds1_gyro_convert(val++, data->gyro[i], sensitivity);
|
|
}
|
|
break;
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lsm9ds1_gyro_channel_get(enum sensor_channel chan, struct sensor_value *val,
|
|
struct lsm9ds1_data *data)
|
|
{
|
|
return lsm9ds1_gyro_get_channel(chan, val, data, data->gyro_gain);
|
|
}
|
|
|
|
#if IS_ENABLED(CONFIG_LSM9DS1_ENABLE_TEMP)
|
|
static void lsm9ds1_temp_channel_get(struct sensor_value *val, struct lsm9ds1_data *data)
|
|
{
|
|
val->val1 = data->temp_sample / TEMP_SENSITIVITY + TEMP_OFFSET;
|
|
val->val2 = (data->temp_sample % TEMP_SENSITIVITY) * (1000000 / TEMP_SENSITIVITY);
|
|
}
|
|
#endif
|
|
|
|
static int lsm9ds1_channel_get(const struct device *dev, enum sensor_channel chan,
|
|
struct sensor_value *val)
|
|
{
|
|
struct lsm9ds1_data *data = dev->data;
|
|
|
|
switch (chan) {
|
|
case SENSOR_CHAN_ACCEL_X:
|
|
case SENSOR_CHAN_ACCEL_Y:
|
|
case SENSOR_CHAN_ACCEL_Z:
|
|
case SENSOR_CHAN_ACCEL_XYZ:
|
|
lsm9ds1_accel_channel_get(chan, val, data);
|
|
break;
|
|
case SENSOR_CHAN_GYRO_X:
|
|
case SENSOR_CHAN_GYRO_Y:
|
|
case SENSOR_CHAN_GYRO_Z:
|
|
case SENSOR_CHAN_GYRO_XYZ:
|
|
lsm9ds1_gyro_channel_get(chan, val, data);
|
|
break;
|
|
#if IS_ENABLED(CONFIG_LSM9DS1_ENABLE_TEMP)
|
|
case SENSOR_CHAN_DIE_TEMP:
|
|
lsm9ds1_temp_channel_get(val, data);
|
|
break;
|
|
#endif
|
|
default:
|
|
return -ENOTSUP;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct sensor_driver_api lsm9ds1_api_funcs = {
|
|
.sample_fetch = lsm9ds1_sample_fetch,
|
|
.channel_get = lsm9ds1_channel_get,
|
|
.attr_set = lsm9ds1_attr_set,
|
|
};
|
|
|
|
static int lsm9ds1_init(const struct device *dev)
|
|
{
|
|
const struct lsm9ds1_config *cfg = dev->config;
|
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
|
struct lsm9ds1_data *lsm9ds1 = dev->data;
|
|
uint8_t chip_id, fs;
|
|
int ret;
|
|
|
|
ret = lsm9ds1_reboot(dev);
|
|
if (ret < 0) {
|
|
LOG_ERR("Failed to reboot device");
|
|
return ret;
|
|
}
|
|
|
|
ret = lsm9ds1_read_reg(ctx, LSM9DS1_WHO_AM_I, &chip_id, 1);
|
|
if (ret < 0) {
|
|
LOG_ERR("failed reading chip id");
|
|
return ret;
|
|
}
|
|
|
|
if (chip_id != LSM9DS1_IMU_ID) {
|
|
LOG_ERR("Invalid ID : got %x", chip_id);
|
|
return -EIO;
|
|
}
|
|
LOG_DBG("chip_id : %x", chip_id);
|
|
|
|
LOG_DBG("output data rate is %d\n", cfg->imu_odr);
|
|
ret = lsm9ds1_imu_data_rate_set(ctx, cfg->imu_odr);
|
|
if (ret < 0) {
|
|
LOG_ERR("failed to set IMU odr");
|
|
return ret;
|
|
}
|
|
|
|
fs = cfg->accel_range;
|
|
LOG_DBG("accel range is %d\n", fs);
|
|
ret = lsm9ds1_xl_full_scale_set(ctx, fs);
|
|
if (ret < 0) {
|
|
LOG_ERR("failed to set accelerometer range %d", fs);
|
|
return ret;
|
|
}
|
|
|
|
lsm9ds1->acc_gain = lsm9ds1_accel_fs_val_to_gain(fs);
|
|
|
|
fs = cfg->gyro_range;
|
|
LOG_DBG("gyro range is %d", fs);
|
|
ret = lsm9ds1_gy_full_scale_set(ctx, fs);
|
|
if (ret < 0) {
|
|
LOG_ERR("failed to set gyroscope range %d\n", fs);
|
|
return ret;
|
|
}
|
|
lsm9ds1->gyro_gain = (lsm9ds1_gyro_fs_sens[fs] * GAIN_UNIT_G);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define LSM9DS1_CONFIG_COMMON(inst) \
|
|
.imu_odr = DT_INST_PROP(inst, imu_odr), \
|
|
.accel_range = DT_INST_PROP(inst, accel_range), \
|
|
.gyro_range = DT_INST_PROP(inst, gyro_range),
|
|
|
|
/*
|
|
* Instantiation macros used when a device is on an I2C bus.
|
|
*/
|
|
|
|
#define LSM9DS1_CONFIG_I2C(inst) \
|
|
{ \
|
|
STMEMSC_CTX_I2C(&lsm9ds1_config_##inst.stmemsc_cfg), \
|
|
.stmemsc_cfg = \
|
|
{ \
|
|
.i2c = I2C_DT_SPEC_INST_GET(inst), \
|
|
}, \
|
|
LSM9DS1_CONFIG_COMMON(inst) \
|
|
}
|
|
|
|
#define LSM9DS1_DEFINE(inst) \
|
|
static struct lsm9ds1_data lsm9ds1_data_##inst = { \
|
|
.acc_gain = 0, \
|
|
}; \
|
|
\
|
|
static struct lsm9ds1_config lsm9ds1_config_##inst = LSM9DS1_CONFIG_I2C(inst); \
|
|
\
|
|
SENSOR_DEVICE_DT_INST_DEFINE(inst, lsm9ds1_init, NULL, &lsm9ds1_data_##inst, \
|
|
&lsm9ds1_config_##inst, POST_KERNEL, \
|
|
CONFIG_SENSOR_INIT_PRIORITY, &lsm9ds1_api_funcs);
|
|
|
|
DT_INST_FOREACH_STATUS_OKAY(LSM9DS1_DEFINE);
|