This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Nordic SDK QSPI driver call

Hi all,

             We had implemented Nordic QSPI using "nrf_drv_qspi_write" and "nrf_drv_qspi_read" operation , however I am seeing for page to write in flash of 4096 bytes with 512 bytes of QSPI write size limitation its taking 8.6 milli sec , when many streams (sensor data at stretch to be written into system) streams are getting hanged when flash logging is enabled .

So, wanted to check basic operations "nrf_drv_qspi_write" and "nrf_drv_qspi_read" if it blocks other sensor operations to process data ? Is it blocking call? If so how do we configure into dma mode?

Please help

Parents
  • What's the write speed of the flash?

    The read and write functions are blocking or non-blocking depending on whether you supplied an event handler to nrfx_qspi_init or not. 

  • Hi ,

             Please find the driver code init.

    #define QSPI_NAND_FLASH_CONFIG                                        \
    {                                                                       \
        .xip_offset  = 0,                         \
        .pins = {                                                           \
           .sck_pin     = QSPI_NAND_FLASH_SCK_PIN,                                \
           .csn_pin     = QSPI_NAND_FLASH_CSN_PIN,                                \
           .io0_pin     = QSPI_NAND_FLASH_IO0_PIN,                                \
           .io1_pin     = QSPI_NAND_FLASH_IO1_PIN,                                \
           .io2_pin     = QSPI_NAND_FLASH_IO2_PIN,                                \
           .io3_pin     = QSPI_NAND_FLASH_IO3_PIN,                                \
        },                                                                  \
        .irq_priority   = (uint8_t)NRFX_QSPI_CONFIG_IRQ_PRIORITY,           \
        .prot_if = {                                                        \
            .readoc     = QSPI_IFCONFIG0_READOC_READ4O,       \
            .writeoc    = QSPI_IFCONFIG0_WRITEOC_PP4O,     \
            .addrmode   = (nrf_qspi_addrmode_t)NRFX_QSPI_CONFIG_ADDRMODE,   \
            .dpmconfig  = false,                                            \
        },                                                                  \
        .phy_if = {                                                         \
            .sck_freq   = NRF_QSPI_FREQ_32MDIV1, \
            .sck_delay  = (uint8_t)NRFX_QSPI_CONFIG_SCK_DELAY,              \
            .spi_mode   = (nrf_qspi_spi_mode_t)NRFX_QSPI_CONFIG_MODE,       \
            .dpmen      = false                                             \
        },                                                                  \
    }
    /*
        select: 1=512byte,0=256byte.
    */
    __STATIC_INLINE void nrf_qspi_ifconfig0_set_page_size(uint8_t select)
    {
        if(select == 0)
        {
            NRF_QSPI->IFCONFIG0 &= 0xffffefff;
        }
        else
        {
            NRF_QSPI->IFCONFIG0 |= 0x00001000;
        }
    }
    uint32_t nand_flash_qspi_init(void)
    {
        uint32_t err_code = NAND_SUCCESS;
        nrf_drv_qspi_config_t config = QSPI_NAND_FLASH_CONFIG;
        err_code = nrf_drv_qspi_init(&config, NULL, NULL);
        if(NRFX_SUCCESS != err_code)
        {
            NRF_LOG_INFO("QSPI init error,err_code=%d",err_code);
            return err_code;
        }
        nrf_qspi_ifconfig0_set_page_size(1);
        return NRFX_SUCCESS;
    }
  • Hi,

        1. Is there a way we could differentiate between read/write/erase. 

    2. Do we need to set handler based Interrupt for qspi?

    Right now NRFX_QSPI_CONFIG_IRQ_PRIORITY 6 .

    1. "You'll have to put a SW state-machine on top of the driver in order to know what source triggered the EVENTS_READY signal."
      Monitor what function last called read/write/erase/custom instr and you know what the source of the NRFX_QSPI_EVENT_DONE  was.

    2. "Do we need to set handler based Interrupt for qspi?"
      What do you mean? as opposed to what? 
  • Hi ,

         Please check below code.

    void qspi_init_call_back(nrfx_qspi_evt_t event, void *p_context)
    {

      if (event == NRFX_QSPI_EVENT_DONE) {
            qSpiXferDone = true;
        }
    }
    uint32_t nand_flash_qspi_init(void)
    {
        uint32_t err_code = NAND_SUCCESS;
        nrf_drv_qspi_config_t config = QSPI_NAND_FLASH_CONFIG;
        err_code = nrf_drv_qspi_init(&config, qspi_init_call_back, NULL);
     
        if(NRFX_SUCCESS != err_code)
        {
            NRF_LOG_INFO("QSPI init error,err_code=%d",err_code);
            return err_code;
        }
        nrf_qspi_ifconfig0_set_page_size(1);
        return NRFX_SUCCESS;
    }
    and this is write API
        eNand_Result ret = NAND_SUCCESS;
        uint32_t flash_address;
        if((size == 0)||(size > 512))
        {
            return NAND_PARAM_ERROR;
        }
        if((size&0x03) != 0)
        {
            size = (int)(floor((size+3)/4))*4;
    #ifdef PRINTS_OUT
            NRF_LOG_INFO("Size calculated=%d",size);
    #endif
        }
        if((NULL == in_array)||((column&0x03) != 0))
        {
            return NAND_PARAM_ERROR;
        }
        flash_address = (column << 8);
        if(size >= 4)
        {
            if(NRFX_SUCCESS != nrf_drv_qspi_write(in_array+4,size-4,flash_address))
            {
                NRF_LOG_INFO("QSPI nrf driver error!");
                return NAND_NRF_DRIVER_ERROR; 
            }
        }  
        while(qSpiXferDone)// prev buffer writing is'nt over skip writing hold buffer to write in next iteration
        {
           MCU_HAL_Delay(1);
        }
  • Basically I am setting even transfer done flag when event ready occurs, and processed after write is over , will be waiting in spi to be completed for it to get set to true.

    I will add state machine to diff b/n read/write/erase . But could I check with the above> 

  • Hi,

           nrf_drv_qspi_init is failing with below mentioned call back; inside 

    init function 

    m_cb.interrupt_driven = false; is set to false ; so it crashes when assigned call back.

Reply Children
No Data
Related