issues configuring LIS2DW12 sensor over I2C for custom board (nRF52840 SOC)

Summary:
I must be doing something wrong when making the board files for a custom board (nRF52840 SOC), because I'm unable to initialize the LIS2DW12 using Zephyr's built-in sensor drivers.

Details:
Here's my device tree, you can see the relevant I2C portions where I'm configuring things for the LIS2DW12:

// Copyright (c) 2024 Nordic Semiconductor ASA
// SPDX-License-Identifier: Apache-2.0

/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>
#include "type2ab_evb-pinctrl.dtsi"

/ {
	model = "Type2AB_EVB";
	compatible = "murata,type2ab-evb";

	chosen {
        zephyr,console = &uart0;
		zephyr,shell-uart = &uart0;
		zephyr,uart-mcumgr = &uart0;
		zephyr,bt-mon-uart = &uart0;
		zephyr,bt-c2h-uart = &uart0;
		zephyr,sram = &sram0;
		zephyr,flash = &flash0;
		zephyr,code-partition = &slot0_partition;
	};

    leds {
		compatible = "gpio-leds";
		led0: led_0 {
			gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
			label = "Green LED 0";
		};
		led1: led_1 {
			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
			label = "Red LED 0";
		};
	};

    /* These aliases are provided for compatibility with samples */
	aliases {
		led0 = &led0;
		led1 = &led1;
	};
};

&gpiote {
	status = "okay";
};

&gpio0 {
	status = "okay";
	sense-edge-mask = <0xffffffff>;
};

&gpio1 {
	status = "okay";
	sense-edge-mask = <0xffffffff>;
};

&i2c0 {
	compatible = "nordic,nrf-twi";
	status = "okay";
	pinctrl-0 = <&i2c0_default>;
	pinctrl-1 = <&i2c0_sleep>;
	pinctrl-names = "default", "sleep";
    lis2dw12: lis2dw12@19 {
        compatible = "st,lis2dw12";
        status = "okay"; // https://devzone.nordicsemi.com/f/nordic-q-a/107801/usage-of-interrupts-from-i2c-device
		reg = <0x19>; // https://community.st.com/t5/mems-sensors/dts-configuration-for-lis2dw12/td-p/148824
        power-mode=<0>;
	};
};

&uart0 {
	compatible = "nordic,nrf-uarte";
	status = "okay";
	current-speed = <115200>;
	pinctrl-0 = <&uart0_default>;
	pinctrl-1 = <&uart0_sleep>;
	pinctrl-names = "default", "sleep";
};

&flash0 {
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x0 0xc000>;
		};
		slot0_partition: partition@c000 {
			label = "image-0";
			reg = <0xc000 0x72000>;
		};
		slot1_partition: partition@7e000 {
			label = "image-1";
			reg = <0x7e000 0x72000>;
		};
		scratch_partition: partition@f0000 {
			label = "image-scratch";
			reg = <0xf0000 0xa000>;
		};
		storage_partition: partition@fa000 {
			label = "storage";
			reg = <0xfa000 0x6000>;
		};
	};
};

Here's my source file showing how I'm initializing the device:

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>

// Basing the sensor stuff on this: https://github.com/nrfconnect/sdk-zephyr/blob/main/samples/shields/x_nucleo_iks01a3/standard/src/main.c or https://github.com/nrfconnect/sdk-zephyr/blob/main/drivers/sensor/st/lis2dw12/lis2dw12.c#L11
#include <zephyr/drivers/sensor.h>
#include <zephyr/device.h>

const struct device *const lis2dw12 = DEVICE_DT_GET_ONE(st_lis2dw12);

static void lis2dw12_config(const struct device *lis2dw12)
{
	struct sensor_value odr_attr, fs_attr;

	/* set LIS2DW12 accel/gyro sampling frequency to 100 Hz */
	odr_attr.val1 = 100;
	odr_attr.val2 = 0;

	if (sensor_attr_set(lis2dw12, SENSOR_CHAN_ACCEL_XYZ,
			    SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr) < 0) {
		printk("Cannot set sampling frequency for LIS2DW12 accel\n");
		return;
	}

	sensor_g_to_ms2(16, &fs_attr);

	if (sensor_attr_set(lis2dw12, SENSOR_CHAN_ACCEL_XYZ,
			    SENSOR_ATTR_FULL_SCALE, &fs_attr) < 0) {
		printk("Cannot set sampling frequency for LIS2DW12 gyro\n");
		return;
	}
}

int main(void)
{
    const struct device *const lis2dw12 = DEVICE_DT_GET_ONE(st_lis2dw12);
    if (!device_is_ready(lis2dw12)) {
		printk("%s: device not ready.\n", lis2dw12->name);
		return 0;
	}
    lis2dw12_config(lis2dw12);
    
	while (1) {
		k_msleep(1000);
	}
	return 0;
}

And here's the output I'm getting:

[00:00:00.786,773] <err> LIS2DW12: Not able to read dev id
*** Booting nRF Connect SDK v3.5.99-ncs1 ***
lis2dw12@19: device not ready.

The reason I suspect it's device-tree related, is because when I try to enable CONFIG_LIS2DW12=y in the prj.conf file, I get the following:

Here's my board files:
/cfs-file/__key/support-attachments/beef5d1b77644c448dabff31668f3a47-c25bd29ee12544218166867fd8023a11/boards.zip

Here's my project:

/cfs-file/__key/communityserver-discussions-components-files/4/6763.sensor.zip

  • Hi,

    Have you tried scoping the SDA/SCL pins? 

    Based on your compiled .dts file, it seems that you are using 100 kHz. Are you using external pull-ups?

    If not, you need to either use external pull resistors or internal in the pad.

    Here's how to setup pull-ups in the pads:

    &pinctrl {
        i2c0_default_alt: i2c0_default_alt {
            group1 {
                psels = <NRF_PSEL(TWIM_SDA, X, XY)>,
                     <NRF_PSEL(TWIM_SCL, X, XZ)>;
                bias-pull-up;
          };
       };
       i2c0_sleep_alt: i2c0_sleep_alt {
          group1 {
             psels = <NRF_PSEL(TWIM_SDA, X, YY)>,
                     <NRF_PSEL(TWIM_SCL, X, YZ)>;
             low-power-enable;
          };
       };
    };
    
    &i2c0 {
       status = "okay";
       pinctrl-0 = <&i2c0_default_alt>;
       pinctrl-1 = <&i2c0_sleep_alt>;
       pinctrl-names = "default", "sleep";
       ....rest
    };

     

    Kind regards,

    Håkon

  • Based on your compiled .dts file, it seems that you are using 100 kHz. Are you using external pull-ups? If not, you need to either use external pull resistors or internal in the pad.

    I didn't include my .dtsi file but I think this answers your question:

    from board file "type2ab_evb-pinctrl.dtsi"

    &pinctrl {
    	i2c0_default: i2c0_default {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 0, 22)>,
    				    <NRF_PSEL(TWIM_SCL, 0, 19)>;
    		};
    	};
    
    	i2c0_sleep: i2c0_sleep {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 0, 22)>,
    				    <NRF_PSEL(TWIM_SCL, 0, 19)>;
    			low-power-enable;
    		};
    	};
    };

    You can also see in the device tree I linked in my original post: #include "type2ab_evb-pinctrl.dtsi"

    Update: You're right! adding the "bias-pull-up" line fixed it! 

    Thanks for your help, and feel free to close this!

    Cal

Related