This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

OTA DFU with a timer and no button

Hi,

I just learned how to do a OTA DFU. I tried it with nrf52840 DK and was successful in it, but our custom board does not have a button on it.    In production we will like the board to start always in the DFU mode when powered ON and look for new packages for initial 30 sec and then switch back to normal application . 

I was reading a lot about DFU_BUTTONLESS example but could not figure out the right procedure to do so.  

Will I have to change the structure of my application or will this logic be implemented inside the bootloader? 

Can you please provide some guiding steps to do so and if possible a pseudo code .

Thanks

Arshdeep

Parents
  • I can see that my colleague has answered your question in ticket 222994. If you want me to elaborate more about anything, please ask.

  • Hi 

    Yes . He says just Enter the DFU mode on startup and then use a timeout  . 

    But how to enter in DFU mode in start up?

    Thanks

  • You don't need to change your application or use the buttonless DFU example in order to enter DFU mode on startup, it can be achieved by modifying the bootloader. I saw that you created a new ticket, where the reset pin is used to enter DFU mode, and I think that is the right approach.

    In order to switch back to the application after 30 seconds you have to set NRF_BL_DFU_INACTIVITY_TIMEOUT_MS equal to 30000.

    Best regards,

    Simon

  • Hi Simon,

    My reset button is not working on custom board. So I tried writing to GPREGRET register to switch to DFU mode. 

    In sdk_config.h I wrote 1 to NRF_BL_DFU_ENTER_METHOD_GPREGRET

    #ifndef NRF_BL_DFU_ENTER_METHOD_GPREGRET
    #define NRF_BL_DFU_ENTER_METHOD_GPREGRET 1
    #endif

    and in the main function wrote sd_power_gpregret_set(0, 0xB1);

    int main(void)
    {
    uint32_t ret_val;


    sd_power_gpregret_set(0, 0xB1);

    ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE, false);
    APP_ERROR_CHECK(ret_val);
    ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE, false);
    APP_ERROR_CHECK(ret_val);

    (void) NRF_LOG_INIT(app_timer_cnt_get);
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("Inside main");

    ret_val = nrf_bootloader_init(dfu_observer);
    APP_ERROR_CHECK(ret_val);
    nrf_bootloader_app_start();
    NRF_LOG_INFO("After main");
    }

    But it is not working . When I Power reset the board, it still remains in the application and does not enter in DFU mode. 

    What am I missing here ?

    Thanks!

  • Try using the call nrf_power_gpregret_set() instead. I tried running sd_power_gpregret_set() similar as you and did not get the return value NRF_SUCCESS. I think this is because the SoftDevice enable function isn't called yet.

    Best regards,

    Simon

  • Hi Simon,

    I tried that: 

     And now when I try to do DFU using nrfconnect mobile app. It goes till 100% but the board remains in DFU mode. May be it does flashes my new application but switches back to DFU mode within milliseconds. What will I have to do stop this ?

    int main(void)

    {

        uint32_t ret_val;

        //  sd_power_gpregret_set(0, 0xB1);

        nrf_power_gpregret_set(0xA5);

        // Protect MBR and bootloader code from being overwritten.

        ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE, false);

        APP_ERROR_CHECK(ret_val);

        ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE, false);

        APP_ERROR_CHECK(ret_val);

     

        (void) NRF_LOG_INIT(app_timer_cnt_get);

        NRF_LOG_DEFAULT_BACKENDS_INIT();

     

        NRF_LOG_INFO("Inside main");

     

        ret_val = nrf_bootloader_init(dfu_observer);

        APP_ERROR_CHECK(ret_val);

        nrf_bootloader_app_start();

       

        // Should never be reached.

        NRF_LOG_INFO("After main");

    }

    Please suggest

    Thanks

Reply
  • Hi Simon,

    I tried that: 

     And now when I try to do DFU using nrfconnect mobile app. It goes till 100% but the board remains in DFU mode. May be it does flashes my new application but switches back to DFU mode within milliseconds. What will I have to do stop this ?

    int main(void)

    {

        uint32_t ret_val;

        //  sd_power_gpregret_set(0, 0xB1);

        nrf_power_gpregret_set(0xA5);

        // Protect MBR and bootloader code from being overwritten.

        ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE, false);

        APP_ERROR_CHECK(ret_val);

        ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE, false);

        APP_ERROR_CHECK(ret_val);

     

        (void) NRF_LOG_INIT(app_timer_cnt_get);

        NRF_LOG_DEFAULT_BACKENDS_INIT();

     

        NRF_LOG_INFO("Inside main");

     

        ret_val = nrf_bootloader_init(dfu_observer);

        APP_ERROR_CHECK(ret_val);

        nrf_bootloader_app_start();

       

        // Should never be reached.

        NRF_LOG_INFO("After main");

    }

    Please suggest

    Thanks

Children
  • The program execution is always starting in the bootloader, then it either enters DFU mode or the main application (depending on different conditions). That is the reason you enter the bootloader after performing a DFU, since it goes directly to the bootloader, sets the  GPREGRET register, and enters DFU mode again.

    The normal way of doing it is to set the GPREGRET register in the main application and then restarting the chip through NVIC_SystemReset() or sd_nvic_SystemReset() (see this ticket for more information). Earlier I said that you didn't need to modify the application, and I am sorry for that, I am still learning about the DFU and don't know how it all works.

    As I understand it, you would like to achieve the following:

    • Enter DFU mode and stay there for 30 seconds --> Boot the application

    There are several ways of achieving this

    • Start the bootloader-->Enter the application-->Press the reset button and start the bootloader-->Enter DFU mode and stay there for 30 seconds --> Boot the application
      • Ask Vidar in the private tickets if you have problems doing this
    • Start the bootloader-->Enter the application-->set the GPREGRET register and restart the chip-->Enter DFU mode and stay there for 30 seconds--> Boot the application
      • Here you would need to modify the application to only start the bootloader (and DFU mode) the first time:
        • One approach is to add a characteristic to your application, and do this by writing to it.
        • Another approach is to create a variable in flash that checks if the application is running for the first time, and start/not start the bootloader depending on that
    • Use the DFU buttonless example  

    Best regards,

    Simon

Related