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-frequency
down 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-gpio
orbmi270,power-mode
property 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!