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

Maximum Reload time for WDT

Hi Guys, 

We have a need to send data every 4 hours. 

In order to do this, we sleep 1 hour at a time (1-hour timer - single shot) and increment counter, and when the count is 4 we send the data. This is working well. 

Due to unknown reasons the device sometimes can get hung when trying to send the data. 

Our plan was to set the WDT_CONFIG_RELOAD_VALUE to 120000000, to make sure we reset the device after 1 hour if it got stuck. 

But we are unable to provide values more than 600000 (which triggers at 100 seconds). 

Can u suggest a way to configure such a large interval? 

regards

Shankar

  • The counter reload value can be specified up to 0xFFFFFFFF which is over 4 billion which is plenty. I suggest you debug through the watchdog code and find out what you're actually setting the CRV register to, perhaps you're truncating a value in your code. 

  • I am not sure what is the problem here, but there is watchdog example in the SDK that should be possible to use as reference. 

    As a side comment, have you done any calculation on the current consumption?

    The system ON idle current with an RTC running is ~1.7uA depending on how much RAM you retain during sleep.

    If you wakeup every 100 seconds for ~50us then the average increase is ~0.002uA. In other words there is no difference in battery life whether you wakeup every 100 seconds or 1hour, because the idle current is about ~1000x larger.

    Best regards,
    Kenneth

  • Hi, 

    Thanks for your reply. 
    I used the APIs example. Didn't change the registers themselves. 

    void ible_watchdog_init(void)
    {
      uint32_t err_code = NRF_SUCCESS;
      nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG;
      config.reload_value = 6000000;
      err_code = nrf_drv_wdt_init(&config, wdt_event_handler);
      err_code = nrf_drv_wdt_channel_alloc(&m_channel_id);
      nrf_drv_wdt_enable();
      APP_ERROR_CHECK(err_code);
    }
    
    /**
     * "Feed" the watchdog, resets the watchdog timer.
     * This must be called after watchdog initialization or the program will reset.
     */
    void ible_watchdog_feed(void)
    {
      printf("feeding wdt..\n");
      nrf_drv_wdt_channel_feed(m_channel_id);
    }

    this 6000000 is triggering at 100 seconds. But if I try to increase it to 8000000, it triggers in like 10 seconds. 
    Is there an example online in using CRV register directly? 

    regards

    Shankar

  • Hi Kenneth, 

    I did use the example as a reference. Please look at my comment on the previous reply. I did try using the example as a reference. 

    The reason why we are trying to do 1 hour, is to make sure the device indeed wakes up after 1 hour, in case the timer for 1 hour was not set right after sending data to server. I have seen some conflicts in running multiple timers at the same time. so this is just a catchall watchdog. 

    regards

    Shankar

  • I can't make any of this make sense. 6,000,000 ought to trigger at 183 seconds, not 100 and obviously 8,000,000 should be longer still. So my first thought is that your constant is having bits trimmed for some reason, however I can find no obvious trimming of the bits which could lead to those results.

    .. 

    and then I went and looked at the source code for the wdt module, here's where it sets the reload time

      nrf_wdt_reload_value_set((p_config->reload_value * 32768) / 1000);
    

    so clearly the reload value passed to the driver is supposed to be in milliseconds (and in fact that's what the documentation says). So for your case you want one hour which is 3600 seconds which is 3,600,000 milliseconds. So that's what you want to set the reload value to if you're using the watchdog driver. 

    However I haven't actually convinced myself that calculation doesn't overflow badly, need to look at some assembler. I think it may do. If I multiply 6,000,000 by 32768, truncate it to 32 bits, then divide by 1000 I get 3,309,568 which would be 101 seconds. If I do that with 8,000,000 I get 4 second which is sort of close to 10 I guess. That would explain your findings. 

    So basically the driver wants milliseconds and I'm not actually sure it works for anything over 131,000 ms or 131 seconds because that calculation overflows in the middle. 

Related