This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nrf5340 qspi flash dma

Dear nordic engineers:

The only example I can find about flash is under zephyr/samples/drivers/spi_flash. However, the flash writing is pretty slow, and the MCU is halting while waiting for writing result. 

If dma buffer is available, I can send the command to write dma data to flash and do other time consuming task. The status of the flash writing can be checked in the next MCU loop.

As I understand there is no dma available in any of the zephyr flash api(flash.h). Do you have examples from nordic internal?  I found a post here https://devzone.nordicsemi.com/f/nordic-q-a/72045/flash-filing-system-for-nrf-connect-sdk  , at least someone in nordic has aware of the useful feature (in the marked answer the config file include "help
Enable support for nrfx QSPI driver with EasyDMA.") 

If there is no available example, I would like to implement it but need some guide on how to change nrf_qspi_nor.c and nrfx_qspi and make it accessible from my main.c.  Please provide some hint how I can proceed. 

  • Hi

    Normally the higher level flash driver will use the Nordic SPI drivers under the hood, and these drivers will utilize the EasyDMA controller by default. 

    In the nRF5340 there is no option to disable EasyDMA in the SPI master peripheral, and DMA will always be used. 

    Have you tried to run the flash writing from a different thread to see if it will still block the system?
    Even if the flash API is a blocking API, as long as DMA is used under the hood other threads should still be able to run. 

    Are you testing this using the external memory chip on the nRF5340DK?

    Best regards
    Torbjørn

  • Thanks for reply, can you give example on how to use different thread? I am testing with external memory chip mx25R6435 on nRF5340DK. 

  • Hi

    Making your own threads in Zephyr is very easy, and there is also a sample available here showing you how you can do it. 

    Essentially you can create a new thread with a single line of code:

    // The thread function should be void(void)
    void thread_func(void)
    {
    
    }
    
    // Make a thread with priority 5 and stacksize 512
    #define MY_THREAD_PRIORITY 5
    #define MY_THREAD_STACKSIZE 512
    K_THREAD_DEFINE(blink0_id, MY_THREAD_STACKSIZE, thread_func, NULL, NULL, NULL, MY_THREAD_PRIORITY, 0, 0);

    If you exit the thread function the thread will be disabled, so normally you would have an infinite loop in the thread function to make it run forever. 

    In order for the thread not to occupy the CPU all the time you can use a sleep function, like k_msleep(), or yield the thread by calling k_yield(), whenever you don't have anything to do in the thread.  

    Best regards
    Torbjørn

  • Hi 

    I tried to implement the thread but experience some set back. I couldn't start the thread. Would you please check my file and let me know where I do wrong. Thanks for help! 

    I use a timer to create a counter and save the number to a fifo. Then I tried to use a thread that handling the flash, in which, I plan to get the data from fifo and write to flash for every 128 samples. However, the tread is never started. 

  • Hi

    There is no need to run k_thread_start(..) manually. It will start automatically as long as you use the K_THREAD_DEFINE(..) macro. 

    I think the problem here is that you have a while(1){} loop in your main function. This will make the main thread run 100%, potentially blocking other threads from running. 

    Could you try either removing the loop (with Zephyr it is fine to exit the main() function), or adding a delay function inside the while(1) loop to allow other threads to run?

    Just changing the loop like this should be sufficient: 

    while(1) {
      k_msleep(1000);
    }

    Best regards
    Torbjørn

Related