| /**************************************************************************** |
| * drivers/sensors/lsm9ds1_uorb.c |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. The |
| * ASF licenses this file to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the |
| * License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| * |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Included Files |
| ****************************************************************************/ |
| |
| #include <nuttx/config.h> |
| |
| #include <math.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <limits.h> |
| #include <fcntl.h> |
| #include <inttypes.h> |
| #include <sys/param.h> |
| |
| #include <nuttx/mutex.h> |
| #include <nuttx/signal.h> |
| #include <nuttx/compiler.h> |
| #include <nuttx/nuttx.h> |
| #include <nuttx/kthread.h> |
| |
| #include <nuttx/sensors/sensor.h> |
| #include <nuttx/sensors/ioctl.h> |
| |
| #include "lsm9ds1_base.h" |
| |
| /**************************************************************************** |
| * Pre-processor Definitions |
| ****************************************************************************/ |
| |
| #define CONSTANTS_ONE_G 9.8f |
| |
| /**************************************************************************** |
| * Private Types |
| ****************************************************************************/ |
| |
| enum lsm9ds1_idx_e |
| { |
| LSM9DS1_ACCEL_IDX = 0, |
| LSM9DS1_GYRO_IDX, |
| LSM9DS1_MAG_IDX, |
| LSM9DS1_MAX_IDX |
| }; |
| |
| struct lsm9ds1_sensor_s |
| { |
| struct sensor_lowerhalf_s lower; |
| uint64_t last_update; |
| float scale; |
| FAR void *dev; |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| bool enabled; |
| uint32_t interval; |
| #endif |
| struct lsm9ds1_dev_s base; |
| }; |
| |
| struct lsm9ds1_sensor_dev_s |
| { |
| struct lsm9ds1_sensor_s priv[3]; |
| mutex_t lock; |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| sem_t run; |
| #endif |
| }; |
| |
| /**************************************************************************** |
| * Private Function Prototypes |
| ****************************************************************************/ |
| |
| /* Sensor methods */ |
| |
| static int lsm9ds1_activate(FAR struct sensor_lowerhalf_s *lower, |
| FAR struct file *filep, |
| bool enable); |
| static int lsm9ds1_set_interval(FAR struct sensor_lowerhalf_s *lower, |
| FAR struct file *filep, |
| FAR uint32_t *period_us); |
| #ifndef CONFIG_SENSORS_LSM9DS1_POLL |
| static int lsm9ds1_fetch(FAR struct sensor_lowerhalf_s *lower, |
| FAR struct file *filep, |
| FAR char *buffer, size_t buflen); |
| #endif |
| static int lsm9ds1_control(FAR struct sensor_lowerhalf_s *lower, |
| FAR struct file *filep, |
| int cmd, unsigned long arg); |
| |
| /* Helpers */ |
| |
| static int lsm9ds1_mag_scale(FAR struct lsm9ds1_sensor_s *priv, |
| uint8_t scale); |
| static int lsm9ds1_accel_scale(FAR struct lsm9ds1_sensor_s *priv, |
| uint8_t scale); |
| static int lsm9ds1_gyro_scale(FAR struct lsm9ds1_sensor_s *priv, |
| uint8_t scale); |
| |
| /**************************************************************************** |
| * Private Data |
| ****************************************************************************/ |
| |
| static const struct sensor_ops_s g_sensor_ops = |
| { |
| NULL, /* open */ |
| NULL, /* close */ |
| .activate = lsm9ds1_activate, |
| .set_interval = lsm9ds1_set_interval, |
| NULL, /* batch */ |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| NULL, /* fetch */ |
| #else |
| .fetch = lsm9ds1_fetch, |
| #endif |
| NULL, /* flush */ |
| NULL, /* selftest */ |
| NULL, /* set_calibvalue */ |
| NULL, /* calibrate */ |
| NULL, /* get_info */ |
| .control = lsm9ds1_control |
| }; |
| |
| /**************************************************************************** |
| * Private Functions |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Name: lsm9ds1_activate |
| ****************************************************************************/ |
| |
| static int lsm9ds1_activate(FAR struct sensor_lowerhalf_s *lower, |
| FAR struct file *filep, bool enable) |
| { |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| FAR struct lsm9ds1_sensor_s *priv = NULL; |
| FAR struct lsm9ds1_sensor_dev_s *dev = NULL; |
| bool start_thread = false; |
| int ret = OK; |
| |
| priv = container_of(lower, struct lsm9ds1_sensor_s, lower); |
| dev = priv->dev; |
| |
| if (enable) |
| { |
| if (!priv->enabled) |
| { |
| start_thread = true; |
| priv->last_update = sensor_get_timestamp(); |
| } |
| |
| ret = priv->base.ops->start(&priv->base); |
| } |
| else |
| { |
| ret = priv->base.ops->stop(&priv->base); |
| } |
| |
| priv->enabled = enable; |
| |
| if (start_thread) |
| { |
| /* Wake up the thread */ |
| |
| nxsem_post(&dev->run); |
| } |
| |
| return ret; |
| #else |
| return OK; |
| #endif |
| } |
| |
| /**************************************************************************** |
| * Name: lsm9ds1_set_interval |
| ****************************************************************************/ |
| |
| static int lsm9ds1_set_interval(FAR struct sensor_lowerhalf_s *lower, |
| FAR struct file *filep, |
| FAR uint32_t *interval) |
| { |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| FAR struct lsm9ds1_sensor_s *priv = NULL; |
| |
| priv = container_of(lower, struct lsm9ds1_sensor_s, lower); |
| |
| priv->interval = *interval; |
| #endif |
| |
| return OK; |
| } |
| |
| /**************************************************************************** |
| * Name: lsm9ds1_data |
| ****************************************************************************/ |
| |
| static int16_t lsm9ds1_data(int16_t data) |
| { |
| /* The value is positive */ |
| |
| if (data < 0x8000) |
| { |
| data = data; |
| } |
| |
| /* The value is negative, so find its absolute value by taking the |
| * two's complement |
| */ |
| |
| else if (data > 0x8000) |
| { |
| data = -(~data + 1); |
| } |
| |
| /* The value is negative and can't be represented as a positive |
| * int16_t value |
| */ |
| |
| else |
| { |
| data = -32768; |
| } |
| |
| return data; |
| } |
| |
| #ifndef CONFIG_SENSORS_LSM9DS1_POLL |
| /**************************************************************************** |
| * Name: lsm9ds1_fetch |
| ****************************************************************************/ |
| |
| static int lsm9ds1_fetch(FAR struct sensor_lowerhalf_s *lower, |
| FAR struct file *filep, FAR char *buffer, |
| size_t buflen) |
| { |
| FAR struct lsm9ds1_sensor_s *priv = NULL; |
| int16_t data[3]; |
| int ret = OK; |
| |
| priv = container_of(lower, struct lsm9ds1_sensor_s, lower); |
| |
| switch (lower->type) |
| { |
| case SENSOR_TYPE_ACCELEROMETER: |
| { |
| struct sensor_accel accel; |
| |
| ret = lsm9ds1_readreg(&priv->base, LSM9DS1_OUT_X_L_XL, |
| (FAR uint8_t *)data, 6); |
| |
| accel.timestamp = sensor_get_timestamp(); |
| accel.x = (int16_t)lsm9ds1_data(data[0]) * priv->scale; |
| accel.y = (int16_t)lsm9ds1_data(data[1]) * priv->scale; |
| accel.z = (int16_t)lsm9ds1_data(data[2]) * priv->scale; |
| |
| memcpy(buffer, &accel, sizeof(accel)); |
| |
| break; |
| } |
| |
| case SENSOR_TYPE_GYROSCOPE: |
| { |
| struct sensor_gyro gyro; |
| |
| ret = lsm9ds1_readreg(&priv->base, LSM9DS1_OUT_X_L_G, |
| (FAR uint8_t *)data, 6); |
| |
| gyro.timestamp = sensor_get_timestamp(); |
| gyro.x = (int16_t)lsm9ds1_data(data[0]) * priv->scale; |
| gyro.y = (int16_t)lsm9ds1_data(data[1]) * priv->scale; |
| gyro.z = (int16_t)lsm9ds1_data(data[2]) * priv->scale; |
| |
| memcpy(buffer, &gyro, sizeof(gyro)); |
| |
| break; |
| } |
| |
| case SENSOR_TYPE_MAGNETIC_FIELD: |
| { |
| struct sensor_mag mag; |
| |
| ret = lsm9ds1_readreg(&priv->base, LSM9DS1_OUT_X_L_M, |
| (FAR uint8_t *)data, 6); |
| |
| mag.timestamp = sensor_get_timestamp(); |
| mag.x = (int16_t)lsm9ds1_data(data[0]) * priv->scale; |
| mag.y = (int16_t)lsm9ds1_data(data[1]) * priv->scale; |
| mag.z = (int16_t)lsm9ds1_data(data[2]) * priv->scale; |
| |
| memcpy(buffer, &mag, sizeof(mag)); |
| |
| break; |
| } |
| |
| default: |
| { |
| ret = -EINVAL; |
| break; |
| } |
| } |
| |
| return ret; |
| } |
| #endif |
| |
| /**************************************************************************** |
| * Name: lsm9ds1_cotrol |
| ****************************************************************************/ |
| |
| static int lsm9ds1_control(FAR struct sensor_lowerhalf_s *lower, |
| FAR struct file *filep, int cmd, |
| unsigned long arg) |
| { |
| FAR struct lsm9ds1_sensor_s *priv = NULL; |
| int ret = OK; |
| |
| priv = container_of(lower, struct lsm9ds1_sensor_s, lower); |
| |
| switch (cmd) |
| { |
| /* Set full scale command */ |
| |
| case SNIOC_SET_SCALE_XL: |
| { |
| if (priv->lower.type == SENSOR_TYPE_GYROSCOPE) |
| { |
| ret = lsm9ds1_gyro_scale(priv, arg); |
| } |
| else if (priv->lower.type == SENSOR_TYPE_ACCELEROMETER) |
| { |
| ret = lsm9ds1_accel_scale(priv, arg); |
| } |
| else if (priv->lower.type == SENSOR_TYPE_MAGNETIC_FIELD) |
| { |
| ret = lsm9ds1_mag_scale(priv, arg); |
| } |
| |
| break; |
| } |
| |
| default: |
| { |
| snerr("ERROR: Unrecognized cmd: %d\n", cmd); |
| ret = -ENOTTY; |
| break; |
| } |
| } |
| |
| return ret; |
| } |
| |
| /**************************************************************************** |
| * Name: lsm9ds1_mag_scale |
| ****************************************************************************/ |
| |
| static int lsm9ds1_mag_scale(FAR struct lsm9ds1_sensor_s *priv, |
| uint8_t scale) |
| { |
| int ret = OK; |
| |
| ret = priv->base.ops->setfullscale(&priv->base, scale); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| |
| if (scale < lsm9ds1_midpoint(4, 8)) |
| { |
| priv->scale = 8.f / 65536.f; |
| } |
| else if (scale < lsm9ds1_midpoint(8, 12)) |
| { |
| priv->scale = 16.f / 65536.f; |
| } |
| else if (scale < lsm9ds1_midpoint(12, 16)) |
| { |
| priv->scale = 24.f / 65536.f; |
| } |
| else |
| { |
| priv->scale = 32.f / 65536.f; |
| } |
| |
| return ret; |
| } |
| |
| /**************************************************************************** |
| * Name: lsm9ds1_accel_scale |
| ****************************************************************************/ |
| |
| static int lsm9ds1_accel_scale(FAR struct lsm9ds1_sensor_s *priv, |
| uint8_t scale) |
| { |
| int ret = OK; |
| |
| ret = priv->base.ops->setfullscale(&priv->base, scale); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| |
| if (scale < lsm9ds1_midpoint(2, 4)) |
| { |
| priv->scale = CONSTANTS_ONE_G / 16384.f; |
| } |
| else if (scale < lsm9ds1_midpoint(4, 8)) |
| { |
| priv->scale = CONSTANTS_ONE_G / 8192.f; |
| } |
| else if (scale < lsm9ds1_midpoint(8, 16)) |
| { |
| priv->scale = CONSTANTS_ONE_G / 4096.f; |
| } |
| else |
| { |
| priv->scale = CONSTANTS_ONE_G / 2048.f; |
| } |
| |
| return ret; |
| } |
| |
| /**************************************************************************** |
| * Name: lsm9ds1_gyro_scale |
| ****************************************************************************/ |
| |
| static int lsm9ds1_gyro_scale(FAR struct lsm9ds1_sensor_s *priv, |
| uint8_t scale) |
| { |
| int ret = OK; |
| |
| ret = priv->base.ops->setfullscale(&priv->base, scale); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| |
| if (scale < lsm9ds1_midpoint(245, 500)) |
| { |
| priv->scale = (M_PI / 180.0f) * 245.f / 32768.f; |
| } |
| else if (scale < lsm9ds1_midpoint(500, 2000)) |
| { |
| priv->scale = (M_PI / 180.0f) * 500.f / 32768.f; |
| } |
| else |
| { |
| priv->scale = (M_PI / 180.0f) * 2000.f / 32768.f; |
| } |
| |
| return ret; |
| } |
| |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| /**************************************************************************** |
| * Name: lsm9ds1_accel_data |
| * |
| * Description: get and push accel data from struct sensor_data_s |
| * |
| * Parameter: |
| * priv - Internal private lower half driver instance |
| * buf - Point to data |
| * |
| * Return: |
| * OK - on success |
| * |
| ****************************************************************************/ |
| |
| static void lsm9ds1_accel_data(FAR struct lsm9ds1_sensor_s *priv, |
| FAR int16_t *buf) |
| { |
| FAR struct sensor_lowerhalf_s *lower = &priv->lower; |
| struct sensor_accel accel; |
| uint64_t now = sensor_get_timestamp(); |
| |
| if (!priv->enabled || now - priv->last_update < priv->interval) |
| { |
| return; |
| } |
| |
| priv->last_update = now; |
| |
| accel.timestamp = now; |
| accel.x = (int16_t)lsm9ds1_data(buf[0]) * priv->scale; |
| accel.y = (int16_t)lsm9ds1_data(buf[1]) * priv->scale; |
| accel.z = (int16_t)lsm9ds1_data(buf[2]) * priv->scale; |
| accel.temperature = 0; |
| |
| lower->push_event(lower->priv, &accel, sizeof(accel)); |
| } |
| |
| /**************************************************************************** |
| * Name: lsm9ds1_gyro_data |
| * |
| * Description: get and push gyro data from struct sensor_data_s |
| * |
| * Parameter: |
| * priv - Internal private lower half driver instance |
| * buf - Point to data |
| * |
| * Return: |
| * OK - on success |
| * |
| ****************************************************************************/ |
| |
| static void lsm9ds1_gyro_data(FAR struct lsm9ds1_sensor_s *priv, |
| FAR int16_t *buf) |
| { |
| FAR struct sensor_lowerhalf_s *lower = &priv->lower; |
| struct sensor_gyro gyro; |
| uint64_t now = sensor_get_timestamp(); |
| |
| if (!priv->enabled || now - priv->last_update < priv->interval) |
| { |
| return; |
| } |
| |
| priv->last_update = now; |
| |
| gyro.timestamp = now; |
| gyro.x = (int16_t)lsm9ds1_data(buf[0]) * priv->scale; |
| gyro.y = (int16_t)lsm9ds1_data(buf[1]) * priv->scale; |
| gyro.z = (int16_t)lsm9ds1_data(buf[2]) * priv->scale; |
| gyro.temperature = 0; |
| |
| lower->push_event(lower->priv, &gyro, sizeof(gyro)); |
| } |
| |
| /**************************************************************************** |
| * Name: lsm9ds1_mag_data |
| * |
| * Description: get and push magnetometer data from struct sensor_data_s |
| * |
| * Parameter: |
| * priv - Internal private lower half driver instance |
| * buf - Point to data |
| * |
| * Return: |
| * OK - on success |
| * |
| ****************************************************************************/ |
| |
| static void lsm9ds1_mag_data(FAR struct lsm9ds1_sensor_s *priv, |
| FAR int16_t *buf) |
| { |
| FAR struct sensor_lowerhalf_s *lower = &priv->lower; |
| struct sensor_mag mag; |
| uint64_t now = sensor_get_timestamp(); |
| |
| if (!priv->enabled || now - priv->last_update < priv->interval) |
| { |
| return; |
| } |
| |
| priv->last_update = now; |
| |
| mag.timestamp = now; |
| mag.x = (int16_t)lsm9ds1_data(buf[0]) * priv->scale; |
| mag.y = (int16_t)lsm9ds1_data(buf[1]) * priv->scale; |
| mag.z = (int16_t)lsm9ds1_data(buf[2]) * priv->scale; |
| mag.temperature = 0; |
| |
| lower->push_event(lower->priv, &mag, sizeof(mag)); |
| } |
| |
| /**************************************************************************** |
| * Name: lsm9ds1_thread |
| * |
| * Description: Thread for performing interval measurement cycle and data |
| * read. |
| * |
| * Parameter: |
| * argc - Number opf arguments |
| * argv - Pointer to argument list |
| * |
| ****************************************************************************/ |
| |
| static int lsm9ds1_thread(int argc, FAR char **argv) |
| { |
| FAR struct lsm9ds1_sensor_dev_s *dev |
| = (FAR struct lsm9ds1_sensor_dev_s *)((uintptr_t)strtoul(argv[1], NULL, |
| 16)); |
| FAR struct lsm9ds1_sensor_s *accel = &dev->priv[LSM9DS1_ACCEL_IDX]; |
| FAR struct lsm9ds1_sensor_s *gyro = &dev->priv[LSM9DS1_GYRO_IDX]; |
| FAR struct lsm9ds1_sensor_s *mag = &dev->priv[LSM9DS1_MAG_IDX]; |
| unsigned long min_interval; |
| int16_t adata[3]; |
| int16_t gdata[3]; |
| int16_t mdata[3]; |
| int ret; |
| |
| while (true) |
| { |
| if ((!accel->enabled) && (!gyro->enabled) && (!mag->enabled)) |
| { |
| /* Waiting to be woken up */ |
| |
| ret = nxsem_wait(&dev->run); |
| if (ret < 0) |
| { |
| continue; |
| } |
| } |
| |
| /* Read accel */ |
| |
| if (accel->enabled) |
| { |
| ret = lsm9ds1_readreg(&accel->base, |
| LSM9DS1_OUT_X_L_XL, (FAR uint8_t *)adata, 6); |
| lsm9ds1_accel_data(accel, adata); |
| } |
| |
| /* Read gyro */ |
| |
| if (gyro->enabled) |
| { |
| ret = lsm9ds1_readreg(&gyro->base, |
| LSM9DS1_OUT_X_L_G, (FAR uint8_t *)gdata, 6); |
| lsm9ds1_gyro_data(gyro, gdata); |
| } |
| |
| /* Read mag */ |
| |
| if (mag->enabled) |
| { |
| ret = lsm9ds1_readreg(&mag->base, |
| LSM9DS1_OUT_X_L_M, (FAR uint8_t *)mdata, 6); |
| lsm9ds1_mag_data(mag, mdata); |
| } |
| |
| /* Sleeping thread before fetching the next sensor data */ |
| |
| min_interval = MIN(accel->interval, gyro->interval); |
| min_interval = MIN(min_interval, mag->interval); |
| nxsig_usleep(min_interval); |
| } |
| |
| return OK; |
| } |
| #endif |
| |
| /**************************************************************************** |
| * Public Functions |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Name: lsm9ds1_register_uorb |
| * |
| * Description: |
| * Register the LSM9DS1 IMU as sensor device |
| * |
| * Input Parameters: |
| * devno - Instance number for driver |
| * config - configuratio |
| * |
| * Returned Value: |
| * Zero (OK) on success; a negated errno value on failure. |
| * |
| ****************************************************************************/ |
| |
| int lsm9ds1_register_uorb(int devno, FAR struct lsm9ds1_config_s *config) |
| { |
| FAR struct lsm9ds1_sensor_dev_s *dev = NULL; |
| FAR struct lsm9ds1_sensor_s *tmp = NULL; |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| FAR char *argv[2]; |
| char arg1[32]; |
| #endif |
| int ret = OK; |
| |
| /* Initialize the device structure. */ |
| |
| dev = (FAR struct lsm9ds1_sensor_dev_s *)kmm_malloc(sizeof(*dev)); |
| if (dev == NULL) |
| { |
| snerr("ERROR: Failed to allocate instance\n"); |
| return -ENOMEM; |
| } |
| |
| memset(dev, 0, sizeof(*dev)); |
| nxmutex_init(&dev->lock); |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| nxsem_init(&dev->run, 0, 0); |
| #endif |
| |
| /* Accelerometer register */ |
| |
| tmp = &dev->priv[LSM9DS1_ACCEL_IDX]; |
| tmp->dev = dev; |
| tmp->base.ops = &g_lsm9ds1accel_ops; |
| tmp->base.i2c = config->i2c; |
| tmp->base.addr = config->addr_acc; |
| tmp->lower.ops = &g_sensor_ops; |
| tmp->lower.type = SENSOR_TYPE_ACCELEROMETER; |
| tmp->lower.nbuffer = 1; |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| tmp->enabled = false; |
| tmp->interval = CONFIG_SENSORS_LSM9DS1_POLL_INTERVAL; |
| #endif |
| |
| ret = sensor_register(&tmp->lower, devno); |
| if (ret < 0) |
| { |
| snerr("sensor_register failed: %d\n", ret); |
| goto gyro_err; |
| } |
| |
| lsm9ds1_accel_scale(tmp, 2); |
| |
| /* Gyroscope register */ |
| |
| tmp = &dev->priv[LSM9DS1_GYRO_IDX]; |
| tmp->dev = dev; |
| tmp->base.ops = &g_lsm9ds1gyro_ops; |
| tmp->base.i2c = config->i2c; |
| tmp->base.addr = config->addr_gyro; |
| tmp->lower.ops = &g_sensor_ops; |
| tmp->lower.type = SENSOR_TYPE_GYROSCOPE; |
| tmp->lower.nbuffer = 1; |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| tmp->enabled = false; |
| tmp->interval = CONFIG_SENSORS_LSM9DS1_POLL_INTERVAL; |
| #endif |
| |
| ret = sensor_register(&tmp->lower, devno); |
| if (ret < 0) |
| { |
| snerr("sensor_register failed: %d\n", ret); |
| goto gyro_err; |
| } |
| |
| lsm9ds1_gyro_scale(tmp, 245); |
| |
| /* Magnetic register */ |
| |
| tmp = &dev->priv[LSM9DS1_MAG_IDX]; |
| tmp->dev = dev; |
| tmp->base.ops = &g_lsm9ds1mag_ops; |
| tmp->base.i2c = config->i2c; |
| tmp->base.addr = config->addr_mag; |
| tmp->lower.ops = &g_sensor_ops; |
| tmp->lower.type = SENSOR_TYPE_MAGNETIC_FIELD; |
| tmp->lower.nbuffer = 1; |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| tmp->enabled = false; |
| tmp->interval = CONFIG_SENSORS_LSM9DS1_POLL_INTERVAL; |
| #endif |
| |
| ret = sensor_register(&tmp->lower, devno); |
| if (ret < 0) |
| { |
| snerr("sensor_register failed: %d\n", ret); |
| goto mag_err; |
| } |
| |
| lsm9ds1_mag_scale(tmp, 4); |
| |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| /* Create thread for polling sensor data */ |
| |
| snprintf(arg1, 16, "%p", dev); |
| argv[0] = arg1; |
| argv[1] = NULL; |
| |
| ret = kthread_create("lsm9ds1_thread", SCHED_PRIORITY_DEFAULT, |
| CONFIG_SENSORS_LSM9DS1_THREAD_STACKSIZE, |
| lsm9ds1_thread, |
| argv); |
| if (ret < 0) |
| { |
| goto thr_err; |
| } |
| #endif |
| |
| return ret; |
| |
| #ifdef CONFIG_SENSORS_LSM9DS1_POLL |
| thr_err: |
| #endif |
| sensor_unregister(&dev->priv[LSM9DS1_MAG_IDX].lower, devno); |
| mag_err: |
| sensor_unregister(&dev->priv[LSM9DS1_GYRO_IDX].lower, devno); |
| gyro_err: |
| sensor_unregister(&dev->priv[LSM9DS1_ACCEL_IDX].lower, devno); |
| |
| kmm_free(dev); |
| |
| return ret; |
| } |