Issues with repeated start on I2C

Hi:

Hardware setup: nRF52840DK interfacing with Adafruit LIS3DH (ST LIS3DH) over I2C on pins P1.14 and P1.15

Software: ncs-v3.2.1, Zephyr 4.2.99

Kconfig: I2C bus drivers enabled; nRF TWI nrfx drivers enabled

Device Tree (hardware-specific overlay file in my project_root/boards/ directory):

 

&i2c0 {
    status = "okay";
    pinctrl-0 = <&i2c0_default>;
	pinctrl-1 = <&i2c0_sleep>;
    pinctrl-names = "default", "sleep";
    lis3dh: lis3dh@18{
        compatible = "i2c-device";
        status = "okay";
        reg = < 0x18 >;
    };
};

&pinctrl {
	/omit-if-no-ref/ i2c0_default: i2c0_default {
		group1  {
			psels = <NRF_PSEL(TWIM_SCL, 1, 14)>,
					<NRF_PSEL(TWIM_SDA, 1, 15)>;
		};
	};

	/omit-if-no-ref/ i2c0_sleep: i2c0_sleep {
		group1  {
			psels = <NRF_PSEL(TWIM_SCL, 1, 14)>,
					<NRF_PSEL(TWIM_SDA, 1, 15)>;
			low-power-enable;
		};
	};
};

The issue: 

I'm currently working through the nRF SDK Connect Fundamentals course and I've encountered an issue on Lesson 6, where we are expected to connect an external sensor to the nRF MCU over TWI (I2C). Since I do not have a BME280 on-hand, I decided to substitute it with an ST LIS3DH IMU sensor. I wanted to check to see if the interface was working by simply checking the WHO_AM_I register of the IMU (register 0x0F). I first did this using the i2c_write_read_dt() function, but it returned a EIO error. I then tried i2c_read_reg_byte_dt(); same result. So I decided to bring out my logic analyzer to see what was going on at the signal level. What I found was that the sensor is successfully ACK'ing when it is addressed by the nRF, but it appears that the nRF fails to send a repeated start, which results in an unsuccessful read. Here's a screenshot of what I measured:

I tried to do my due diligence and search the web for this issue and it appears that it has to do with the TWI I2C driver needing the I2C_MSG_RESTART constant needing to be set. As far as I can tell, this is already included in the i2c.h driver that comes with Zephyr. Also, both i2c_write_read_dt() and i2c_read_reg_byte_dt() end up calling i2c_write_read(), which includes the I2C_MSG_RESTART as part of its flags: 

So, what I'm wondering is do I have to do anything to set I2C_MSG_RESTART? It seems like it's already being done in i2c.h. This post seems like the most relevant, but it's from two years ago. I'm wondering if I2C_MSG_RESTART was not automatically set in i2c.h two years ago. I'm sure this is something I'm doing wrong, but I would really appreciate any advice. 

Thanks!

Parents
  • Hello,

    I think there is bugs in the "nordic,nrf-twi" driver in ncs v3.2.1. 

    You can use twim instead of twi for compatible device (when you use ncs V3.2.1) and if you are using internal pull-up, try to add this in the overlay.

    &i2c0 {
        status = "okay";
        compatible = "nordic,nrf-twim";
        pinctrl-0 = <&i2c0_default>;
    	pinctrl-1 = <&i2c0_sleep>;
        pinctrl-names = "default", "sleep";
        lis3dh: lis3dh@18{
            compatible = "i2c-device";
            status = "okay";
            reg = < 0x18 >;
        };
    };
    
    &pinctrl {
    	/omit-if-no-ref/ i2c0_default: i2c0_default {
    		group1  {
    			psels = <NRF_PSEL(TWIM_SCL, 1, 14)>,
    					<NRF_PSEL(TWIM_SDA, 1, 15)>;
    					 bias-pull-up; 
    		};
    	};
    
    	/omit-if-no-ref/ i2c0_sleep: i2c0_sleep {
    		group1  {
    			psels = <NRF_PSEL(TWIM_SCL, 1, 14)>,
    					<NRF_PSEL(TWIM_SDA, 1, 15)>;
    			low-power-enable;
    		};
    	};
    };

    I have talked to team about the bug; I will get back to you lately when there is an update. In the meantime, you can Try this and let us know if it works. 

    Thanks.

    BR

    Kazi

  • Hi Kazi:

    Looks like your proposed changes to the overlay file work. I am now able to communicate the the sensor over I2C. 

    Thanks!

Reply Children
Related