Unable to mount fat FS using external partition manager using pm_static.yml file

Hi,

I am trying to mount Fat FS using pm_static.yml instead of devicetree overlay fixed partition. I can generate a memory report, but when I try to mount file system I get the following mount errors. 

Errors:

winbondw25q02@0 SPI flash testing
==========================

Perform test on single sector
Test 1: Flash erase
*** Booting nRF Connect SDK v2.7.0-5cb85570ca43 ***
*** Using Zephyr OS v3.6.99-100befc70c74 ***
[00:00:00.257,232] <err> usb_msc: Storage init ERROR !!!! - Aborting USB init
Flash erase succeeded!

Test 2: Flash write
Attempting to write zu bytes
Data read matches data written. Good!!
[00:00:00.380,065] <err> fs: fs mount error (-5)
Error mounting FATFS: -5. Formatting now...
[00:00:00.380,126] <err> fs: fs not mounted (mp == 0x200000d0)
Error unmounting FATFS: -22
Error formatting FATFS: 3
[00:00:00.380,218] <err> fs: fs mount error (-5)
Error mounting FATFS after formatting: -5
[00:00:00.380,249] <err> fs: mount point not found!!
[00:00:00.380,279] <err> flash_test: Failed to open file /NAND:/test.txt (err: -2)
[00:00:00.380,279] <err> fs: mount point not found!!
[00:00:00.380,310] <err> flash_test: Failed to open file /NAND:/test.txt (err: -2)
[00:00:00.380,401] <dbg> flash_test: enable_usb_device: USB mass storage enabled
[00:00:00.380,432] <inf> flash_test: USB mass storage enabled.

Prj.Conf

# Copyright (c) 2018 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# Enable the UART driver
CONFIG_UART_ASYNC_API=y
CONFIG_NRFX_UARTE0=y

# print
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

# I2C
CONFIG_I2C=y
CONFIG_I2C_NRFX=y
CONFIG_NRFX_TWIM1=y
CONFIG_NFCT_PINS_AS_GPIOS=y

#SPI
CONFIG_SPI=y
CONFIG_SPI_ASYNC=y
CONFIG_SPI_SLAVE=y

CONFIG_HEAP_MEM_POOL_SIZE=2048
# Enable DK LED and Buttons library
CONFIG_DK_LIBRARY=y
CONFIG_STDOUT_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_ERR=y
CONFIG_USB_MASS_STORAGE=y
CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
CONFIG_APP_MSC_STORAGE_FLASH_FATFS=y
CONFIG_MAIN_STACK_SIZE=10240
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=n

CONFIG_SPI_NOR=y
CONFIG_FLASH_JESD216_API=y
CONFIG_SPI_NRFX=y
CONFIG_SPI_NOR_IDLE_IN_DPD=y

#FLASH Config ##############################################
CONFIG_DISK_ACCESS=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_FS_FATFS_LFN=y

CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH_LOG_LEVEL_ERR=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_DISK_DRIVER_FLASH=y
CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y

overlay file:

/ {
	chosen {
		nordic,pm-ext-flash = &winbond;
	};
};

/* Disable conflicting buttons and UART */
&button2 {
	status = "disabled";
};

&button3 {
	status = "disabled";
};

&gpio_fwd {
	status = "disabled";
};

&pinctrl {
		spi_master_default: spi_master_default {
				group1 {
						psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
										<NRF_PSEL(SPIM_MOSI, 0, 9)>,
										<NRF_PSEL(SPIM_MISO, 0, 3)>;
				};
		};

		spi_master_sleep: spi_master_sleep {
				group1 {
						psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
										<NRF_PSEL(SPIM_MOSI, 0, 9)>,
										<NRF_PSEL(SPIM_MISO, 0, 3)>;
						low-power-enable;
				};
		};
};

&spi4 {
		compatible = "nordic,nrf-spim";
		pinctrl-0 = <&spi_master_default>;
		pinctrl-1 = <&spi_master_sleep>;
		pinctrl-names = "default", "sleep";
		cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;	
		status = "okay";
		winbond:winbondw25q02@0 {
			compatible = "jedec,spi-nor";
			reg = <0>;
			spi-max-frequency = <32000000>;
			jedec-id = [ ef 70 22 ];
			size = <268435456>;
			has-dpd;
		};
};

pm_static.yml and memory report

app:
  address: 0x00010200
  end_address: 0x00E4000
  region: flash_primary
  size: 0x00D3E00

external_flash:
  address: 0x00000000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x10000000  # 256MB
  region: external_flash
  size: 0x10000000

mcuboot:
  address: 0x00000000
  end_address: 0x00010000
  region: flash_primary
  size: 0x00010000

mcuboot_pad:
  address: 0x00010000
  end_address: 0x00010200
  region: flash_primary
  size: 0x00000200

mcuboot_primary:
  address: 0x00010000
  end_address: 0x00E4000
  orig_span: &id001
    - mcuboot_pad
    - app
  region: flash_primary
  size: 0x00D4000
  span: *id001

mcuboot_secondary:
  address: 0x00000000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x00D4000
  region: external_flash
  size: 0x00D4000

mcuboot_secondary_1:
  address: 0x00D4000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x0114000
  region: external_flash
  size: 0x0040000

EMPTY_1:
  address: 0x0114000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x0120000
  region: external_flash
  size: 0x000C000

mcuboot_primary_2:
  address: 0x0120000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x0160000
  region: external_flash
  size: 0x0040000

mcuboot_secondary_2:
  address: 0x0160000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x01A0000
  region: external_flash
  size: 0x0040000

storage_partition:
  address: 0x01A0000  # Start of FATFS storage partition after mcuboot_secondary_2
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x10000000  # End of storage partition (remaining memory)
  region: external_flash
  size: 0x0FE50000  # Remaining memory for storage (260416KB or approx 254MB)
  type: storage

msc_disk0:
  address: 0x01A0000  # Place MSC Disk inside storage_partition
  device: DT_CHOSEN(nordic_pm_ext_flash)
  end_address: 0x01B0000  # 0x01A0000 + 0x10000 (64KB for disk with cache)
  region: storage_partition  
  type: cache
  cache_size: 0x10000  # 64KB cache size
  disk_name: "NAND"
 external_flash (0x10000000 - 262144kB):
+----------------------------------------------------+
| 0x0: external_flash (0x10000000 - 262144kB)        |
| 0x0: mcuboot_secondary (0xd4000 - 848kB)           |
| 0xd4000: mcuboot_secondary_1 (0x40000 - 256kB)     |
| 0x114000: EMPTY_1 (0xc000 - 48kB)                  |
| 0x120000: mcuboot_primary_2 (0x40000 - 256kB)      |
| 0x160000: mcuboot_secondary_2 (0x40000 - 256kB)    |
| 0x1a0000: storage_partition (0xfe50000 - 260416kB) |
+----------------------------------------------------+

  flash_primary (0x100000 - 1024kB):
+----------------------------------------------+
| 0x0: mcuboot (0x10000 - 64kB)                |
+---0x10000: mcuboot_primary (0xd4000 - 848kB)-+
| 0x10000: mcuboot_pad (0x200 - 512B)          |
| 0x10200: app (0xefe00 - 959kB)               |
+----------------------------------------------+

  otp (0x2fc - 764B):
+------------------------------+
| 0xff8100: otp (0x2fc - 764B) |
+------------------------------+

  sram_primary (0x80000 - 512kB):
+--------------------------------------------+
| 0x20000000: sram_primary (0x80000 - 512kB) |
+--------------------------------------------+

main.c

#include <sample_usbd.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <stdio.h>
#include <string.h>
#include <zephyr/fs/fs.h>
#include <zephyr/storage/disk_access.h>
#include <zephyr/logging/log.h>
#include <ff.h>  // FATFS definition
#include <zephyr/usb/usb_device.h>
#include <zephyr/usb/usbd.h>
#include <zephyr/usb/class/usbd_msc.h>

#define STORAGE_PARTITION		storage_partition
#define STORAGE_PARTITION_ID		DEVICE_DT_GET(DT_CHOSEN_nordic_pm_ext_flash)

LOG_MODULE_REGISTER(flash_test, LOG_LEVEL_DBG);

#if defined(CONFIG_BOARD_ADAFRUIT_FEATHER_STM32F405)
#define SPI_FLASH_TEST_REGION_OFFSET 0xf000
#else
#define SPI_FLASH_TEST_REGION_OFFSET 0xff000
#endif

#define SPI_FLASH_SECTOR_SIZE 4096
#define FATFS_MOUNT_POINT "/NAND:"
static FATFS fat_fs;

static struct fs_mount_t fatfs_mount = {
    .type = FS_FATFS,
    .fs_data = &fat_fs,
    .mnt_point = FATFS_MOUNT_POINT,
};

// Define a LUN for USB MSC (similar to your original code)
USBD_DEFINE_MSC_LUN(NAND, "Zephyr", "FlashDisk", "0.00");

// Declare the "erased" array
const uint8_t erased[] = { 0xff, 0xff, 0xff, 0xff };

// Function to enable USB device for mass storage
static int enable_usb_device(void)
{
    int err = usb_enable(NULL);  // Use standard Zephyr USB enable function
    if (err != 0) {
        LOG_ERR("Failed to enable USB device support: %d", err);
        return err;
    }
    LOG_DBG("USB mass storage enabled");
    return 0;
}

void format_fatfs(void)
{
    struct fs_mount_t *mp = &fatfs_mount;
    int res = fs_unmount(mp);  // Unmount before formatting
    if (res != 0) {
        printk("Error unmounting FATFS: %d\n", res);
    }

    MKFS_PARM fs_options = {
        .fmt = FM_FAT,  // FAT format
        .n_fat = 1,     // Number of FATs (1 or 2)
        .align = 0,     // Alignment (0 for default)
        .n_root = 0,    // Number of root directory entries (0 for default)
        .au_size = 0    // Allocation unit size (0 for default)
    };

    res = f_mkfs("", &fs_options, NULL, 0);  // Format the filesystem
    if (res == FR_OK) {
        printk("FATFS format successful.\n");
    } else {
        printk("Error formatting FATFS: %d\n", res);
    }
}

void mount_fatfs(void)
{
    int res = fs_mount(&fatfs_mount);
    if (res == 0) {
        printk("FATFS mounted successfully.\n");
    } else {
        printk("Error mounting FATFS: %d. Formatting now...\n", res);
        format_fatfs();  // Format the flash if mounting fails
        res = fs_mount(&fatfs_mount);  // Try to mount again after formatting
        if (res == 0) {
            printk("FATFS mounted successfully after formatting.\n");
        } else {
            printk("Error mounting FATFS after formatting: %d\n", res);
        }
    }
}

void create_write_file(const char *file_path)
{
    struct fs_file_t file;
    int res;

    fs_file_t_init(&file);
    res = fs_open(&file, file_path, FS_O_CREATE | FS_O_RDWR);
    if (res < 0) {
        LOG_ERR("Failed to open file %s (err: %d)", file_path, res);
        return;
    }

    const char *sample_data = "Hello FATFS on SPI Flash!";
    res = fs_write(&file, sample_data, strlen(sample_data));
    if (res < 0) {
        LOG_ERR("Failed to write to file %s (err: %d)", file_path, res);
        fs_close(&file);
        return;
    }

    fs_close(&file);
    printk("File write successful!\n");
}

void read_file(const char *file_path)
{
    struct fs_file_t file;
    int res;
    char buffer[64];

    fs_file_t_init(&file);
    res = fs_open(&file, file_path, FS_O_READ);
    if (res < 0) {
        LOG_ERR("Failed to open file %s (err: %d)", file_path, res);
        return;
    }

    printk("Reading file content:\n");
    while ((res = fs_read(&file, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[res] = '\0';  // Null-terminate the read data
        printk("%s", buffer);  // Print to console
    }

    fs_close(&file);
}

void single_sector_test(const struct device *flash_dev)
{
    const uint8_t expected[] = {0x55, 0xaa, 0x66, 0x99};
    const size_t len = sizeof(expected);
    uint8_t buf[sizeof(expected)];
    int rc;

    printf("\nPerform test on single sector\n");
    printf("Test 1: Flash erase\n");

    rc = flash_erase(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, SPI_FLASH_SECTOR_SIZE);
    if (rc != 0) {
        printf("Flash erase failed! %d\n", rc);
    } else {
        memset(buf, 0, len);
        rc = flash_read(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, buf, len);
        if (rc != 0) {
            printf("Flash read failed! %d\n", rc);
            return;
        }
        if (memcmp(erased, buf, len) != 0) {
            printf("Flash erase failed at offset 0x%x got 0x%x\n",
                SPI_FLASH_TEST_REGION_OFFSET, *(uint32_t *)buf);
            return;
        }
        printf("Flash erase succeeded!\n");
    }

    printf("\nTest 2: Flash write\n");

    printf("Attempting to write %zu bytes\n", len);
    rc = flash_write(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, expected, len);
    if (rc != 0) {
        printf("Flash write failed! %d\n", rc);
        return;
    }

    memset(buf, 0, len);
    rc = flash_read(flash_dev, SPI_FLASH_TEST_REGION_OFFSET, buf, len);
    if (rc != 0) {
        printf("Flash read failed! %d\n", rc);
        return;
    }

    if (memcmp(expected, buf, len) == 0) {
        printf("Data read matches data written. Good!!\n");
    } else {
        printf("Data read does not match data written!!\n");
    }
}

void winbond_begin(void)
{
    const struct device *flash_dev = DEVICE_DT_GET(DT_CHOSEN(nordic_pm_ext_flash));

    if (!device_is_ready(flash_dev)) {
        printk("%s: device not ready.\n", flash_dev->name);
        return;
    }

    printf("\n%s SPI flash testing\n", flash_dev->name);
    printf("==========================\n");

    // Perform a sector test to ensure flash is working
    single_sector_test(flash_dev);

    // Mount the FATFS file system or format if necessary
    mount_fatfs();

    // Perform file operations (create and read a file)
    const char *file_path = FATFS_MOUNT_POINT "/test.txt";
    create_write_file(file_path);
    read_file(file_path);

    // Enable USB for mass storage
    int usb_err = enable_usb_device();
    if (usb_err == 0) {
        LOG_INF("USB mass storage enabled.");
    } else {
        LOG_ERR("Failed to enable USB mass storage.");
    }
}

regards,

Barsha

Parents Reply Children
  • Hi Simonr,

    When I try to build the same code without this pm_static.yml and add fixed partition part in the overlay file I can mount the Fat FS into my winbond NOR storage and even write into it:

    overlay file:

     / {
    	chosen {
    		nordic,pm-ext-flash = &winbond;
    	};
    };
    
    /* Disable conflicting buttons and UART */
    &button2 {
    	status = "disabled";
    };
    
    &button3 {
    	status = "disabled";
    };
    
    &gpio_fwd {
    	status = "disabled";
    };
    
    &pinctrl {
    		spi_master_default: spi_master_default {
    				group1 {
    						psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
    										<NRF_PSEL(SPIM_MOSI, 0, 9)>,
    										<NRF_PSEL(SPIM_MISO, 0, 3)>;
    				};
    		};
    
    		spi_master_sleep: spi_master_sleep {
    				group1 {
    						psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
    										<NRF_PSEL(SPIM_MOSI, 0, 9)>,
    										<NRF_PSEL(SPIM_MISO, 0, 3)>;
    						low-power-enable;
    				};
    		};
    };
    
    &spi4 {
    		compatible = "nordic,nrf-spim";
    		pinctrl-0 = <&spi_master_default>;
    		pinctrl-1 = <&spi_master_sleep>;
    		pinctrl-names = "default", "sleep";
    		cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;	
    		status = "okay";
    		winbond:winbondw25q02@0 {
    			compatible = "jedec,spi-nor";
    			reg = <0>;
    	//      irq-gpios = <&gpio0 21 0>;
    			spi-max-frequency = <32000000>;
    			//label = "WINBOND";
    			jedec-id = [ ef 70 22 ];
    			size = <0x10000000>;
    			has-dpd;
    			// sfdp-bfp = [
    		 	// 	e5 20 f1 ff  ff ff ff 03  44 eb 08 6b  08 3b 04 bb
    		 	// 	ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52
    		 	// 	10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 68 44
    		 	// 	30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff
    		 	// ];
    		};
    };
    
    /delete-node/ &storage_partition;
    
    &winbond {
    	partitions {
    		compatible = "fixed-partitions";
    		#address-cells = <1>;
    		#size-cells = <1>;
    
    		storage_partition: partition@0 {
    			label = "storage";
    			reg = <0x00000000 0x01000000>;
    		};
    	};
    };
    
    / {
    	msc_disk0 {
    		compatible = "zephyr,flash-disk";
    		partition = <&storage_partition>;
    		disk-name = "NAND";
    		cache-size = <65536>;
    	};
    };

    output terminal:

    winbondw25q02@0 SPI flash testing
    ==========================
    
    Perform test on single sector
    Test 1: Flash erase
    *** Booting nRF Connect SDK v2.7.0-5cb85570ca43 ***
    *** Using Zephyr OS v3.6.99-100befc70c74 ***
    Flash erase succeeded!
    
    Test 2: Flash write
    Attempting to write 4 bytes
    Data read matches data written. Good!!
    [00:00:00.378,845] <inf> flashdisk: Initialize device NAND
    [00:00:00.378,875] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 16777216
    [00:00:00.386,016] <inf> flashdisk: Initialize device NAND
    [00:00:00.386,047] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 16777216
    [00:00:01.456,390] <inf> flashdisk: Initialize device NAND
    [00:00:01.456,420] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 16777216
    FATFS mounted successfully.
    File write successful!
    Reading file content:
    Hello FATFS on SPI Flash!
    


    But my application also requires bluetooth functionality, and when I add CONFIG_BT=y in project config, it says "partition manager enabled and all partitions of devicetree will now be ignored" and I get the following build error:


    C:/ncs/v2.7.0/zephyr/drivers/disk/flashdisk.c:484:1: error: return type defaults to 'int' [-Werror=implicit-int]
    484 | PM_FOREACH_AFFILIATED_TO_disk(DEFINE_FLASHDISKS_CACHE)
    | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    That is why I thought pm_static.yml would fix this problem, but its still the same. However, with CONFIG_BT=n I can at least build and generate the memory report but still cant mount.

  • I have a similar setup on a custom PCB using nrf5340 with external flash chip.

    See  RE: DFU using USB file system (not serial emulation)? 

    in that thread is my pm_static.yml - btw I define staticallly all the partitions on the internal and external flash to ensure that future builds don't move them, and break mcuboot DFU...

    For mounting the FAT FS, I use the ELM FAT subsystem also. I don't actually do a mkfs at all, but it works...

    My init code (you'll need to replace my log_X calls...also I decided to call my fatfs flash area a different name to ensure no interaction with any other random code zephyr/nrf decide to pull in...)

    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/usb/usb_device.h>
    #include <zephyr/usb/usbd.h>
    #include <zephyr/usb/class/usbd_msc.h>
    #include <zephyr/fs/fs.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "util/wutils.h"
    
    #if CONFIG_DISK_DRIVER_FLASH
    #include <zephyr/storage/flash_map.h>
    #endif
    
    #if CONFIG_FAT_FILESYSTEM_ELM
    #include <ff.h>
    #endif
    
    #include "usb_fs.h"
    
    //#define STORAGE_PARTITION		storage_partition
    #define STORAGE_PARTITION		fatfs_storage
    #define STORAGE_PARTITION_ID		FIXED_PARTITION_ID(STORAGE_PARTITION)
    
    static struct fs_mount_t _fs_mnt;
    
    static int _erase_flash(unsigned int id) {
    	const struct flash_area *pfa;
    	int rc = -1;
    
    	rc = flash_area_open(id, &pfa);
    	if (rc<0) {
    		log_warn("Erasing flash area ... failed to open it (%d)",rc);
    		return rc;
    	}
    	log_warn("Opened flash area (%d) -> trying to erase it....",rc);
    	rc = flash_area_erase(pfa, 0, pfa->fa_size);
    	if (rc<0) {
    		log_warn("Erasing flash area ... failed! (%d)",rc);
    	} else {
    		log_warn("Erased flash area OK.");
    	}
    	flash_area_close(pfa);
    	return rc;
    }
    static int _setup_flash(unsigned int id, struct fs_mount_t *mnt)
    {
    	int rc = -1;
    #if CONFIG_DISK_DRIVER_FLASH
    	const struct flash_area *pfa;
    
    	mnt->storage_dev = (void *)id;
    	rc = flash_area_open(id, &pfa);
    	if (rc < 0) {
    		log_warn("Failed to open flash area (%d) -> trying to erase it....",rc);
    		rc = flash_area_erase(pfa, 0, pfa->fa_size);
    		if (rc<0) {
    			log_warn("Erasing flash area ... failed! (%d)",rc);
    			flash_area_close(pfa);
    			return rc;
    		} 
    		log_warn("Erased flash area OK.");
    		rc = flash_area_open(id, &pfa);
    		if (rc<0) {
    			log_warn("Erasing flash area ... didn't help, still can't open it! (%d)",rc);
    			flash_area_close(pfa);
    			return rc;
    		} 
    	}
    	log_info("Flash USB mass storage opened : area %u at 0x%x on %s for %u bytes\n",
    		id, (unsigned int)pfa->fa_off, pfa->fa_dev->name,
    		(unsigned int)pfa->fa_size);
    #endif
    	return pfa->fa_size;
    }
    
    static int _mount_app_fs(struct fs_mount_t *mnt, char* mnt_point)
    {
    	int rc;
    
    #if CONFIG_FAT_FILESYSTEM_ELM
    	static FATFS fat_fs;
    
    	mnt->type = FS_FATFS;
    	mnt->fs_data = &fat_fs;
    	mnt->mnt_point = mnt_point;
    #else
    	log_warn("no file system type defined in firmware build, no FS mount available.");
    	return -1;
    #endif
    	rc = fs_mount(mnt);
    
    	return rc;
    }
    
    static bool _setup_disk(struct fs_mount_t *mp, char* mnt_point) {
    	int rc;
    	int flash_partition_size = 0;
    	if (IS_ENABLED(CONFIG_DISK_DRIVER_FLASH)) {
    		// _erase_flash(STORAGE_PARTITION_ID);		// Only do this if created a FATFS on partition of wrong size initially...
    		flash_partition_size = _setup_flash(STORAGE_PARTITION_ID, mp);
    		if (flash_partition_size < 0) {
    			log_error("Failed to setup flash area");
    			return false;
    		}
    	} else {
    		log_error("No flash driver enabled");
    		return false;
    	}
    
    	if (!IS_ENABLED(CONFIG_FAT_FILESYSTEM_ELM)) {
    		log_error("No file system enabled");
    		return false;
    	}
    
    	rc = _mount_app_fs(mp, mnt_point);
    	if (rc < 0) {
    		log_error("Failed to mount filesystem on %s", mnt_point);
    		return false;
    	}
    	// If fatfs size is not the partition size, then we need to erase the partition and start again
    	struct fs_statvfs fvol;
    	rc = fs_statvfs(mnt_point, &fvol);
    	log_info("statvfs says block size %d, total blocks %d -> %u bytes volume size", fvol.f_blocks, fvol.f_frsize, fvol.f_blocks*fvol.f_frsize);
    	if (abs((fvol.f_blocks*fvol.f_frsize)-flash_partition_size)>100000) {		// approx
    		log_warn("File system size (%u) not equal to flash zone size (%u) -> wiping and reformatting", (fvol.f_blocks*fvol.f_frsize), flash_partition_size);
    		_erase_flash(STORAGE_PARTITION_ID);		// Only do this if created a FATFS on partition of wrong size initially...
    		// And redo?
    		// Need to close parition, unmountfs?
    		fs_unmount(mp);
    		flash_partition_size = _setup_flash(STORAGE_PARTITION_ID, mp);
    		rc = _mount_app_fs(mp, mnt_point);
    		if (rc < 0) {
    			log_error("Failed to mount filesystem on %s", mnt_point);
    			return false;
    		}
    	}
    	/* Allow log messages to flush to avoid interleaved output */
    	k_sleep(K_MSEC(50));
    
    	return true;
    }
    
    And then call during init phase:
    	if (_setup_disk(&_fs_mnt, "/NAND:")) {
    		log_info("USB mass storage mode enabled.\n");
    	} else {
        	log_warn("USB mass storage mode FS failed!");
        }

    Hopefully this will help you... it took me a while to get to this point...

  • Hi BrianW,

    Thank you so much for your response.

    I tried following your suggestion and now my code looks like this:
    main.c

    /*
     * Copyright (c) 2016 Intel Corporation.
     * Copyright (c) 2019-2020 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <sample_usbd.h>
    
    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/usb/usb_device.h>
    #include <zephyr/usb/usbd.h>
    #include <zephyr/usb/class/usbd_msc.h>
    #include <zephyr/fs/fs.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    LOG_MODULE_REGISTER(main);
    
    #include <zephyr/storage/flash_map.h>
    #include <ff.h>
    
    #if CONFIG_FILE_SYSTEM_LITTLEFS
    #include <zephyr/fs/littlefs.h>
    FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage);
    #endif
    
    #define STORAGE_PARTITION fatfs_storage
    #define STORAGE_PARTITION_ID FIXED_PARTITION_ID(STORAGE_PARTITION)
    
    static struct fs_mount_t _fs_mnt;
    
    #if defined(CONFIG_USB_DEVICE_STACK_NEXT)
    static struct usbd_context *sample_usbd;
    
    #if CONFIG_DISK_DRIVER_RAM
    USBD_DEFINE_MSC_LUN(RAM, "Zephyr", "RAMDisk", "0.00");
    #endif
    
    USBD_DEFINE_MSC_LUN(NAND, "Zephyr", "FlashDisk", "0.00");
    
    #if CONFIG_DISK_DRIVER_SDMMC
    USBD_DEFINE_MSC_LUN(SD, "Zephyr", "SD", "0.00");
    #endif
    
    static int enable_usb_device_next(void)
    {
    	int err;
    
    	sample_usbd = sample_usbd_init_device(NULL);
    	if (sample_usbd == NULL)
    	{
    		LOG_ERR("Failed to initialize USB device");
    		return -ENODEV;
    	}
    
    	err = usbd_enable(sample_usbd);
    	if (err)
    	{
    		LOG_ERR("Failed to enable device support");
    		return err;
    	}
    
    	LOG_DBG("USB device support enabled");
    
    	return 0;
    }
    #endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK_NEXT) */
    
    static int _erase_flash(unsigned int id)
    {
    	const struct flash_area *pfa;
    	int rc = -1;
    
    	rc = flash_area_open(id, &pfa);
    	if (rc < 0)
    	{
    		LOG_ERR("Erasing flash area ... failed to open it (%d)", rc);
    		return rc;
    	}
    	LOG_ERR("Opened flash area (%d) -> trying to erase it....", rc);
    	rc = flash_area_erase(pfa, 0, pfa->fa_size);
    	if (rc < 0)
    	{
    		LOG_ERR("Erasing flash area ... failed! (%d)", rc);
    	}
    	else
    	{
    		LOG_ERR("Erased flash area OK.");
    	}
    	flash_area_close(pfa);
    	return rc;
    }
    
    static int _setup_flash(unsigned int id, struct fs_mount_t *mnt)
    {
    	int rc = -1;
    #if CONFIG_DISK_DRIVER_FLASH
    	const struct flash_area *pfa;
    
    	mnt->storage_dev = (void *)id;
    	rc = flash_area_open(id, &pfa);
    	if (rc < 0)
    	{
    		LOG_ERR("Failed to open flash area (%d) -> trying to erase it....", rc);
    		rc = flash_area_erase(pfa, 0, pfa->fa_size);
    		if (rc < 0)
    		{
    			LOG_ERR("Erasing flash area ... failed! (%d)", rc);
    			flash_area_close(pfa);
    			return rc;
    		}
    		LOG_ERR("Erased flash area OK.");
    		rc = flash_area_open(id, &pfa);
    		if (rc < 0)
    		{
    			LOG_ERR("Erasing flash area ... didn't help, still can't open it! (%d)", rc);
    			flash_area_close(pfa);
    			return rc;
    		}
    	}
    	LOG_ERR("Flash USB mass storage opened : area %u at 0x%x on %s for %u bytes\n",
    			id, (unsigned int)pfa->fa_off, pfa->fa_dev->name,
    			(unsigned int)pfa->fa_size);
    #endif
    	return pfa->fa_size;
    }
    
    static int _mount_app_fs(struct fs_mount_t *mnt, char *mnt_point)
    {
    	int rc;
    
    #if CONFIG_FAT_FILESYSTEM_ELM
    	static FATFS fat_fs;
    
    	mnt->type = FS_FATFS;
    	mnt->fs_data = &fat_fs;
    	mnt->mnt_point = mnt_point;
    #else
    	LOG_ERR("no file system type defined in firmware build, no FS mount available.");
    	return -1;
    #endif
    	rc = fs_mount(mnt);
    
    	return rc;
    }
    
    static bool _setup_disk(struct fs_mount_t *mp, char *mnt_point)
    {
    	int rc;
    	int flash_partition_size = 0;
    	if (IS_ENABLED(CONFIG_DISK_DRIVER_FLASH))
    	{
    		// _erase_flash(STORAGE_PARTITION_ID);		// Only do this if created a FATFS on partition of wrong size initially...
    		flash_partition_size = _setup_flash(STORAGE_PARTITION_ID, mp);
    		if (flash_partition_size < 0)
    		{
    			LOG_ERR("Failed to setup flash area");
    			return false;
    		}
    	}
    	else
    	{
    		LOG_ERR("No flash driver enabled");
    		return false;
    	}
    
    	if (!IS_ENABLED(CONFIG_FAT_FILESYSTEM_ELM))
    	{
    		LOG_ERR("No file system enabled");
    		return false;
    	}
    
    	rc = _mount_app_fs(mp, mnt_point);
    	if (rc < 0)
    	{
    		LOG_ERR("Failed to mount filesystem on %s", mnt_point);
    		return false;
    	}
    	// If fatfs size is not the partition size, then we need to erase the partition and start again
    	struct fs_statvfs fvol;
    	rc = fs_statvfs(mnt_point, &fvol);
    	LOG_INF("statvfs says block size %d, total blocks %d -> %u bytes volume size", fvol.f_blocks, fvol.f_frsize, fvol.f_blocks * fvol.f_frsize);
    	if (abs((fvol.f_blocks * fvol.f_frsize) - flash_partition_size) > 100000)
    	{ // approx
    		LOG_ERR("File system size (%u) not equal to flash zone size (%u) -> wiping and reformatting", (fvol.f_blocks * fvol.f_frsize), flash_partition_size);
    		_erase_flash(STORAGE_PARTITION_ID); // Only do this if created a FATFS on partition of wrong size initially...
    		// And redo?
    		// Need to close parition, unmountfs?
    		fs_unmount(mp);
    		flash_partition_size = _setup_flash(STORAGE_PARTITION_ID, mp);
    		rc = _mount_app_fs(mp, mnt_point);
    		if (rc < 0)
    		{
    			LOG_ERR("Failed to mount filesystem on %s", mnt_point);
    			return false;
    		}
    	}
    	/* Allow log messages to flush to avoid interleaved output */
    	k_sleep(K_MSEC(50));
    
    	return true;
    }
    
    int main(void)
    {
    	int ret;
    
    	if (_setup_disk(&_fs_mnt, "/NAND:"))
    	{
    		LOG_INF("USB mass storage mode enabled.\n");
    	}
    	else
    	{
    		LOG_ERR("USB mass storage mode FS failed!");
    	}
    
    #if defined(CONFIG_USB_DEVICE_STACK_NEXT)
    	ret = enable_usb_device_next();
    #else
    	ret = usb_enable(NULL);
    #endif
    	if (ret != 0)
    	{
    		LOG_ERR("Failed to enable USB");
    		return 0;
    	}
    
    	LOG_INF("The device is put in USB mass storage mode.\n");
    	return 0;
    }
    

    Here is my complete pm_static.yml file that I used:

    mcuboot:
        address: 0x0
        end_address: 0xe000
        region: flash_primary
        size: 0xe000
    
    mcuboot_pad:
        address: 0xe000
        end_address: 0xe200
        region: flash_primary
        size: 0x200
    
    app:
        address: 0xe200
        end_address: 0x100000
        region: flash_primary
        size: 0xf1e00
    
    mcuboot_primary_app:
        address: 0xe200
        end_address: 0x100000
        region: flash_primary
        size: 0xf1e00
        span: [app]
    
    mcuboot_primary:
        address: 0xe000
        end_address: 0x100000
        region: flash_primary
        size: 0xf2000
        span: [mcuboot_pad, mcuboot_primary_app]
    
    # define partition for fatfs disk, on the external flash storage (probably the device defined by nordic,pm-ext-flash in the DTS)
    fatfs_storage:
        region: external_flash
        affiliation: 
            - disk
        extra_params: {
            disk_name: "NAND",
            disk_cache_size: 4096,
            disk_sector_size: 512,
            disk_read_only: 0
        }
        # 6Mb size, external flash is 8Mb total
        address: 0x0
        size: 0x600000
    
    nvs_storage:
        region: external_flash
        affiliation: 
            - nvs
        # 64kB size, its just for small stuff
        address: 0x600000
        size: 0x10000
    
    mcuboot_secondary_1:
        region: external_flash
        affiliation: 
            - mcuboot
        # 256kb size, its for netcore flash image
        address: 0x610000
        size: 0x40000
    
    mcuboot_secondary:
        region: external_flash
        affiliation: 
            - mcuboot
        address: 0x650000
        # MUST be same size as the primary application slot size, and share_size does not appear to work
        size: 0xf1e00
        #share_size: [mcuboot_primary_app]
    
    # internal cuisine
    otp:
        address: 0xff8100
        end_address: 0xff83fc
        region: otp
        size: 0x2fc
    pcd_sram:
        address: 0x20000000
        end_address: 0x20002000
        #placement:
        #    after:
        #    - start
        region: sram_primary
        size: 0x2000
    rpmsg_nrf53_sram:
        address: 0x20070000
        end_address: 0x20080000
        #placement:
        #    before:
        #    - end
        region: sram_primary
        size: 0x10000
    sram_primary:
        address: 0x20002000
        end_address: 0x20070000
        region: sram_primary
        size: 0x6e000
    
    # TODO need fake flash ram flash partition to do cpunet DFU...
    #mcuboot_primary_1:
    #  address: 0x0
    #  device: nordic_ram_flash_controller
    #  end_address: 0x40000
    #  region: ram_flash
    #  size: 0x40000
    #
    #ram_flash:
    #  address: 0x40000
    #  end_address: 0x40000
    #  region: ram_flash
    #  size: 0x0

    Here is my overlay:

    / {
    	chosen {
    		nordic,pm-ext-flash = &winbond;
    	};
    };
    
    
    
    
    &button2 {
    	status = "disabled";
    };
    
    &button3 {
    	status = "disabled";
    };
    
    &gpio_fwd {
    	status = "disabled";
    };
    
    &uicr {nfct-pins-as-gpios; };
    
    &pinctrl {
    	spi_master_default: spi_master_default {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,   // SCLK
    			<NRF_PSEL(SPIM_MOSI, 0, 9)>,  // MOSI
    			<NRF_PSEL(SPIM_MISO, 0, 3)>;  // MISO
    		};
    	};
    
    	spi_master_sleep: spi_master_sleep {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,   // SCLK
    			<NRF_PSEL(SPIM_MOSI, 0, 9)>,  // MOSI
    			<NRF_PSEL(SPIM_MISO, 0, 3)>;  // MISO
    			low-power-enable;
    		};
    	};
    };
    
    
    &spi3 {
    	compatible = "nordic,nrf-spim";
    	pinctrl-0 = <&spi_master_default>;
    	pinctrl-1 = <&spi_master_sleep>;
    	pinctrl-names = "default", "sleep";
    	cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;    // Chip Select (CS) on Pin 11
    	status = "okay";
    	winbond: winbond@0 {
    		compatible = "jedec,spi-nor";
    		reg = <0>;                               // CS0
    		spi-max-frequency = <32000000>;
    		// SPI max frequency (32 MHz)
    		jedec-id = [ ef 70 22  ];                  // JEDEC ID for W25Q02JV
    		size = <268435456>;                      // 256MB NOR flash size
    		has-dpd;                                 // Deep Power Down (DPD) support
    	};
    };
    

    And using this I get this partition report:

     external_flash (0x10000000 - 262144kB): 
    +-------------------------------------------------+
    | 0x0: external_flash (0x10000000 - 262144kB)     |
    | 0x0: fatfs_storage (0x600000 - 6144kB)          |
    | 0x600000: nvs_storage (0x10000 - 64kB)          |
    | 0x610000: mcuboot_secondary_1 (0x40000 - 256kB) |
    | 0x650000: mcuboot_secondary (0xf1e00 - 967kB)   |
    +-------------------------------------------------+
    
      flash_primary (0x100000 - 1024kB):
    +-------------------------------------------------+
    | 0x0: mcuboot (0xe000 - 56kB)                    |
    +---0xe000: mcuboot_primary (0xf2000 - 968kB)-----+
    | 0xe000: mcuboot_pad (0x200 - 512B)              |
    +---0xe200: mcuboot_primary_app (0xf1e00 - 967kB)-+
    | 0xe200: app (0xf1e00 - 967kB)                   |
    +-------------------------------------------------+
    
      otp (0x2fc - 764B):
    +------------------------------+
    | 0xff8100: otp (0x2fc - 764B) |
    +------------------------------+
    
      sram_primary (0x80000 - 512kB):
    +-----------------------------------------------+
    | 0x20000000: pcd_sram (0x2000 - 8kB)           |
    | 0x20002000: sram_primary (0x6e000 - 440kB)    |
    | 0x20070000: rpmsg_nrf53_sram (0x10000 - 64kB) |
    +-----------------------------------------------+
    
     CPUNET flash_primary (0x40000 - 256kB):
    +--------------------------------------+
    +---0x1000000: app (0x40000 - 256kB)---+
    | 0x1000000: hci_ipc (0x40000 - 256kB) |
    +--------------------------------------+
    
     CPUNET sram_primary (0x10000 - 64kB):
    +-------------------------------------------+
    | 0x21000000: sram_primary (0x10000 - 64kB) |
    +-------------------------------------------+

    prj.conf

    CONFIG_STDOUT_CONSOLE=y
    
    # CONFIG_LOG=y
    # CONFIG_RTT_CONSOLE=y
    # CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG_BACKEND_UART=y
    
    CONFIG_FLASH=y
    
    # # Enable mcumgr.
    # CONFIG_MCUMGR=y
    
    # # Enable most core commands.
    # CONFIG_MCUMGR_CMD_IMG_MGMT=y
    # CONFIG_MCUMGR_CMD_OS_MGMT=y
    
    # # Ensure an MCUboot-compatible binary is generated.
    # CONFIG_BOOTLOADER_MCUBOOT=y
    
    # CONFIG_MULTITHREADING=y
    
    # # Some command handlers require a large stack.
    # CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    
    # CONFIG_NORDIC_QSPI_NOR=y
    # CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    # CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16
    
    # CONFIG_MCUMGR_SMP_UART=y
    
    # CONFIG_MCUBOOT_IMAGE_VERSION="0.1.1+8"
    
    # CONFIG_PM_PARTITION_REGION_FATFS_STORAGE_EXTERNAL=y
    
    
    #USB related configs
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Very FATFS storage"
    CONFIG_USB_DEVICE_PID=0x0008
    CONFIG_LOG=y
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    CONFIG_USB_MASS_STORAGE=y
    CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
    CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
    CONFIG_USB_CDC_ACM=n
    CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
    CONFIG_APP_MSC_STORAGE_FLASH_FATFS=y
    CONFIG_MAIN_STACK_SIZE=10240
    CONFIG_APP_WIPE_STORAGE=y
    CONFIG_NORDIC_QSPI_NOR=n
    CONFIG_SPI=y
    CONFIG_SPI_NOR=y
    CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    CONFIG_NRFX_SPIM3=y
    
    CONFIG_MULTITHREADING=y
    CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y
    CONFIG_BT=y
    

    After doing this now, when I flash I get nothing in the terminal, not even 
    *** Booting nRF Connect SDK v2.7.0-5cb85570ca43 ***
    *** Using Zephyr OS v3.6.99-100befc70c74 ***workingFlash.zip

    I have also attached the zip file, if you want to take a look. It is my first time working with storage, file system and Bluetooth together, I would really appreciate if you could provide any further suggestions here.

    Regards,

    Barsha

  • If its possible can you share your prj.conf and overlay file?

  • It looks like your prj.conf has commented out the critical mcuboot keys?

    # CONFIG_BOOTLOADER_MCUBOOT=y

    if you make a partition map with mcuboot at 0x0, you need to build an image with mcuboot in there...

    in prj.conf:
    CONFIG_BOOTLOADER_MCUBOOT=y
    # put slot2 in external flash
    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y
    CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH=y
    And then you need to put a 'mcuboot.conf' file in the directory 'child_image' containing:
    CONFIG_MCUBOOT_SERIAL=n
    CONFIG_BOOT_MAX_IMG_SECTORS=256
    CONFIG_FPROTECT=n

    CONFIG_BOOTLOADER_MCUBOOT=y
    (this is also where you put the config for image signing keys files etc).
    My proj.conf (but this is still a work in progress especially as I'm fighting with the wifi stuff right now..)
    #
    # Copyright (c) 2021 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    #debug core dump : TODO change to use flash partition
    CONFIG_DEBUG_COREDUMP=n
    CONFIG_DEBUG_COREDUMP_BACKEND_LOGGING=n
    CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN=n
    
    # debug/memory/thread/stack check analysis : 
    # TODO remove for runtime
    CONFIG_DEBUG=n
    CONFIG_DEBUG_INFO=n
    
    CONFIG_THREAD_NAME=y
    # TODO remove for runtime
    CONFIG_THREAD_ANALYZER=y
    CONFIG_THREAD_ANALYZER_USE_PRINTK=n
    CONFIG_THREAD_ANALYZER_AUTO=n
    #CONFIG_THREAD_ANALYZER_AUTO_INTERVAL=60
    #CONFIG_THREAD_ANALYZER_RUN_UNLOCKED=y
    
    CONFIG_SYS_HEAP_RUNTIME_STATS=y
    CONFIG_INIT_STACKS=y
    
    # TODO remove for runtime
    CONFIG_ASSERT=y
    CONFIG_ASSERT_VERBOSE=y
    CONFIG_ASSERT_NO_COND_INFO=n
    CONFIG_ASSERT_NO_MSG_INFO=n
    CONFIG_STACK_SENTINEL=y
    # system HALT on error (useful for debugger?)
    # TODO remove for runtime
    CONFIG_RESET_ON_FATAL_ERROR=n
    CONFIG_REBOOT=y
    
    #CONFIG_NCS_SAMPLES_DEFAULTS=y
    CONFIG_LOG=y
    CONFIG_LOG_MODE_MINIMAL=y
    CONFIG_LOG_MODE_IMMEDIATE=y
    CONFIG_LOG_BACKEND_UART=y
    CONFIG_LOG_DEFAULT_LEVEL=3
    CONFIG_LOG_PRINTK=n
    # warning : if shell enabled this caused fatal crash at boot...
    CONFIG_SHELL=n
    CONFIG_SHELL_MINIMAL=n
    CONFIG_SHELL_LOG_BACKEND=n
    
    # cannot access binary says ninja, also the info is not available to the source code
    #CONFIG_BINDESC=y
    #CONFIG_BINDESC_DEFINE=y
    #CONFIG_BINDESC_DEFINE_BUILD_TIME=y
    #CONFIG_BINDESC_BUILD_DATE_TIME_STRING=y
    #CONFIG_BINDESC_BUILD_DATE_TIME_STRING_FORMAT="%Y-%m-%dT%H:%M"
    
    CONFIG_GPIO=y
    CONFIG_GPIO_MCP230XX=y
    CONFIG_SERIAL=y
    CONFIG_UART_CONSOLE=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_ASYNC_API=y
    CONFIG_UART_LINE_CTRL=y
    
    CONFIG_I2C=y
    CONFIG_I2C_CALLBACK=y
    CONFIG_I2C_NRFX=y
    #CONFIG_I2C_NRFX_TWIM=y
    #CONFIG_NRFX_TXI_ENABLED=y
    
    CONFIG_SPI=y
    CONFIG_SPI_ASYNC=y
    
    # Using AEF event system for inter-module comm and sync
    CONFIG_APP_EVENT_MANAGER=y
    CONFIG_APP_EVENT_MANAGER_POSTINIT_HOOK=y
    CONFIG_CAF=y
    CONFIG_CAF_PM_EVENTS=y
    CONFIG_CAF_POWER_MANAGER=n
    #CONFIG_CAF_BUTTONS=y
    #CONFIG_CAF_BUTTONS_DEF_PATH="cc1_med_buttons_def.h"
    CONFIG_CAF_BUTTON_EVENTS=y
    #CONFIG_CAF_BUTTONS_PM_EVENTS=y
    # button polarity inverse on DK board... tbd on real hw
    #CONFIG_CAF_BUTTONS_POLARITY_INVERSED=y
    #CONFIG_CAF_BUTTONS_PM_KEEP_ALIVE=n
    CONFIG_CAF_CLICK_DETECTOR=y
    CONFIG_CAF_CLICK_DETECTOR_LONG_CLICK_MSEC=2000
    CONFIG_CAF_CLICK_DETECTOR_PM_EVENTS=y
    CONFIG_CAF_CLICK_DETECTOR_DEF_PATH="cc1_med_buttons_click_def.h"
    CONFIG_LED=y
    CONFIG_LED_GPIO=y
    
    # libaries
    CONFIG_NEWLIB_LIBC=y
    CONFIG_NEWLIB_LIBC_NANO=n
    CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
    CONFIG_COMMON_LIBC_CALLOC=y
    CONFIG_COMMON_LIBC_REALLOCARRAY=y
    # use malloc that maps to k_malloc(), and allocate all remaing RAM to heap (-1)
    CONFIG_COMMON_LIBC_MALLOC=y
    CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=180000
    CONFIG_HEAP_MEM_POOL_SIZE=50000
    
    CONFIG_FLASH=y
    CONFIG_I2S=y
    CONFIG_I2S_NRFX=y
    CONFIG_NRFX_PDM=y
    CONFIG_PWM=y
    CONFIG_SYS_HASH_MAP=y
    # using cJSON
    CONFIG_CJSON_LIB=y
    CONFIG_JSON_LIBRARY=n
    CONFIG_BASE64=y
    CONFIG_UTF8=y
    CONFIG_CHARACTER_FRAMEBUFFER=y
    # using NVS system for blobmgr. NVS partition defined in pm_static.yml
    CONFIG_NVS=y
    
    CONFIG_STDOUT_CONSOLE=y
    
    # turn on Partition manager (must be on) to use partitions from pm_static.yml
    CONFIG_PM_SINGLE_IMAGE=y
    
    #USB related configs
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Infrafon CC2-WDD"
    # USB VID is MCS electronics, who sell individual PIDs. 0x138F is for CC2 purchases 25/08/2024
    CONFIG_USB_DEVICE_VID=0x16D0
    CONFIG_USB_DEVICE_PID=0x138F
    CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
    
    CONFIG_USB_DEVICE_HID=y
    CONFIG_USB_HID_DEVICE_COUNT=2
    
    CONFIG_USB_MASS_STORAGE=y
    CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
    CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
    CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
    CONFIG_NORDIC_QSPI_NOR=y
    
    # flash disk config
    # The mx25 erase page size
    CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
    CONFIG_DISK_DRIVERS=y
    CONFIG_DISK_DRIVER_FLASH=y
    # use ELM FATFS with long file names (not 8.3)
    CONFIG_FILE_SYSTEM=y
    CONFIG_FAT_FILESYSTEM_ELM=y
    CONFIG_FS_FATFS_MOUNT_MKFS=y
    CONFIG_FS_FATFS_LFN=y
    CONFIG_FS_FATFS_EXFAT=n
    
    CONFIG_MASS_STORAGE_DISK_NAME="NAND"
    CONFIG_FLASH_MAP=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    
    # BT/BLE config
    CONFIG_BT=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_DEVICE_NAME="CC2-WDD-2"
    CONFIG_BT_DEVICE_APPEARANCE=512
    CONFIG_BT_DEVICE_NAME_DYNAMIC=y
    
    CONFIG_BT_EXT_ADV=y
    CONFIG_BT_EXT_ADV_MAX_ADV_SET=2
    
    CONFIG_BT_DIS=y
    CONFIG_BT_DIS_PNP=y
    CONFIG_BT_DIS_MANUF="Infrafon"
    CONFIG_BT_DIS_PNP_VID_SRC=2
    CONFIG_BT_DIS_PNP_VID=0x1915
    CONFIG_BT_DIS_PNP_PID=0xEEF1
    CONFIG_BT_DIS_PNP_VER=0x0100
    
    CONFIG_BT_OBSERVER=y
    CONFIG_BT_SCAN=y
    CONFIG_BT_NUS=y
    
    # WIFI config
    CONFIG_WIFI=y
    CONFIG_WIFI_NRF700X=y
    CONFIG_NRF_WIFI_PATCHES_BUILTIN=y
    #CONFIG_NRF700X_RADIO_COEX=y
    CONFIG_NRF_WIFI_LOW_POWER=y
    CONFIG_NRF_WIFI_IF_AUTO_START=y
    
    CONFIG_NRF700X_AP_MODE=n
    CONFIG_NRF700X_P2P_MODE=n
    CONFIG_NRF700X_STA_MODE=y
    
    # WPA supplicant
    CONFIG_WPA_SUPP=y
    #CONFIG_WPA_SUPP_LOG_LEVEL_INF=y
    #CONFIG_WIFI_NM=y
    #CONFIG_WIFI_NM_LOG_LEVEL_INF=y
    
    # No, follwing is experimental bad code
    #CONFIG_WIFI_NM_WPA_SUPPLICANT=y
    #CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_INF=y
    #CONFIG_NO_WPA=n
    
    CONFIG_NET_L2_ETHERNET=y
    #CONFIG_NET_L2_WIFI_MGMT=y
    
    # Networking layers
    CONFIG_NETWORKING=y
    CONFIG_NET_SOCKETS=y
    CONFIG_NET_LOG=y
    CONFIG_NET_IPV4=y
    CONFIG_NET_UDP=y
    CONFIG_NET_TCP=y
    CONFIG_NET_DHCPV4=y
    #CONFIG_DNS_RESOLVER=y
    #CONFIG_HTTP_CLIENT=y
    #CONFIG_MQTT_LIB=y
    
    CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=1
    CONFIG_NET_MAX_CONTEXTS=5
    CONFIG_NET_CONTEXT_SYNC_RECV=y
    #Note that sockets are used by WPA suppliant code
    CONFIG_NET_SOCKETS_POLL_MAX=10
    
    # net_config is only for testing to set IP address directly
    CONFIG_NET_CONFIG_SETTINGS=n
    #CONFIG_NET_CONFIG_SETTINGS=y
    #CONFIG_NET_CONFIG_INIT_TIMEOUT=0
    # Must call net_config_init() explicitly
    #CONFIG_NET_CONFIG_AUTO_INIT=n
    #CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.1.99"
    #CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
    #CONFIG_NET_CONFIG_MY_IPV4_GW="192.168.1.1"
    
    # Memory usage
    CONFIG_NET_TX_STACK_SIZE=4096
    CONFIG_NET_RX_STACK_SIZE=4096
    CONFIG_WPA_SUPP_WQ_STACK_SIZE=4096
    CONFIG_NET_MGMT_EVENT_STACK_SIZE=4096
    
    # Optimized networking settings for memory usage (STA MODE IOT DEVICES profile)
    # https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/wifi/stack_configuration.html
    CONFIG_NRF700X_MAX_TX_TOKENS=5
    CONFIG_NRF700X_MAX_TX_AGGREGATION=1
    CONFIG_NRF700X_RX_NUM_BUFS=6
    
    CONFIG_NET_TC_TX_COUNT=1
    CONFIG_NET_PKT_RX_COUNT=6
    CONFIG_NET_PKT_TX_COUNT=6
    
    CONFIG_NET_BUF_RX_COUNT=6
    CONFIG_NET_BUF_TX_COUNT=12
    # can take BUF_DATAT_SIZE down to 500
    CONFIG_NET_BUF_DATA_SIZE=800
    
    # NFC config
    CONFIG_NFC_T2T_NRFXLIB=y
    CONFIG_NFC_T4T_NRFXLIB=y
    CONFIG_NFC_T4T_ISODEP=y
    
    CONFIG_NFC_NDEF=y
    CONFIG_NFC_NDEF_MSG=y
    CONFIG_NFC_NDEF_RECORD=y
    CONFIG_NFC_NDEF_URI_REC=y
    CONFIG_NFC_NDEF_URI_MSG=y
    
    CONFIG_MAIN_STACK_SIZE=4096
    # need big stack for system workqueue thread, as this is where we execute pretty much all real operations
    #CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=32796
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    
    CONFIG_BOOTLOADER_MCUBOOT=y
    # put slot2 in external flash
    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y
    CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH=y
    CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE=y
    #CONFIG_MCUBOOT_BOOTUTIL_LIB=n
    #CONFIG_MCUBOOT_IMG_MANAGER=n
    CONFIG_MCUBOOT_SHELL=n
    #CONFIG_MCUBOOT_USB_SUPPORT=n
    #CONFIG_MCUBOOT_UTIL_LOG_LEVEL_ERR=n
    
    # sign with our own key
    CONFIG_MCUBOOT_BUILD_STRATEGY_FROM_SOURCE=y
    #CONFIG_BOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    #CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    # not using 2 stage bootloader
    #CONFIG_SECURE_BOOT=y
    #CONFIG_SB_SIGNING_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    #CONFIG_SB_SIGNING_OPENSSL=y
    # want bin and hexes
    CONFIG_BUILD_OUTPUT_BIN=y
    CONFIG_BUILD_OUTPUT_HEX=y
    
    # to allow net CPU update (complex & hard...)
    #CONFIG_UPDATEABLE_IMAGE_NUMBER=2
    #CONFIG_PCD_APP=y
    #CONFIG_FLASH_SIMULATOR=y
    #CONFIG_NRF53_MULTI_IMAGE_UPDATE=n
    #CONFIG_USE_NRF53_MULTI_IMAGE_WITHOUT_UPGRADE_ONLY=n
    
    # Enable DFU target for application image, this lets us write an image downloaded from whereever into the secondary slot for update by mcuboot
    CONFIG_DFU_TARGET=y
    CONFIG_STREAM_FLASH=y
    CONFIG_STREAM_FLASH_ERASE=y
    CONFIG_DFU_TARGET_STREAM=y
    CONFIG_IMG_MANAGER=y
    CONFIG_DFU_TARGET_MCUBOOT=y
    and child_image/mcuboot.conf
    CONFIG_MCUBOOT_SERIAL=n
    CONFIG_BOOT_MAX_IMG_SECTORS=256
    CONFIG_FPROTECT=n
    
    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y
    CONFIG_BOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    #CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="/work/dev/if-device-nrf53/keys/bootloader_priv-ecdsa256.pem"
    
    
     
    I don't use an overlay, just a single DTS file as my board is custom. And my flash chip is different (only 8Mb...)
Related