SSD1306 OLED display fails for nRF52840 boards using nRF Connect SDK 3.2.1

Hello,

I’ve been using SSD1306 128x64 OLED displays with nRF52840 boards for several years without any issues, building with nRF Connect SDK 2.5.x to 3.1.0. Recently, I've been attempting to move existing NCS 3.1.0 projects over to NCS 3.2.1. However, I’m unable to successfully get the SSD1306 OLED display to work with any of the nRF52840 boards using the latest nRF Connect SDK 3.2.1.

All the nRF52840 boards with SSD1306 display work fine when built with vanilla Zephyr 4.1.x and 4.2.x.

Also, the target for thingy53/nrf5340/cpuapp/ns failed to run successfully with both NCS 3.1.0 and NCS 3.2.1. The target thingy53/nrf5340/cpuapp ran fine with the SSD1306 OLED.

To try to isolate the issue, I’ve taken the Zephyr sample, “/opt/nordic/ncs/v3.2.1/zephyr/samples/subsys/display/cfb_custom_font” and built it for a couple of different nRF52840 boards (e.g. particle_xenon_nrf52840, promicro_nrf52840) plus thingy/nrf5340/cpuapp.

Built exactly the same sample "cfb_custom_font" main.c (modified to display board target and Zephyr version) & used the same devicetree overlays. All the builds compiled and linked without any issues.  However, only particle_xenon/nrf52840 using NCS 3.1.0 and thingy53/nrf5340/cpuapp using NCS 3.2.1 ran successfully with the SSD1306 displays.

I used the below board configuration and the overlays with the ssd1306 devicetree included in the I2C sections of the overlays. Default sysbuild option used from with the nRF Connect SDKs.

I don't see anything that is obvious that may be wrong. I would appreciate if you could determine the cause of the issue with the nRF52840 boards with SSD1306 when using  nRF Connect SDK 3.2.1.

Also, Is there any reason as to why the target for thingy53/nrf5340/ns doesn’t run successfully with the I2C SSD1306 display?

Thank you.

particle_xenon_nrf52840.overlay:

/ {
	chosen {
		zephyr,display = &ssd1306;
		zephyr,console = &uart0;
		zephyr,shell-uart = &uart0;
	};
};

&uart0 {
	compatible = "nordic,nrf-uarte";
	status = "okay";
	current-speed = <115200>;
	pinctrl-0 = <&uart0_default>;
	pinctrl-1 = <&uart0_sleep>;
	pinctrl-names = "default", "sleep";
};

&gpio0{
	status = "okay";
};

&i2c0 {
	compatible = "nordic,nrf-twi";
	status = "okay";
	pinctrl-0 = <&i2c0_default>;
	pinctrl-1 = <&i2c0_sleep>;
    pinctrl-names = "default", "sleep";
	ssd1306: 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>;
	};
};

thingy53_nrf5340_cpuapp.overlay

/ {
	chosen {
		zephyr,display = &ssd1306;
	};
};

&pinctrl {
	i2c0_default: i2c0_default {
		group1 {
			psels = <NRF_PSEL(TWIM_SDA, 0, 5)>,
				<NRF_PSEL(TWIM_SCL, 0, 4)>;
		};
	};

	i2c0_sleep: i2c0_sleep {
		group1 {
			psels = <NRF_PSEL(TWIM_SDA, 0, 5)>,
				<NRF_PSEL(TWIM_SCL, 0, 4)>;
		};
	};
};

&i2c0 {
	compatible = "nordic,nrf-twim";
	status = "okay";
	clock-frequency = <I2C_BITRATE_FAST>;
	zephyr,concat-buf-size = <4096>;
	pinctrl-0 = <&i2c0_default>;
	pinctrl-1 = <&i2c0_sleep>;
    pinctrl-names = "default", "sleep";
	ssd1306: 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>;
	};
};

prj.conf:

CONFIG_HEAP_MEM_POOL_SIZE=16384

CONFIG_DISPLAY=y
CONFIG_SSD1306=y

CONFIG_CHARACTER_FRAMEBUFFER=y
CONFIG_CHARACTER_FRAMEBUFFER_USE_DEFAULT_FONTS=n

CONFIG_LOG=y

# Preferred SHELL options
CONFIG_SHELL=y
CONFIG_DEVICE_SHELL=y
CONFIG_INIT_STACKS=y
CONFIG_KERNEL_SHELL=y
CONFIG_SHELL_STATS=n
CONFIG_I2C_SHELL=y

# Enable RTT to replace UART
CONFIG_UART_CONSOLE=y
CONFIG_USE_SEGGER_RTT=n
CONFIG_SHELL_BACKEND_RTT=n

CONFIG_LOG_BACKEND_UART=y
CONFIG_SHELL_LOG_BACKEND=y

Console Output 

NCS 3.2.1 build  - particle_xenon_nrf52840 with  SSD1306 (particle_xenon/nrf52840):

*** Booting nRF Connect SDK v3.2.1-d8887f6f32df ***
*** Using Zephyr OS v4.2.99-ec78104f1569 ***

Display device not ready

Failed to turn off display blanking

NCS 3.1.0 build  - particle_xenon_nrf52840 with  SSD1306 (particle_xenon/nrf52840):

*** Booting nRF Connect SDK v3.1.0-6c6e5b32496e ***
*** Using Zephyr OS v4.1.99-1612683d4010 ***
Zephyr v4.1.99
Board target: particle_xenon/nrf52840

NCS 3.2.1 build  - thingy53_nrf5340_cpuapp with  SSD1306:

*** Booting nRF Connect SDK v3.2.1-d8887f6f32df ***
*** Using Zephyr OS v4.2.99-ec78104f1569 ***
[00:00:00.035,614] <inf> udc_nrf: Initialized
Zephyr v4.2.99
Board target: thingy53/nrf5340/cpuapp

NCS 3.1.0 build  - thingy53_nrf5340_cpuapp with  SSD1306:

[Disconnected]
[Connected]
*** Booting nRF Connect SDK v3.1.0-6c6e5b32496e ***
*** Using Zephyr OS v4.1.99-1612683d4010 ***
Zephyr v4.1.99
Board target: thingy53/nrf5340/cpuapp

Vanilla Zephyr 4.2.x from terminal command line: SSD1306 displays works fine.

*** Booting Zephyr OS build v4.2.0-717-g85e135362445 ***
Zephyr v4.2.99
Board target: particle_xenon/nrf52840
uart:~$ 

  • Hi Vidar,

    Yes, I've been attempting to get a successful run for the thingy53/nrf5340/cpuapp/ns target with the same pins and driver.

    I've tried to debug with Segger's Edu Mini probe and also the nrf54l15dk debug with Thingy53, with debug info to RTT. In both cases, I never get to a point where there is any output to RTT. Weird! 

    I'll dig further tomorrow.

    The same application for nrf54l15dk/nrf54l15/ns works fine. It seems Nordic is deprecating thingy53/nrf5340/cpuapp/ns. I've had TFM overflows by 200%! with Thing53 on another project (still debugging)  although it has 64MB external RAM and I've used successfully used the Thingy53 external FLASH before quite a few times.


    Best Regards,
    Ravi

  • Hi Ravi,

    zpm1066 said:
    I've tried to debug with Segger's Edu Mini probe and also the nrf54l15dk debug with Thingy53, with debug info to RTT. In both cases, I never get to a point where there is any output to RTT. Weird! 

    This suggests that there may be an error occurring during startup before the logger is available. To troubleshoot this further I would disable the CONFIG_RESET_ON_FATAL_ERROR symbol in the project configuration and attach the debugger to see if the program entered the error handler.

    zpm1066 said:
    It seems Nordic is deprecating thingy53/nrf5340/cpuapp/ns

    The Zephyr Bluetooth Host switched to using PSA Crypto instead having crypto support from tinycrypt built into the stack. For /ns targets  this requires building TF-M with these crypto services enabled, which significantly increases its memory footprint compared to the minimal TF-M builds used previously. The Thingy53 board uses static memory partitions that do not allocate sufficient memory to the secure region. For this reason, we have removed this board target from the BLE samples.

    Best regards,

    Vidar

  • Hi Vidar,

    I'll try your suggestion of disabling CONFIG_RESET_ON_FATAL_ERROR for the Thingy53 debugging. I'll sync up with you on the findings.

    For thingy53/nrf5340/ns targets where the TF-M overflows FLASH significantly, can we not use the external FLASH?


    Best Regards,
    Ravi

  • Hi Vidar,

    I tried the following.

    • Added CONFIG_RESET_ON_FATAL_ERROR=n to prj.conf
    • Built a debug version of  thingy53/nrf5340/cpuapp/ns target

    • Got build errors with TFM FLASH overflow


    /nordic/ncs/v3.2.1/nrfxlib/crypto/nrf_oberon/lib/cortex-m33/soft-float/liboberon_3.0.17.a && :
    /opt/nordic/ncs/toolchains/322ac893fe/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld: address 0x1c300 of bin/tfm_s.axf section `.TFM_UNPRIV_CODE' is not within region `FLASH'
    /opt/nordic/ncs/toolchains/322ac893fe/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld: address 0x1fc40 of bin/tfm_s.axf section `.gnu.sgstubs' is not within region `FLASH'
    /opt/nordic/ncs/toolchains/322ac893fe/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld: bin/tfm_s.axf section `.TFM_DATA' will not fit in region `FLASH'
    /opt/nordic/ncs/toolchains/322ac893fe/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld: address 0x1c300 of bin/tfm_s.axf section `.TFM_UNPRIV_CODE' is not within region `FLASH'
    /opt/nordic/ncs/toolchains/322ac893fe/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld: address 0x1fc40 of bin/tfm_s.axf section `.gnu.sgstubs' is not within region `FLASH'
    /opt/nordic/ncs/toolchains/322ac893fe/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld: region `FLASH' overflowed by 15856 bytes
    Memory region         Used Size  Region Size  %age Used
               FLASH:       64496 B      48640 B    132.60%
                 RAM:       14560 B        32 KB     44.43%
    collect2: error: ld returned 1 exit status
    ninja: build stopped: subcommand failed.

    CONFIG_PM_PARTITION_SIZE_TFM suggests TFM FLASH size can be increased.

    • Resolved TFM overflow by disabling TFM logging and increased TFM partition size to 256kB (0x40000)

    CONFIG_TFM_PROFILE_TYPE_MINIMAL=n
    CONFIG_TFM_LOG_LEVEL_SILENCE=y
    CONFIG_PM_PARTITION_SIZE_TFM=0x40000


    • Build was successful. 
    • Disabling TFM logging was enough to prevent TFM FLASH overflow in this "cfb" sample
    • However, the TFM partition size remained the same.
    • Why hasn’t the FLASH region size changed to 320KB (0x40000) as per link above? Thanks.


    RTT output:

    SEGGER J-Link V8.96 - Real time terminal output
    SEGGER J-Link (unknown) V1.0, SN=<xxxxxxxxxxxx>
    Process: JLinkExe
    
    rtt:~$ Initialized ssd1306@3c
    font width 10, font height 16
    font width 15, font height 24
    font width 20, font height 32
    x_res 128, y_res 64, ppt 8, rows 8, cols 128
    [00:00:00.001,617] <inf> udc_nrf: Preinit
    *** Booting nRF Connect SDK v3.2.1-d8887f6f32df ***
    *** Using Zephyr OS v4.2.99-ec78104f1569 ***
    [00:00:00.012,725] <inf> udc_nrf: Initialized
    Zephyr v4.2.99
    Board target: thingy53/nrf5340/cpuapp/ns
    [00:00:00.013,153] <dbg> cfb: cfb_framebuffer_init: number of fonts 3
    [00:00:00.016,937] <inf> udc_nrf: SUSPEND state detected
    [00:00:00.115,203] <inf> udc_nrf: Reset
    [00:00:00.115,264] <inf> udc: ep 0x80 is not halted|disabled
    [00:00:00.115,295] <inf> udc_nrf: RESUMING from suspend

    The sample "cfb" for NS build runs successfully.  However, for a typical NS application with BT, the TFM size would be greater than the default ~47.5KB.

    How do I configure CONFIG_PM_PARTITION_SIZE_TFM correctly? Thank you.


    Best Regards,
    Ravi

  • Hi Ravi,

    The thingy53 board includes a static memory partition file to ensure consistent memory layout for all samples built for this board and keep compatibility with the version of the bootloader that comes pre-programmed on the board. But when you have an external debugger you can safely change the memory layout without worrying about bricking the device.

    zpm1066 said:
    How do I configure CONFIG_PM_PARTITION_SIZE_TFM correctly? Thank you.

    The static partitioning file takes precedence. If you want to allow dynamic allocation, you need to remove this partitioning file from the board directory: https://github.com/nrfconnect/sdk-zephyr/blob/ncs-v3.2.1/boards/nordic/thingy53/pm_static_thingy53_nrf5340_cpuapp_ns.yml 

    Best regards,

    Vidar

Related