USB Mass Storage example configured for external NOR flash FAT FS not keeping files

Hi,

I am using nrf5340dk board with NCS 2.3.
I have taken the USB Mass Storage example and am trying to configure it to work over spi with an 8miby NOR JEDEC flash.
The external flash appears to be correctly read by the spi-nor driver including the JEDEC parameters.

When I first connect to a windows pc the drive appears to only have 64kb of space. If I then use windows to format the drive to 8mb then it appears correctly and I can add files and folders. 

However, if I eject the device and reconnect it, then it again shows up as having 64kb and all of the files and folders are gone.

In code I can use the zephyr file system api to create a folder on the flash that will persist over powercycles, so I believe the flash device is working correctly.

I have simplified the mass storage example to do nothing other than start the USB.

Below are is the start up output, my config file and the overlay file I am using to configure things.

[00:00:00.251,983] <inf> spi_nor: is25: SFDP v 1.6 AP ff with 1 PH
[00:00:00.258,911] <inf> spi_nor: PH0: ff00 rev 1.6: 16 DW @ 30
[00:00:00.265,686] <inf> spi_nor: is25: 8 MiBy flash
*** Booting Zephyr OS build v3.2.99-ncs2 ***
[00:00:00.275,451] <inf> flashdisk: Initialize device NAND
[00:00:00.281,585] <inf> flashdisk: offset 0, sector size 512, page size 65536, volume size 8388608
[00:00:00.291,656] <inf> usb_msc: Sect Count 16384
[00:00:00.297,088] <inf> usb_msc: Memory Size 8388608
[00:00:01.303,039] <inf> main: The device is put in USB mass storage mode.

CONFIG_STDOUT_CONSOLE=n
CONFIG_DEBUG=y
CONFIG_DEBUG_OPTIMIZATIONS=y
CONFIG_NO_OPTIMIZATIONS=y
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y
CONFIG_LOG_OVERRIDE_LEVEL=2
CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y

#USB related configs
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_PRODUCT="Zephyr MSC sample"
CONFIG_USB_DEVICE_PID=0x0008
CONFIG_LOG=y
CONFIG_USB_DRIVER_LOG_LEVEL_INF=y
CONFIG_USB_MASS_STORAGE=y
CONFIG_USB_DEVICE_LOG_LEVEL_INF=y
CONFIG_USB_MASS_STORAGE_LOG_LEVEL_INF=y
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n

CONFIG_MAIN_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
CONFIG_USB_NRFX_WORK_QUEUE_STACK_SIZE=4096
CONFIG_USB_WORKQUEUE_STACK_SIZE=4096
CONFIG_MASS_STORAGE_STACK_SIZE=4096

#CONFIG_MAIN_STACK_SIZE=1536

CONFIG_DISK_DRIVER_FLASH=y

##jxl added
#CONFIG_FLASH=y
CONFIG_FLASH_JESD216_API=y
CONFIG_FLASHDISK_LOG_LEVEL_INF=y
#CONFIG_DISK_DRIVER_SDMMC=y
CONFIG_SPI=y
CONFIG_NRFX_SPIM3=y
CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=8
CONFIG_MULTITHREADING=y
CONFIG_SPI_NOR_SFDP_RUNTIME=y
CONFIG_SPI_NOR=y

CONFIG_NORDIC_QSPI_NOR=n

CONFIG_APP_MSC_STORAGE_FLASH_FATFS=y

##trials and error
#CONFIG_USB_WORKQUEUE=y

/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */



&qspi{
    status = "disabled";
};




&pinctrl {
    spi3_default: spi3_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 1, 6)>,
				<NRF_PSEL(SPIM_MISO, 1, 9)>,
				<NRF_PSEL(SPIM_MOSI, 1, 7)>;
                
		};
	};

	spi3_sleep: spi3_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 1, 6)>,
				<NRF_PSEL(SPIM_MISO, 1, 9)>,
				<NRF_PSEL(SPIM_MOSI, 1, 7)>;
			low-power-enable;
		};
	};
};

&spi3{
status = "okay";
 cs-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
 pinctrl-0 = <&spi3_default>;
 pinctrl-1 = <&spi3_sleep>;
 pinctrl-names = "default", "sleep";

   is25: is25lp064d@0 {
    compatible = "jedec,spi-nor";
    status="okay";
    label = "is25";
    reg = <0>;
    spi-max-frequency = <8000000>; // Max frequency achievable with nRF5340 at 64Mhz //
    size =  <67108864>;	// Size in bit set to 1 Gb (128 MBytes) //
    jedec-id = [9d 60 17];
	

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

		mass_storage_partition: partition@0 {
			label = "mass_storage";
			reg = <0x00000000 0x0800000>;
		};
	};
   };
};

/ {
	aliases {
		spi-flash0 = &is25;
	};
	msc_disk0 {
		compatible = "zephyr,flash-disk";
		partition = <&mass_storage_partition>;
		disk-name = "NAND";
		cache-size = <65536>;
	};
};

I wonder if you are able to help me understand what is going on?
Thanks,

Justin

  • Hi,

    I have just discovered that my flash is no longer writable for some reason. I am guessing that windows does not know that the block writes on format and file copy have failed. So the issue I am seeing may well be the windows disk cache making it seem like it was formatted. Once the cache is refreshed the original 64kb partition is back again. 

    I will fix the write problem and confirm.

    Thanks,

    Justin

  • Hi,

    For anyone else having trouble like this I found the following problem that required a change to the usb mass storage class in Zephyr (not the sample application).

    My nor flash device had become write protected but this was not the issue (once I re-enabled write I still had the problem above only this time the device was not accessible to windows until formatted).

    The issue seems to be that my spi nor flash device had a sector size of 4096 rather than the 512 default in the flash disk configuration. This can be changed with an overlay using 

    sector-size = < 4096 >;
    However, this then caused the mass storage module to throw a runtime error:
    <err> usb_msc: Block Size reported by the storage side is different from Mass Storage Class page Buffer - Aborting

    This in turn is because zephyr\subsys\usb\device\class\msc.c hardcodes its BLOCK_SIZE variable to 512 which it then checks against the disks reported sector size. It also confusing that it refers to block size rather than sector size.
    if (disk_access_ioctl(disk_pdrv,
    				DISK_IOCTL_GET_SECTOR_SIZE, &block_size)) {
    		LOG_ERR("Unable to get sector size - Aborting USB init");
    		return 0;
    	}
    
    	if (block_size != BLOCK_SIZE) {
    		LOG_ERR("Block Size reported by the storage side is "
    			"different from Mass Storage Class page Buffer - "
    			"Aborting");
    		return 0;
    	}

     So I thought maybe it doesn't matter if the flash disk sector size if 512 since the spi_nor driver does know the correct parameters for my flash via its runtime look up of the JEDEC parameters.

    This incorrect sector size at the flashdisk level (in order to allow the usb_msc to work) seems to be the root cause of my problems. 

    Changing the hardcoded BLOCK_SIZE define in msc.c to 4096 and setting the sector size in the overlay sector-size = < 4096 >; seems to have fixed the issues.


  • Thanks for sharing the workaround, could the following kconfig option also work?
    CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096

    Kenneth

  • I don't think so. I believe that config sets the layout page size (e.g. block size) rather than the sector size within spi-nor.
    Actually spi-nor has all the correct values it is just that msc.c has a hardcoded requirement that the sector size reported from spi-nor (via flashdisk) =512.

    I have raised it as a bug on the zephyr repo https://github.com/zephyrproject-rtos/zephyr/issues/57735

    So if I am wrong or there is another way to do it hopefully that will be sorted out in the ticket.

Related