nRF5340 and W25Q512NW Nor Flash R/W problem?

Hello,

I am using W25Q512NW (https://www.winbond.com/resource-files/W25Q512NW%20RevB%2007192021.pdf) in my custom board. I want to store the sensor data in this flash.

My custom board use the nRF5340 MCU and the version of the nrf connect sdk is V2.5.2.

the problem i am facing that i am not able to read the data from the flash.

 

*** Booting nRF Connect SDK v2.5.2 ***
[00:00:00.252,868] <inf> main: iMedrix External flash Application Started.

Device name: w25q512nw@0
Data written. Good!!
23 22 33 44 55 66 77 88 
Data read. Good!!
FF FF FF FF FF FF FF FF 
Data not matched..!!
JEDEC ID : EF  60  20 

In above log, i am writing 8 bytes and also read those 8 bytes. but when i read data from the flash i am getting only FF. 
And when i read the JEDEC id of the flash, i am getting right JEDEC id.

Here is the prj.conf file.

# Logger module
CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG=y
CONFIG_LOG_MODE_DEFERRED=y
CONFIG_LOG_SPEED=y
CONFIG_UART_CONSOLE=n

CONFIG_DEBUG=y


# spi Configuration
CONFIG_SPI=y

#External flash configuration
CONFIG_FLASH=y
CONFIG_FLASH_JESD216_API=y
CONFIG_FLASH_PAGE_LAYOUT=y


CONFIG_NEWLIB_LIBC=y

Here is the .overlay file below.

 

&qspi {
	status = "okay";
	pinctrl-0 = <&qspi_default>;
	pinctrl-1 = <&qspi_sleep>;
	pinctrl-names = "default", "sleep";
	w25q512: w25q512nw@0 {
		compatible = "nordic,qspi-nor";
		reg = <0>;
		/* MX25R64 supports only pp and pp4io */
		writeoc = "pp4io";
		// writeoc = "pp4o";
		/* MX25R64 supports all readoc options */
		readoc = "read4io";
		sck-frequency = <8000000>;
		// jedec-id = [c2 28 17];
		jedec-id = [EF 60 20];
		sfdp-bfp = [
  			e5 20 fb ff  ff ff ff 1f  44 eb 08 6b  08 3b 42 bb
  			fe ff ff ff  ff ff 00 00  ff ff 40 eb  0c 20 0f 52
  			10 d8 00 00  33 02 a6 00  81 e7 14 d9  e9 63 76 33
  			7a 75 7a 75  f7 bd d5 5c  19 f7 5d ff  e9 70 f9 a5
  		];
		size = <536870912>;
		// address-size-32;
		has-dpd;
		// t-enter-dpd = <10000>;
		// t-exit-dpd = <35000>;
		t-enter-dpd = <3000>;
		t-exit-dpd = <30000>;
	};
};

Please give me your suggestion in this.  

Let me know if any modification is required.

Thank you in advance.

Gautam.

Parents Reply Children
  • Hi Simonr,

    Sorry for the late replay,

    Initially, the memory of my external flash (W25Q512NWEIQ) is write-protected because the BP3 and BP2 bits in the status register are 1, but they should be 0.

    I included the has-lock property in the device tree as shown in below, but I'm still unable to write to the flash memory.

    &qspi {
    	status = "okay";
    	pinctrl-0 = <&qspi_default>;
    	pinctrl-1 = <&qspi_sleep>;
    	pinctrl-names = "default", "sleep";
    	w25q512: w25q512@0 {
    		compatible = "nordic,qspi-nor";
    		reg = <0>;
    		sck-frequency = <DT_FREQ_M(8)>;
    		jedec-id = [ef 60 20];
    		address-size-32;
    		enter-4byte-addr = <0x01>;
    		writeoc = "pp4o";
    		readoc = "read4io";
    		quad-enable-requirements = "S2B1v4";
    		size = <536870912>;
    		status = "okay";
    		
    		has-lock = <0xb0>;
    	};
    };

    I tried manually writing 0 to status register 1 using qspi, but I couldn’t write to it because the status register is write-protected (the SRP bit in SR_1 is 1). To disable write protection for the status register, we need to pull the /WP pin high or drive it high before writing to status register 1.

    When I used the SPI protocol for the flash and added the has-lock property to the device tree, I was able to write data to the external flash memory. This is because the spi_nor driver includes logic to write 0 to status register 1 when the has-lock property is added. After that, I flashed the code using QSPI, and it worked fine as well.

    	/* Check for block protect bits that need to be cleared.  This
    	 * information cannot be determined from SFDP content, so the
    	 * devicetree node property must be set correctly for any device
    	 * that powers up with block protect enabled.
    	 */
    	if (cfg->has_lock != 0) {
    		acquire_device(dev);
    
    		rc = spi_nor_rdsr(dev);
    
    		/* Only clear if RDSR worked and something's set. */
    		if (rc > 0) {
    			rc = spi_nor_wrsr(dev, rc & ~cfg->has_lock);
    		}
    
    		if (rc != 0) {
    			LOG_ERR("BP clear failed: %d\n", rc);
    			return -ENODEV;
    		}
    
    		release_device(dev);
    	}

    The above logic is already present in spi_nor.c (spi_nor_configure() function) file but not present in the nrf_qspi_nor.c.

    To avoid flashing the SPI code first and then the QSPI code each time, I've decided on a single approach:

    1. Initialize QSPI and read status register 1.

    2. Check if bits [7:2] of the status register are greater than 0(That means memory is write protected).

      • If the value is greater than 0:

        • Uninitialize QSPI.
        • Initialize SPI.
        • Write 0 to status register 1.
        • Uninitialize SPI.
        • Reset the entire device (MCU) using software.
      • If the value is 0:

        • Do nothing.

    But when i use the above approach the device stuck in spi_nor driver and not able to do anything.

    Here's few question:

     1. Is there any way to pull the /wp pin high in qspi mode?

    NOTE(From Winbond support) :- Write SR command only support 1-1-1, when flash receive write SR command, pin3 is /WP pin.

    2. How can i do the pin internally pull up using software (device tree).

    3. What is the ideal state of the QSPI bus?

    4. Can i use the spi and qspi on single bus simultaneously? If yes please guide me.

    5. How can i get the configured qspi pin number from the device tree to my custom code.?  

    Thank you

    Your response is valuable to us.

Related