This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Unable to Connect nRF5340DK with BMI270 Over I2C

I am attempting to get the BMI270 sample working on an nRF5340DK, using nRF Connect SDK v1.6.0, but all attempts at device_get_binding("BMI270"), device_get_binding(DT_LABEL(DT_INST(0, bosch_bmi270))), and similar return null.  I am using the following config and overlay files

#prj.conf

CONFIG_UART_CONSOLE=n
CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y

CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_BMI270=y

/* nrf5340dk_nrf5340_cpuapp.overlay - no shield */

&arduino_i2c {
	status = "okay";

	bmi270@68 {
		compatible = "bosch,bmi270";
		reg = <0x68>;
		label = "BMI270";
	};
};

On the hardware side I'm using a BMI270 breakout connecting SDA to P1.02 and SCL to P1.03.

I have also used a shield that sends SDA to P0.25 and SCL to P0.26, with the following overlay

/* nrf5340dk_nrf5340_cpuapp.overlay - with shield */

&i2c1 {
    sda-pin = <25>;
    scl-pin = <26>;
};

&arduino_i2c {
	status = "okay";

	bmi270@68 {
		compatible = "bosch,bmi270";
		reg = <0x68>;
		label = "BMI270";
	};
};

In all attempted cases

#include <zephyr.h>
#include <device.h>
#include <drivers/sensor.h>
#include <stdio.h>

void main(void)
{
	const struct device *dev;

	dev = device_get_binding("BMI270");

	if (dev == NULL) {
		printf("Could not get %s device\n",
		       DT_LABEL(DT_INST(0, bosch_bmi270)));
		return;
	}
	...
}

gives the output

00> *** Booting Zephyr OS build v2.6.0-rc1-ncs1  ***
00> Could not get BMI270 device

in J-Link RTT Viewer.

Any help would be greatly appreciated.

  • Hi again, Jonathan!

    After digging a little and reading through Marti's comments here I finally tracked down the problem. This issue arises because of how the TWI with easyDMA hardware is implemented on the nRF5340. You can read more about it in this GitHub issue.

    In summary burst writes from the nRF5340 generates repeated starts, which are not handled well by some sensors/devices. Seemingly BMI270 is one of these. The fix for this issue is to use the normal i2c_write() function instead of i2c_burst_write(). If you choose to change the driver to work with the nRF5340, please consider doing a PR for the fix for the Zephyr RTOS GitHub repository as well. EDIT: try the method presented in my comment below instead.

    You do not see this issue on the nRF52833 as it by default is using TWI without easyDMA.

    Thank you for your patience and thank you Marti for the help. It was the following comment that helped me pick up the scent:

    marti.bolivar.nordic said:
    From your screenshot, you're getting -EIO from the i2c_burst_write() call on line 35, which indicates a real error coming out of i2c_nrfx_twim_transfer() in the I2C driver, i2c_nrfx_twim.c.

    Best regards,
    Carl Richard

  • Additional note here. Before changing the driver you can try to use the concat-buf-size property of the TWIM peripheral. This was implemented/added to prevent the issues you are seeing.

    Just add the property to your overlay file with a suitable size. Looking at threads describing the same issue as yours the following overlay, with concat-buf-size at 128, seems to work:

    /*
     * Copyright (c) 2021 Bosch Sensortec GmbH
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    &arduino_i2c {
        status = "okay";
        zephyr,concat-buf-size = <128>;
        bmi270@68 {
            compatible = "bosch,bmi270";
            reg = <0x68>;
            label = "BMI270";
        };
    };


    Best regards,
    Carl Richard

  • Hi Carl,

    Thank you, that's very helpful in understanding the cause of the i2c problems.  Unfortunately, adding zephyr, concat-buf-size=<128>; to the overlay didn't help.  I modified bmi270.c so that reg_write() uses i2c_write() instead of i2c_burst_write() as follows:

    static int reg_write(uint8_t reg, const uint8_t *data, uint16_t length,
    		     struct bmi270_data *dev)
    {
    	uint8_t buffer[1+length];
            __ASSERT((1U + length) <= sizeof(buffer),
                              "burst buffer too small");
            buffer[0]=reg;
            memmove(buffer+1,data,length);
            return i2c_write(dev->i2c,buffer,1+length,dev->i2c_addr);
    }

    With this change to the BMI270 driver, I get streaming data on both the 5340dk and the 52833dk.

    As suggested in the struck-through text, I created a pull request here: github.com/.../37190

  • Hi,

    I encountered the same issue in NCS version 2.0.0, the suggested fix to change the BMI270 driver does indeed fix it but that doesn't seem very desirable. Is there already an other more elegant fix or is this still the suggested solution?

    Thanks

Related