Openthread and i2c not working in the same project

Hello nordic team,

I am trying to build up a mesh network using openthread and reading some sensor data via i2c and broadcasting them in the network. I have code that broadcasts data with udp over openthread and i have code that reads sensor data over i2c. Both function separadly as they should but as soon as i try merging them nothing works at all. The code compiles, i even can flash it but after flashing the mcu is completely dead/frozen, no prints are shown and even the reset button doesn't react. Because of that i have no errortrace to share. As soon as I comment CONFIG_I2C=y out of the prj.conf file and together every line related to i2c in main.c openThread works again and vice versa for i2c too. I really don't understand this.

If someone could point something for me out I would really appreciate this.

GG

I am using the two nrf5340DK and nrf Connect for VS Code on Windows 10. SDK Version 2.1.1

Client prj.conf (same for Server)

# nRF board library
CONFIG_DK_LIBRARY=y

# # Enable Debug
# CONFIG_DEBUG_OPTIMIZATIONS=y
# CONFIG_DEBUG_THREAD_INFO=y

CONFIG_BUILD_WITH_TFM=y
CONFIG_OPENTHREAD_CRYPTO_PSA=y

# Configure sample logging setting
CONFIG_LOG=y
CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
CONFIG_OPENTHREAD_DEBUG=y

# Generic networking options
CONFIG_NETWORKING=y

# L2 OpenThread enabling
CONFIG_NET_L2_OPENTHREAD=y

# Network shell
CONFIG_SHELL=y
CONFIG_OPENTHREAD_SHELL=y
CONFIG_SHELL_ARGC_MAX=26
CONFIG_SHELL_CMD_BUFF_SIZE=416

# Network sockets
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_SOCKETS_POLL_MAX=4

# Same network Master Key for client and server
CONFIG_OPENTHREAD_MANUAL_START=n
CONFIG_OPENTHREAD_NETWORK_NAME="OT-Mesh"
CONFIG_OPENTHREAD_PANID=10000
CONFIG_OPENTHREAD_XPANID="fd:02:00:00:ab:cd:00:00"
CONFIG_OPENTHREAD_NETWORKKEY="00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff"

# Additional Options
CONFIG_MBEDTLS_SHA1_C=n
CONFIG_FPU=y
CONFIG_I2C=y    # <-- this kills everything

  

Client dts Overlay: (no overlay for the server)

&i2c1 {  
    compatible = "nordic,nrf-twim";
    status = "okay";
    
    msgeq7: msgeq7@1{
        compatible = "i2c-device";
        reg = < 0x1 >;
        label = "MSGEQ7";
    };
};

Client main.c 

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

#include <net/openthread.h>
#include <openthread/thread.h>
#include <openthread/udp.h> 

#include <drivers/i2c.h>
#include <stdio.h>


/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   50

#define I2C0_NODE DT_NODELABEL(msgeq7)


static void udp_send(uint8_t payload); 


void main(void) {	
	printk("Hello World! %s\n", CONFIG_BOARD);

	static const struct i2c_dt_spec dev_i2c = I2C_DT_SPEC_GET(I2C0_NODE);
	if (!device_is_ready(dev_i2c.bus)) {
		printk("I2C bus %s at Adress %x is not ready! \n\r", dev_i2c.bus->name, dev_i2c.addr);
		return;
	}

	while (1) {
		uint8_t data;
		int ret = i2c_read_dt(&dev_i2c, &data, sizeof(data));
		if (ret != 0) {
			printk("Failed to read from I2C device address %x \n", dev_i2c.addr);
		}
		
		printk("I2C - Adresse: %x - Data: %d \n", dev_i2c.addr, data);
		udp_send(data);
		k_msleep(SLEEP_TIME_MS);
	}
}


static void udp_send(uint8_t payload) 
{
	otError error = OT_ERROR_NONE;
	char buf[50];
	sprintf(buf, "hallo thread: %d", payload);

	otInstance *myInstance; 
	myInstance = openthread_get_default_instance();
	otUdpSocket mySocket; 

	otMessageInfo messageInfo;
	memset(&messageInfo, 0, sizeof(messageInfo)); 
	otIp6AddressFromString("ff03::1", &messageInfo.mPeerAddr);	// ff03::1 ist eine Broadcastdresse
	messageInfo.mPeerPort = 2222; 

	do{
		error = otUdpOpen(myInstance, &mySocket, NULL, NULL);
		if (error != OT_ERROR_NONE) break;

		otMessage *test_Message = otUdpNewMessage(myInstance, NULL);
		error = otMessageAppend(test_Message, buf, (uint16_t)strlen(buf));
		if (error != OT_ERROR_NONE) break;

		error = otUdpSend(myInstance, &mySocket, test_Message, &messageInfo);
		if (error != OT_ERROR_NONE) {printk("udpSend failed \n"); break; }

		error = otUdpClose(myInstance, &mySocket);
		
	}while(false); 

	if (error == OT_ERROR_NONE)
		printk("%d Sent.\n", payload);
	else	
		printk("udpSend error: %d\n", error);
}

Server main.c (this code works perfectly)

#include <zephyr/zephyr.h>
#include <zephyr/drivers/gpio.h>

#include <net/openthread.h>
#include <openthread/thread.h>
#include <openthread/udp.h> 


void udpReceive_cb(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
static void udp_init(void);


void main(void)
{

	udp_init(); 
	
	while (1) {
		k_msleep(1000); 
	}
}

void udpReceive_cb(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo) {
	uint16_t payloadLength = otMessageGetLength(aMessage) - otMessageGetOffset(aMessage);
	char buf[payloadLength+1];
	otMessageRead(aMessage, otMessageGetOffset(aMessage), buf, payloadLength);
	buf[payloadLength]='\0';
	printk("Received: %s\n", buf);
}

static void udp_init(void)
{
	otError error = OT_ERROR_NONE;

	otInstance *myInstance = openthread_get_default_instance();

	otUdpSocket mySocket;
	otSockAddr mySockAddr;
	memset(&mySockAddr,0,sizeof(mySockAddr));
	mySockAddr.mPort = 2222; // we chose this port.


	do{
		error = otUdpOpen(myInstance, &mySocket, udpReceive_cb, NULL); //udp mesajı gelince tanımlanan callback funca giriyor.
		if (error != OT_ERROR_NONE) break;
		error = otUdpBind(myInstance, &mySocket, &mySockAddr, OT_NETIF_THREAD);
	}while(false);

	if (error != OT_ERROR_NONE){
		printk("init_udp error: %d\n", error);
	}
}

Parents
  • Hi,

    Please try with this overlay:

    &i2c2 {  
        compatible = "nordic,nrf-twim";
        status = "okay";
        pinctrl-0 = <&i2c2_default>;
    	pinctrl-1 = <&i2c2_sleep>;
    	pinctrl-names = "default", "sleep";
        
        msgeq7: msgeq7@1{
            compatible = "i2c-device";
            reg = < 0x1 >;
            label = "MSGEQ7";
        };
    };
    
    /delete-node/ &i2c1_default;
    /delete-node/ &i2c1_sleep;
    
    &pinctrl {
    	i2c2_default: i2c2_default {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 1, 2)>,
    				<NRF_PSEL(TWIM_SCL, 1, 3)>;
    		};
    	};
    
    	i2c2_sleep: i2c2_sleep {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 1, 2)>,
    				<NRF_PSEL(TWIM_SCL, 1, 3)>;
    			low-power-enable;
    		};
    	};
    };

    the i2c1 peripheral may be clashing with the uart1 used by TFM, so this tries to use i2c2 instead.

  • thank you for your answer.

    the two /delete-node/ line cause this errortrace. Did you try to disable i2c1? Compiling without this lines work but doesnt change anything

     *  Executing task: nRF Connect: Build [pristine]: openThread_coap_client/build (active) 
    
    Building openThread_coap_client
    west build --build-dir c:\Users\Gabriel\Documents\VS_Code_WS\openThread_coap_client\build c:\Users\Gabriel\Documents\VS_Code_WS\openThread_coap_client --pristine --board nrf5340dk_nrf5340_cpuapp_ns -- -DNCS_TOOLCHAIN_VERSION:STRING="NONE" -DBOARD_ROOT:STRING="c:/Users/Gabriel/Documents/VS_Code_WS/openThread_CLI;c:/Users/Gabriel/Documents/VS_Code_WS/led_ws2812_demo;c:/Users/Gabriel/Documents/VS_Code_WS/template;c:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client;c:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_server" -DCONFIG_DEBUG_OPTIMIZATIONS:STRING="y" -DCONFIG_DEBUG_THREAD_INFO:STRING="y" -DDTC_OVERLAY_FILE:STRING="c:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/nrf5340dk_nrf5340_cpuapp_ns.overlay" -DCONF_FILE:STRING="c:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/prj.conf;c:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/boards/nrf5340dk_nrf5340_cpuapp_ns.conf"
    
    -- west build: generating a build system
    Loading Zephyr default modules (Zephyr base).
    -- Application: C:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client
    -- Found Python3: C:/ncs/toolchains/v2.1.1/opt/bin/python.exe (found suitable exact version "3.8.2") found components: Interpreter 
    -- Cache files will be written to: C:/ncs/v2.1.1/zephyr/.cache
    -- Zephyr version: 3.1.99 (C:/ncs/v2.1.1/zephyr)
    -- Found west (found suitable version "0.14.0", minimum required is "0.7.1")
    CMake Warning at C:/ncs/v2.1.1/zephyr/cmake/modules/boards.cmake:85 (message):
      BOARD_ROOT element without a 'boards' subdirectory:
    
      c:/Users/Gabriel/Documents/VS_Code_WS/template
    
      Hints:
    
        - if your board directory is '/foo/bar/boards/<ARCH>/my_board' then add '/foo/bar' to BOARD_ROOT, not the entire board directory
        - if in doubt, use absolute paths
    Call Stack (most recent call first):
      C:/ncs/v2.1.1/zephyr/cmake/modules/zephyr_default.cmake:121 (include)
      C:/ncs/v2.1.1/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)
      C:/ncs/v2.1.1/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
      CMakeLists.txt:8 (find_package)
    
    
    -- Board: nrf5340dk_nrf5340_cpuapp_ns
    -- Found host-tools: zephyr 0.14.1 (C:/ncs/toolchains/v2.1.1/opt/zephyr-sdk)
    -- Found dtc: C:/ncs/toolchains/v2.1.1/opt/bin/dtc.exe (found suitable version "1.4.7", minimum required is "1.4.6")
    -- Found toolchain: zephyr 0.14.1 (C:/ncs/toolchains/v2.1.1/opt/zephyr-sdk)
    -- Found BOARD.dts: C:/ncs/v2.1.1/zephyr/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpuapp_ns.dts
    -- Found devicetree overlay: c:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/nrf5340dk_nrf5340_cpuapp_ns.overlay
    devicetree error: /soc/peripheral@40000000/i2c@9000: undefined node label 'i2c1_default'
    CMake Error at C:/ncs/v2.1.1/zephyr/cmake/modules/dts.cmake:230 (message):
      gen_defines.py failed with return code: 1
    Call Stack (most recent call first):
      C:/ncs/v2.1.1/zephyr/cmake/modules/zephyr_default.cmake:121 (include)
      C:/ncs/v2.1.1/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)
      C:/ncs/v2.1.1/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
      CMakeLists.txt:8 (find_package)
    
    
    -- In: C:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/build/zephyr, command: C:/ncs/toolchains/v2.1.1/opt/bin/python.exe;C:/ncs/v2.1.1/zephyr/scripts/dts/gen_defines.py;--dts;C:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/build/zephyr/zephyr.dts.pre;--dtc-flags;'-Wno-unique_unit_address_if_enabled';--bindings-dirs;C:/ncs/v2.1.1/nrf/dts/bindings;C:/ncs/v2.1.1/zephyr/dts/bindings;--header-out;C:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/build/zephyr/include/generated/devicetree_unfixed.h.new;--device-header-out;C:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/build/zephyr/include/generated/device_extern.h.new;--dts-out;C:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/build/zephyr/zephyr.dts.new;--edt-pickle-out;C:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/build/zephyr/edt.pickle;--vendor-prefixes;C:/ncs/v2.1.1/nrf/dts/bindings/vendor-prefixes.txt;--vendor-prefixes;C:/ncs/v2.1.1/zephyr/dts/bindings/vendor-prefixes.txt
    -- Configuring incomplete, errors occurred!
    FATAL ERROR: command exited with status 1: 'c:\ncs\toolchains\v2.1.1\opt\bin\cmake.EXE' '-DWEST_PYTHON=c:\ncs\toolchains\v2.1.1\opt\bin\python.exe' '-Bc:\Users\Gabriel\Documents\VS_Code_WS\openThread_coap_client\build' -GNinja -DBOARD=nrf5340dk_nrf5340_cpuapp_ns -DNCS_TOOLCHAIN_VERSION:STRING=NONE '-DBOARD_ROOT:STRING=c:/Users/Gabriel/Documents/VS_Code_WS/openThread_CLI;c:/Users/Gabriel/Documents/VS_Code_WS/led_ws2812_demo;c:/Users/Gabriel/Documents/VS_Code_WS/template;c:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client;c:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_server' -DCONFIG_DEBUG_OPTIMIZATIONS:STRING=y -DCONFIG_DEBUG_THREAD_INFO:STRING=y -DDTC_OVERLAY_FILE:STRING=c:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/nrf5340dk_nrf5340_cpuapp_ns.overlay '-DCONF_FILE:STRING=c:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/prj.conf;c:/Users/Gabriel/Documents/VS_Code_WS/openThread_coap_client/boards/nrf5340dk_nrf5340_cpuapp_ns.conf' '-Sc:\Users\Gabriel\Documents\VS_Code_WS\openThread_coap_client'

    I have to add though that I think it can't be caused by a blocked uart. Because the ot server didn't receive any messages after I started the client. This means that the mcu didnt started open thread or any service

  • Try keeping the /delete-node/ lines, but adding:

    &i2c1 {
        status = "disabled";
    };

    I am wondering if TFM is trying and failing to initialize uart1 during boot.

    If it doesn't work, are you able to connect a debugger and see how far it gets?

  • I tried it but with no success. Same errortrace.

    devicetree error: /soc/peripheral@40000000/i2c@9000: undefined node label 'i2c1_default'

    It seems like i2c1_default and i2c1_sleep are unknown.

    I tried debugging bevor but also hier something strange happens. After the debugger starts it changes the view but no "yellow marked debug-line" appears. As if the program would never start. Also when I comment i2c and everything related to it out of prj.conf and main.c, the debugger works as expected.

    But I think you may be right with your though that TFM causes this issue. Is there a way to build an open thread project without TFM or is this necessary because its an network project?  

  • I finally fixed it. Changing the i2c channel to i2c2 and disabling i2c1 was the right way. I had previosly problems using i2c0 is there a reason why the first channel riders? Or is it better practice to start from behind?

    the final overlay looks like this:

    &i2c2 {  
        compatible = "nordic,nrf-twim";
        status = "okay";
        pinctrl-0 = <&i2c2_default>;
    	pinctrl-1 = <&i2c2_sleep>;
    	pinctrl-names = "default", "sleep";
        
        msgeq7: msgeq7@1{
            compatible = "i2c-device";
            reg = < 0x1 >;
            label = "MSGEQ7";
        };
    };
    
    &i2c1 {
        status = "disabled";
    };
    
    // /delete-node/ &i2c1_default;
    // /delete-node/ &i2c1_sleep;
    
    &pinctrl {
    	i2c2_default: i2c2_default {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 1, 2)>,
    				<NRF_PSEL(TWIM_SCL, 1, 3)>;
    		};
    	};
    
    	i2c2_sleep: i2c2_sleep {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 1, 2)>,
    				<NRF_PSEL(TWIM_SCL, 1, 3)>;
    			low-power-enable;
    		};
    	};
    };
    

    Thank you again for your help!

    GG

Reply
  • I finally fixed it. Changing the i2c channel to i2c2 and disabling i2c1 was the right way. I had previosly problems using i2c0 is there a reason why the first channel riders? Or is it better practice to start from behind?

    the final overlay looks like this:

    &i2c2 {  
        compatible = "nordic,nrf-twim";
        status = "okay";
        pinctrl-0 = <&i2c2_default>;
    	pinctrl-1 = <&i2c2_sleep>;
    	pinctrl-names = "default", "sleep";
        
        msgeq7: msgeq7@1{
            compatible = "i2c-device";
            reg = < 0x1 >;
            label = "MSGEQ7";
        };
    };
    
    &i2c1 {
        status = "disabled";
    };
    
    // /delete-node/ &i2c1_default;
    // /delete-node/ &i2c1_sleep;
    
    &pinctrl {
    	i2c2_default: i2c2_default {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 1, 2)>,
    				<NRF_PSEL(TWIM_SCL, 1, 3)>;
    		};
    	};
    
    	i2c2_sleep: i2c2_sleep {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 1, 2)>,
    				<NRF_PSEL(TWIM_SCL, 1, 3)>;
    			low-power-enable;
    		};
    	};
    };
    

    Thank you again for your help!

    GG

Children
No Data
Related