Skip to main content
Visitor II
August 6, 2026
Solved

SPI clock not working on STM32MP257F-DK: CS toggles but SCK never clocks, despite firewall open and clocks running

  • August 6, 2026
  • 1 reply
  • 21 views

OpenSTLinux: Starter Package, plain image (FlashLayout_sdcard_stm32mp257f-dk-optee.tsv), version 5.0.17-openstlinux-6.6-yocto-scarthgap-mpu-v26.06.10
M33 firmware: Zephyr RTOS (4.4.99), board target stm32mp257f_dk/stm32mp257fxx/m33, loaded and started from Linux via remoteproc.

Goal: Drive a SPI device (Qorvo DW3000) from the Cortex-M33 over SPI6, which is exposed on the CN5 header (GPIO10/SPI6_MOSI = PC7, GPIO9/SPI6_MISO = PC4, GPIO11/SPI6_SCK = PF7).

When the M33 firmware performs a SPI transfer, the GPIO chip-select line toggles correctly (verified on a logic analyzer), but SCK never produces any clock pulses & the line stays flat. Consequently no data is exchanged (MOSI/MISO flat). The transfer call itself returns; it just produces no clock.

What I have already checked:

-RIFSC firewall: SPI6 shows as NSEC, NPRIV, CID filtering disabled (from the RIFSC debug dump) — i.e. not blocked/assigned exclusively to the A35.
-Clocks: clk_summary shows both ck_icn_p_spi6 (~200 MHz) and ck_ker_spi6 (~133 MHz) present.
-Linux side: SPI6 is status = "disabled" in the running device tree, so Linux is not using it. In the Zephyr device tree, SPI6 is enabled with correct pinctrl (PF7/PC4/PC7) and the generated DTB confirms clocks + pinctrl resolved.
-From the M33 I manually set SPI6EN (bit 1) in RCC_SPI6CFGR (0x4420076C); the bit reads back as set (so the M33 can write RCC), but SCK still does not toggle.
-I do not see any obvious IAC/SERC firewall error on the Linux console when the M33 runs.

On the plain STM32MP257F-DK Starter Package image, with SPI6 disabled on the Linux side and the RIFSC firewall not blocking it, what is required for the Cortex-M33 to actually drive SPI6? thank you!

Best answer by Renaatv

SOLVED:

The board's default M33 firmware (USBPD_DRP_UCSI_CM33_NonSecure_stripped.elf, which handles USB-C Power Delivery) was occupying SPI6. stopping it manually is not enough:

echo stop > /sys/class/remoteproc/remoteprocN/state

The systemd service that manages it, st-m33firmware-load.service, has auto-reload on failure. It interprets a manual stop as a crash, so it reloads and restarts the PD firmwarE, silently killing the Zephyr image a few seconds after it starts. This is mentioned briefly in the wiki: https://wiki.st.com/stm32mpu/wiki/Linux_remoteproc_framework_overview#Remote_processor_stop

Fixed by:

systemctl disable st-m33firmware-load.service

After a power cycle, SPI6 works correctly from the M33 and the spi_loopback test passes. No device tree changes, no firewall changes, and no need for the m33-examples image.
Beware: disabling that service also disables USB-C networking, since the PD firmware handles USB-C role negotiation. The usb0 interface goes to NO-CARRIER, so SSH over 192.168.7.1 stops working. Use Ethernet (end0) or the ST-LINK serial console for access instead.

Things that tested and turned out NOT to be the cause, in case it saves someone time:
RIFSC firewall: SPI6 was already unrestricted (NSEC, no CID filtering), and no IAC/SERC errors were logged
Device tree assignment: status = "disabled" on the Linux side plus an open firewall is the correct configuration for M33 use
The -m33-examples image variant: not required. The plain starter image works
Peripheral reset/missing resets property in the Zephyr DT node
Pin configuration: verified via pinconf-pins, which correctly showed PC4/PC7/PF7 in alternate 3
Hardware fault: three separate DK boards behaved identically

1 reply

RenaatvAuthorBest answer
Visitor II
August 10, 2026

SOLVED:

The board's default M33 firmware (USBPD_DRP_UCSI_CM33_NonSecure_stripped.elf, which handles USB-C Power Delivery) was occupying SPI6. stopping it manually is not enough:

echo stop > /sys/class/remoteproc/remoteprocN/state

The systemd service that manages it, st-m33firmware-load.service, has auto-reload on failure. It interprets a manual stop as a crash, so it reloads and restarts the PD firmwarE, silently killing the Zephyr image a few seconds after it starts. This is mentioned briefly in the wiki: https://wiki.st.com/stm32mpu/wiki/Linux_remoteproc_framework_overview#Remote_processor_stop

Fixed by:

systemctl disable st-m33firmware-load.service

After a power cycle, SPI6 works correctly from the M33 and the spi_loopback test passes. No device tree changes, no firewall changes, and no need for the m33-examples image.
Beware: disabling that service also disables USB-C networking, since the PD firmware handles USB-C role negotiation. The usb0 interface goes to NO-CARRIER, so SSH over 192.168.7.1 stops working. Use Ethernet (end0) or the ST-LINK serial console for access instead.

Things that tested and turned out NOT to be the cause, in case it saves someone time:
RIFSC firewall: SPI6 was already unrestricted (NSEC, no CID filtering), and no IAC/SERC errors were logged
Device tree assignment: status = "disabled" on the Linux side plus an open firewall is the correct configuration for M33 use
The -m33-examples image variant: not required. The plain starter image works
Peripheral reset/missing resets property in the Zephyr DT node
Pin configuration: verified via pinconf-pins, which correctly showed PC4/PC7/PF7 in alternate 3
Hardware fault: three separate DK boards behaved identically