Hi,
I’m trying to enable access to a STM32 as a I2C slave, I have this working in a isolated project but when I try a pulling it into our main project and enable CONFIG_I2C=y in the prj.conf I am getting the error

gen_isr_tables.py: error: multiple registrations at table_index 9 for irq 9 (0x9)
Existing handler 0x2c837, new handler 0x2c837
Has IRQ_CONNECT or IRQ_DIRECT_CONNECT accidentally been invoked on the same irq multiple times?

I can get the two projects working in isolation getting GNSS fix and data + LTE comms and posting data to API in one project and reading writing data to I2C slave in the other

When pulling in the slave project all I did was add

&i2c1 {
  stm32slave: stm32@2A {
        compatible = "st,stm32-slave";
        reg = <0x2A>; // I2C address of the STM32 device
        label = "STM32_AUDIO_WING";
    };
};

to the circuitdojo_feather_nrf9160_ns.overlay and CONFIG_I2C=y to the prj.conf plus the code for reading and writing to the slave

I see zephyr.dts has

...
                        uart1: uart@9000 {
				compatible = "nordic,nrf-uarte";
				reg = < 0x9000 0x1000 >;
				interrupts = < 0x9 0x1 >;
				status = "disabled";
				current-speed = < 0x1c200 >;
				pinctrl-0 = < &uart1_default >;
				pinctrl-1 = < &uart1_sleep >;
				pinctrl-names = "default", "sleep";
			};
...
			i2c1: i2c@9000 {
				compatible = "nordic,nrf-twim";
				#address-cells = < 0x1 >;
				#size-cells = < 0x0 >;
				reg = < 0x9000 0x1000 >;
				clock-frequency = < 0x186a0 >;
				interrupts = < 0x9 0x1 >;
				status = "okay";
				pinctrl-0 = < &i2c1_default >;
				pinctrl-1 = < &i2c1_sleep >;
				pinctrl-names = "default", "sleep";
				pcf85063a@51 {
					compatible = "nxp,pcf85063a";
					reg = < 0x51 >;
				};
				lis2dh: lis2dh@18 {
					compatible = "st,lis2dh";
					reg = < 0x18 >;
					irq-gpios = < &gpio0 0x1d 0x0 >;
					disconnect-sdo-sa0-pull-up;
				};
				stm32slave: stm32@2A {
					compatible = "st,stm32-slave";
					reg = < 0x2a >;
					label = "STM32_AUDIO_WING";
				};
			};
...
                       spi1: spi@9000 {
				compatible = "nordic,nrf-spim";
				#address-cells = < 0x1 >;
				#size-cells = < 0x0 >;
				reg = < 0x9000 0x1000 >;
				interrupts = < 0x9 0x1 >;
				max-frequency = < 0x7a1200 >;
				easydma-maxcnt-bits = < 0xd >;
				status = "disabled";
			};
...

but spi1 and uart1 are disabled so that shouldn’t be it

here is the prj.conf for reference just in case there is a conflict I don’t know about.

# General
CONFIG_FPU=y
# CONFIG_UART=n
CONFIG_NRF_MODEM_LIB=y
CONFIG_STDOUT_CONSOLE=y
# CONFIG_UART_INTERRUPT_DRIVEN=n
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

# Networking
CONFIG_NETWORKING=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_NATIVE=n

# Enable I2C
CONFIG_I2C=y

# Memory and stack configuration
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=1536

# GPS Antenna configuration
CONFIG_MODEM_ANTENNA=y
CONFIG_MODEM_ANTENNA_AT_COEX0="AT%XCOEX0=1,1,1565,1586"

# PDN library
CONFIG_PDN=y
CONFIG_PDN_ESM_STRERROR=y

# LTE Link Control
CONFIG_MODEM_KEY_MGMT=y
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_NETWORK_MODE_LTE_M_GPS=y
# Request eDRX from the network
CONFIG_LTE_EDRX_REQ=y
CONFIG_LTE_PSM_REQ=y
# PSM requested periodic TAU 6 hours and 40 minutes (400 minutes)
CONFIG_LTE_PSM_REQ_RPTAU="00101000"
# PSM requested active time 6 seconds
CONFIG_LTE_PSM_REQ_RAT="00000011"

# IPV4 only thanks Telstra
CONFIG_PDN_DEFAULTS_OVERRIDE=y
CONFIG_PDN_DEFAULT_FAM_IPV4=y

CONFIG_TFM_KEY_FILE_S="C:/ncs/v2.4.1/modules/tee/tf-m/trusted-firmware-m/bl2/ext/mcuboot/root-RSA-3072.pem"
CONFIG_TFM_KEY_FILE_NS="C:/ncs/v2.4.1/modules/tee/tf-m/trusted-firmware-m/bl2/ext/mcuboot/root-RSA-3072_1.pem"
CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y
CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=2048
CONFIG_DEBUG_THREAD_INFO=y
CONFIG_DEBUG_OPTIMIZATIONS=y

CONFIG_MODEM=y
CONFIG_MODEM_INFO=y
CONFIG_HTTP_PARSER_URL=y
CONFIG_HTTP_CLIENT=y

# Logging
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y
CONFIG_LOG_BACKEND_UART=n
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LTE_LINK_CONTROL_LOG_LEVEL_DBG=n
CONFIG_NET_LOG=y
CONFIG_NET_PKT_LOG_LEVEL_DBG=n
CONFIG_NET_HTTP_LOG_LEVEL_DBG=y
CONFIG_NRF_MODEM_LIB_LOG_LEVEL_DBG=y

# Date Time library
CONFIG_DATE_TIME=y

# Power management
CONFIG_PM_DEVICE=y

# Settings
CONFIG_SETTINGS=y
CONFIG_SETTINGS_RUNTIME=y

# Nordic trace
CONFIG_NRF_MODEM_LIB_TRACE=y
CONFIG_AT_HOST_LIBRARY=y #(note this is optional)
``` 

Has anyone encountered a similar issue before or can provide some guidance on how to resolve this? I appreciate any help!

Thanks in advance.

I managed to fix this by modifying the interrupt of i2c1. It’s still not clear as to why I needed to make this change.

Changed overlay:

// boards/circuitdojo_feather_nrf9160_ns.overlay
&i2c1 {
  stm32slave: stm32@2A {
        compatible = "st,stm32-slave";
        reg = <0x2A>; // I2C address of the STM32 device
        label = "STM32_AUDIO_WING";

        // Power control pin
        power-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; 
    };

  interrupts = <10>, <NRF_DEFAULT_IRQ_PRIORITY>; // Don't know why, but it works for now.
};

Think I have found the issue, looks like CONFIG_NRF_MODEM_LIB_TRACE=y wants to take over the pins and interrupt for i2c1, setting this to CONFIG_NRF_MODEM_LIB_TRACE=n and all the issues went away.

was able to remove the interrupt reassignment from the overlay and everything is working.

a month later

The root cause is the resource sharing of the nRF9160 peripherals, I2C1 and UART1, which gets enabled by the CONFIG_NRF_MODEM_LIB_TRACE. If the modem trace is required you may consider to use i2c3 in an overlay instead of i2c1.

Thanks @AchimKraus,

For future reference what I ended up doing as a quick and dirty workaround was to change the I2C number in /ncs/v2.4.x/zephyr/boards/arm/circuitdojo_feather_nrf9160/circuitdojo_feather_nrf9160_common.dts

from

&i2c1 {
	compatible = "nordic,nrf-twim";
	status = "okay";

	pinctrl-0 = <&i2c1_default>;
	pinctrl-1 = <&i2c1_sleep>;
	pinctrl-names = "default", "sleep";
	pcf85063a@51 {
		compatible = "nxp,pcf85063a";
		reg = <0x51>;
	};

	lis2dh: lis2dh@18 {
		compatible = "st,lis2dh";
		reg = <0x18>;
		irq-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
		disconnect-sdo-sa0-pull-up;
	};

};

to

&i2c2 {
	compatible = "nordic,nrf-twim";
	status = "okay";

	pinctrl-0 = <&i2c1_default>;
	pinctrl-1 = <&i2c1_sleep>;
	pinctrl-names = "default", "sleep";
	pcf85063a@51 {
		compatible = "nxp,pcf85063a";
		reg = <0x51>;
	};

	lis2dh: lis2dh@18 {
		compatible = "st,lis2dh";
		reg = <0x18>;
		irq-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
		disconnect-sdo-sa0-pull-up;
	};

};

as well as my overlay.

Yes, I was wrong.
I considered SPI2 was used for the flash, but it’s SPI3.
So I2C2 is the right one, if UART1 must be used for the modem trace.

Finally got around to playing with this. It’s a bit puzzling for sure. Working on a more elegant solution to avoid editing the common.dts file. Thanks @Yendor @AchimKraus for bringing this up.

If I enable CONFIG_NRF_MODEM_LIB_TRACE_BACKEND_UART=y looks like it resolves the issue. (Seems to happen even when not initializing I2C.) (See later posts) I disabled I2C1 just for good measure:

&i2c1 {
	status="disabled";
};

In the case you need to use I2C you can remap it as @AchimKraus had suggested but simply do it in your overlay:

your app/boards/circuitdojo_feather_nrf9160_ns.overlay

/delete-node/ &i2c1;

&i2c1 {
	compatible = "nordic,nrf-twim";
	status = "okay";

	pinctrl-0 = <&i2c1_default>;
	pinctrl-1 = <&i2c1_sleep>;
	pinctrl-names = "default", "sleep";
	pcf85063a@51 {
		compatible = "nxp,pcf85063a";
		reg = <0x51>;
	};

	lis2dh: lis2dh@18 {
		compatible = "st,lis2dh";
		reg = <0x18>;
		irq-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
		disconnect-sdo-sa0-pull-up;
	};

};

If, for some reason, you need to change your bootloader image, you can add an overlay for that as well:

your app/child_image/mucboot/boards/circuitdojo_nrf9160_feather.overlay (Note this is without the _ns suffix)

Also enabling &uart1 is not necessary according to the documentation. I did have to re-map to the TX/RX pins of the feather as well:

&uart1 {
	current-speed = <1000000>;
	pinctrl-0 = <&uart1_alt>;
	pinctrl-1 = <&uart1_sleep_alt>;
	pinctrl-names = "default", "sleep";
};

&pinctrl {
	uart1_alt: uart1_alt {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 24)>,
				<NRF_PSEL(UART_RX, 0, 23)>;
		};
	};

	uart1_sleep_alt: uart1_sleep_alt {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 24)>,
				<NRF_PSEL(UART_RX, 0, 23)>;
			low-power-enable;
		};
	};
};

This is in the overlay.

My assumption is that the standard UART driver and the modem trace library are trying to bind/register to UART1 when enabled. When you leave it disabled, the modem trace will bind and configure it no matter what. Thus the “Multiple Registrations at table_index 9 for irq 9” error

Final overlay:

/ {
	chosen {
		nordic,modem-trace-uart = &uart1;
	};
}; 

&i2c1 {
	status = "disabled";
};

&uart1 {
	current-speed = <1000000>;
	pinctrl-0 = <&uart1_alt>;
	pinctrl-1 = <&uart1_sleep_alt>;
	pinctrl-names = "default", "sleep";
};

&pinctrl {
	uart1_alt: uart1_alt {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 24)>,
				<NRF_PSEL(UART_RX, 0, 23)>;
		};
	};

	uart1_sleep_alt: uart1_sleep_alt {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 24)>,
				<NRF_PSEL(UART_RX, 0, 23)>;
			low-power-enable;
		};
	};
};

I was able to start a trace with this. The cellular monitor does not support non-Nordic boards. So I opened up a case with Nordic about it.

Hey @jaredwolff,

Firstly, thanks for all effort!

I’m trying to get a better understanding of how to implement a modem trace in my project that also uses the I2C bus. I think I’ve got it, but I just want to double-check with you.

Instead hacking the circuitdojo_feather_nrf9160_common.dts it is better to change the project board overlay to something like:

/ {
	chosen {
		nordic,modem-trace-uart = &uart1;
	};
}; 

&i2c1 {
	status = "disabled";
};

&uart1 {
	current-speed = <1000000>;
	pinctrl-0 = <&uart1_alt>;
	pinctrl-1 = <&uart1_sleep_alt>;
	pinctrl-names = "default", "sleep";
};

&pinctrl {
	uart1_alt: uart1_alt {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 24)>,
				<NRF_PSEL(UART_RX, 0, 23)>;
		};
	};

	uart1_sleep_alt: uart1_sleep_alt {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 24)>,
				<NRF_PSEL(UART_RX, 0, 23)>;
			low-power-enable;
		};
	};
};

&i2c2 {
	compatible = "nordic,nrf-twim";
	status = "okay";

	pinctrl-0 = <&i2c1_default>;
	pinctrl-1 = <&i2c1_sleep>;
	pinctrl-names = "default", "sleep";
	pcf85063a@51 {
		compatible = "nxp,pcf85063a";
		reg = <0x51>;
	};

	lis2dh: lis2dh@18 {
		compatible = "st,lis2dh";
		reg = <0x18>;
		irq-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
		disconnect-sdo-sa0-pull-up;
	};
};

Also, is it necessary to include the line /delete-node/ &i2c1;?

Apologies for the basic question. I’m still trying to wrap my head around the whole device tree concept. Any guidance would be super appreciated!

    Yendor Instead hacking the circuitdojo_feather_nrf9160_common.dts it is better to change the project board overlay to something like:

    Yes that looks great.

    Yendor Also, is it necessary to include the line /delete-node/ &i2c1;?

    Very much so. Otherwise the original i2c1 is still enabled and could cause a conflict when CONFIG_I2C=y

    Yendor Apologies for the basic question. I’m still trying to wrap my head around the whole device tree concept. Any guidance would be super appreciated!

    No worries. Hope that helps

    Terms and Conditions | Privacy Policy