nRF5340 DK: how to access external QSPI Flash from network core?

Hi Support team,

I want to try a scenario that writes some data to external QSPI flash (mx25r6435 on the development kit) from the application core, then reads these data from the network core.
Based on the sample 'SPI Flash', the data written on the application core is successful.

But the device mx25r6435 was only defined in \zephyr\boards\arm\nrf5340dk_nrf5340\nrf5340_cpuapp_common.dtsi, seems not defined in the device tree of the network core, is it right?
How can I read/write data to the external Flash from the network core? Any guidance or samples are appreciated.

Thank you very much.

Best regards,
Yanpeng Wu

  • Hello Yanpeng,

    Are you going to run a custom application on the network core then?

    I want to try a scenario that writes some data to external QSPI flash (mx25r6435 on the development kit) from the application core, then reads these data from the network core.

    I am afraid that the requirement that you listed here is not possible. At the very least, it would be quite complicated to do.

    To access the MX25R6435 External Flash, an application needs continuous access to the device over SPI or QSPI. As the Application Core already have that access, it is not possible to share the access to the Network Core.

    Furthermore, the Network Core does not have a QSPI peripheral. It does have SPI and can control the MX25R6435 with that. However, even then, that would also require both cores to act as a SPI Master on the same SPI net.

    I understand that technically you can implement a mutex mechanism to ensure one core doesn't touch the SPI bus while the other is running. However, there are no native solution for that. As for a custom solution, because there are several layers of the Zephyr RTOS between physical hardware and the application, I believe it would be very complicated to do.

    Unless you have a very strong reason for this, I don't recommend pursuing this.

    If you can share your goal, I could help you look for an alternative.

    If you simply need to pass data from the Application Core to the Network Core, please consider using the Shared SRAM or the IPC Service instead. You can refer to: IPC service — nRF Connect SDK 2.5.0 documentation (nordicsemi.com).

    Should you try to pursue the sharing of the SPI bus, you probably also want to use the IPC Service for mutexing purpose.

    Finally, regarding this point:

    But the device mx25r6435 was only defined in \zephyr\boards\arm\nrf5340dk_nrf5340\nrf5340_cpuapp_common.dtsi, seems not defined in the device tree of the network core, is it right?

    You will need to provide a DeviceTree overlay to both core's applications. The overlay needs to add the mx25r6435 subnode to under the spi0 node in nrf5340 cpunet DeviceTree files. On the Application Core, you will also have to have GPIO forwarding to give the SPI pins that the Network Core will need for the SPI bus.

    An example of GPIO forwarding is shown where the Application Core gives 4 pins for the Network Core to use for UART purpose:

    Refer:

    Application Core GPIO Forwarder: https://github.com/nrfconnect/sdk-zephyr/blob/v3.4.99-ncs1/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common.dtsi#L113-L119

    Network Core UART0 using the forwarded pins: https://github.com/nrfconnect/sdk-zephyr/blob/main/boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet.dts#L132-L138

    Hieu

  • Hi Hieu,

    Thank you so much for the complete guidance. I'd like to introduce a little of our application. We will not use these short-range protocols (BLE, matter, etc.) on nRF53. In our case, the applications on two cores are separated:
    1. The application core will be used to collect monitoring data from sensors with a resolution of 1 data record per minute for example.
    2. the network core will use LTE to report these monitoring data to the third party per week.
    Power optimization is a key feature, so the net-core will be in deep sleep mode most time, and only be awake once a week, so there is no frequent resource concurrent between two cores.

    Seems there are several potential methods for this purpose:
    (1) Using external flash to exchange the mass data, app-core writes data and wakes up the net-core to read and report data when needed, with a mechanism to synchronize the access of the external flash.
    (2) Storing the monitoring data in the external flash, and app-core using IPC to exchange the mass data after waking up the net-core.
    (3) Storing the monitoring data in the external flash, and app-core uses the-shared-SRAM to load and exchange the mass data after waking up the net-core.

    Could you give some suggestions for the most feasible solution for my purpose from the performance and the effort of implementation? Appreciate your analysis and guidance.

    Best regards,
    Yanpeng

  • Hi Yanpeng,

    Yanpengwu said:
    Could you give some suggestions for the most feasible solution for my purpose from the performance and the effort of implementation? Appreciate your analysis and guidance.

    Sure, I take it we are only talking about transferring data from the application core to the network core here. I won't comment about implementing a custom image for the network core or running LTE on it though.

    Yanpengwu said:
    (2) Storing the monitoring data in the external flash, and app-core using IPC to exchange the mass data after waking up the net-core.

    This is feasible, and there is already a sample setup, linked in my previous reply.

    Please give the sample a try to see if the transfer speed is good enough for you.

    Yanpengwu said:
    (3) Storing the monitoring data in the external flash, and app-core uses the-shared-SRAM to load and exchange the mass data after waking up the net-core.

    This could provide better performance and power saving, since writing to RAM might be faster than an IPC transfer.

    You probably will still need to use IPC to wake up the network core from the application core. Although I imagine the two cores can also wake the other up with a pair of GPIO lines.

    Depends on the person, this might be a more or less complicated solution than the pure IPC one.

    There is a previous case on DevZone about it with some code shared for you to have a starting point:  How to allocate shared SRAM on the nrf5340.

    The Peripheral CPU DFU library also uses this approach in its implementation if you would like to refer to it.

    Yanpengwu said:
    (1) Using external flash to exchange the mass data, app-core writes data and wakes up the net-core to read and report data when needed, with a mechanism to synchronize the access of the external flash.

    I am not certain that you can guarantee absolute device usage exclusivity. Refer to this case:  How to put NET core into and out from SLEEP (or DEEP-SLEEP) mode in nRF530 Chip from APP core? .

    I put some thoughts about possible approaches, but overall I recommend against this option.

    In my previous reply, I mentioned the option of adding a mutex implementation to existing External Flash and SPI driver in the Zephyr RTOS. This would likely require some additional hardware work as well.

    There is technically another option, which is to use the nrfx driver directly. With that, you can ensure a core completely releases the bus before the other takes over.
    However, this requires you to implement the External Flash functionality on your own.

    In conclusion, it is feasible, but for the use case, there is no benefit over the other options, while there is too much cost.

    Best regards,

    Hieu

  • Hi Hieu,

    Thank you very much for the complete analysis and great guidance, and these references. I will try the feasible solutions and evaluate them.
    Thank you so much.

    Best regards,
    Yanpeng

  • Hi Yanpeng,

    I'm happy to help. Please feel free to follow-up, or close this ticket when you think everything has been resolved.

    Best regards,

    Hieu

Related