LittleFS failing to mount on QSPI NOR Flash (err -28)

I am trying to implement LittleFS on 1Gb QSPI NOR flash (W25Q01JV) on the nRF5340.

I am running nRF Connect SDK version 2.4.2 and am using a slightly modified version of the LittleFS example to work with my custom board.

Whenever I try to mount the file system I get this error:

Here is the relevant Device tree bindings:

/ {
    chosen {
        nordic,pm-ext-flash = &w25q01;
    };
    fstab {
		compatible = "zephyr,fstab";
		lfs: lfs {
			compatible = "zephyr,fstab,littlefs";
			mount-point = "/lfs";
			partition = <&lfs_part>;
			read-size = <16>;
			prog-size = <16>;
			cache-size = <64>;
			lookahead-size = <32>;
			block-cycles = <512>;
		};
	};
};

//delete-node/ &storage_partition;

&qspi {
	status = "okay";
	pinctrl-0 = <&qspi_default>;
	pinctrl-1 = <&qspi_sleep>;
	pinctrl-names = "default", "sleep";
    w25q01: w25q01@0 {
        compatible = "nordic,qspi-nor";
		reg = <0>;
		writeoc = "pp4o";
		readoc = "read4io";
		sck-frequency = <8000000>;
		jedec-id = [EF 40 21];
        sfdp-bfp = [
        e5 20 fb ff  ff ff ff 3f  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  36 02 a6 00  82 ea 14 e2  e9 63 76 33
        7a 75 7a 75  f7 a2 d5 5c  19 f7 4d ff  e9 70 f9 a5
        ];
        //has-lock = <0x7C>;
		size = <1073741824>;
		has-dpd;
		t-enter-dpd = <3000>;
		t-exit-dpd = <3000>;
        quad-enable-requirements= "S2B1v1";
        //requires-ulbpr;
        address-size-32;
        enter-4byte-addr= <0xB7>; // 0xA5 is what is reported, but DS says 0xB7?
        partitions {
            compatible = "fixed-partitions";
            #address-cells = <1>;
            #size-cells = <1>;
    
            lfs_part: partition@0 {
                label = "lfs_storage";
                reg = <0x00000000 0x08000000>;
            };
        };
	};
};

And here is my relevant prj.conf settings:

# file system
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_FS_LITTLEFS_BLK_DEV=y
CONFIG_DISK_ACCESS=y
CONFIG_FILE_SYSTEM_MKFS=y

# nvs and partitioning
CONFIG_NVS=y
CONFIG_SETTINGS=y
CONFIG_SETTINGS_NVS=y
CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE=y
CONFIG_NORDIC_QSPI_NOR=y
CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=65536
CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y
CONFIG_PM_PARTITION_SIZE_LITTLEFS=0x8000000
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_FLASH_JESD216_API=y

CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y
CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=n

I've been messing with Device tree and overlay settings for a while without getting anywhere past this error -28 so far.

I did find that if I removed the CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL setting, it would mount and run, but to the internal flash controller instead of external flash, despite any of the partition settings in the device tree.

I've ran the jesd216 example code to generate the following config information:

w25q01jv@0: SFDP v 1.6 AP ff with 2 PH
PH0: ff00 rev 1.6: 16 DW @ 80
Summary of BFP content:
DTR Clocking supported
Addressing: 3- or 4-Byte
4-KiBy erase: uniform
Support QSPI XIP
Support 1-1-1
Support 1-1-2: instr 3Bh, 0 mode clocks, 8 waits
Support 1-1-4: instr 6Bh, 0 mode clocks, 8 waits
Support 1-2-2: instr BBh, 2 mode clocks, 2 waits
Support 1-4-4: instr EBh, 2 mode clocks, 4 waits
Support 4-4-4: instr EBh, 2 mode clocks, 0 waits
Flash density: 134217728 bytes
ET1: instr 20h for 4096 By; typ 64 ms, max 896 ms
ET2: instr 52h for 32768 By; typ 128 ms, max 1792 ms
ET3: instr D8h for 65536 By; typ 160 ms, max 2240 ms
Chip erase: typ 60928 ms, max 365568 ms
Byte program: type 32 + 3 * B us, max 192 + 18 * B us
Page program: typ 704 us, max 4224 us
Page size: 256 By
Suspend: 75h ; Resume: 7Ah
DPD: Enter B9h, exit ABh ; delay 3000 ns ; poll 0x3d
HOLD or RESET Disable: unsupported
QER: 4
0-4-4 Mode methods: entry 0xd ; exit 0x3d
4-4-4 Mode sequences: enable 0x11 ; disable 0x9
4-byte addressing support: enter 0xa5, exit 0x3e5
Soft Reset and Rescue Sequence support: 0x30
Status Register 1 support: 0x69
size = <1073741824>;
sfdp-bfp = [
        e5 20 fb ff  ff ff ff 3f  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  36 02 a6 00  82 ea 14 e2  e9 63 76 33
        7a 75 7a 75  f7 a2 d5 5c  19 f7 4d ff  e9 70 f9 a5
        ];
PH1: ff84 rev 1.0: 2 DW @ d0
sfdp-ff84 = [
        ff 0a f0 ff  21 ff dc ff
        ];
jedec-id = [ef 40 21];

I've tried manually declaring the partition in pm_static.yml, as well as modifying a lot of the devicetree and prj.conf settings without any success. I've seen others with similar issues when trying to use a NOR Flash chip greater than 128mb, is it a known issue? Or is there something obviously wrong in my configuration code that I am not catching?

Thanks,

- Brett

Parents
  • Hi,

    Could you also test the SPI Flash sample? (It is configured for QSPI for the nRF5340)

    It would be interesting to see if you see the same error without a filesystem.

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd, 
    I ran the example for multiple sectors, and the output looks to be good:




    So If the QSPI flash seems to be working properly, I'd assume the filesystem or partitioning configuration is probably at fault.

    Any ideas for what to change in the configuration?

    - Brett

  • Integration into my main application is going well. I want to round off this thread with some of the config settings I've found to have made a difference, and others I've settled on. Just in case someone finds it helpful.

    My relevant device tree came out to be this:

    &qspi {
    	status = "okay";
    	pinctrl-0 = <&qspi_default>;
    	pinctrl-1 = <&qspi_sleep>;
    	pinctrl-names = "default", "sleep";
        w25q01: w25q01@0 {
            compatible = "nordic,qspi-nor";
    		reg = <0>;
    		writeoc = "pp4o";
    		readoc = "read4io";
    		sck-frequency = <16000000>;
    		jedec-id = [EF 40 21];
            //sfdp-bfp = [
            //e5 20 fb ff  ff ff ff 3f  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  36 02 a6 00  82 ea 14 e2  e9 63 76 33
            //7a 75 7a 75  f7 a2 d5 5c  19 f7 4d ff  e9 70 f9 a5
            //];
    
    		size = <1073741824>;
    		has-dpd;
    		t-enter-dpd = <3000>;
    		t-exit-dpd = <3000>;
            //requires-ulbpr;
            sck-delay = <5>;
            quad-enable-requirements= "S2B1v1";
            address-size-32;
            enter-4byte-addr= <0xB7>; // 0xA5 is what is reported, but DS says 0xB7?
    	};
    };


    I found that the sdfp-bfp field, and a few others from the JESD216 example weren't exactly accurate for some reason. But the manual config above seemed to work well. Also having nordic,drive-mode = <NRF_DRIVE_H0H1>; in my qspi pinctrl  proved necessary.

    Since I'm using the partition manager, and FSTAB or partition setting in the DTS would not have any effect, instead I could either manually declare it in pm_static, or use the prj.conf settings to put it in external and set the size. I chose the latter, with this code configuration to set the mount point:
    FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(lfs_storage);
    static struct fs_mount_t lfs_storage_mnt = {
    	.type = FS_LITTLEFS,
    	.fs_data = &lfs_storage,
    	.storage_dev = (void *)FIXED_PARTITION_ID(littlefs_storage),
    	.mnt_point = "/lfs",
    };


    My current prf.conf settings regarding qspi and FS are:

    # file system
    CONFIG_FLASH=y
    CONFIG_FLASH_MAP=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FILE_SYSTEM=y
    CONFIG_DISK_ACCESS=y
    CONFIG_FILE_SYSTEM_MKFS=y
    CONFIG_FILE_SYSTEM_LITTLEFS=y
    
    # nvs and partitioning
    CONFIG_NVS=y
    CONFIG_SETTINGS=y
    CONFIG_SETTINGS_NVS=y
    CONFIG_NORDIC_QSPI_NOR=y
    CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=65536
    CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y
    CONFIG_PM_PARTITION_SIZE_LITTLEFS=0x8000000
    CONFIG_MPU_ALLOW_FLASH_WRITE=y
    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=n


    Obviously having pullups on CS, IO3/HOLD and IO2/WP was the main difference maker in getting it working, but wanted to cover the other lessens learned.

    I had already begun the process to update to 2.6.X, just to stay up to date, but it is good to hear that a possible fix has already been rolled out.

    - Brett

  • We are considering using w25q01jvzeim (1Gbit) or w25q01jvzeiq (1Gbit) . These are dual die 2x512Mbit. 
    1. Does the QSPI driver handle the die switching?
    2. If not than what would I have to do in order to be able to use all 128 MB of storage?
    3. Is this memory w25q01j compatible with mcuboot on nrf5340 (  did you successfully updated firmware using the external memory)?

  • Its been a while since I've had to think on this, so my memory is a bit stale, but I did not have implement anything extra for die switching within the w25q01. With the proper configuration, you should be able to access all 128MB.

    My use case did not involve loading firmware onto external flash so unfortunately I cannot speak to its compatibility with mcuboot.

  • I found this in the datasheet:
     "The W25Q01JV device is a two 512M-bit stack die that supports linear addressing for the full 1G-bit memory address range."

Reply Children
No Data
Related