Hi all,
I've been trying to get the samples/sensor/lsm6dsl example working with the nrf52840-based Xiao BLE Sense and have had no luck.
I guess that it's due to the power line for the sensor being connected to the P1.08
I dug into the xiao_ble_sense.dts and I can indeed see:
lsm6ds3tr-c-en {
compatible = "regulator-fixed-sync", "regulator-fixed";
enable-gpios = <&gpio1 8 (NRF_GPIO_DRIVE_S0H1 | GPIO_ACTIVE_HIGH)>;
regulator-name = "LSM6DS3TR_C_EN";
regulator-boot-on;
startup-delay-us = <3000>;
};
However no matter how I try and drive it from the code the sensor refuses to initialize with the console output:
[00:00:00.794,647] <dbg> LSM6DSL: lsm6dsl_init_chip: failed to reboot device [00:00:00.794,677] <err> LSM6DSL: Failed to initialize chip *** Booting nRF Connect SDK d96769faceca *** Begin init of lsm6ds3tr and regulator sensor: device not ready.
My code to run is based of the sample code for the sensor with the lsm6ds3tr_c_en modifications:
/*
* Copyright (c) 2018 STMicroelectronics
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <stdio.h>
#include <zephyr/sys/util.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/regulator.h>
static const struct device *lsm6ds3tr_c_en;
static inline float out_ev(struct sensor_value *val)
{
return (val->val1 + (float)val->val2 / 1000000);
}
static int print_samples;
static int lsm6dsl_trig_cnt;
static struct sensor_value accel_x_out, accel_y_out, accel_z_out;
static struct sensor_value gyro_x_out, gyro_y_out, gyro_z_out;
#if defined(CONFIG_LSM6DSL_EXT0_LIS2MDL)
static struct sensor_value magn_x_out, magn_y_out, magn_z_out;
#endif
#if defined(CONFIG_LSM6DSL_EXT0_LPS22HB)
static struct sensor_value press_out, temp_out;
#endif
#ifdef CONFIG_LSM6DSL_TRIGGER
static void lsm6dsl_trigger_handler(const struct device *dev,
const struct sensor_trigger *trig)
{
static struct sensor_value accel_x, accel_y, accel_z;
static struct sensor_value gyro_x, gyro_y, gyro_z;
#if defined(CONFIG_LSM6DSL_EXT0_LIS2MDL)
static struct sensor_value magn_x, magn_y, magn_z;
#endif
#if defined(CONFIG_LSM6DSL_EXT0_LPS22HB)
static struct sensor_value press, temp;
#endif
lsm6dsl_trig_cnt++;
sensor_sample_fetch_chan(dev, SENSOR_CHAN_ACCEL_XYZ);
sensor_channel_get(dev, SENSOR_CHAN_ACCEL_X, &accel_x);
sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Y, &accel_y);
sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Z, &accel_z);
/* lsm6dsl gyro */
sensor_sample_fetch_chan(dev, SENSOR_CHAN_GYRO_XYZ);
sensor_channel_get(dev, SENSOR_CHAN_GYRO_X, &gyro_x);
sensor_channel_get(dev, SENSOR_CHAN_GYRO_Y, &gyro_y);
sensor_channel_get(dev, SENSOR_CHAN_GYRO_Z, &gyro_z);
#if defined(CONFIG_LSM6DSL_EXT0_LIS2MDL)
/* lsm6dsl external magn */
sensor_sample_fetch_chan(dev, SENSOR_CHAN_MAGN_XYZ);
sensor_channel_get(dev, SENSOR_CHAN_MAGN_X, &magn_x);
sensor_channel_get(dev, SENSOR_CHAN_MAGN_Y, &magn_y);
sensor_channel_get(dev, SENSOR_CHAN_MAGN_Z, &magn_z);
#endif
#if defined(CONFIG_LSM6DSL_EXT0_LPS22HB)
/* lsm6dsl external press/temp */
sensor_sample_fetch_chan(dev, SENSOR_CHAN_PRESS);
sensor_channel_get(dev, SENSOR_CHAN_PRESS, &press);
sensor_sample_fetch_chan(dev, SENSOR_CHAN_AMBIENT_TEMP);
sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp);
#endif
if (print_samples) {
print_samples = 0;
accel_x_out = accel_x;
accel_y_out = accel_y;
accel_z_out = accel_z;
gyro_x_out = gyro_x;
gyro_y_out = gyro_y;
gyro_z_out = gyro_z;
#if defined(CONFIG_LSM6DSL_EXT0_LIS2MDL)
magn_x_out = magn_x;
magn_y_out = magn_y;
magn_z_out = magn_z;
#endif
#if defined(CONFIG_LSM6DSL_EXT0_LPS22HB)
press_out = press;
temp_out = temp;
#endif
}
}
#endif
int main(void)
{
int cnt = 0;
char out_str[64];
struct sensor_value odr_attr;
const struct device *const lsm6dsl_dev = DEVICE_DT_GET_ONE(st_lsm6dsl);
printk("Begin init of lsm6ds3tr and regulator \n");
/* Initialize the regulator device */
lsm6ds3tr_c_en = DEVICE_DT_GET(DT_PATH(lsm6ds3tr_c_en));
if (!device_is_ready(lsm6ds3tr_c_en)) {
printk("Regulator device not ready\n");
return 0;
}
/* Enable the regulator */
if (regulator_enable(lsm6ds3tr_c_en) < 0) {
printk("Failed to enable regulator\n");
return 0;
}
k_sleep(K_MSEC(10000));
if (!device_is_ready(lsm6dsl_dev)) {
printk("sensor: device not ready.\n");
return 0;
}
/* set accel/gyro sampling frequency to 104 Hz */
odr_attr.val1 = 104;
odr_attr.val2 = 0;
if (sensor_attr_set(lsm6dsl_dev, SENSOR_CHAN_ACCEL_XYZ,
SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr) < 0) {
printk("Cannot set sampling frequency for accelerometer.\n");
return 0;
}
if (sensor_attr_set(lsm6dsl_dev, SENSOR_CHAN_GYRO_XYZ,
SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr) < 0) {
printk("Cannot set sampling frequency for gyro.\n");
return 0;
}
#ifdef CONFIG_LSM6DSL_TRIGGER
struct sensor_trigger trig;
trig.type = SENSOR_TRIG_DATA_READY;
trig.chan = SENSOR_CHAN_ACCEL_XYZ;
if (sensor_trigger_set(lsm6dsl_dev, &trig, lsm6dsl_trigger_handler) != 0) {
printk("Could not set sensor type and channel\n");
return 0;
}
#endif
if (sensor_sample_fetch(lsm6dsl_dev) < 0) {
printk("Sensor sample update error\n");
return 0;
}
while (1) {
/* Erase previous */
printk("\0033\014");
printf("LSM6DSL sensor samples:\n\n");
/* lsm6dsl accel */
sprintf(out_str, "accel x:%f ms/2 y:%f ms/2 z:%f ms/2",
out_ev(&accel_x_out),
out_ev(&accel_y_out),
out_ev(&accel_z_out));
printk("%s\n", out_str);
/* lsm6dsl gyro */
sprintf(out_str, "gyro x:%f dps y:%f dps z:%f dps",
out_ev(&gyro_x_out),
out_ev(&gyro_y_out),
out_ev(&gyro_z_out));
printk("%s\n", out_str);
#if defined(CONFIG_LSM6DSL_EXT0_LIS2MDL)
/* lsm6dsl external magn */
sprintf(out_str, "magn x:%f gauss y:%f gauss z:%f gauss",
out_ev(&magn_x_out),
out_ev(&magn_y_out),
out_ev(&magn_z_out));
printk("%s\n", out_str);
#endif
#if defined(CONFIG_LSM6DSL_EXT0_LPS22HB)
/* lsm6dsl external press/temp */
sprintf(out_str, "press: %f kPa - temp: %f deg",
out_ev(&press_out), out_ev(&temp_out));
printk("%s\n", out_str);
#endif
printk("loop:%d trig_cnt:%d\n\n", ++cnt, lsm6dsl_trig_cnt);
print_samples = 1;
k_sleep(K_MSEC(2000));
}
}
And my prj.conf:
CONFIG_STDOUT_CONSOLE=y CONFIG_I2C=y CONFIG_SPI=n CONFIG_SENSOR=y CONFIG_LSM6DSL_TRIGGER_GLOBAL_THREAD=y CONFIG_CBPRINTF_FP_SUPPORT=y CONFIG_LOG=y CONFIG_LOG_DEFAULT_LEVEL=3 CONFIG_SENSOR_LOG_LEVEL_DBG=y CONFIG_UART_CONSOLE=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_LINE_CTRL=y
I am trying to drive this the proper way but am I missing something obvious?
Should I just ignore the config and drive P1.08 manually?
Thanks for taking a look!
I'm using nRF Connect SDK v2.6.0 (latest available at the time of posting)