Enabling uarte0 causes i2c0 ssd1306 driver initialization failure

I'm using zephyr with a custom board (nrf52840) which has a ssd1306 OLED. I have it configured to use i2c0 and is working fine with lvgl.

When I try to enable uart0 (using the async API), the ssd1306 device initialization fails. I can confirm that both display and uart work as expected individually. When enabled together is when this issue occurs. I have triple checked that they don't have any overlapping pin configurations.

Is there anything else I should be checking?

  • Hi,

     

    Which GPIOs are you using for I2C0?

    I have triple checked that they don't have any overlapping pin configurations.

    Have you checked that the RTS/CTS does not overlap? That is by-default P0.05 to P0.08 on the nRF52840-DK.

     

    Kind regards,

    Håkon

  • I have my own board definition. In this board, I define the following:

    &pinctrl {
    	uart0_default: uart0_default {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 1, 11)>;
    		};
    		group2 {
    			psels = <NRF_PSEL(UART_RX, 1, 12)>;
    			bias-pull-up;
    		};
    	};
    
    	uart0_sleep: uart0_sleep {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 1, 11)>,
    				<NRF_PSEL(UART_RX, 1, 12)>;
    			low-power-enable;
    		};
    	};
    
    	i2c0_default: i2c0_default {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 0, 4)>,
    				<NRF_PSEL(TWIM_SCL, 0, 5)>;
    		};
    	};
    
    	i2c0_sleep: i2c0_sleep {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 0, 4)>,
    				<NRF_PSEL(TWIM_SCL, 0, 5)>;
    			low-power-enable;
    		};
    	};
    };

    And the the ssd1306 entry:

    &i2c0 {
    	status = "okay";
    	ssd1306_128x64: ssd1306@3c {
    		compatible = "solomon,ssd1306fb";
    		reg = <0x3c>;
    		width = <128>;
    		height = <64>;
    		segment-offset = <0>;
    		page-offset = <0>;
    		display-offset = <0>;
    		multiplex-ratio = <63>;
    		segment-remap;
    		com-invdir;
    		prechargep = <0x22>;
    	};
    };

  • Can you please share the zephyr.dts file, located in build/application-name/zephyr folder?

  • The relevant sections:

    / {
    	soc {
    		uart0: uart@40002000 {
    			reg = < 0x40002000 0x1000 >;
    			interrupts = < 0x2 0x1 >;
    			compatible = "nordic,nrf-uarte";
    			status = "okay";
    			current-speed = < 0x1c200 >;
    			pinctrl-0 = < &uart0_default >;
    			pinctrl-1 = < &uart0_sleep >;
    			pinctrl-names = "default",
    			                "sleep";
    			phandle = < 0x12 >;
    		};
    
    		i2c0: i2c@40003000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40003000 0x1000 >;
    			interrupts = < 0x3 0x1 >;
    			easydma-maxcnt-bits = < 0x10 >;
    			zephyr,pm-device-runtime-auto;
    			compatible = "nordic,nrf-twi";
    			pinctrl-0 = < &i2c0_default >;
    			pinctrl-names = "default";
    			status = "okay";
    
    			ssd1306_128x64: ssd1306@3c {
    				compatible = "solomon,ssd1306fb";
    				reg = < 0x3c >;
    				width = < 0x80 >;
    				height = < 0x40 >;
    				segment-offset = < 0x0 >;
    				page-offset = < 0x0 >;
    				display-offset = < 0x0 >;
    				multiplex-ratio = < 0x3f >;
    				segment-remap;
    				com-invdir;
    				prechargep = < 0x22 >;
    			};
    		};
    	};
    };

  • Hi,

     

    Those are not the relevant parts from the file. In the future, please do not truncate information when asked for specific files (or other things, like build logs etc).

     

    The segment I am after is the pinctrl definitions, as you have used the same definition as in the board itself.

    In the board, the RTS/CTS is also defined, which are inherited when you re-use the same pinctrl names. So, if you rather make a new pinctrl definition, like this:

    &pinctrl {
    	my_uart0_default: my_uart0_default {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 1, 11)>;
    		};
    		group2 {
    			psels = <NRF_PSEL(UART_RX, 1, 12)>;
    			bias-pull-up;
    		};
    	};
    
    	my_uart0_sleep: my_uart0_sleep {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 1, 11)>,
    				<NRF_PSEL(UART_RX, 1, 12)>;
    			low-power-enable;
    		};
    	};
        ...rest of definitions
    };
    
    &uart0 {
        status = "okay";
    	pinctrl-0 = < &my_uart0_default >;
    	pinctrl-1 = < &my_uart0_sleep >;
    	pinctrl-names = "default",
    	                "sleep";
    	...rest of configuration
    };

    Does it then work?

     

    Kind regards,

    Håkon

Related