Unusual File System Behavior

Hello,

I am working on an application that requires saving a large amount of data onto a NOR flash. We have a custom board using an NRF52840 and a Winbond 2G-Bit NOR flash. 

I am trying to mount a file system to the NOR to be able to save files to it, and then switch to a USB mass storage mode for offloading. These issues pertain to both modes of operation. While LittleFS would be preferred, I have only been able to get FAT working with some significant problems. After long periods of data collection, the filesystem corrupts and I seem to lose all data on the file system. I suspect this could potentially be due to 24-bit addressing on the NOR. To utilize 2Gigabits of NOR, 32 bit addressing would be required, but enabling address-size-32 in the boards .dts prevents the file system from mounting. Specifically I run into the following error code:

00> [00:00:00.004,150] <inf> flashdisk: Initialize device NAND
00> [00:00:00.004,150] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 2147483648
...
00> [00:00:01.114,501] <inf> StorageLib: Area 0 at 0x0 on w25q02jv@0 for 2147483648 bytes
00> [00:00:01.114,501] <inf> StorageLib: Setup Flash completed successfully
00> [00:00:01.114,562] <inf> flashdisk: Initialize device NAND
00> [00:00:01.114,593] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 2147483648
00> [00:00:02.192,596] <inf> flashdisk: Initialize device NAND
00> [00:00:02.192,626] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 2147483648
00> [00:00:03.408,508] <inf> flashdisk: Initialize device NAND
00> [00:00:03.408,538] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 2147483648
00> [00:00:04.485,931] <err> fs: fs mount error (-19)
00> [00:00:04.485,961] <err> StorageLib: Failed to mount filesystem
00> [00:00:04.485,961] <err> StorageLib: Could not setup disk, -19

Removing address-size-32 does allow the system to mount and "work" for a limited period:

00> [00:00:00.004,150] <inf> flashdisk: Initialize device NAND
00> [00:00:00.004,150] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 2147483648
...
00> [00:00:01.137,786] <inf> StorageLib: Area 0 at 0x0 on w25q02jv@0 for 2147483648 bytes
00> [00:00:01.137,786] <inf> StorageLib: Setup Flash completed successfully
00> [00:00:01.137,847] <inf> flashdisk: Initialize device NAND
00> [00:00:01.137,878] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 2147483648
00> [00:00:02.215,911] <inf> flashdisk: Initialize device NAND
00> [00:00:02.215,942] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 2147483648
00> [00:00:03.652,221] <inf> flashdisk: Initialize device NAND
00> [00:00:03.652,252] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 2147483648
00> [00:00:04.730,895] <inf> StorageLib: File System Mounted
00> [00:00:04.781,005] <inf> StorageLib: Mount /NAND:: 0
00> [00:00:04.831,146] <inf> StorageLib: /NAND:: bsize = 512 ; frsize = 32768 ; blocks = 65527 ; bfree = 65526
00> [00:00:04.831,207] <inf> StorageLib: /NAND: opendir: 0
00> [00:00:04.831,420] <inf> StorageLib: End of files

This is the overlay I am trying to use:

&qspi {
	status = "okay";
	pinctrl-0 = <&qspi_default>;
	pinctrl-1 = <&qspi_sleep>;
	pinctrl-names = "default", "sleep";
	w25q02jv: w25q02jv@0 {
		compatible = "nordic,qspi-nor";
		reg = <0>;
		writeoc = "pp4o";
		readoc = "read4io";
		sck-frequency = <16000000>;
		jedec-id = [ef 70 22];
		size-in-bytes = <2147483648>;
		has-dpd;
		t-enter-dpd = <20000>;
		t-exit-dpd = <20000>;
		quad-enable-requirements = "S2B1v1";
		//address-size-32;
	};
};

&w25q02jv {
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		storage_partition: partition@0 {
			label = "storage";
			reg = <0x00000000 0x80000000>;
		};
	};
};

/ {
	msc_disk0 {
		compatible = "zephyr,flash-disk";
		partition = <&storage_partition>;
		disk-name = "NAND";
		cache-size = <4096>;
	};
};

Weirdly, I don't believe the Quad enable requirement to be setup correctly. The flash I am using has a unique system for enabling quad mode. I don't believe the qspi-nor driver includes the necessary operation to enable quad mode on this nor. I chose "S2B1v1" through trial and error.

Attempting to use Little FS I run into similar mounting issues. Specifically I run into a "Little FS Corrupted dir pair at {0x1, 0x0}" error regardless of the address size setting. This error happens every time.

00> [00:00:00.063,110] <inf> littlefs: LittleFS version 2.5, disk version 2.0
00> [00:00:00.557,556] <inf> littlefs: FS at w25q02jv@0:0x0 is 524288 0x1000-byte blocks with 512 cycle
00> [00:00:00.557,586] <inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32
00> [00:00:00.558,013] <err> littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:1234: Corrupted dir pair at {0x0, 0x1}
00> [00:00:00.558,013] <wrn> littlefs: can't mount (LFS -84); formatting
00> [00:00:00.761,596] <inf> littlefs: /lfs mounted
00> [00:00:00.811,676] <inf> StorageLib: Mount /lfs: 0
00> [00:00:00.812,164] <inf> StorageLib: /lfs: bsize = 16 ; frsize = 4096 ; blocks = 524288 ; bfree = 524286
00> [00:00:00.812,713] <inf> StorageLib: /lfs opendir: 0
00> 
00> [00:00:00.813,171] <inf> StorageLib: End of files
00> 
00> [00:00:00.813,201] <inf> StorageLib: The device is put in USB mass storage mode.

I understand this is a lot of weirdness without much direct code, so here are some specific questions:
- If I wanted to utilize the full 2gigabit size of the NOR, I would need to use a FAT32 fs and 32 bit addressing, right? Is there any issue with this combination?

- Is my setup for QSPI in the DTS correct for the nor I am using? Is there away to send specific commands to the NOR using the qspi-nor driver if the quad operation setting that my drive requires is not

Thank you for any help.

The datasheet for the flash can be found here: - Relevant info on page 12
https://www.mouser.com/datasheet/2/949/W25Q02JV_DTR_RevB_04192021-2329042.pdf

For main.c and library code I am pulling form the Mass storage example and LittleFS example. Running those directly gives the same error code.

Parents
  • Hi,

     

    It looks like you have written size-in-bytes in bits. Could you try to set it to "268435456" (256MByte) instead?

     

    Kind regards,

    Håkon

  • Good catch. I did change it to 256MByte but still run into the same issues. 

  • Hi,

     

    Attempting to use Little FS I run into similar mounting issues. Specifically I run into a "Little FS Corrupted dir pair at {0x1, 0x0}" error regardless of the address size setting. This error happens every time.

    This is normal on the very first run, as it needs to generate the filesystem. Here's how it looks when I try the samples/subsys/fs/littlefs with boards/nrf52840dk_nrf52840_qspi.conf / .overlay in my build:

    I: LittleFS version 2.5, disk version 2.0
    I: FS at mx25r6435f@0:0x0 is 16 0x1000-byte blocks with 512 cycle
    I: sizes: rd 16 ; pr 16 ; ca 64 ; la 32
    E: WEST_TOPDIR/modules/fs/littlefs/lfs.c:1234: Corrupted dir pair at {0x0, 0x1}
    W: can't mount (LFS -84); formatting
    I: /lfs1 mounted
    I: Automount /lfs1 succeeded
    *** Booting nRF Connect SDK v2.5.2 ***
    Sample program to r/w files on littlefs
    Area 0 at 0x0 on mx25r6435f@0 for 65536 bytes
    /lfs1 automounted
    /lfs1: bsize = 16 ; frsize = 4096 ; blocks = 16 ; bfree = 14
    

     It will still generate the file, and list it successfully afterwards:

    /lfs1 automounted
    /lfs1: bsize = 16 ; frsize = 4096 ; blocks = 16 ; bfree = 14
    
    Listing dir /lfs1 ...
    /lfs1/boot_count read count:0 (bytes: 0)
    /lfs1/boot_count write new boot count 1: [wr:1]
    I: Test file: /lfs1/pattern.bin not found, create one!
    ------ FILE: /lfs1/pattern.bin ------
    01 55 55 55 55 55 55 55 02 55 55 55 55 55 55 55
    03 55 55 55 55 55 55 55 04 55 55 55 55 55 55 55
    05 55 55 55 55 55 55 55 06 55 55 55 55 55 55 55
    07 55 55 55 55 55 55 55 08 55 55 55 55 55 55 55
    09 55 55 55 55 55 55 55 0a 55 55 55 55 55 55 55
    0b 55 55 55 55 55 55 55 0c 55 55 55 55 55 55 55
    0d 55 55 55 55 55 55 55 0e 55 55 55 55 55 55 55
    0f 55 55 55 55 55 55 55 10 55 55 55 55 55 55 55
    11 55 55 55 55 55 55 55 12 55 55 55 55 55 55 55
    13 55 55 55 55 55 55 55 14 55 55 55 55 55 55 55
    15 55 55 55 55 55 55 55 16 55 55 55 55 55 55 55
    17 55 55 55 55 55 55 55 18 55 55 55 55 55 55 55
    19 55 55 55 55 55 55 55 1a 55 55 55 55 55 55 55
    1b 55 55 55 55 55 55 55 1c 55 55 55 55 55 55 55
    1d 55 55 55 55 55 55 55 1e 55 55 55 55 55 55 55
    1f 55 55 55 55 55 55 55 20 55 55 55 55 55 55 55
    21 55 55 55 55 55 55 55 22 55 55 55 55 55 55 55
    23 55 55 55 55 55 55 55 24 55 55 55 55 55 55 55
    25 55 55 55 55 55 55 55 26 55 55 55 55 55 55 55
    27 55 55 55 55 55 55 55 28 55 55 55 55 55 55 55
    29 55 55 55 55 55 55 55 2a 55 55 55 55 55 55 55
    2b 55 55 55 55 55 55 55 2c 55 55 55 55 55 55 55
    2d 55 55 55 55 55 55 55 2e 55 55 55 55 55 55 55
    2f 55 55 55 55 55 55 55 30 55 55 55 55 55 55 55
    31 55 55 55 55 55 55 55 32 55 55 55 55 55 55 55
    33 55 55 55 55 55 55 55 34 55 55 55 55 55 55 55
    35 55 55 55 55 55 55 55 36 55 55 55 55 55 55 55
    37 55 55 55 55 55 55 55 38 55 55 55 55 55 55 55
    39 55 55 55 55 55 55 55 3a 55 55 55 55 55 55 55
    3b 55 55 55 55 55 55 55 3c 55 55 55 55 55 55 55
    3d 55 55 55 55 55 55 55 3e 55 55 55 55 55 55 55
    3f 55 55 55 55 55 55 55 40 55 55 55 55 55 55 55
    
    41 55 55 55 55 55 55 55 42 55 55 55 55 55 55 55
    43 55 55 55 55 55 55 55 44 55 55 55 55 55 55 55
    45 55 aa 
    I: /lfs1 unmounted
    /lfs1 unmount: 0
    

     

    Did you also adjust your storage partition size?

    &qspi {
    	status = "okay";
    	pinctrl-0 = <&qspi_default>;
    	pinctrl-1 = <&qspi_sleep>;
    	pinctrl-names = "default", "sleep";
    	w25q02jv: w25q02jv@0 {
    		compatible = "nordic,qspi-nor";
    		reg = <0>;
    		writeoc = "pp4o";
    		readoc = "read4io";
    		sck-frequency = <16000000>;
    		jedec-id = [ef 70 22];
    		size-in-bytes = <268435456>;
    		has-dpd;
    		t-enter-dpd = <20000>;
    		t-exit-dpd = <20000>;
    		quad-enable-requirements = "S2B1v1";
    		address-size-32;
    	};
    };
    
    &w25q02jv {
    	partitions {
    		compatible = "fixed-partitions";
    		#address-cells = <1>;
    		#size-cells = <1>;
    
    		storage_partition: partition@0 {
    			label = "storage";
    			reg = <0x00000000 0x10000000>;
    		};
    	};
    };
    
    / {
    	msc_disk0 {
    		compatible = "zephyr,flash-disk";
    		partition = <&storage_partition>;
    		disk-name = "NAND";
    		cache-size = <4096>;
    	};
    };

     

    Could you share the full log?

     

    Kind regards,

    Håkon

  • I can confirm that Little FS has the same behavior after the restart. After further testing, I am confident that the issue is with the configuration of the QSPI. I have switched over to the soc_flash_nrf example. I have found that the address-size-32 breaks the example. The flash_write and flash_read commands execute without error, but the two don't match. The example works with the following configuration:

    &qspi {
    	status = "okay";
    	pinctrl-0 = <&qspi_default>;
    	pinctrl-1 = <&qspi_sleep>;
    	pinctrl-names = "default", "sleep";
    	w25q02jv: w25q02jv@0 {
    		compatible = "nordic,qspi-nor";
    		reg = <0>;
    		writeoc = "pp4o";
    		readoc = "read4io";
    		sck-frequency = <16000000>;
    		jedec-id = [ef 70 22];
    		size-in-bytes = <67108864>;
    		//size-in-bytes = <268435456>; - Same Result
    		// has-dpd;
    		// t-enter-dpd = <20000>;
    		// t-exit-dpd = <20000>;
    		quad-enable-requirements = "S2B1v1";
    		//address-size-32;
    	};
    };

    The NOR flash is divided into 4 512MB die that require some additional commands to switch beyond. I have found that any changes regarding writeoc, readoc, and quad-enable-requirement also break the sample. I have been unable to run the flash in a non quad configuration options.
    -What mistakes could I be making in regard to this .dts configuration?
    -How could I send the "Software Die Select (C2h)" command mentioned on page 6 of the data sheet using the build in QSPI commands?

    Thank you

Reply
  • I can confirm that Little FS has the same behavior after the restart. After further testing, I am confident that the issue is with the configuration of the QSPI. I have switched over to the soc_flash_nrf example. I have found that the address-size-32 breaks the example. The flash_write and flash_read commands execute without error, but the two don't match. The example works with the following configuration:

    &qspi {
    	status = "okay";
    	pinctrl-0 = <&qspi_default>;
    	pinctrl-1 = <&qspi_sleep>;
    	pinctrl-names = "default", "sleep";
    	w25q02jv: w25q02jv@0 {
    		compatible = "nordic,qspi-nor";
    		reg = <0>;
    		writeoc = "pp4o";
    		readoc = "read4io";
    		sck-frequency = <16000000>;
    		jedec-id = [ef 70 22];
    		size-in-bytes = <67108864>;
    		//size-in-bytes = <268435456>; - Same Result
    		// has-dpd;
    		// t-enter-dpd = <20000>;
    		// t-exit-dpd = <20000>;
    		quad-enable-requirements = "S2B1v1";
    		//address-size-32;
    	};
    };

    The NOR flash is divided into 4 512MB die that require some additional commands to switch beyond. I have found that any changes regarding writeoc, readoc, and quad-enable-requirement also break the sample. I have been unable to run the flash in a non quad configuration options.
    -What mistakes could I be making in regard to this .dts configuration?
    -How could I send the "Software Die Select (C2h)" command mentioned on page 6 of the data sheet using the build in QSPI commands?

    Thank you

Children
  • Hi,

     

    Could you share a full log showing the issue?

    Ecic2002 said:
    -What mistakes could I be making in regard to this .dts configuration?

    You could try to reduce the sck-frequency, to see if this has any impact on the overall process, but if the physical routing from nRF to spi-flash is quite short, it should not really have an impact.

    Ecic2002 said:
    -How could I send the "Software Die Select (C2h)" command mentioned on page 6 of the data sheet using the build in QSPI commands?

    According to the datasheet, addressing is already handled inside the IC itself:

    The W25Q stack die product series introduces a new “Software Die Select (C2h)” instruction, and a factory
    assigned “Die ID#” for each stacked die. Each 512M-bit die can be accessed independently, even though
    the interface is shared and memory addressing is linear from 0 to 2G-bit memory address. Each 512M-bit
    die has its own 64-bit Unique Serial Number. Each die also has their individual (independent) ‘Status only’
    Status Register bits including BUSY bit, and SUS bit that provides the current state of the die.

    I read this as it will automatically address the correct internal stacked die based on the address that you provide.

    Ecic2002 said:
    I have been unable to run the flash in a non quad configuration options.

    Could you share this log as well as the .overlay that you used?

     

    Kind regards,

    Håkon

Related