Hi everyone,
1) Hardware
-
Thingy:91X (the nRF9151 variant, HW rev 1.0.0)
-
On-board ADXL367 (I²C @ 0x1D) ← works
-
Extra BMI270 IMU on breakout board, wired to SPIM3
-
SCK → P0.14
-
MOSI → P0.13
-
MISO → P0.12
-
CS → P0.10 (active LOW)
-
VDD 3 V, VDDIO 1V8 (same rail as ADXL367)
-
GND common
-
2) Software
-
nRF Connect SDK v2.9.1 (Zephyr 3.7.99)
-
Building with
west build -p always -b thingy91x/nrf9151/ns -
Bootloader MCUboot enabled (default Thingy:91X sysbuild)
3) Device-tree overlay
/* thingy91x_bmi270.overlay */
&pinctrl {
spi3_bmi270_default: spi3_bmi270_default {
group1 {
psels = <
NRF_PSEL(SPIM_SCK, 0, 14)
NRF_PSEL(SPIM_MOSI, 0, 13)
NRF_PSEL(SPIM_MISO, 0, 12)
>;
};
};
spi3_bmi270_sleep: spi3_bmi270_sleep {
group1 {
psels = <
NRF_PSEL(SPIM_SCK, 0, 14)
NRF_PSEL(SPIM_MOSI, 0, 13)
NRF_PSEL(SPIM_MISO, 0, 12)
>;
low-power-enable;
};
};
};
/* SPI-connected BMI270 -------------------------------------------------- */
&spi3 {
status = "okay";
pinctrl-0 = <&spi3_bmi270_default>;
pinctrl-1 = <&spi3_bmi270_sleep>;
pinctrl-names = "default", "sleep";
cs-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
bmi270: bmi270@0 {
compatible = "bosch,bmi270";
reg = <0>;
spi-max-frequency = <DT_FREQ_M(10)>;
status = "okay";
};
};
/* keep the on-board ADXL367 on I²C2 “as is” ----------------------------- */
&i2c2 {
accel: accelerometer_lp: adxl367@1d {
status = "okay";
compatible = "adi,adxl367";
reg = <0x1d>;
odr = <3>;
};
};
4) prj.conf
# Core + console CONFIG_GPIO=y CONFIG_SPI=y CONFIG_I2C=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y CONFIG_PRINTK=y CONFIG_LOG=y # Sensors CONFIG_SENSOR=y CONFIG_ADXL367=y CONFIG_BMI270=y CONFIG_SENSOR_LOG_LEVEL_DBG=y # verbose driver logs # Toolchain / libc CONFIG_CPP=y CONFIG_GLIBCXX_LIBCPP=y CONFIG_NEWLIB_LIBC=y CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y CONFIG_FPU=y CONFIG_MAIN_STACK_SIZE=8192 # Drivers CONFIG_I2C_NRFX=y CONFIG_SPI_NRFX=y CONFIG_GPIO_NRFX=y # Boot CONFIG_BOOTLOADER_MCUBOOT=y
5) Minimal main.c
#include <zephyr/kernel.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(app, LOG_LEVEL_INF);
#define ADXL367_NODE DT_NODELABEL(accelerometer_lp)
#define BMI270_NODE DT_NODELABEL(bmi270)
static const struct device *const adxl367_dev = DEVICE_DT_GET(ADXL367_NODE);
static const struct device *const bmi270_dev = DEVICE_DT_GET(BMI270_NODE);
static void read_print(const struct device *dev, const char *name)
{
struct sensor_value acc[3], gyr[3];
if (sensor_sample_fetch(dev) < 0) { LOG_ERR("%s fetch", name); return; }
sensor_channel_get(dev, SENSOR_CHAN_ACCEL_XYZ, acc);
printk("%s ACC %d.%06d %d.%06d %d.%06d\n",
name,
acc[0].val1, abs(acc[0].val2),
acc[1].val1, abs(acc[1].val2),
acc[2].val1, abs(acc[2].val2));
if (strcmp(name, "BMI270") == 0 &&
sensor_channel_get(dev, SENSOR_CHAN_GYRO_XYZ, gyr) == 0) {
printk("%s GYR %d.%06d %d.%06d %d.%06d\n",
name,
gyr[0].val1, abs(gyr[0].val2),
gyr[1].val1, abs(gyr[1].val2),
gyr[2].val1, abs(gyr[2].val2));
}
}
void main(void)
{
if (!device_is_ready(adxl367_dev) || !device_is_ready(bmi270_dev)) {
LOG_ERR("Sensors not ready");
return;
}
LOG_INF("Sensors OK. Reading…");
while (1) {
read_print(adxl367_dev, "ADXL367");
read_print(bmi270_dev, "BMI270");
k_sleep(K_MSEC(1000));
}
}
6) Logs
<err> bmi270: Unexpected chip id (0). Expected (24)
<err> app: BMI270 not ready
ADXL367 always works; BMI270 never gets past the chip-ID test.
What I have tried
-
Scope on CS/SCK/MOSI/MISO
CS stays low only during transfers, no obvious glitches. -
Verified 3 V supply and 1.8 V IO rail — both solid.
-
Lowered
spi-max-frequencydown to 1 MHz → same result. -
Swapped breakout board (two different BMI270 modules).
-
Confirmed pull-ups on INT pins disabled (left floating).
Questions to the community
-
Does anyone have BMI270 working on a Thingy:91X (nRF9151) with NCS ≥ 2.9?
-
Is there any extra GPIO/power sequencing needed (e.g. CS high > t_boot)?
-
Am I missing a
reset-gpioorbmi270,power-modeproperty in the DTS? -
Any gotchas with SPIM3 + external sensor while the on-board ADXL367 is
enabled on I²C2?
Thanks a lot for any hints!