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,

Lurn.

Parents
  • I only found examples of ble and uart in the dfu/secure_bootloader folder, Which one should I use or how should I modify it to adapt my program.

  • Hello,

    It is correct that you will only find BLE and UART in our samples, but I know that several customers have ported this to SPI, so if you need it over ESB, then that should also be possible. The transport layers in the bootloader for the nRF5 SDK are on purpose quite separated from the rest of the libraries, to make it easier to change the transport layer, or to add your own transport layer.

    But you do need to implement it yourself. Also note that we do not have the "DFU Master" as an official part of our SDK. We have tools like nrfutil (open source) or nRF Connect for Desktop (not open source), and applications for mobile phones that are open source (but mobile phones doesn't have ESB). However, there is an unofficial implementation (not properly tested. You can use it, but on your own "risk"), which you can find here. I have not tested these myself, but you can give it a go. I suggest you test out the UART master, in combination with the uart bootloader, and then you can port both to ESB once you are up and running.

    Best regards,

    Edvin

  • Hi Edvin:

    Thanks for your advice, I will try this, and hope you can give me some help when I encounter some difficulties.

    Best regards,

    Lurn

  • Hi Edvin:

    I'm sorry that I was interrupted by something, so I just started to try the method you said today.

    I used the bootloader_uart and ble_app_uart to test, used the following cmd

    nrfutil settings generate --family NRF52 --aplication app.hex --application-version 0 --bootloader-version 0 --bl-settings-version 2 settings.hex

    mergehex --merge bootloader.hex settings.hex --output bl_temp.hex
    metgehex --merge bl_temp.hex app.hex s132_nrf52_7.2.0_softdevice.hex --output bl_app_setting.hex

    then download

    nrfjprog --eraseall -f NRF52
    nrfjprog --program bl_app_setting.hex --verify -f NRF52
    nrfjprog --reset -f NRF52

    until now, no problem has been found.

    nrfutil pkg generate --hw-version 52 --application-version 1 --application app.hex --sd-req 0x98 --softdevice s132_nrf52_7.2.0_softdevice.hex --key-file private.key dfu_uart.zip

    but when I use this cmd to update, I ran into some errors like this.

    nrfutil dfu serial -pkg dfu_uart.zip -p COM3
    Or
    nrfutil dfu serial -pkg dfu_uart.zip -p COM3 -fc 0 -b 9600

    port

    err

    I want to know which step is wrong, and how should I modify it.

    Best regards,

    Lurn

  • By the way, My program is not using softdevice, How should I generate the update package.

  • Hello,

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

    nrfutil --verbose dfu serial -pkg dfu_uart.zip -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\dfu_image.zip
    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\dfu_image.zip
    
    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\dfu_image.zip -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,

    Edvin

  • 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)     
    #define BOOTLOADER_DFU_START        (BOOTLOADER_DFU_GPREGRET_MASK | BOOTLOADER_DFU_START_BIT_MASK)
    
    sd_power_gpregret_clr(0,0xffffffff);
    sd_power_gpregret_set(BOOTLOADER_DFU_START);
    nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
    NVIC_SystemReset();

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

    Best regards,

    Lurn

Reply
  • 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)     
    #define BOOTLOADER_DFU_START        (BOOTLOADER_DFU_GPREGRET_MASK | BOOTLOADER_DFU_START_BIT_MASK)
    
    sd_power_gpregret_clr(0,0xffffffff);
    sd_power_gpregret_set(BOOTLOADER_DFU_START);
    nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
    NVIC_SystemReset();

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

    Best regards,

    Lurn

Children
  • 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)     
    #define BOOTLOADER_DFU_START        (BOOTLOADER_DFU_GPREGRET_MASK | BOOTLOADER_DFU_START_BIT_MASK)
    
    
    
    ...
    {
        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;
        
        sd_power_gpregret_set(new_gpregret);
        while ((temp & BOOTLOADER_DFU_START) != BOOTLOADER_DFU_START)
        {
            // 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.
        nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
        NVIC_SystemReset();
    }
    

    Best regards,

    Edvin

  • Hello Edvin:

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

    Best regrads,

    Lurn

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

    BR,
    Edvin

  • yes, I used it, but my rtt does not display logs. so I don't know what's wrong.

    ps: I used the pca10040_uart_debug, so It should display logs

  • I can't find my device by nrf connect, I suspect the device is not started。

Related