nrf52832 OTA over ESB based on SDK17.1.0

Hi everyone:    I developed an application based on ESB wireless communication protocol ofr the nRF52832, and I would like to perform an OTA DFU with it.    Do you know any example of some over the air FW upgrade of nRF52832 chip via ESB protocol.

    SDK is 17.1.0.

Best regards,


  • Hello,

    From your screenshot from attempting the DFU, you can try to add --verbose:

    nrfutil --verbose dfu serial -pkg -p COM3

    However, you probably need to put the device in DFU mode. If you are using a DK, this can be done by holding button4 while resetting the DK (the GPIO for this can be configured in sdk_config.h in the bootloader project. Search for NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN).

    So this is probably why nrfutil can't receive a ping response. The device is not in DFU mode. 

    Regarding the command you use to generate the DFU image. If your image doesn't contain the softdevice, you should not have "--softdevice ..."in your command. I suppose you want to leave this out. You still need --sd-req, and it should match the already present softdevice's ID. Set itto 0x00 if no softdevice is present.

    If your application doesn't use the softdevice at all, you should try something that doesn't use the softdevice at all. I suggest the blinky example found in SDK\examples\peripheral\blinky\pca10040\mbr\

    As an example on how to use the UART bootloader, I attached a script that you can paste into SDK\examples\dfu\secure_bootloader\pca10040_uart\armgcc:

    make -j9
    make -j9 -C ..\..\..\..\peripheral\blinky\pca10040\mbr\armgcc
    ::mkdir files
    del files\app.hex
    del files\settings.hex
    del files\
    copy ..\..\..\..\peripheral\blinky\pca10040\mbr\armgcc\_build\nrf52832_xxaa.hex files\app.hex
    nrfutil settings generate --family NRF52 --application files\app.hex --application-version 0 --bootloader-version 0 --bl-settings-version 1 files\settings.hex
    nrfutil pkg generate --application files\app.hex --application-version 2 --sd-req 0x00 --hw-version 52 --key-file ..\..\..\private.key files\
    nrfjprog -e
    nrfjprog --program ..\..\..\..\..\components\softdevice\mbr\hex\mbr_nrf52_2.4.1_mbr.hex --verify
    nrfjprog --program _build\nrf52832_xxaa_mbr.hex --verify
    nrfjprog --program files\app.hex --verify
    nrfjprog --program files\settings.hex --verify
    nrfjprog --reset
    ::nrfutil -v -v -v -v dfu serial -pkg files\ -p COM17

    It may require some changes. Mainly, you need to adjust the path and name of your private key. The last line is commented out. Before you call this line, you need to hold button 4 and press reset, to put the device in DFU mode, and then you can call the "nrfutil dfu serial ..." command.

    Best regards,


  • Hello

    yes, I found this problem, but when I try to enter the DFU mode (using ble_app_uart), the device always reboot, and unable to enter DFU mode. Because my device is no key, I use the following code.

    #define BOOTLOADER_DFU_GPREGRET_MASK            (0xB0)         
    #define BOOTLOADER_DFU_START_BIT_MASK           (0x01)     

    Now, I try use the blinky example, but I don't know how to enter DFU mode in this example.

    Best regards,


  • Hello Lurn,

    So you are struggling to get the device into DFU mode, is that the case?

    If you test the pca10040_uart_debug bootloader project, you can monitor the RTT log. Inside the dfu_enter_check() function in nrf_bootloader.c, you can see the different checks it does to see whether it should enter DFU mode or not. I believe the one you are trying to use now is the GPREGRET method, so make sure that NRF_BL_DFU_ENTER_METHOD_GPREGRET is set to 1 (it is by default).

    So if you set the GPREGRET register to 0xB1, then it should enter DFU mode. 

    I guess that if you test the pca10040_uart_debug project and check the RTT log, and you do not see DFU mode requested via GPREGRET, then the issue is probably that the gpregret was not written before you reset. 

    You can read out the gpregret manually by using the nrfjprog command:

    nrfjprog --memrd 0x4000051c

    To see whether it is written.

    So to fix this, you can use something like this:

    #define BOOTLOADER_DFU_GPREGRET_MASK            (0xB0)         
    #define BOOTLOADER_DFU_START_BIT_MASK           (0x01)     
        uint32_t old_gpregret = sd_power_gpregret_get();
        uint32_t new_gpregret = old_gpregret & BOOTLOADER_DFU_START; //Just to retain other things written to gpregret. Not necessarily needed.
        uint32_t temp = 0;
            // Wait until the gpregret is written, and refresh the value of temp.
            sd_power_gpregret_get(0, &temp);
        // When this is reached, the gpregret is successfully written.

    Best regards,


  • Hello Edvin:

    I used the command to read out the gpregret, but the value is 00000000.

    Best regrads,


  • So did you use the while loop to wait for it to be set correctly?