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

Need QPI code example for my memory chip

Hi,

I cannot locate any QPI sample code in the example. Was it possible for anyone to share me the sample code?

Thanks a bunch.

Parents Reply Children
  • Here is the test configure code.

    #define QSPI_STD_CMD_WRSR   0x01
    #define QSPI_STD_CMD_RSTEN  0x66
    #define QSPI_STD_CMD_RST    0x99
    
    static void configure_memory()
    {
        uint8_t temporary[2] = {0x02,0x02};
        uint32_t err_code;
        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      = false
        };
    
        // Send reset enable
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        // Send reset command
        cinstr_cfg.opcode = QSPI_STD_CMD_RST;
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        // Send WREN
        cinstr_cfg.opcode = 0x71;
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        // Switch to qspi mode
        cinstr_cfg.opcode = QSPI_STD_CMD_WRSR;
        cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_2B;
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, &temporary, NULL);
        APP_ERROR_CHECK(err_code);
    }
    

    And I tried capture the reset enable command send when configure_memory function is called, the I notice there is extra data in front of the 0x66 command is that correct? What are those data for?

    Here is the capture for RST command 0x99

    Here is the capture for WRAR command 0x06

    Here is the capture for WRR (0x01) + SR1NV (0x02) + CR1NV (0x02), it seem tgat CR1NV is not written

  • So I decided to modify the NRF_QSPI_CINSTR_LEN_2B to NRF_QSPI_CINSTR_LEN_3B

    static void configure_memory()
    {
        uint8_t temporary[2] = {0x02,0x02};
        uint32_t err_code;
        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      = false
        };
    
        // Send reset enable
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        // Send reset command
        cinstr_cfg.opcode = QSPI_STD_CMD_RST;
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        // Send WREN
        cinstr_cfg.opcode = 0X06;
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        // Switch to qspi mode
        cinstr_cfg.opcode = QSPI_STD_CMD_WRSR;
        cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_3B;
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, &temporary, NULL);
        APP_ERROR_CHECK(err_code);
    }

    The data output achieve what I wanted. But I not able to get any data reply from the memory chip

    And sub-sequence I capture the nrf_drv_qspi_erase() data frame

  • Next, I decided to enable the .wren bit and hence it will added an extra 0x06 after the unknown data (0x5, 0x0) for all our configuration frame. Therefore I disable the WREN command, and I still not able to get a reply from the memory chip. Disappointed I suspect the unknown 0x5,0x00 data is the one affecting my memory, as I tried to read using normal spi mode, it fails. It only works when I replace the memory with flash memory chip.

    static void configure_memory()
    {
        uint8_t temporary[2] = {0x02,0x02};
        uint32_t err_code;
        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
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        // Send reset command
        cinstr_cfg.opcode = QSPI_STD_CMD_RST;
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
    //    // Send WREN
    //      cinstr_cfg.opcode = 0x06;
    //    err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
    //    APP_ERROR_CHECK(err_code);
    
        // Switch to qspi mode
        cinstr_cfg.opcode = QSPI_STD_CMD_WRSR;
        cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_3B;
        err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, &temporary, NULL);
        APP_ERROR_CHECK(err_code);
    }

  • My first thoughts are that those I/O lines are way too capacitively loaded. I need you to set the drive strength of the IO pins to NRF_GPIO_PIN_H0H1

  • Thanks.

    I tried the change the below code(under nrf_gpio.h), still no improvement. I was able to read the register using SPI master sample code from nordic nRF5_SDK_15.2.0_9412b96\examples\peripheral\spi

    Do you know how can I use the qspi example(using nrf_drv_qspi_cinstr_xfer()) to read the register? I believe it will be great if I could at least test whether the register read is working before go into writing it.

    __STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number)
    {
        nrf_gpio_cfg(
            pin_number,
            NRF_GPIO_PIN_DIR_OUTPUT,
            NRF_GPIO_PIN_INPUT_DISCONNECT,
            NRF_GPIO_PIN_NOPULL,
    //old        NRF_GPIO_PIN_S0S1,
    		NRF_GPIO_PIN_H0H1,
            NRF_GPIO_PIN_NOSENSE);
    }

Related