Hey so I just wanted to use the BMI270 on the Thingy:53 and Polling the acceleration values seems to be working just fine. I wanted to use the DATA_READY Trigger. I am working with the nrf SDK v2.6.0 and with the Zephyr Sensor Driver API. So on the Thingy there is only the Interuptline INT1 Pin connected with the nRF5340 SoC. But in the zephyr/drivers/sensor/bmi270/bmi70_trigger.c there is:
case SENSOR_TRIG_DATA_READY:
if (!cfg->int2.port) {
return -ENOTSUP;
}
k_mutex_lock(&data->trigger_mutex, K_FOREVER);
data->drdy_handler = handler;
data->drdy_trigger = trig;
k_mutex_unlock(&data->trigger_mutex);
return bmi270_drdy_config(dev, handler != NULL);
default:
return -ENOTSUP;
So by the hardware I can only use the INT1 but with using Zephyr I can not use this Pin for the DATA_READY Trigger? Or did I missunderstand something? I always geht the error:
[00:00:00.088,348] <err> accel_trigg: Could not set trigger: -134
Even if I just change it to
:
if (!cfg->int1.port) {
return -ENOTSUP;
}
I used the overlay:
/ {
aliases {
accel1 = &bmi270;
};
};
&spi3{
bmi270: spi-dev-bmi270@1 {
compatible = "bosch,bmi270";
status = "okay";
spi-max-frequency = <8000000>;
reg = <1>;
int1-gpios = <&gpio0 23 0>;
};
};
and the bmi270-trigger.conf:
CONFIG_ADXL362=n
CONFIG_BMI270=y
CONFIG_BMI270_TRIGGER_OWN_THREAD=y
CONFIG_GPIO=y
For my main.c:
/*
* Copyright 2024 NXP
* Copyright (c) 2018 Phytec Messtechnik GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/drivers/sensor.h>
#include <stdio.h>
#include <zephyr/sys/timeutil.h>
#include <zephyr/logging/log.h>
K_SEM_DEFINE(sem, 0, 1); /* starts off "not available" */
LOG_MODULE_REGISTER(accel_trigg, LOG_LEVEL_INF);
#define ODR_HZ 1600
#define RANGE 2
#if defined(CONFIG_ADXL362)
/* Get the node identifier from the devicetree alias for the ADXL362 (thingy53_nrf5340_comon.dtsi) */
#define ACCEL_NODE DT_ALIAS(accel0)
#elif defined(CONFIG_BMI270)
/* Get the node identifier from the devicetree alias for the BMI270 from own devicetree-overlay (thingy53_nrf5340_comon.dtsi) */
#define ACCEL_NODE DT_ALIAS(accel1)
#endif
const struct device *const dev = DEVICE_DT_GET(ACCEL_NODE);
static void trigger_handler(const struct device *dev, const struct sensor_trigger *trigger)
{
ARG_UNUSED(trigger);
/* Always fetch the sample to clear the data ready interrupt in the
* sensor.
*/
if (sensor_sample_fetch(dev))
{
LOG_ERR("sensor_sample_fetch failed\n");
return;
}
k_sem_give(&sem);
}
/* Function to set the sampling frequency from the ADXL362 at runtime for increased flexibility and time efficiency during development */
#if defined(CONFIG_ADXL362_ACCEL_ODR_RUNTIME) || defined(CONFIG_BMI270)
static int set_sampling_freq(const struct device *dev)
{
int ret;
double odr_hz = ODR_HZ;
struct sensor_value odr = {
.val1 = (int)odr_hz,
.val2 = (int)((odr_hz - (int)odr_hz) * 1000000)
};
ret = sensor_attr_set(dev, SENSOR_CHAN_ACCEL_XYZ, SENSOR_ATTR_SAMPLING_FREQUENCY, &odr);
if (ret != 0) {
LOG_ERR("%s : failed to set sampling frequency\n", dev->name);
} else{
LOG_INF("%s : Set sampling frequency successfully: %d\n", dev->name, (int)odr_hz);
}
return 0;
}
#endif
#if defined(CONFIG_ADXL362_ACCEL_RANGE_RUNTIME) || defined(CONFIG_BMI270)
static int set_range(const struct device *dev)
{
int ret;
double range_g = RANGE;
struct sensor_value range = {
.val1 = range_g,
.val2 = 0,
};
ret = sensor_attr_set(dev, SENSOR_CHAN_ACCEL_XYZ, SENSOR_ATTR_FULL_SCALE, &range);
if (ret != 0) {
LOG_ERR("%s : failed to set range\n", dev->name);
}
LOG_INF("%s : Set range: %f\n", dev->name, range_g);
return 0;
}
#endif
int main(void)
{
int err;
struct sensor_value data[3];
struct sensor_trigger trig = {
.type = SENSOR_TRIG_DATA_READY,
.chan = SENSOR_CHAN_ACCEL_XYZ,
};
if (!device_is_ready(dev))
{
LOG_ERR("Device %s is not ready\n", dev->name);
return 0;
}
#if defined(CONFIG_ADXL362_ACCEL_ODR_RUNTIME) || defined(CONFIG_BMI270)
set_range(dev);
set_sampling_freq(dev);
#endif
err = sensor_trigger_set(dev, &trig, trigger_handler);
if (err) {
LOG_ERR("Could not set trigger: %d", err);
return 0;
}
uint32_t sample_count = 0;
int64_t start_time = k_uptime_get();
while (1)
{
k_sem_take(&sem, K_FOREVER);
uint64_t timestamp_us = k_cyc_to_us_floor64(k_uptime_ticks());
sensor_channel_get(dev, SENSOR_CHAN_ACCEL_XYZ, data);
/* Print accel x,y,z data with timestamp */
// LOG_INF("%16s @ %llu µs [m/s^2]: (%12.6f, %12.6f, %12.6f)\n", dev->name,
// timestamp_us,
// sensor_value_to_double(&data[0]),
// sensor_value_to_double(&data[1]),
// sensor_value_to_double(&data[2]));
sample_count++;
if ((k_uptime_get() - start_time) >= 1000)
{
LOG_INF("Samples in last second: %u", sample_count);
start_time = k_uptime_get();
sample_count = 0;
}
}
}
Otherwise I think I just stay with polling the data.
But I am glad if someone can help me :-)