Can't program XIAO nrf52840 Sense using NRF connect SDK in vscode

Hi there,

WOW, That’s pretty Awesome and Tricky…:+1: The pm_static.yml was always a PITA to get right for external QSPI_fash (2MB) and trimming the MCUBoot down is also a “thing” :grin: It’s setting up the Slots (kinda evenly) for the Crash proof DFU I’m working on. i.e if the DFU doesn’t take or crashes it Auto-Magically reverts/Switches back to the OG. :crossed_fingers:

Your Students are very lucky, I have seen discussions on the "chaining the BootLoader and MCUBoot, never got it going though, the double-tap reset is also selected in MCUBoot for DFU ? or no?
The reset button bootloader (double-tap) disappeared when I tried it as well. so maybe something there.

I’ll check out the beacon_dfu that attached.

HTH
GL :slight_smile: PJ :v:

Well, my board is no longer working for neither single tap reset…

Before my first SWD write, I took a memory dump. Even if i write back that memory dump, I can´t get single tap reset or double tab bootloader mode.

So, I’ll wait a new Xiao with working bootloader double tap and test my solution with uf2.

Regarding MCUBOOT and double tap bootloader mode, I’m not sure it is supported…

And, I also noticed when building for xiao_ble_sense, the only uf2 generated is the zephyr.uf2 based on zephyr.hex that is the application only, no mcuboot.
To have a uf2 with mcuboot + application, we would need to get to zephyr/scripts/build and run something like:
python uf2conv.py -c -b 0x27000 -o merged.uf2 -f NRF52840 merged.hex
To get a proper uf2 with both mcuboot and application.

1 Like

Hi there,

AFAIK, that was the old way now, the Build adds it as a kconfig
and there is an option for the Double tap also.
MCUBoot does support double-tap reset detection as a trigger to enter bootloader mode, but it’s optional and hardware/board-specific. NRF_SDK

In the prj.conf or via menuconfig, look for:

kconfig

CONFIG_BOOT_SERIAL_DETECT_DOUBLE_RESET=y

This enables double-reset detection when using serial recovery mode, and optionally:

kconfig

CONFIG_BOOT_SERIAL_DETECT_PORT=<GPIO_PIN>

This sets the GPIO pin used to detect the reset via an external circuit — typically a capacitor between the pin and VCC.

Also FYI, it’s present on the Nordic BLE dongle * thingy devices as well. :+1:

HTH
GL :slight_smile: PJ :v:

I just recieved a fresh PLUS version of the Nrf52840 & S3 so I’ll be testing with those too.

1 Like

And final discovery of the day:

When we build for xiao_ble_sense without sysbuild and without mcuboot, it knows where to put the application properly. You can notice in the build log that it considers the application will start on 0x27000 and due to that will have up to 788KB in size. I assume it gets that from partitions definitions on dts.

If you build with sysbuild and without mcuboot, it will not consider the partiioning information, place the application at 0x0000 and due to that consider up to 1MB in size. It won´t run because the adafruit bootloader will try to load application from 0x27000.

So I tested *with sysbuild and with mcuboot, so that I could use the pm_static.yml to tell zephyr where to place the application and it worked.

Tomorrow I’ll try the following: I want to use uf2 with sysbuild and without MCUBOOT on the this dual bootloader approach. I wonder if i can set the pm_static.yml without MCUBOOT to drive sysbuild to place stuff on the right place.

I could not wait for tomorrow :slight_smile:
You can get xiao_ble_sense kinda working with sysbuild and without mcuboot using the factory uf2 loader if you add a pm_static.yml similar to this:

adafruit_boot:
address: 0xf4000
end_address: 0x100000
region: flash_primary
size: 0xc000
app:
address: 0x27000
end_address: 0xec000
region: flash_primary
size: 0xc5000
sd_partition:
address: 0x0
end_address: 0x27000
region: flash_primary
size: 0x27000
storage:
address: 0xec000
end_address: 0xf4000
region: flash_primary
size: 0x8000
sram_primary:
address: 0x20000000
end_address: 0x20040000
region: sram_primary
size: 0x40000

This will instruct sysbuild to know where to place the application (0x27000, just where the adafruit bootloeader will jump to).

The issue is that it wont generate a uf2. But it will generate a merged.hex (even without mcuboot) that you can convert to a uf2 and it will run properly.

1 Like

Hi there,

OK, So

  • The Adafruit UF2 bootloader expects the app to be at 0x27000
  • If Zephyr/sysbuild places the app at 0x0000, the bootloader can’t find it
  • Sysbuild defaults to full-chip partitioning unless overridden
  • MCUboot adds partition logic that aligns with many dual-boot systems
  • The workaround is:
    * Use pm_static.yml or custom .dts overlays to explicitly set app flash offset
    * Ensure alignment with UF2 or MCUboot expectations
    • Manually define partitions using pm_static.yml
  • Confirm that Zephyr links the app to 0x27000
  • Avoid hardcoding 0x0000 or using default sysbuild memory layout

I would un tick the Create build and generate the config. then use the Kmenu config to set the options. (nrf_sdk)

Good stuff, More testing tomorrow :v:

GL :slight_smile: PJ :+1:

EDIT:
LOL, perfect… :grin:

Great summary.
Just have in mind that:

  • No Sysbuild and No Mcuboot - Partitions are get from dts
  • No Sysbuild and With Mcuboot - Partitions are get from Partition Manager (pm_static to fix it)
  • Sysbuild - Partitions are always get from Partition Manager (pm_static to fix it)
1 Like

I read the a bunch about this and tested all I could find, but I still can’t get my code to work. I’m trying to use the fast pair fmdn example from nRF which uses the mergehex to embed some configuration.

The problem I ran into:

  • If I use the generated zephyr.uf2 the code runs, but the configuration is not included and the code fails.
  • If I use the merged.hex converted to uf2 the code doesn’t even run and the flashing directory doesn’t unmount itself after the whole file has finished writing.

I’m not using mcuboot but I’m using (and have to use because of mergehex and the fast pair configuration) sysbuild.

Is there a specific thing I have to do to make sure my code will run even with mergehex?

Hi there,

So , It sounds like you’re running into a common pain point when using mergehex together with sysbuild and Fast Pair configs on the nRF platform. They definitely could improve the FMD integration but G & co. is NOT real keen to change there stuff. ANy way :thinking:

A few things to consider:

  • Sysbuild Output Format: Sysbuild by default can generate multiple artifacts (like .hex, .bin, .uf2). When using mergehex, you’re typically combining multiple .hex files (e.g., application + config). But the final merged hex may not always be fully UF2-compatible without an extra conversion step. mergehex doesn’t “rebuild” the metadata needed for UF2 properly, it just merges the memory contents.
  • UF2 Bootloader Expectations: If you’re flashing via drag-and-drop onto a device mass storage (like a DK board or dongle), the UF2 loader expects certain address alignments and metadata. If your merged UF2 isn’t working (e.g., flashing never completes/unmounts), it could be because the merged HEX isn’t producing a correct UF2 file afterward — it’s likely missing essential vector table addresses or metadata. :+1:
  • Not Using MCUboot: Without MCUboot, your app needs to be positioned and built in a way that the bootloader (or ROM bootloader) expects. If mergehex changes the memory map (even slightly), but the device expects a clean app image, it might hang at boot.
  • Tips:
    • After merging, rebuild the UF2 properly (don’t just hex2uf2 blindly) — maybe re-parse the hex into a bin + generate UF2.
    • Check your linker script or sysbuild config to make sure the memory layout remains consistent even after merging.
    • Double-check whether your Fast Pair config blob needs to be linked differently (e.g., as a section inside your main app instead of merged externally).
    • If possible, try merging at build time using sysbuild config instead of post-build mergehex, so the build system knows everything that will be included.

You might want to dig into how sysbuild sets the partition layouts too — sometimes merged.hex isn’t just app+config but includes other parts like settings.hex or bootloader.hex that need to be properly accounted for. I would also post it on the NRF Forum too. I have seen a few FMD issues there in different scenarios.

HTH
GL :slight_smile: PJ :v:

Stay at it , your almost there. :crossed_fingers: