Overal Goal & Problem
I'm struggling to port our nrf5 QSPI display driver to the nrf54L15's sQSPI. There is a lack of documentation and especially examples on using the nrfx sqspi driver or the high performance framework.
What I understand
There are basically 4 different ways of how to interact with the FLPR. A Zephyr core, using the high performance framework, soft peripheral using nrfx, and the MSPI shim driver that wraps the nrfx and makes it work within zephyr.
What does work
Following some other posters' leads I've managed to run the MSPI shim driver example (https://github.com/nrfconnect/sdk-nrf/tree/main/samples/zephyr/drivers/spi_flash). There is no ram chip on our board but I can see the clock during startup on my scope.
What doesn't work.
Following the soft peripheral porting guide, and starting with the spi_flash sample application I've got:
CMakeLists.txt:find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(spi_nrfx)
target_include_directories(app PRIVATE
include
${ZEPHYR_NRFXLIB_MODULE_DIR}/softperipheral/include
${ZEPHYR_NRFXLIB_MODULE_DIR}/softperipheral/sQSPI/include
${ZEPHYR_NRFXLIB_MODULE_DIR}/softperipheral/sQSPI/include/nrf54l15
${ZEPHYR_HAL_NORDIC_MODULE_DIR}/nrfx
${ZEPHYR_HAL_NORDIC_MODULE_DIR}/nrfx/drivers/include
${ZEPHYR_HAL_NORDIC_MODULE_DIR}/nrfx/mdk
)
target_sources(app PRIVATE
src/main.c
${ZEPHYR_NRFXLIB_MODULE_DIR}/softperipheral/sQSPI/src/nrf_sqspi.c
)
prj.conf:
# CONFIG_STDOUT_CONSOLE=y
CONFIG_CONSOLE=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y
CONFIG_UART_CONSOLE=n
# CONFIG_FLASH=y
CONFIG_LOG=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_DEFAULT_LEVEL=3
main.c:
#include <zephyr/kernel.h>
#include <nrf_sqspi.h>
#define SP_REGIF_BASE (NRF_SQSPI_SP_FIRMWARE_ADDR + 0x3B40)
// Initialize sQSPI with the virtual register interface placed at SP_REGIF_BASE
static nrf_sqspi_t m_sqspi = {.p_reg = (void *)SP_REGIF_BASE, .drv_inst_idx = 0};
int main(void)
{
static nrf_sqspi_cfg_t qspi_config = {
.skip_gpio_cfg = false,
.skip_pmux_cfg = false,
};
printk("Initializing sQSPI...\n");
nrfx_err_t err = nrf_sqspi_init(&m_sqspi, &qspi_config);
if (err != NRFX_SUCCESS) {
printk("nrf_sqspi_init failed: %d\n", err);
} else {
printk("nrf_sqspi_init succeeded\n");
}
while (1) {
k_msleep(1);
}
return 0;
}
include/nrfx_config.h#ifndef NRFX_CONFIG_H__
#define NRFX_CONFIG_H__
#include "softperipheral_regif.h" // To Resolve correct VPR IRQn for the SoC.
#define nrf_sqspi_irq_handler SP_VPR_IRQHandler
#define NRF_SQSPI_ENABLED (1)
#define NRF_SQSPI_MAX_NUM_DATA_LINES (4)
#define NRF_SQSPI_SP_FIRMWARE_ADDR 0x2003c000
#endif // NRFX_CONFIG_H__
boards/nrf54l15dk_nrf54l15_cpuapp_sqspi.overlay: Unchanged except the mx25r64 block commented out.
Bus Fault
When running this I get
00> Initializing sQSPI...
00> [00:00:00.001,948] <err> os: ***** BUS FAULT *****
00> [00:00:00.001,954] <err> os: Precise data bus error
00> [00:00:00.001,958] <err> os: BFAR Address: 0x5004c808
00> [00:00:00.001,968] <err> os: r0/a1: 0x2003c000 r1/a2: 0x0000e1f1 r2/a3: 0x0000e1f1
00> [00:00:00.001,974] <err> os: r3/a4: 0x2003c000 r12/ip: 0x00000000 r14/lr: 0x000008b3
00> [00:00:00.001,978] <err> os: xpsr: 0x69000000
00> [00:00:00.001,982] <err> os: Faulting instruction address (r15/pc): 0x000008b4
00> [00:00:00.001,999] <err> os: >>> ZEPHYR FATAL ERROR 25: Unknown error on CPU 0
00> [00:00:00.002,013] <err> os: Current thread: 0x20000c48 (unknown)
00> [00:00:01.152,448] <err> os: Halting system
Debugging shows this happens at the nrf_vpr_initpc_set() call in nrf_sqspi.c. the init_pc pointer is set to 0x2003C00, same as in the MSPI
Is this some RAM configuration issue? But the differences to the MSPI example are minimal.
The docs say
Your build environment must reserve the required RAM and ensure that it is readable and writable by both the application core and the FLPR core. The following table details the memory regions required for your nRF54L Series device.
The build environment described in the sQSPI application code section must comply with these requirements. This includes proper settings in linker scripts, device tree specifications (DTS), and resource allocation.
And that link just jumps back up. It's not clear to me what I need to do - is the softperipheral_ram: memory@2003c000 block in the dts no good?