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?

Parents
  • 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>;
    	};
    };

  • Like I said, I'm defining my own board, so there isn't anything to inherit from.

    Here is my pinctrl definitions:

    / {
    	pinctrl: pin-controller {
    		uart0_default: uart0_default {
    			phandle = < 0x2 >;
    			group1 {
    				psels = < 0x2b >;
    			};
    			group2 {
    				psels = < 0x100002c >;
    				bias-pull-up;
    			};
    		};
    
    		uart0_sleep: uart0_sleep {
    			phandle = < 0x3 >;
    			group1 {
    				psels = < 0x2b >,
    				        < 0x100002c >;
    				low-power-enable;
    			};
    		};
    
    		i2c0_default: i2c0_default {
    			phandle = < 0x4 >;
    			group1 {
    				psels = < 0xc000004 >,
    				        < 0xb000005 >;
    			};
    		};
    
    		i2c0_sleep: i2c0_sleep {
    			group1 {
    				psels = < 0xc000004 >,
    				        < 0xb000005 >;
    				low-power-enable;
    			};
    		};
    	};
    };

  • Hi,

     

    Your custom board has external pull resistors on SDA/SCL? What is the speed? If using 400 kHz mode, you will need strong pulls, in the order of < 5kOhm. I suggest that you scope your pins on both scenarios, share run time logs of both working and non-working scenarios.

     

    Kind regards,

    Håkon

  • I have 4.7K external pull-ups on SCL and SDA lines. The clock speed was unset till now, but setting it to 100 kHZ (with `clock-frequency = <I2C_BITRATE_STANDARD>;` in the i2c0 node) has no effect.

    I can post scope screenshots and logs tomorrow when I get back to my desk.
    But I'm curious to understand your reasoning... Since i2c0 works if I disable uart0, I'd expect the issue to have something to the way they interact with each other. If it were a physical issue, that would still be the case with i2c0 alone no?
  • Hi,

     

    On the nRF52-series devices, the UART is not a shared resource, which it is on the nRF53-series and on-ward.

    This means that TWIM0 and UARTE0 can be used simultaneously without any issues, provided that they do not create a pin conflict for each other. Ie. there is no reason why these two peripherals cannot coexist on the nRF52840.

     

    sidcha said:
    I can post scope screenshots and logs tomorrow when I get back to my desk.

    perfect, this would be great.

     

    Kind regards,

    Håkon

  • Thanks for the response. I'm aware that those peripherals are non-shared. I was wondering if anything else was shared, such as IRQs, DMAs etc.,

    Here is a scope capture of the failure:

    I found Zephyr tries to send a single 0 byte to the OLED at address 0x3c. This can be seen in the capture as well.

Reply Children
  • Hi,

     

    There is no direct error in the image that you show. The sensor ACK, by keeping the line low at the LSBit.

    Do you have any runtime logs or similar? What happens in a normal scenario?

    Is this the very first transaction, or is it in the middle of the init? There is so much information that is not presented here. You need to provide traces/logs from boot-up.

     

    sidcha said:
    I was wondering if anything else was shared, such as IRQs, DMAs etc.,

    No, they are not shared between TWIM0 and UARTE0 on the nRF52840.

     

    Kind regards,

    Håkon

Related