Need clarification over QSPI driver for NRF54L15

Hello everyone,
I need to attach a QSPI memory to an NRF54L15 module. I am led to believe that this should be supported out of the box but cannot understand how to use the provided drivers.
The IC I'm going to use is an IS25WP016D, but for now I'd be happy to see an example working for the mx25r6435f that should be present in the NRF54L15-DK I'm experimenting on.

For starters, the datasheet does not mention a QSPI peripheral except for the pins function table. I have found an example under `zephyr/samples/drivers/spi_flash` that doesn't work because I can't construct the device tree `qspi` node for this reason.
I have also found the JESD216 example under `nrf/samples/zephyr/drivers/jesd216` but that doesn't work either, complaining the lack of a `jesd216.h` header.

For reference, I've been following the discussion here and here to get started.

Can anyone give me some pointers?

Parents
  • Hi,

    It is correct that the nRF54L15 does not have it's own physical dedicated QSPI peripheral as the datasheet states. But it does however support a SoftPeripheral for the Fast Lightweight Peripheral Processor (FLPR) which can be configured as a sQSPI (software based QSPI). https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/nrf54l-series-fourth-package-now-in-production-with-more-coming#mcetoc_1irrtbppg6  

    See https://docs.nordicsemi.com/bundle/ncs-latest/page/nrfxlib/softperipheral/doc/sQSPI/README.html and https://docs.nordicsemi.com/bundle/ncs-latest/page/nrfxlib/softperipheral/doc/sQSPI/nrf54L15_porting_v1_1_0.html 

    Kind regards,
    Andreas

  • Thank you for the clarification.
    I am trying to define an `sqspi` node by looking at the example under `nrf/samples/zephyr/drivers/spi_flash` but when I try to fetch a device reference (`    const struct device *flash_dev = DEVICE_DT_GET_ONE(SPI_FLASH_COMPAT);`) the compilation fails at the linking stage, complaining of an undefined reference to `__device_dts_ord_61'.

    I then figured I should add the `CONFIG_FLAG` option to `prj.conf`, but that alone gives a different error about another missing identifier:

    In file included from /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/toolchain.h:50,
                     from /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/sys/__assert.h:11,
                     from /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/drivers/mspi.h:19,
                     from /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:9:
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c: In function 'dev_init':
    /home/maldus/Projects/Treedom/dive-computer/build/dive-computer/zephyr/include/generated/zephyr/devicetree_generated.h:16511:48: error: 'DT_N_S_soc_S_peripheral_50000000_S_vpr_4c000_IRQ_IDX_0_VAL_priority' undeclared (first use in this f
    unction); did you mean 'DT_N_S_soc_S_peripheral_50000000_S_spi_4a000_IRQ_IDX_0_VAL_priority'?
    16511 | #define DT_N_NODELABEL_cpuflpr_vpr             DT_N_S_soc_S_peripheral_50000000_S_vpr_4c000
          |                                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/toolchain/gcc.h:87:52: note: in definition of macro 'BUILD_ASSERT'
       87 | #define BUILD_ASSERT(EXPR, MSG...) _Static_assert((EXPR), "" MSG)
          |                                                    ^~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/arch/arm/irq.h:120:9: note: in expansion of macro '_CHECK_PRIO'
      120 |         _CHECK_PRIO(priority_p, flags_p) \
          |         ^~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/irq.h:49:9: note: in expansion of macro 'ARCH_IRQ_CONNECT'
       49 |         ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p)
          |         ^~~~~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:514:9: note: in expansion of macro 'IRQ_CONNECT'
      514 |         IRQ_CONNECT(DT_IRQN(VPR_NODE), DT_IRQ(VPR_NODE, priority),
          |         ^~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:2669:9: note: in expansion of macro 'DT_CAT5'
     2669 |         DT_CAT5(node_id, _IRQ_IDX_, idx, _VAL_, cell)
          |         ^~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:2696:31: note: in expansion of macro 'DT_IRQ_BY_IDX'
     2696 | #define DT_IRQ(node_id, cell) DT_IRQ_BY_IDX(node_id, 0, cell)
          |                               ^~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:514:40: note: in expansion of macro 'DT_IRQ'
      514 |         IRQ_CONNECT(DT_IRQN(VPR_NODE), DT_IRQ(VPR_NODE, priority),
          |                                        ^~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:5229:24: note: in expansion of macro 'DT_N_NODELABEL_cpuflpr_vpr'
     5229 | #define DT_CAT(a1, a2) a1 ## a2
          |                        ^~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:196:29: note: in expansion of macro 'DT_CAT'
      196 | #define DT_NODELABEL(label) DT_CAT(DT_N_NODELABEL_, label)
          |                             ^~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:30:18: note: in expansion of macro 'DT_NODELABEL'
       30 | #define VPR_NODE DT_NODELABEL(cpuflpr_vpr)
          |                  ^~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:514:47: note: in expansion of macro 'VPR_NODE'
      514 |         IRQ_CONNECT(DT_IRQN(VPR_NODE), DT_IRQ(VPR_NODE, priority),
          |                                               ^~~~~~~~
    /home/maldus/Projects/Treedom/dive-computer/build/dive-computer/zephyr/include/generated/zephyr/devicetree_generated.h:16511:48: note: each undeclared identifier is reported only once for each function it appears in
    16511 | #define DT_N_NODELABEL_cpuflpr_vpr             DT_N_S_soc_S_peripheral_50000000_S_vpr_4c000
          |                                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/toolchain/gcc.h:87:52: note: in definition of macro 'BUILD_ASSERT'
       87 | #define BUILD_ASSERT(EXPR, MSG...) _Static_assert((EXPR), "" MSG)
          |                                                    ^~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/arch/arm/irq.h:120:9: note: in expansion of macro '_CHECK_PRIO'
      120 |         _CHECK_PRIO(priority_p, flags_p) \
          |         ^~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/irq.h:49:9: note: in expansion of macro 'ARCH_IRQ_CONNECT'
       49 |         ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p)
          |         ^~~~~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:514:9: note: in expansion of macro 'IRQ_CONNECT'
      514 |         IRQ_CONNECT(DT_IRQN(VPR_NODE), DT_IRQ(VPR_NODE, priority),
          |         ^~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:2669:9: note: in expansion of macro 'DT_CAT5'
     2669 |         DT_CAT5(node_id, _IRQ_IDX_, idx, _VAL_, cell)
          |         ^~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:2696:31: note: in expansion of macro 'DT_IRQ_BY_IDX'
     2696 | #define DT_IRQ(node_id, cell) DT_IRQ_BY_IDX(node_id, 0, cell)
          |                               ^~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:514:40: note: in expansion of macro 'DT_IRQ'
      514 |         IRQ_CONNECT(DT_IRQN(VPR_NODE), DT_IRQ(VPR_NODE, priority),
          |                                        ^~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:5229:24: note: in expansion of macro 'DT_N_NODELABEL_cpuflpr_vpr'
     5229 | #define DT_CAT(a1, a2) a1 ## a2
          |                        ^~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:196:29: note: in expansion of macro 'DT_CAT'
      196 | #define DT_NODELABEL(label) DT_CAT(DT_N_NODELABEL_, label)
          |                             ^~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:30:18: note: in expansion of macro 'DT_NODELABEL'
       30 | #define VPR_NODE DT_NODELABEL(cpuflpr_vpr)
          |                  ^~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:514:47: note: in expansion of macro 'VPR_NODE'
      514 |         IRQ_CONNECT(DT_IRQN(VPR_NODE), DT_IRQ(VPR_NODE, priority),
          |                                               ^~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/toolchain/gcc.h:87:51: error: expression in static assertion is not an integer
       87 | #define BUILD_ASSERT(EXPR, MSG...) _Static_assert((EXPR), "" MSG)
          |                                                   ^
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/arch/arm/irq.h:97:9: note: in expansion of macro 'BUILD_ASSERT'
       97 |         BUILD_ASSERT(((flags_p & IRQ_ZERO_LATENCY) && \
          |         ^~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/arch/arm/irq.h:120:9: note: in expansion of macro '_CHECK_PRIO'
      120 |         _CHECK_PRIO(priority_p, flags_p) \
          |         ^~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/irq.h:49:9: note: in expansion of macro 'ARCH_IRQ_CONNECT'
       49 |         ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p)
          |         ^~~~~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:514:9: note: in expansion of macro 'IRQ_CONNECT'
      514 |         IRQ_CONNECT(DT_IRQN(VPR_NODE), DT_IRQ(VPR_NODE, priority),
          |         ^~~~~~~~~~~
    In file included from /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/arch/arm/irq.h:19,
                     from /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/arch/arm/arch.h:24,
                     from /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/arch/cpu.h:19,
                     from /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/kernel_includes.h:36,
                     from /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/kernel.h:17,
                     from /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/drivers/mspi.h:21:
    /home/maldus/Projects/Treedom/dive-computer/build/dive-computer/zephyr/include/generated/zephyr/devicetree_generated.h:16511:48: error: 'DT_N_S_soc_S_peripheral_50000000_S_vpr_4c000_IRQ_IDX_0_VAL_irq' undeclared (first use in this functi
    on); did you mean 'DT_N_S_soc_S_peripheral_50000000_S_spi_4a000_IRQ_IDX_0_VAL_irq'?
    16511 | #define DT_N_NODELABEL_cpuflpr_vpr             DT_N_S_soc_S_peripheral_50000000_S_vpr_4c000
          |                                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/sw_isr_table.h:276:26: note: in definition of macro 'Z_ISR_DECLARE'
      276 |                         {irq, flags, (void *)&func, (const void *)param}
          |                          ^~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/irq.h:49:9: note: in expansion of macro 'ARCH_IRQ_CONNECT'
       49 |         ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p)
          |         ^~~~~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:514:9: note: in expansion of macro 'IRQ_CONNECT'
      514 |         IRQ_CONNECT(DT_IRQN(VPR_NODE), DT_IRQ(VPR_NODE, priority),
          |         ^~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/sys/util_internal.h:69:53: note: in expansion of macro '__DEBRACKET'
       69 | #define __GET_ARG2_DEBRACKET(ignore_this, val, ...) __DEBRACKET val
          |                                                     ^~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/sys/util_internal.h:64:9: note: in expansion of macro '__GET_ARG2_DEBRACKET'
       64 |         __GET_ARG2_DEBRACKET(one_or_two_args _if_code, _else_code)
          |         ^~~~~~~~~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/sys/util_internal.h:59:9: note: in expansion of macro '__COND_CODE'
       59 |         __COND_CODE(_XXXX##_flag, _if_1_code, _else_code)
          |         ^~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/sys/util_macro.h:196:9: note: in expansion of macro 'Z_COND_CODE_1'
      196 |         Z_COND_CODE_1(_flag, _if_1_code, _else_code)
          |         ^~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:2870:9: note: in expansion of macro 'COND_CODE_1'
     2870 |         COND_CODE_1(IS_ENABLED(CONFIG_MULTI_LEVEL_INTERRUPTS),                                     \
          |         ^~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:2669:9: note: in expansion of macro 'DT_CAT5'
     2669 |         DT_CAT5(node_id, _IRQ_IDX_, idx, _VAL_, cell)
          |         ^~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:2872:22: note: in expansion of macro 'DT_IRQ_BY_IDX'
     2872 |                     (DT_IRQ_BY_IDX(node_id, idx, irq)))
          |                      ^~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:2884:26: note: in expansion of macro 'DT_IRQN_BY_IDX'
     2884 | #define DT_IRQN(node_id) DT_IRQN_BY_IDX(node_id, 0)
          |                          ^~~~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:514:21: note: in expansion of macro 'DT_IRQN'
      514 |         IRQ_CONNECT(DT_IRQN(VPR_NODE), DT_IRQ(VPR_NODE, priority),
          |                     ^~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:5229:24: note: in expansion of macro 'DT_N_NODELABEL_cpuflpr_vpr'
     5229 | #define DT_CAT(a1, a2) a1 ## a2
          |                        ^~
    /home/maldus/Source/sdk-nrf/v3.0.0/zephyr/include/zephyr/devicetree.h:196:29: note: in expansion of macro 'DT_CAT'
      196 | #define DT_NODELABEL(label) DT_CAT(DT_N_NODELABEL_, label)
          |                             ^~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:30:18: note: in expansion of macro 'DT_NODELABEL'
       30 | #define VPR_NODE DT_NODELABEL(cpuflpr_vpr)
          |                  ^~~~~~~~~~~~
    /home/maldus/Source/sdk-nrf/v3.0.0/nrf/drivers/mspi/mspi_sqspi.c:514:29: note: in expansion of macro 'VPR_NODE'
      514 |         IRQ_CONNECT(DT_IRQN(VPR_NODE), DT_IRQ(VPR_NODE, priority),
          |                             ^~~~~~~~
    


    I understand the FLPR core is a RISC-V coprocessor in the NRF54l15, but I don't understand if I need to build and entirely different application for it to emulate QSPI. Could you give me some pointers in that regard as well?

  • Could you go to the build folder for the image that thros the undefined reference and find which device it is that it complains about? I.e \build\<your_app>\zephyr\include\generated\zephyr\devicetree_generated.h and go to the device corresponding to dts_ord_61

    Since the SQSPI is relatively new (for those of us who are not the author of the peripheral), this is unfortunately where my current knowledge stops. But I will spend some time next week trying to use this peripheral with some input from the authors of that sample. I suspect it may be due to either the undefined reference or due to a misconfiguration between the sqspi and the spi_flash device your trying to connect it to. 

    I'll get back to you when I've looked more into it and please feel free to update me if you resolve it before I get back to you

    Kind regards,
    Andreas

  • Thank you for the follow up on this issue.
    Does this mean that the nrf54l15 is unable to connect to a QSPI memory natively? Or is it possible to do so with sQSPI without relying on the JEDEC216 protocol?

Reply Children
Related