Sharing External QSPI Flash IS25LP for Both XIP and LittleFS on Custom nRF5340 Board - BUS FAULT with High File System Activity

Hello,

I have been attempting to implement a system on my custom nRF5340 board where the external QSPI flash (IS25LP) is shared between eXecute-in-Place (XIP) functionality and the LittleFS file system for data storage.

I have observed that with significant activity on the file system, the system has BUS FAULT.

Given that both XIP and LittleFS are accessing the same external flash resource, I experimented with using a mutex to regulate access between the two. It work but it presents a very limited solution.

The main project files are attached for your review.

I am requesting guidance on how to implement a more robust and efficient solution for sharing the external flash between XIP and LittleFS, or if there are any relevant examples available that address this specific scenario.

Thank you for your time and assistance.

SDK: 2.9.0

Toolchain: 2.9.0

/ {
	chosen {
		/*nordic,pm-ext-flash = &mx25r64;*/
		nordic,pm-ext-flash = &is25lp_;
		/* zephyr,console = &cdc_acm_uart0; */
                /* zephyr,shell-uart = &cdc_acm_uart0; */
                /* uart0 is default */
		zephyr,console = &uart0;
                zephyr,shell-uart = &uart0;
        };
};

&zephyr_udc0 {
/*        
        cdc_acm_uart0: cdc_acm_uart0 {
                compatible = "zephyr,cdc-acm-uart";
        };
*/
        cdc_acm_uart1: cdc_acm_uart1 {
                compatible = "zephyr,cdc-acm-uart";
        };
/*
        cdc_acm_uart2: cdc_acm_uart2 {
                compatible = "zephyr,cdc-acm-uart";
        };
*/
};

&qspi {
        mx25r64: mx25r6435f@0 {
                        status = "disabled";
        };
        is25lp_: is25lp128f@0 {
                status = "okay";
                compatible = "nordic,qspi-nor";
                reg = <0>;
                
                writeoc = "pp4o";
                readoc = "read4io";
                
                sck-frequency = <8000000>; 
                
                jedec-id = [9d 60 18];
/*
                sfdp-bfp = [												
                        53 46 44 50  06 01 00 FF  00 06 01 10  30 00 00 FF    
                        FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF    
                        FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF
                        E5 20 FB FF  FF FF FF 07  44 EB 08 6B  08 3B 80 BB
                        FE FF FF FF  FF FF 00 FF  FF FF 44 EB  0C 20 0F 52
                        10 D8 00 FF  62 42 A9 00  82 D8 01 C8  EC 8D 69 4C
                        7A 75 7A 75  F7 A2 D5 5C  
                        4A C2 2C FF  E8 30 FA A9 
                ];
*/		
                size = <134217728>; /* # 16MB = 128Mb */ 
                quad-enable-requirements = "S1B6";

                has-dpd;
                t-enter-dpd = <3000>;
                t-exit-dpd = <3000>;

        };
};         


&pinctrl {

        uart0_default: uart0_default {
                group1 {
                        psels = <NRF_PSEL(UART_TX, 1, 13)>;
                };
                group2 {
                        psels = <NRF_PSEL(UART_RX, 1, 14)>;
                        //bias-pull-up;
                };
        };

        uart0_sleep: uart0_sleep {
                group1 {
                        psels = <NRF_PSEL(UART_TX, 1, 13)>;
                };
                group2 {
                        psels = <NRF_PSEL(UART_RX, 1, 14)>;
                        //bias-pull-up;
                };
        };

        i2c1_default: i2c1_default {
                group1 {
                        psels = <NRF_PSEL(TWIM_SDA, 1, 3)>,
                                <NRF_PSEL(TWIM_SCL, 1, 2)>;
                };
        };

        i2c1_sleep: i2c1_sleep {
                group1 {
                        psels = <NRF_PSEL(TWIM_SDA, 1, 3)>,
                                <NRF_PSEL(TWIM_SCL, 1, 2)>;
                        low-power-enable;
                };
        };        
};

&pinctrl {
        spi_master_default: spi_master_default {
                group1 {
                        psels = <NRF_PSEL(SPIM_SCK, 0, 26)>,
                                <NRF_PSEL(SPIM_MOSI, 1, 8)>,
                                <NRF_PSEL(SPIM_MISO, 0, 27)>;
                };
        };

        spi_master_sleep: spi_master_sleep {
                group1 {
                        psels = <NRF_PSEL(SPIM_SCK, 0, 26)>,
                                        <NRF_PSEL(SPIM_MOSI, 1, 8)>,
                                        <NRF_PSEL(SPIM_MISO, 0, 27)>;
                        low-power-enable;
                };
        };
};
&button0 {
        status = "disabled";
};
&button1 {
        status = "disabled";
};
&button2 {
        status = "disabled";
};
&button3 {
        status = "disabled";
};
&led1 {
        status = "disabled";
};
&led2 {
        status = "disabled";
};
&led3 {
        status = "disabled";
};

my_spi_master: &spi4 {
        compatible = "nordic,nrf-spim";
        status = "okay";
        pinctrl-0 = <&spi_master_default>;
        pinctrl-1 = <&spi_master_sleep>;
        pinctrl-names = "default", "sleep";
        
        cs-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>,
                   <&gpio1  5 GPIO_ACTIVE_LOW>, 
                   <&gpio0 29 GPIO_ACTIVE_LOW>; 

        reg_my_spi_master:  spi-dev-a@0 {
                reg = <0>;
        };        
        ad5291_a_master:  spi-dev-b@1 {
                reg = <1>;
        };
        ad5291_b_master:  spi-dev-c@2 {
                reg = <2>;
        };
};
       
/ {
        single_gpio {
                compatible = "gpio-leds";
                adc_drdy: adc_drdy_gpio {
                        gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
                        label = "ADC DRDY";
                };
                adc_start: adc_start_gpio {
                        gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
                        label = "ADC START";
                };
/*                
                v_exc_enable: v_exc_enable_gpio {
                        gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
                        label = "V EXC ENABLE";
                };
*/
                happy_led: happy_led_gpio {
                        gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
                        label = "HAPPY LED";
                };
                in1: in1_gpio {
                        gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
                        label = "IN1";
                };
                in2: in2_gpio {
                        gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
                        label = "IN2";
                };
        };

};

&i2c1 {  
/*        
//        EEPROM_CPU Address: 1 0 1 0 A2 A1 A0 --> 1010000 --> 0x50 
//        EEPROM_IO  Address: 1 0 1 0 A2 A1 A0 --> 1010001 --> 0x51 
//        EEPROM_TST1  Address: 1 0 1 0 A2 A1 A0 --> 1010010 --> 0x52
//        EEPROM_TST2  Address: 1 0 1 0 A2 A1 A0 --> 1010011 --> 0x53
//        EEPROM_TST3  Address: 1 0 1 0 A2 A1 A0 --> 1010100 --> 0x54
//        IO_EXP     Address: 0 1 0 0  0  0 AA --> 0100001 --> 0x21
//        IO_EXP_CPU Address: 0 1 0 0  0  0 AA --> 0100000 --> 0x20
//        I2C_MULTI  Address: 1 1 1 0 AA AA AA --> 1110000 --> 0x70
//        SENS_CURR  Address: 0 0 1 1  0  1  0 --> 0011010 --> 0x1A
*/
        e2pcpu: e2pcpu@50{
                compatible = "i2c-device";
                status = "okay";
                reg = < 0x50 >;
        };	
        e2pio: e2pio@51{
                compatible = "i2c-device";
                status = "okay";
                reg = < 0x51 >;
        };
        eepromtst1: eepromtst1@52{
                compatible = "i2c-device";
                status = "okay";
                reg = < 0x52 >;
        };
        eepromtst2: eepromtst2@53{
                compatible = "i2c-device";
                status = "okay";
                reg = < 0x53 >;
        };
        eepromtst3: eepromtst2@54{
                compatible = "i2c-device";
                status = "okay";
                reg = < 0x54 >;
        };
        ioexp: ioexp@21{
                compatible = "i2c-device";
                status = "okay";
                reg = < 0x21 >;
        };
        ioexpcpu: ioexpcpu@20{
                compatible = "i2c-device";
                status = "okay";
                reg = < 0x20 >;
        };
        icmulti: icmulti@70{
                compatible = "i2c-device";
                status = "okay";
                reg = < 0x70 >;
        };
        senscurr: senscurr@1A{
                compatible = "i2c-device";
                status = "okay";
                reg = < 0x1A >;
        };
};


/ {
        aliases {
                qspi-flash0 = &is25lp_;
        };
};

&timer0 {
        status = "okay";
};
&adc {
        status = "okay";
};

&timer2 {
        status = "okay";
};

&led0 {
        gpios = <&gpio0 28 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
};
&pinctrl {
        uart2_default: uart2_default {
                group1 {
                        psels = <NRF_PSEL(UART_TX, 0, 31)>;
                };
                group2 {
                        psels = <NRF_PSEL(UART_RX, 0, 30)>;
                };
        };
        uart2_sleep: uart2_sleep {
                group1 {
                        psels = <NRF_PSEL(UART_TX, 0, 31)>, <NRF_PSEL(UART_RX, 0, 30)>;


                };
        };
};
&uart2 {
	status = "okay";
	current-speed = <115200>;
	pinctrl-0 = <&uart2_default>;
	pinctrl-1 = <&uart2_sleep>;
	pinctrl-names = "default", "sleep";
};
/* Remove flow control pins*/
&gpio_fwd {
        uart {
                gpios = <&gpio1 1 0>, <&gpio1 0 0>;
        };
};

/{
        pwmleds {
                compatible = "pwm-leds";
                pwm_led0: pwm_led_0 {
                        pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
                };
        };
};

&pwm0 {
        status = "okay";
        pinctrl-0 = <&pwm0_custom>;
        pinctrl-1 = <&pwm0_csleep>;
        pinctrl-names = "default", "sleep";
};

&pinctrl {
        pwm0_custom: pwm0_custom {
            group1 {
                psels = <NRF_PSEL(PWM_OUT0, 0, 8)>;
                nordic,invert;
            };
        };
	pwm0_csleep: pwm0_csleep {
            group1 {
                psels = <NRF_PSEL(PWM_OUT0, 0, 8)>;
                low-power-enable;
            };
        };
};

&pinctrl {

        uart3_default: uart3_default {
                group1 {
                        psels = <NRF_PSEL(UART_TX, 0, 19)>;
                };
		group2 {
			psels = <NRF_PSEL(UART_RX, 0, 20)>;
		};
        };

        uart3_sleep: uart3_sleep {
                group1 {
                        psels = <NRF_PSEL(UART_TX, 0, 19)>;
                };
                group2 {
                        psels = <NRF_PSEL(UART_RX, 0, 20)>;
                };
        };
};

&uart3 { 
        status = "okay";
	current-speed = <38400>;
	pinctrl-0 = <&uart3_default>;
	pinctrl-1 = <&uart3_sleep>;
	pinctrl-names = "default", "sleep";
};


app:
  address: 0x10200
  end_address: 0xe4000
  region: flash_primary
  size: 0xd3e00
external_flash:
  address: 0x120000
  device: IS25LP_
  end_address: 0x1000000  # 16MB
  region: external_flash
  size: 0xee0000
mcuboot:
  address: 0x0
  end_address: 0x10000
  region: flash_primary
  size: 0x10000
mcuboot_pad:
  address: 0x10000
  end_address: 0x10200
  region: flash_primary
  size: 0x200
mcuboot_primary:
  address: 0x10000
  end_address: 0xe4000
  orig_span: &id001
  - mcuboot_pad
  - app
  region: flash_primary
  size: 0xd4000
  span: *id001
mcuboot_primary_1:
  address: 0x0
  device: flash_ctrl
  end_address: 0x40000
  region: ram_flash
  size: 0x40000
mcuboot_primary_app:
  address: 0x10200
  end_address: 0xe4000
  orig_span: &id002
  - app
  region: flash_primary
  size: 0xd3e00
  span: *id002
mcuboot_secondary:
  address: 0x0
  device: IS25LP_
  end_address: 0xd4000
  region: external_flash
  size: 0xd4000
mcuboot_secondary_1:
  address: 0xd4000
  device: IS25LP_
  end_address: 0x114000
  region: external_flash
  size: 0x40000
EMPTY_1:
  address: 0x114000
  device: IS25LP_
  end_address: 0x120000
  region: external_flash
  size: 0xc000
mcuboot_primary_2:
  address: 0x120000
  device: IS25LP_
  end_address: 0x1A0000
  orig_span: &id003
  - mcuboot_primary_2_pad
  - mcuboot_primary_2_app
  region: external_flash
  size: 0x80000
  span: *id003
mcuboot_primary_2_pad:
  address: 0x120000
  end_address: 0x120200
  region: external_flash
  size: 0x200
# La xip viene fatta in mcuboot_primary_2_app
mcuboot_primary_2_app:
  address: 0x120200
  device: IS25LP_
  end_address: 0x1A0000
  region: external_flash
  size: 0x7FE00
# Deve essere in grado di contenere mcuboot_primary_2 per gestire l'aggiornamento: devono avere la stessa dimensione
mcuboot_secondary_2:
  address: 0x1A0000
  device: IS25LP_
  end_address: 0x220000
  region: external_flash
  size: 0x80000
littlefs_storage:
  address: 0x220000
  device: IS25LP_
  end_address: 0x1000000
  region: external_flash
  size: 0xDE0000
otp:
  address: 0xff8100
  end_address: 0xff83fc
  region: otp
  size: 0x2fc
pcd_sram:
  address: 0x20000000
  end_address: 0x20002000
  region: sram_primary
  size: 0x2000
ram_flash:
  address: 0x40000
  end_address: 0x40000
  region: ram_flash
  size: 0x0
rpmsg_nrf53_sram:
  address: 0x20070000
  end_address: 0x20080000
  placement:
    before:
    - end
  region: sram_primary
  size: 0x10000
settings_storage:
  address: 0xf0000
  end_address: 0x100000
  region: flash_primary
  size: 0x10000
sram_primary:
  address: 0x20002000
  end_address: 0x20070000
  region: sram_primary
  size: 0x6e000

/*
 * Copyright (c) 2022 Carlo Caione <[email protected]>
 * Copyright# Copyright (c) 2024 Nordic Semiconductor
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

/**
 * @file
 * @brief External QSPI flash Linker command/script file
 *
 * Linker script for moving desired .text and .data to the external
 * memory space.
 */

#include <zephyr/linker/sections.h>
#include <zephyr/devicetree.h>

#include <zephyr/linker/linker-defs.h>
#include <zephyr/linker/linker-tool.h>


/* Let SystemInit() be called in place of z_arm_platform_init() by default. */
PROVIDE(z_arm_platform_init = SystemInit);

/*
 * nRF5340dk and thingy53 are shipping QSPI external flashes.
 * These memories are mapped beginning from 0x1000_0000 internal SoC memory
 * address. This addressing space can be used for XIP and direct data access.
 */
MEMORY
{
#if CONFIG_NCS_IS_VARIANT_IMAGE
     /* This maps in mcuboot_secondary_1 partition defined in pm_static_no_network_core_directxip.yml
      * components for ORIGIN calculation:
      *  - 0x10000000: offset of QSPI external memory in SoC memory mapping.
      *  - 0xD4000: mcuboot_secondary_1 offset in QSPI external memory
      *  - 0x200: image header size.
      * The size of this region is size of mcuboot_secondary_1 reduced by the
      * image header size.
      */
     EXTFLASH (wx) : ORIGIN = 0x100D4200, LENGTH = 0x3FE00
#else
     /* This maps in mcuboot_primary_2 partition defined in pm_static.yml
      * components for ORIGIN calculation:
      *  - 0x10000000: offset of QSPI external memory in SoC memory mapping.
      *  - 0x120000: mcuboot_primary_2 offset in QSPI external memory
      *  - 0x200: image header size.
      * The size of this region is size of mcuboot_primary_2 reduced by the
      * image header size.
      */
     EXTFLASH (wx) : ORIGIN = 0x10120200, LENGTH = 0x3FE00
#endif
}

#include <zephyr/arch/arm/cortex_m/scripts/linker.ld>

# Enable MCUmgr and dependencies.
CONFIG_NET_BUF=y
CONFIG_ZCBOR=y
CONFIG_CRC=y
CONFIG_MCUMGR=y
CONFIG_STREAM_FLASH=y
CONFIG_FLASH_MAP=y

# Some command handlers require a large stack.
#CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304
CONFIG_MAIN_STACK_SIZE=2048

# Ensure an MCUboot-compatible binary is generated.
CONFIG_BOOTLOADER_MCUBOOT=y


# Enable flash operations.
CONFIG_FLASH=y

# Required by the `taskstat` command.
CONFIG_THREAD_MONITOR=y

# Support for taskstat command
CONFIG_MCUMGR_GRP_OS_TASKSTAT=y

# Enable statistics and statistic names.
#CONFIG_STATS=y
#CONFIG_STATS_NAMES=y

# Enable most core commands.
CONFIG_FLASH=y
CONFIG_IMG_MANAGER=y
CONFIG_MCUMGR_GRP_IMG=y
CONFIG_MCUMGR_GRP_OS=y
CONFIG_MCUMGR_GRP_STAT=y

# File system
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_MCUMGR_GRP_FS=y
CONFIG_FILE_SYSTEM_MKFS=y


# Enable logging
CONFIG_LOG=y
CONFIG_MCUBOOT_UTIL_LOG_LEVEL_WRN=y

# Disable debug logging
CONFIG_LOG_MAX_LEVEL=3
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y

# Allow for large Bluetooth data packets.
CONFIG_BT_L2CAP_TX_MTU=498
CONFIG_BT_BUF_ACL_RX_SIZE=502
CONFIG_BT_BUF_ACL_TX_SIZE=502
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251

# Enable the Bluetooth mcumgr transport (unauthenticated).
CONFIG_MCUMGR_TRANSPORT_BT=y
CONFIG_MCUMGR_TRANSPORT_BT_PERM_RW=y
CONFIG_MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL=y

# Enable the Shell mcumgr transport.
CONFIG_BASE64=y
CONFIG_SHELL=y
CONFIG_SHELL_BACKEND_SERIAL=y
CONFIG_MCUMGR_TRANSPORT_SHELL=y
CONFIG_MCUMGR_TRANSPORT_SHELL_RX_BUF_COUNT=8

# Enable the mcumgr Packet Reassembly feature over Bluetooth and its configuration dependencies.
# MCUmgr buffer size is optimized to fit one SMP packet divided into five Bluetooth Write Commands,
# transmitted with the maximum possible MTU value: 498 bytes.
CONFIG_MCUMGR_TRANSPORT_BT_REASSEMBLY=y
CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE=2475
CONFIG_MCUMGR_GRP_OS_MCUMGR_PARAMS=y
CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE=4608

# Enable the storage erase command.
CONFIG_MCUMGR_GRP_ZBASIC=y
CONFIG_MCUMGR_GRP_ZBASIC_STORAGE_ERASE=y

# Disable Bluetooth ping support
CONFIG_BT_CTLR_LE_PING=n

# Disable shell commands that are not needed
CONFIG_CLOCK_CONTROL_NRF_SHELL=n
CONFIG_DEVICE_SHELL=n
CONFIG_DEVMEM_SHELL=n
CONFIG_FLASH_SHELL=n

# Configuration for split application (internal flash and XIP)
CONFIG_CUSTOM_LINKER_SCRIPT="linker_arm_extxip.ld"

# Init changes for QSPI XIP code placement
CONFIG_FLASH_INIT_PRIORITY=40
CONFIG_SHELL_BACKEND_SERIAL_INIT_PRIORITY=50

# General
CONFIG_NEWLIB_LIBC=y
CONFIG_CAF=y
CONFIG_SB_DEBUG=n
CONFIG_APP_EVENT_MANAGER=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

# BLE
#CONFIG_BT=y
#CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="SmartBrick XXX"
CONFIG_BT_DEVICE_NAME_DYNAMIC=y
#CONFIG_BT_DEVICE_NAME_MAX=40
#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="Nordic Semiconductor ASA"
#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_AUTO_PHY_UPDATE=n
# CONFIG_BT_AUTO_PHY_UPDATE=n It is needed to work with some androids

# Enable CTS client
#CONFIG_BT_SMP=y
#CONFIG_BT_GATT_DM=y
#CONFIG_BT_GATT_CLIENT=y
#CONFIG_BT_CTS_CLIENT=y

# Stack
CONFIG_ISR_STACK_SIZE=4096
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_IDLE_STACK_SIZE=320
CONFIG_LOG_BUFFER_SIZE=4096
# original 768
CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=1024
CONFIG_USB_NRFX_WORK_QUEUE_STACK_SIZE=1024
# original 1200
CONFIG_BT_RX_STACK_SIZE=4096
# original 1024
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
# original 1024 
CONFIG_USB_WORKQUEUE_STACK_SIZE=1024
# heap for malloc 4096(original) --> 96K = 98304 for FFT malloc version
# 8192
CONFIG_HEAP_MEM_POOL_SIZE=32768
#CONFIG_SYS_HEAP_RUNTIME_STATS=y

#stack analYiser
#CONFIG_THREAD_ANALYZER=y
#CONFIG_THREAD_ANALYZER_USE_PRINTK=y
#CONFIG_THREAD_ANALYZER_AUTO=y
#CONFIG_THREAD_ANALYZER_AUTO_INTERVAL=30
#CONFIG_THREAD_NAME=y

#stack canary
CONFIG_STACK_CANARIES=y

 # USB
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_REMOTE_WAKEUP=n
CONFIG_USB_DEVICE_MANUFACTURER="SestoSensor"
CONFIG_USB_DEVICE_PRODUCT="SmartBrick UART"
CONFIG_USB_DEVICE_VID=0x0403
CONFIG_USB_DEVICE_PID=0xABC0
CONFIG_USB_DEVICE_SN="SmartBrick" # This is overridden at runtime
CONFIG_USB_COMPOSITE_DEVICE=y
CONFIG_USB_CDC_ACM_RINGBUF_SIZE=2048
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
CONFIG_USB_MAX_NUM_TRANSFERS=12
CONFIG_USB_CDC_ACM=y

# Settings
#CONFIG_FLASH_PAGE_LAYOUT=y      # Enables API for retrieving the layout of flash memory pages
#CONFIG_FLASH_MAP=y              # Enable support of flash map abstraction
CONFIG_NVS=y                    # Enable support of Non-volatile Storage
CONFIG_SETTINGS=y               # Enable serialize and deserialize state memory into and from non-volatile memory
#CONFIG_PM_PARTITION_SIZE_SETTINGS_STORAGE=0x10000
CONFIG_SETTINGS_NVS=y

# UART
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_ASYNC_API=n
CONFIG_UART_WIDE_DATA=n
CONFIG_UART_USE_RUNTIME_CONFIGURE=n
CONFIG_UART_LINE_CTRL=n
CONFIG_UART_DRV_CMD=n

#I2C
CONFIG_I2C=y

#SPI
CONFIG_SPI=y
CONFIG_SPI_ASYNC=y
#CONFIG_SPI_SLAVE=y

#RTC
# deprecated CONFIG_POSIX_CLOCK=y
#CONFIG_DATE_TIME=y

#TIMER
CONFIG_COUNTER=y
#CONFIG_NRFX_TIMER0=y

#GPIO
CONFIG_GPIO=y
#CONFIG_NFCT_PINS_AS_GPIOS=y

#FFT
CONFIG_GPIO=y
CONFIG_FPU=y
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
CONFIG_CMSIS_DSP=y
CONFIG_CMSIS_DSP_TRANSFORM=y
CONFIG_CMSIS_DSP_COMPLEXMATH=y
#CONFIG_CMSIS_DSP_TABLES_ARM_SIN_F32=y

#ADC
CONFIG_ADC=n
CONFIG_NRFX_SAADC=y
#CONFIG_NRFX_PPI=y
#CONFIG_NRFX_DPPI=y
CONFIG_NRFX_TIMER2=y

#PWM
CONFIG_PWM=y
#CONFIG_PWM_LOG_LEVEL_DBG=y
CONFIG_LED=y
CONFIG_LED_PWM=y

#WATCHDOG
CONFIG_WATCHDOG=y

# ASSERT
CONFIG_ASSERT=y 
CONFIG_ASSERT_LEVEL=2


#CONFIG_LOG_MAX_LEVEL=0

cmake_minimum_required(VERSION 3.20.0)

macro(app_set_runner_args)
#  if(CONFIG_BOARD_THINGY53_NRF5340_CPUAPP)
    # Use alternative QSPI configuration file when flashing Thingy53
    #board_runner_args(nrfjprog "--qspiini=${CMAKE_CURRENT_SOURCE_DIR}/Qspi_thingy53.ini")
    #board_runner_args(nrfjprog "--log")
    board_runner_args(nrfjprog "--qspiini=${CMAKE_CURRENT_SOURCE_DIR}/Qspi_nrf5340dk.ini")
#  endif()
endmacro()

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

project(extxip_smp_svr_v28_custom)

# This project uses orginal sdk-zephyr C source code
target_sources(app PRIVATE src/main.c)
#target_sources(app PRIVATE src/bluetooth.c)
#target_sources(app PRIVATE ${ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/main.c)
#target_sources_ifdef(CONFIG_MCUMGR_TRANSPORT_BT app PRIVATE ${ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c)

add_subdirectory(src/ble)
add_subdirectory(src/conf)
add_subdirectory(src/driver)
add_subdirectory(src/events)
add_subdirectory(src/handler)
add_subdirectory(src/sensors)
add_subdirectory(src/store)
add_subdirectory(src/test)
add_subdirectory(src/prot/meas_iot)
add_subdirectory(src/prot/shape_array)
add_subdirectory(src/utility)

# This places the application bluetooth.c file and some MCUmgr libraries into QSPI XIP

#zephyr_code_relocate(FILES src/main.c LOCATION EXTFLASH_TEXT NOCOPY)

#zephyr_code_relocate(FILES ${ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c LOCATION EXTFLASH_TEXT NOCOPY)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__mgmt LOCATION EXTFLASH_TEXT NOCOPY)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__transport LOCATION EXTFLASH_TEXT NOCOPY)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__util LOCATION EXTFLASH_TEXT NOCOPY)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__smp LOCATION EXTFLASH_TEXT NOCOPY)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__grp__img_mgmt LOCATION EXTFLASH_TEXT NOCOPY)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__grp__os_mgmt LOCATION EXTFLASH_TEXT NOCOPY)

#zephyr_code_relocate(FILES src/main.c LOCATION RAM_DATA)

#zephyr_code_relocate(FILES ${ZEPHYR_BASE}/samples/subsys/mgmt/mcumgr/smp_svr/src/bluetooth.c LOCATION RAM_DATA)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__mgmt LOCATION RAM_DATA)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__transport LOCATION RAM_DATA)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__util LOCATION RAM_DATA)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__smp LOCATION RAM_DATA)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__grp__img_mgmt LOCATION RAM_DATA)
zephyr_code_relocate(LIBRARY subsys__mgmt__mcumgr__grp__os_mgmt LOCATION RAM_DATA)

;----------------------------------------------
; Deprecated, use config.toml format instead
;----------------------------------------------

; nrfjprog QSPI configuration file.

[DEFAULT_CONFIGURATION]
; Define the capacity of the flash memory device in bytes. Set to 0 if no external memory device is present in your board.
MemSize = 0x1000000

; Define the desired ReadMode. Valid options are FASTREAD, READ2O, READ2IO, READ4O and READ4IO
ReadMode = READ4IO

; Define the desired WriteMode. Valid options are PP, PP2O, PP4O and PP4IO
WriteMode = PP4O

; Define the desired AddressMode. Valid options are BIT24 and BIT32
AddressMode = BIT24

; Define the desired Frequency. Valid options are M2, M4, M8, M16 and M32
Frequency = M16

; Define the desired SPI mode. Valid options are MODE0 and MODE3
SpiMode = MODE0

; Define the desired SckDelay. Valid options are in the range 0 to 255
SckDelay = 0x80

; Define SPI interface timing. Valid options are in the range of 0 to 7.
; This argument is only used for devices where the dll function NRFJPROG_qspi_set_rx_delay() is supported.
RxDelay = 2

; Define the desired IO level for DIO2 and DIO3 during a custom instruction. Valid options are LEVEL_HIGH and LEVEL_LOW
CustomInstructionIO2Level = LEVEL_LOW
CustomInstructionIO3Level = LEVEL_HIGH

; Define the assigned pins for the QSPI peripheral. Valid options are those existing in your device
; For nRF53, QSPI pins are not configurable and these values are ignored.
CSNPin = 17
CSNPort = 0
SCKPin = 19
SCKPort = 0
DIO0Pin = 20
DIO0Port = 0
DIO1Pin = 21
DIO1Port = 0
DIO2Pin = 22
DIO2Port = 0
DIO3Pin = 23
DIO3Port = 0

; Define the Index of the Write In Progress (WIP) bit in the status register. Valid options are in the range of 0 to 7.
WIPIndex = 0

; Define page size for commands. Valid sizes are PAGE256 and PAGE512.
PPSize = PAGE256

; Custom instructions to send to the external memory after initialization. Format is instruction code plus data to send in between optional brackets.
; These instructions will be executed each time the qspi peripheral is initiated by nrfjprog.
; To improve execution speed on consecutive interactions with QSPI, you can run nrfjprog once with custom initialization, and then comment out the lines below.
; Numbers can be given in decimal, hex (starting with either 0x or 0X) and binary (starting with either 0b or 0B) formats.
; The custom instructions will be executed in the order found.
; This example includes two commands, first a WREN (WRite ENable) and then a WRSR (WRite Status Register) enabling the Quad Operation and the High Performance
; mode for the MX25R6435F memory present in the nRF52840 DK.
;InitializationCustomInstruction =  0x06
;InitializationCustomInstruction =  0x01, [0x40, 0, 0x2]

; If retention is enabled, device RAM contents will be read and buffered during QSPI driver initialization.
; The buffered data will be written back to the device when uninitializing the driver, restoring the original device RAM state.
; Enabled: RetainRAM = 1, Disabled: RetainRAM = 0
RetainRAM = 0

Related