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

Missing qspi quad mode enable in nrf_blk_dev_init

Hi,

I had a problem using your (nRf's) implementation of block device with my flash memory (I think that exact model is not relevant here). I'm using SDK 15.2 with NRF52840. Earlier I was using some code taken from qspi example - on it I was able to read, write and so on my flash memory. When I moved to block device based implementation the whole thing stopped working. 

After some research I found that in the method of qspi initialization in block device:

static ret_code_t block_dev_qspi_init(nrf_block_dev_t const * p_blk_dev,
                                      nrf_block_dev_ev_handler ev_handler,
                                      void const * p_context)
{
....
nrf_qspi_cinstr_conf_t cinstr_cfg = {
        .opcode    = QSPI_STD_CMD_RSTEN,
        .length    = NRF_QSPI_CINSTR_LEN_1B,
        .io2_level = true,
        .io3_level = true,
        .wipwait   = true,
        .wren      = true
    };

    /* Send reset enable */
    ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
    if (ret != NRF_SUCCESS)
    {
        NRF_LOG_INST_ERROR(p_qspi_dev->p_log, "QSPI reset enable command error: %"PRIu32"", ret);
        return ret;
    }

    /* Send reset command */
    cinstr_cfg.opcode = QSPI_STD_CMD_RST;
    ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
    if (ret != NRF_SUCCESS)
    {
        NRF_LOG_INST_ERROR(p_qspi_dev->p_log, "QSPI reset command error: %"PRIu32"", ret);
        return ret;
    }

    /* Get 3 byte identification value */
    uint8_t rdid_buf[3] = {0, 0, 0};
    cinstr_cfg.opcode = QSPI_STD_CMD_READ_ID;
    cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_4B;
    ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, rdid_buf);
    if (ret != NRF_SUCCESS)
    {
        NRF_LOG_INST_ERROR(p_qspi_dev->p_log, "QSPI get 3 byte id error: %"PRIu32"", ret);
        return ret;
    }
....
}


there is missing one (I think important) thing, which is setting quad mode. 

What I've done was to add to my flash driver this method:
ret_code_t BlockDeviceNrf::enable_qspi_quad_mode() {
#define QSPI_MEM_CMD_WRSR 0x01
#define QSPI_MEM_QUAD_MODE 0x40

    uint8_t transfer_byte = QSPI_MEM_QUAD_MODE;
    uint8_t rx_byte = 0x00;
    nrf_qspi_cinstr_conf_t cinstr;
    cinstr.io2_level = true;
    cinstr.io3_level = true;
    cinstr.wipwait = true;
    cinstr.wren = true;

    cinstr.opcode = QSPI_MEM_CMD_WRSR;
    cinstr.length = NRF_QSPI_CINSTR_LEN_4B;
    return nrfx_qspi_cinstr_xfer(&cinstr, &transfer_byte, nullptr);
}


and I'm calling it after nrf_blk_dec_init call. I'm not sure if that is correct solution, but it works for me. 

Am I right that setting quad mode is missing in qspi initialization in block device? What is a reason for that (maybe that is expected)? Am I missing something? 

Parents
  • Hi,

    The block implementation used in the SDK examples actually use the SPI mode of the QSPI. For example, the config file of the usbd_msc example in the sdk has following definition:

    // <o> NRFX_QSPI_CONFIG_READOC  - Number of data lines and opcode used for reading.
     
    // <0=> FastRead 
    // <1=> Read2O 
    // <2=> Read2IO 
    // <3=> Read4O 
    // <4=> Read4IO 
    
    #ifndef NRFX_QSPI_CONFIG_READOC
    #define NRFX_QSPI_CONFIG_READOC 0
    #endif
    
    // <o> NRFX_QSPI_CONFIG_WRITEOC  - Number of data lines and opcode used for writing.
     
    // <0=> PP 
    // <1=> PP2O 
    // <2=> PP4O 
    // <3=> PP4IO 
    
    #ifndef NRFX_QSPI_CONFIG_WRITEOC
    #define NRFX_QSPI_CONFIG_WRITEOC 0
    #endif

    Which is specified in the documentation as SPI. You would have to configure it to use the QSPI feature as you've done if you want to use it.

    Best regards

    Jared 

Reply
  • Hi,

    The block implementation used in the SDK examples actually use the SPI mode of the QSPI. For example, the config file of the usbd_msc example in the sdk has following definition:

    // <o> NRFX_QSPI_CONFIG_READOC  - Number of data lines and opcode used for reading.
     
    // <0=> FastRead 
    // <1=> Read2O 
    // <2=> Read2IO 
    // <3=> Read4O 
    // <4=> Read4IO 
    
    #ifndef NRFX_QSPI_CONFIG_READOC
    #define NRFX_QSPI_CONFIG_READOC 0
    #endif
    
    // <o> NRFX_QSPI_CONFIG_WRITEOC  - Number of data lines and opcode used for writing.
     
    // <0=> PP 
    // <1=> PP2O 
    // <2=> PP4O 
    // <3=> PP4IO 
    
    #ifndef NRFX_QSPI_CONFIG_WRITEOC
    #define NRFX_QSPI_CONFIG_WRITEOC 0
    #endif

    Which is specified in the documentation as SPI. You would have to configure it to use the QSPI feature as you've done if you want to use it.

    Best regards

    Jared 

Children
No Data
Related