Secure Fault and SPI Write Hang with UC8151D E-Paper Display on nRF5340 (peripheral_esl, SDK 3.0.2)

We are working with Nordic’s official peripheral_esl (https://github.com/NordicPlayground/nrf-esl-bluetooth/tree/main/samples/peripheral_esl)sample application for Electronic Shelf Labels (ESL), using the nRF5340DK with SDK and Toolchain version 3.0.2. Our setup targets the application core (nonsecure), and our goal is to integrate a UC8151D-based 296×128 E-Paper display connected to SPI2. The intent is for the ESL peripheral to receive image updates via Bluetooth PAwR from the central and display them on the e-paper screen.

Attempt 1: Using ssd16xx.c with mipi_dbi_spi.c (solomon,ssd1680 binding)

  • Integrated the display using the solomon,ssd1680 compatible via Zephyr’s ssd16xx.c and mipi_dbi_spi.c drivers.

  • Used SPI2 in full-duplex 8-bit mode.

  • All SPI buffers were aligned using __aligned(4) and placed in .noinit to ensure DMA-safe memory access.

  • Applied sys_cache_data_flush_range() before all chunked SPI writes.

  • Manually controlled chip select (CS) using gpio_pin_set_dt() instead of assigning .cs inside spi_config.

  • All required GPIOs (busy, dc, reset, cs) were validated and configured properly.

The secure fault was resolved by avoiding the .cs field in spi_config and managing CS through GPIO directly.

Issue: Despite successful command-only transfers, spi_write() consistently hangs when the command includes a nonzero data length (len > 0). For example:

  • ssd16xx_write_cmd(dev, 0x32, data, 30) hangs after sending the command.

  • ssd16xx_write_cmd(dev, 0x01, data, 3) hangs.

  • ssd16xx_write_cmd(dev, 0x12, NULL, 0) works as expected.

This occurs even with correct buffer alignment, SPI configuration, and GPIO toggling. The driver initialization progresses until the point where command+data SPI transfers begin.

Attempt 2: Migrated to uc81xx.c driver with ultrachip,uc8151 binding

To isolate the problem from the mipi_dbi infrastructure, we migrated to Zephyr’s native uc81xx.c driver and the ultrachip,uc8151 compatible:

  • The device is defined using DEVICE_DT_DEFINE() with correct .quirks, .profiles, and SPI configuration.

  • Used SPI_CS_GPIOS_DT_SPEC_GET(...) for defining CS and assigned .cs inside spi_cfg.

  • All GPIOs (dc, reset, busy, cs) are configured and ready.

  • The display is connected via SPI2, and the SPI configuration is consistent with the datasheet for UC8151D.

New Issue: After shifting to uc81xx.c, we encountered a secure fault during the first spi_write() call (command-only, len = 1):

This occurs even before reaching any data transfer, during the initial command send sequence in uc81xx_write_cmd().

TrustZone Configuration (SPIM2):

All required TrustZone and partition configuration steps have been applied:

  • CONFIG_TFM_NS_DEVICE_SPIM2=y is set in tfm.conf.

  • CONFIG_TFM_PERIPHERALS_DEFAULT_NS_ACCESS_LIST="SPIM2" is set in sysbuild.conf.

  • The spi2 node is marked secure = <0> in the devicetree overlay.

  • Full west build --pristine --sysbuild was performed, and both cores were flashed.

Despite this, the secure fault persists when using spi_cfg.cs, unlike in the previous setup where CS was managed manually via GPIO and .cs was left null.

We are seeking input on:

  • Correct and complete setup for allowing nonsecure access to SPIM2 with .cs used inside spi_config.

  • Whether CS GPIO control must always be done manually (i.e., not using .cs) to avoid secure faults on nRF5340.

  • Known issues or workarounds for using spi_write() from the nonsecure application core in combination with DMA and Zephyr SPI driver on this SoC.

  • Any confirmed integration examples of UC8151D or SSD1680-based e-paper displays with Zephyr on nRF5340 (especially inside peripheral_esl).

We appreciate any insights or recommendations from the community and Nordic support regarding this issue.

Thankyou

[00:00:00.572,387] <err> os: ***** SECURE FAULT *****
[00:00:00.572,631] <err> os:   Address: 0x0
[00:00:00.572,814] <err> os:   Attribution unit violation
[00:00:00.573,028] <err> os: r0/a1:  0x0002451c  r1/a2:  0x00000001  r2/a3:  0x00000001
[00:00:00.573,364] <err> os: r3/a4:  0x00000000 r12/ip:  0xffffffff r14/lr:  0x000213e9
[00:00:00.573,699] <err> os:  xpsr:  0x01000000
[00:00:00.573,913] <err> os: Faulting instruction address (r15/pc): 0x000213ba
[00:00:00.574,188] <err> os: >>> ZEPHYR FATAL ERROR 41: Unknown error on CPU 0
[00:00:00.574,493] <err> os: Current thread: 0x20012d78 (main)
[00:00:00.574,737] <err> os: Halting system

Related