External flash stops working after enabling MCUboot

I am doing some development where I use the external flash for storage external to my application.  When I enable MCUboot, I can no longer access the external flash.  This is on an nrf52840.  Pretty new to Zephyr, so I think I've got my overlay configured correctly.  flash0 looks to be all on the mcu flash partitions, so unsure at the moment why I can't access the external flash.  If I disable MCUboot, I can access external flash again.

Any help is appreciated.

Thanks

Parents
  • Hi Kenny, 
    Could you show how you access the external flash ? 
    Also please show the partition configuration (pm_static.yml or the partitions.yml in the build folder) . Usually the partitions configuration will show how the mcuboot occupy the flash/external flash. 

    Which error do you see when you try to access the flash ? 

  • Hi Hung,

    Thanks for the prompt reply.  I implemented a command line to direct access the flash functions, using SPI transfers.  I started with the nrf52840dk and now working with a custom board so I have an overlay.  I am currently using it in standard x1, rather than quad.

    My overlay defines SPI config as follows:

    spi2_default: spi2_default {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 0, 19)>,
                    <NRF_PSEL(SPIM_MOSI, 0, 23)>,
                    <NRF_PSEL(SPIM_MISO, 1, 00)>;
            };
        };
    spi2: &spi2 {
        compatible = "nordic,nrf-spim";
        status = "okay";
        pinctrl-0 = <&spi2_default>;
        pinctrl-1 = <&spi2_sleep>;
        pinctrl-names = "default", "sleep";
        cs-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
        w25q64: w25q64@0 {
            compatible = "jedec,spi-nor";
            label = "W25Q64";
            reg = < 0 >;
            spi-max-frequency = < 40000000 >;
            wp-gpios = < &gpio0 22 GPIO_ACTIVE_LOW >;
            hold-gpios = < &gpio0 21 GPIO_ACTIVE_LOW >;
            size = < 0x1000000 >;
            has-dpd;
            t-enter-dpd = < 3000 >;
            t-exit-dpd = < 30000 >;
            jedec-id = [ ef 40 16  ];
        };
    };
    The command line functions can write and read the flash just fine.  I wanted to tinker with the bootloader, so I added the following, and can no longer read from flash via command line:
    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y

    Here are the partitions.yml contents:

    app:
      address: 0xc200
      end_address: 0x86000
      region: flash_primary
      size: 0x79e00
    mcuboot:
      address: 0x0
      end_address: 0xc000
      placement:
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0xc000
    mcuboot_pad:
      address: 0xc000
      end_address: 0xc200
      placement:
        align:
          start: 0x1000
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x200
    mcuboot_primary:
      address: 0xc000
      end_address: 0x86000
      orig_span: &id001
      - app
      - mcuboot_pad
      region: flash_primary
      sharers: 0x1
      size: 0x7a000
      span: *id001
    mcuboot_primary_app:
      address: 0xc200
      end_address: 0x86000
      orig_span: &id002
      - app
      region: flash_primary
      size: 0x79e00
      span: *id002
    mcuboot_secondary:
      address: 0x86000
      end_address: 0x100000
      placement:
        after:
        - mcuboot_primary
        align:
          start: 0x1000
        align_next: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_primary
      size: 0x7a000
    sram_primary:
      address: 0x20000000
      end_address: 0x20040000
      region: sram_primary
      size: 0x40000
    Is it possible there's something from the original nrf52840dk dts that's configured using the external flash and I just haven't undefined it in my overlay?
    Thanks,
    Kenny
  • Hi Kenny,

    The nRF52840dk device tree defined mx25r64 external flash on qspi in nrf52840dk_nrf52840.dts: 

    &qspi {
    	status = "okay";
    	pinctrl-0 = <&qspi_default>;
    	pinctrl-1 = <&qspi_sleep>;
    	pinctrl-names = "default", "sleep";
    	mx25r64: mx25r6435f@0 {
    		compatible = "nordic,qspi-nor";
    		reg = <0>;
    		/* MX25R64 supports only pp and pp4io */
    		writeoc = "pp4io";
    		/* MX25R64 supports all readoc options */
    		readoc = "read4io";
    		sck-frequency = <8000000>;
    		jedec-id = [c2 28 17];
    		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
    		];
    		size = <67108864>;
    		has-dpd;
    		t-enter-dpd = <10000>;
    		t-exit-dpd = <35000>;
    	};
    };

    If you are not using the same flash you should disable it. 

    But we would need to know more debug information when you no longer be able to read. Have you checked if there is any signal on SPI pins ? Any error in the code? 

    From what I can see in the partition file MCUBoot doesn't use the external flash for image storing so I am not sure why it affect your SPI communication. 

    Could you find the .config file(s) in the build folders before and after you enable MCUBoot. We can take a look at what's changed and see if we can find anything. The .config file is the generated file for all the configuration of the application. 

  • Hi Hung,

    Probing the SPI pins, there are no signals coming out.  Hence, rx buffer returning all 0s.

    I have also gone through to disable the external flash and disabled QSPI as well from the original dts/dtsi files with no luck.

    When building without the mcuboot configured, I don't have any .config files under the build directory.  After adding mcuboot in prj.conf, a pm.config file gets generated.  Contents below:

    PM_MCUBOOT_OFFSET=0x0
    PM_MCUBOOT_ADDRESS=0x0
    PM_MCUBOOT_END_ADDRESS=0xc000
    PM_MCUBOOT_SIZE=0xc000
    PM_MCUBOOT_NAME=mcuboot
    PM_MCUBOOT_ID=0
    PM_mcuboot_ID=PM_MCUBOOT_ID
    PM_mcuboot_IS_ENABLED=1
    PM_0_LABEL=MCUBOOT
    PM_MCUBOOT_PAD_OFFSET=0xc000
    PM_MCUBOOT_PAD_ADDRESS=0xc000
    PM_MCUBOOT_PAD_END_ADDRESS=0xc200
    PM_MCUBOOT_PAD_SIZE=0x200
    PM_MCUBOOT_PAD_NAME=mcuboot_pad
    PM_MCUBOOT_PAD_ID=1
    PM_mcuboot_pad_ID=PM_MCUBOOT_PAD_ID
    PM_mcuboot_pad_IS_ENABLED=1
    PM_1_LABEL=MCUBOOT_PAD
    PM_MCUBOOT_PRIMARY_OFFSET=0xc000
    PM_MCUBOOT_PRIMARY_ADDRESS=0xc000
    PM_MCUBOOT_PRIMARY_END_ADDRESS=0x86000
    PM_MCUBOOT_PRIMARY_SIZE=0x7a000
    PM_MCUBOOT_PRIMARY_NAME=mcuboot_primary
    PM_MCUBOOT_PRIMARY_ID=2
    PM_mcuboot_primary_ID=PM_MCUBOOT_PRIMARY_ID
    PM_mcuboot_primary_IS_ENABLED=1
    PM_2_LABEL=MCUBOOT_PRIMARY
    PM_MCUBOOT_PRIMARY_SPAN="mcuboot_pad app"
    PM_APP_OFFSET=0xc200
    PM_APP_ADDRESS=0xc200
    PM_APP_END_ADDRESS=0x86000
    PM_APP_SIZE=0x79e00
    PM_APP_NAME=app
    PM_APP_ID=3
    PM_app_ID=PM_APP_ID
    PM_app_IS_ENABLED=1
    PM_3_LABEL=APP
    PM_MCUBOOT_PRIMARY_APP_OFFSET=0xc200
    PM_MCUBOOT_PRIMARY_APP_ADDRESS=0xc200
    PM_MCUBOOT_PRIMARY_APP_END_ADDRESS=0x86000
    PM_MCUBOOT_PRIMARY_APP_SIZE=0x79e00
    PM_MCUBOOT_PRIMARY_APP_NAME=mcuboot_primary_app
    PM_MCUBOOT_PRIMARY_APP_ID=4
    PM_mcuboot_primary_app_ID=PM_MCUBOOT_PRIMARY_APP_ID
    PM_mcuboot_primary_app_IS_ENABLED=1
    PM_4_LABEL=MCUBOOT_PRIMARY_APP
    PM_MCUBOOT_PRIMARY_APP_SPAN="app"
    PM_MCUBOOT_SECONDARY_OFFSET=0x86000
    PM_MCUBOOT_SECONDARY_ADDRESS=0x86000
    PM_MCUBOOT_SECONDARY_END_ADDRESS=0x100000
    PM_MCUBOOT_SECONDARY_SIZE=0x7a000
    PM_MCUBOOT_SECONDARY_NAME=mcuboot_secondary
    PM_MCUBOOT_SECONDARY_ID=5
    PM_mcuboot_secondary_ID=PM_MCUBOOT_SECONDARY_ID
    PM_mcuboot_secondary_IS_ENABLED=1
    PM_5_LABEL=MCUBOOT_SECONDARY
    PM_SRAM_PRIMARY_OFFSET=0x0
    PM_SRAM_PRIMARY_ADDRESS=0x20000000
    PM_SRAM_PRIMARY_END_ADDRESS=0x20040000
    PM_SRAM_PRIMARY_SIZE=0x40000
    PM_SRAM_PRIMARY_NAME=sram_primary
    PM_NUM=6
    PM_ALL_BY_SIZE="mcuboot_pad mcuboot sram_primary app mcuboot_primary_app mcuboot_secondary mcuboot_primary"

    Is it possible the bootloader (mcuboot) is doing something with those pins and fails to reconfigure when loading the application?

    I might have to recreate my custom board on the nrf52840dk for easier debugging.  I should also create a custom board instead of using the overlay.

    Thanks

  • Hi Hung,

    Update.  Doing some digging, I don't think it's CONFIG_BOOTLOADER_MCUBOOT=y that is causing the issue but rather CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y causing basic SPI to no longer function.  Then I found this thread:

     CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU doesn't work with SPI NOR 

    Looks like a workaround until it gets addressed.  It also looks like CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU is using external flash.  What is the easiest way to configure it for internal flash?

    Thanks

  • Hi Kenny,
    Thanks for the info, from what I can see in NCS v2.8.0 the NORDIC_QSPI_NOR imply is removed. Please try to update to the latest NCS. 
    From what I can see in the MCUBoot partition you provided, the MCUBoot is using internal flash. 
    Please try to check the partitions.yml after build. 

  • Hi Hung,

    First, my apologies for misreading CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU.  You are correct it is not using external flash unless that config is enabled.

    I also should've clarified, I was only able to probe the SPI chip select pin on the custom board as that is the only one with a test point.  I created a dumbed down version of my project where it is a pure SPI read and MCUboot with FOTA to make sure I can reproduce the following issues:

    • No MCUboot and FOTA, SPI works.
    • Enabling MCUboot and FOTA, SPI stops working.

    After reproducing the issue, I updated my toolchain and SDK to v2.8.0.  After upgrading, I had to switch to using sysbuild with SB_CONFIG_BOOTLOADER_MCUBOOT and the issue persisted.  What I realized is once i removed MCUboot and FOTA, and rebuilt/reprogrammed, the SPI (chip select) still was not working.  The SPI (chip select) would not work until I performed an Erase Board.  Then reprogramming worked.

    This led me to digging into the Erase Board.  I realized it is also erasing the UICR so I repeated the steps above, skipped the Erase Board and issued an nrfjprog --eraseuicr and performed a soft reset and the SPI (chip select) worked again.

    I think the problem I'm seeing was compounded by two issues:

    1. CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU made simple SPI stop working (addressed in previous post) but SDK v2.8.0 fixes this.

    2. My SPI chip select is on pin P0.18 which defaults to being used for reset.  I need to add the following to my overlay to specify the UICR not program it as a reset.  Once the UICR gets programmed to issue it as a reset, it needs to be cleared by the tools.

    &uicr {
        /delete-property/ gpio-as-nreset;
    };
    Questions I have are:
    • Is the bootloader setting UICR for P0.18 as a reset?
    • Can I add something in my application to clear this register?

    Thanks

Reply
  • Hi Hung,

    First, my apologies for misreading CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU.  You are correct it is not using external flash unless that config is enabled.

    I also should've clarified, I was only able to probe the SPI chip select pin on the custom board as that is the only one with a test point.  I created a dumbed down version of my project where it is a pure SPI read and MCUboot with FOTA to make sure I can reproduce the following issues:

    • No MCUboot and FOTA, SPI works.
    • Enabling MCUboot and FOTA, SPI stops working.

    After reproducing the issue, I updated my toolchain and SDK to v2.8.0.  After upgrading, I had to switch to using sysbuild with SB_CONFIG_BOOTLOADER_MCUBOOT and the issue persisted.  What I realized is once i removed MCUboot and FOTA, and rebuilt/reprogrammed, the SPI (chip select) still was not working.  The SPI (chip select) would not work until I performed an Erase Board.  Then reprogramming worked.

    This led me to digging into the Erase Board.  I realized it is also erasing the UICR so I repeated the steps above, skipped the Erase Board and issued an nrfjprog --eraseuicr and performed a soft reset and the SPI (chip select) worked again.

    I think the problem I'm seeing was compounded by two issues:

    1. CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU made simple SPI stop working (addressed in previous post) but SDK v2.8.0 fixes this.

    2. My SPI chip select is on pin P0.18 which defaults to being used for reset.  I need to add the following to my overlay to specify the UICR not program it as a reset.  Once the UICR gets programmed to issue it as a reset, it needs to be cleared by the tools.

    &uicr {
        /delete-property/ gpio-as-nreset;
    };
    Questions I have are:
    • Is the bootloader setting UICR for P0.18 as a reset?
    • Can I add something in my application to clear this register?

    Thanks

Children
  • Confirmed using nrfjprog --memrd 0x10001200 that with the MCUboot and FOTA, the PSELRESET registers are getting written to 0x00000012.

    I've added a function to erase UICR at the beginning of my application.  I verified by reading back but the chip select is still not registering.  I think I need to reconfigure the SPI peripheral after erasing UICR.  I haven't the slightest clue how to do that with zephyr, so I will probably have to dig into the nrfx libraries and the hardware registers to try that next.  Please let me know if there's an easier fix for this.

    Thanks,

    Kenny

Related