I2C device failing device_is_ready() with init_res == 5 on Ophelia-III (similar to Wurth Elektronik's proteus3ev)

Hello fellow Nordic users,

I'm completely new to NRF technology (started about a month ago) and I've hit a wall, though I'm not sure of its origin.

I know may be similar to these 2:

 Custom board I2C, device_is_ready() failing with init_res == 5 

 I built and flashed an I2C sample on nrf54l15dk and device_is_ready failed with init_res == 5. 

But after reading them and trying to apply their solutions to my case it seems to be something different.

Long story short, I started with the radio-test example of nRF Connect, and broke it down so that I now have a transmitter and a receiver communicating on a custom frequency.

Now that I have 2 modules successfully communicating with each other, I wanted to add an I2C thermometer to transmit real data from on to the other. So I mounted a WE WSEN-TIDS to it, with those pins:
- VDD → VDD_MOD (3.3V)
- SCL → P0.22
- SDA → P0.21

I also had to customize the Device Tree and prj.conf files, so I tried the following:

prj.conf:

CONFIG_CLOCK_CONTROL=y
CONFIG_I2C=y
CONFIG_I2C_SHELL=y
CONFIG_SENSOR=y
CONFIG_WSEN_TIDS=y

Ophelia-III.overlay:

/ {
    model = "we_proteus3ev_nrf52840";
	compatible = "we,we-proteus3ev-nrf52840";

    aliases {
        tids = &we_wsen_tids;
    };
};


&pinctrl {
    uart0_default: uart0_default {
		group1 {
			psels = <NRF_PSEL(UART_TX, 1, 8)>,
				<NRF_PSEL(UART_RTS, 0, 11)>;
		};
		group2 {
			psels = <NRF_PSEL(UART_RX, 1, 9)>,
				<NRF_PSEL(UART_CTS, 0, 12)>;
			bias-pull-up;
		};
	};
	uart0_sleep: uart0_sleep {
		group1 {
			psels = <NRF_PSEL(UART_TX, 1, 8)>,
				<NRF_PSEL(UART_RX, 1, 9)>,
				<NRF_PSEL(UART_RTS, 0, 11)>,
				<NRF_PSEL(UART_CTS, 0, 12)>;
			low-power-enable;
		};
	};

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

&gpiote {
	status = "okay";
};

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


&i2c0 {
	compatible = "nordic,nrf-twi";
	status = "okay";
    clock-frequency = <I2C_BITRATE_STANDARD>;

	pinctrl-0 = <&i2c0_default>;
	pinctrl-1 = <&i2c0_sleep>;
	pinctrl-names = "default", "sleep";

    we_wsen_tids: wsen_tids@38 { 
        compatible = "we,wsen-tids";
        status = "okay";
        reg = <0x38>;
        odr = <100>;
    };
};

I kept the UART pins 1.08 and 1.09 for easy debugging, and using them, I found that the issue was that dev->state->init_res = 5, no matter what I tried.

I'm simply initializing the device with: "const struct device *dev = DEVICE_DT_GET_ANY(we_wsen_tids);" but device_is_ready(dev) always returns false.

I suspect this could be a hardware issue (wrong pin assignments or a bad configuration), but I can’t seem to figure it out. So I’m reaching out for assistance.

I contacted Wurth Elektronik for some advices about pins, and theorically 0.21 and 0.22 can be working with I2C (no matter which is SDA or SCL).

Here's documentation about my hardware if needed: https://www.we-online.com/components/products/manual/2611149022001_Manual%20Family%20Boards_rev1.5.pdf

Thank you for any guidance you can provide!

Parents
  • Hello,

    Troubleshooting I2C communication issues is generally a lot easier if you can probe the bus lines with an oscilloscope or logic analyzer (if you have acccess to one). Either way, error -EIO ('5') indicates that the slave did not respond to your command. Have you enabled CONFIG_LOG in your project configuration? The log should include more information about why this error code was returned.

    Best regards,

    Vidar

  • Hello, thanks for the quick answer!

    I once tried enabling CONFIG_LOG, and after increasing its stack size to make it work, I still couldn’t make sense of what it was saying:
    os: z_impl_k_mutex_unlock: mutex 0x200006ec lock_count: 1
    os: z_impl_k_mutex_lock: 0x20000728 took mutex 0x200006ec, count: 1, orig prio: 14
    os: z_impl_k_mutex_unlock: new owner of mutex 0x200006ec: 0 (prio: -1000)

    These are the three messages I get at a high rate, and I’m not sure why a mutex is involved here...

    From what I understand, this seems to indicate some kind of I2C device overlap, but as far as I know, I’ve only configured and mounted one device, so I’m completely lost at this point.

    I’d really appreciate any help on this.

  • Hello,

    It seems like you have too many logs enabled making the logs we are interested in disapear in the noise. We are mostly interested in debug messages from the i2c driver in this case. Have you changed the CONFIG_LOG_DEFAULT_LEVEL setting in your project configuration? It should be set to '3'.

  • Thank you for this clarification.

    Now that I added this to the prj.conf:
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=3
    CONFIG_SENSOR_LOG_LEVEL_DBG=y
    CONFIG_I2C_LOG_LEVEL_DBG=y

    I... have my program working... in some ways I think:
    [00:03:44.906,372] <dbg> temp_nrf5: temp_nrf5_sample_fetch: sample: 84
    [00:03:44.906,372] <dbg> temp_nrf5: temp_nrf5_channel_get: Temperature:21,0

    The result of my program doesn't seems to match my expectations but I think this is from my part (miscalculations).

    I just don't understand why it work with logs but... well it work I guess.

    If you have any clue I'm interested. Thank you for your guidance!



    PS: Sorry, it looks like I answered too quickly. I just noticed that I now get this message at startup:
    <err> WSEN_TIDS: Failed to read device ID.

    I also got the I/O error again, so it seems to work only intermittently. However, I’m still receiving temperature logs, which means it can access the value, but if I get this error at startup, it seems like it’s struggling to extract it properly.

    PS2: I got an answer from Wurth Elektronik, and the problem may come from the absence of pull up resistance for the I2C bus, which looks like mandatory in my case

  • Benjamin H. said:
    I... have my program working... in some ways I think:
    [00:03:44.906,372] <dbg> temp_nrf5: temp_nrf5_sample_fetch: sample: 84
    [00:03:44.906,372] <dbg> temp_nrf5: temp_nrf5_channel_get: Temperature:21,0

    This is from the on-chip temperature sensor and doesn't have anything to do with i2c.

    Benjamin H. said:
    PS: Sorry, it looks like I answered too quickly. I just noticed that I now get this message at startup:
    <err> WSEN_TIDS: Failed to read device ID.

    Did you not see any debug messages from the nrfx twi driver?

    Benjamin H. said:
    I got an answer from Wurth Elektronik, and the problem may come from the absence of pull up resistance for the I2C bus, which looks like mandatory in my case

    Pull-ups are always required. If you don't have external pull-ups, you can enable the internal ones by applying the 'bias-pull-up' property in your devictree here:

        i2c0_default: i2c0_default {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 0, 21)>,
    				<NRF_PSEL(TWIM_SCL, 0, 22)>;
    				bias-pull-up;
    		};
    	};
    	i2c0_sleep: i2c0_sleep {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 0, 21)>,
    				<NRF_PSEL(TWIM_SCL, 0, 22)>;
    			low-power-enable;
    		};
    	};

  • Did you not see any debug messages from the nrfx twi driver?

    I don't have any debug message mentionning the nrfx twi driver no, only what I send in the last message, but :

    If you don't have external pull-ups, you can enable the internal ones by applying the 'bias-pull-up' property in your devictree here

    I added that, and now it seems to work just fine, so I guess it really was only a resistance missing issue.

    Thank you for your help, I'm really grateful !

Reply Children
Related