TWI/I2C no communication with Sensor Devices

Hello,

my first Post here, so i hope i do it correctly.

I have the following Problem with the Configuration and Communication over TWI/I2C.

The Voltage of the TWI/I2C Bus is not 3.3V.

Reference Mesurment with a RPI and ESP32 for the same Sensor Hardware. I can say it's not a hardware fault.


I use as Hardwarebase the nRF52833-DK.

As Development runtime Zephyr with the nRF connect SDK V2.0.0 in Visual Studio Code.

As Test-Project to find the Problem, i use the follwing Code and Settings:

The used Overlay for I2C

&i2c0 {
	compatible = "nordic,nrf-twim";
	status = "okay";
	pinctrl-0 = <&i2c0_default>;
	pinctrl-1 = <&i2c0_sleep>;
	pinctrl-names = "default", "sleep";
	clock-frequency = <100000>;
	/*adxl372@53 {
		compatible = "adi,adxl372";
		reg = <0x53>;
		int1-gpios = <&gpio0 54 GPIO_ACTIVE_HIGH>;
		label = "ADXL372";
	};*/
    /*pca9536@41 {
        compatible = "ti,pca9536";
        reg = <0x41>;
        label = "PCA9536";
    };
	gyro_adc@40 {
		compatible = "i2c-device";
		reg = < 0x40 >;
		label = "gyro";
	};
	bq35100@55 {
		compatible = "i2c-device";
		reg = < 0x55 >;
		label = "bms";
	};*/
};

and run it with this Project Configuration

CONFIG_STDOUT_CONSOLE=y
CONFIG_PRINTK=y

CONFIG_NEWLIB_LIBC=y
CONFIG_CPLUSPLUS=y
CONFIG_STD_CPP17=y
CONFIG_LIB_CPLUSPLUS=y
#CONFIG_RTTI=y
CONFIG_THREAD_ANALYZER=y
CONFIG_DEBUG=y
CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=2048

CONFIG_I2C=y
CONFIG_I2C_NRFX=y
CONFIG_I2C_GPIO=y
CONFIG_NRFX_TWI0=y

Source-Code (main.cpp):

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

#include <zephyr.h>
#include <sys/printk.h>

#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>
#include <drivers/i2c.h>

#define FRAM_I2C_ADDR 41

#define MY_TWIM DT_NODELABEL(i2c0)

void main(void)
{
	const struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c0));
	uint8_t cmp_data[16];
	uint8_t data[16];
	uint8_t w_data[16];
	uint8_t r_data[16];
	int i, ret;
	int rc1, rc2, rc3, rc4;
	rc1 = rc2 = rc3 = rc4 = -999;

	//Initalisierung Speicehr Bereiche
	for (i = 0; i < 16; ++i)
	{ data[i] = w_data[i] =  r_data[i] = 0; }

	while (1)
	{
		if (!device_is_ready(i2c_dev))
		{ printk("I2C: Device is not ready.\n"); return; }	
		else
		{ printk("I2C: is ready.\n"); break; }
	}

	uint32_t dev_config = I2C_SPEED_SET(I2C_SPEED_STANDARD) | I2C_MODE_MASTER;

	if (i2c_configure(i2c_dev, dev_config))
	{ printk("Configure Fault\n"); }
	else
	{
		printk("Configure Done\n");
		/*printk("I2C Master: Slave ADDR: 0x%x SCL: %d, SDA: %d, CLK(Hz): %u\n\n",
          DT_REG_ADDR(DT_NODELABEL(i2c_dev)), 
          DT_PROP(MY_TWIM, pinctrl-0),
          DT_PROP(MY_TWIM, pinctrl-1),
          DT_PROP(MY_TWIM, clock_frequency));*/
	}

	k_sleep(K_MSEC(1));

	//Auslesen Config ist nicht Implementiert Fehler -88 ENOSYS
	//uint32_t dev_config_tmp;
	//rc1 = i2c_get_config(i2c_dev, &dev_config_tmp);
	//if (rc1 != 0) {
	//	printk("I2C get_config failed\n");
	//}
	//if (dev_config != dev_config_tmp) {
	//	printk("I2C get_config returned invalid config\n");
	//}

	uint8_t reg_to_read = 3;

	w_data[0] = reg_to_read;

	uint8_t wr_addr[2];
	/* FRAM address */
	wr_addr[0] = reg_to_read;
	wr_addr[1] = 0x00;
	struct i2c_msg msgs[2];
	/* Send the address to read from */
	msgs[0].buf = wr_addr;
	msgs[0].len = 2U;
	msgs[0].flags = I2C_MSG_WRITE;

	/* Read from device. STOP after this. */
	msgs[1].buf = data;
	msgs[1].len = 1;
	msgs[1].flags = I2C_MSG_READ | I2C_MSG_STOP;

	rc1 = i2c_write(i2c_dev, &wr_addr[0], 1, (uint16_t)FRAM_I2C_ADDR);
	rc2 = i2c_read(i2c_dev, &data[0], 1, (uint16_t)FRAM_I2C_ADDR);
	rc3 = i2c_write_read(i2c_dev, (uint16_t)FRAM_I2C_ADDR, &w_data[0], 1, &r_data[0], 1);
	rc4 = i2c_transfer(i2c_dev, &msgs[0], 2, (uint16_t)FRAM_I2C_ADDR);
	//read_byte(i2c_dev, 0x00, &data[0], FRAM_I2C_ADDR);
	if (rc1 == 0 || rc2 == 0 || rc3 == 0 || rc4 == 0)
	{ 
		printk("all read. \n");
		printk("Value write data: %d \n", w_data);
		printk("Value read data: %d \n", r_data);
	}
	else
	{ printk("read fault \n"); }
	
	return;
}

NRF-Terminal Output:

Connected via Serial Port with settings COM3 115200 8n1 rtscts:off

*** Booting Zephyr OS build v3.0.99-ncs1  ***
I2C: is ready.
Configure Done
read fault
*** Booting Zephyr OS build v3.0.99-ncs1  ***
I2C: is ready.
Configure Done
read fault
[00:00:09.736,724] <err> i2c_nrfx_twim: Error 0x0BAE0001 occurred for message 0
[00:00:09.736,938] <err> i2c_nrfx_twim: Error 0x0BAE0001 occurred for message 0
[00:00:09.737,121] <err> i2c_nrfx_twim: Error 0x0BAE0001 occurred for message 0
[00:00:09.737,304] <err> i2c_nrfx_twim: Error 0x0BAE0001 occurred for message 0


The Project-Copy:

I2C-Test.zip

Thanks for Help

  • Hello Björn,

    Sorry for not being able to pin point exactly what is causing the voltage drop right away, but I see that most cases where the NCS SDK (including Zephyr) uses:

    compatible = "i2c-device"

    it actually says:

    compatible = "vnd,i2c-device"

    It is at least worth a shot. 

    So the measurements with the voltage drop, is that done with a DK or a custom board?

    What happens if you detach whatever is connected to the I2C bus. What voltage does the pin have then?

    Is there some way for me to reproduce what you are seeing on a DK without any external HW?

    BR,
    Edvin

  • Hello Edvin,

    all measurments are currently done with a DK Board, the custom Boards are in production.

    To the Driver compatible, i check the yaml-Drivers Files and see it in the first version. Only at specific Drivers the vnd shows the shortname of the producer. For a Basic-Driver-Componentlike I2C, i don't found anything in the "vnd, driver" notaition.

    I will tomorrow check the DK Board with out a device.

    Best Regards,

    Björn

  • Hallo Edvin,

    i have check the DK-Board, without any external Device and have the same Problem, but the Project-Partner has checed in this Time the differences between Zephyr-I2C-API and Nordic-TWIM-API. The Zephyr-API disable at the end of a transmission the TWI-Interface.This Produce by undefined Powerlevel of the Interface-Pins the Undefined Voltage-Level.

    So we test the DTS - PINCTL - Parameter "bias-pull-up" to solve the undefined Powerlevel for the Interface.

    Afterthis we can now find all Device at the Bus.The I2C-Devices at the Bus are, so it looks for me, Bus-Power sensitive. They need a defined Bus-Volatage-Level to work correctly.

    Best Regards

    Björn

Related