Skip to content

Commit

Permalink
Merge pull request #2635 from particle-iot/fix/nrf52_watchdog/sc116493
Browse files Browse the repository at this point in the history
nRF52: watchdog timeout is not accurate
  • Loading branch information
XuGuohui authored and technobly committed May 24, 2023
1 parent d78fe27 commit 6d1e226
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
17 changes: 12 additions & 5 deletions hal/src/nRF52840/watchdog_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class WatchdogLock {
class Nrf52Watchdog : public Watchdog {
public:
int init(const hal_watchdog_config_t* config) {
CHECK_FALSE(initialized_, SYSTEM_ERROR_INVALID_STATE);
CHECK_FALSE(started(), SYSTEM_ERROR_INVALID_STATE);
CHECK_TRUE(config && (config->size > 0), SYSTEM_ERROR_INVALID_ARGUMENT);
CHECK_TRUE(config->timeout_ms >= WATCHDOG_MIN_TIMEOUT, SYSTEM_ERROR_INVALID_ARGUMENT);
CHECK_TRUE(config->timeout_ms <= WATCHDOG_MAX_TIMEOUT, SYSTEM_ERROR_INVALID_ARGUMENT);
Expand All @@ -80,10 +80,17 @@ class Nrf52Watchdog : public Watchdog {
} else {
nrfConfig.behaviour = NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT;
}
nrfx_err_t ret = nrfx_wdt_init(&nrfConfig, nrf52WatchdogEventHandler);
SPARK_ASSERT(ret == NRF_SUCCESS);
ret = nrfx_wdt_channel_alloc(&channelId_);
SPARK_ASSERT(ret == NRF_SUCCESS);
if (!initialized_) {
nrfx_err_t ret = nrfx_wdt_init(&nrfConfig, nrf52WatchdogEventHandler);
SPARK_ASSERT(ret == NRF_SUCCESS);
ret = nrfx_wdt_channel_alloc(&channelId_);
SPARK_ASSERT(ret == NRF_SUCCESS);
} else {
nrf_wdt_behaviour_set(nrfConfig.behaviour);
uint64_t ticks = (nrfConfig.reload_value * 32768ULL) / 1000;
SPARK_ASSERT(ticks <= UINT32_MAX);
nrf_wdt_reload_value_set((uint32_t)ticks);
}

memcpy(&info_.config, config, std::min(info_.config.size, config->size));
info_.state = HAL_WATCHDOG_STATE_CONFIGURED;
Expand Down
2 changes: 1 addition & 1 deletion third_party/nrf5_sdk/nrf5_sdk
30 changes: 30 additions & 0 deletions user/tests/wiring/watchdog/watchdog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,5 +174,35 @@ test(WATCHDOG_07_notify_2) {
assertEqual(magick, 0xdeadbeef);
}

#include "nrf_wdt.h"
static void checkError(system_tick_t expectedTo) {
uint32_t reg = nrf_wdt_reload_value_get();
uint64_t actualTo = (reg * 1000ULL) / 32768;
uint32_t delta = (expectedTo > actualTo) ? (expectedTo - actualTo) : (actualTo - expectedTo);
// Serial.printlnf("expected: %ld, actual: %lu, delta: %d", expectedTo, (uint32_t)actualTo, delta);
assertLessOrEqual(delta, 1);
assertMoreOrEqual(delta, 0);
}

#endif // HAL_PLATFORM_NRF52840

test(WATCHDDOG_100_reload_value_is_calculated_correctly) {
constexpr system_tick_t TEST_LOOP_CNT = 100;

WatchdogInfo info;
assertEqual(0, Watchdog.getInfo(info));

for (uint16_t i = 1; i <= TEST_LOOP_CNT; i++) {
system_tick_t expectedTo;
if (i == 1) {
expectedTo = info.minTimeout();
} else if (i == TEST_LOOP_CNT) {
expectedTo = info.maxTimeout();
} else {
expectedTo = random(info.minTimeout(), info.maxTimeout());
}
assertEqual(0, Watchdog.init(WatchdogConfiguration().timeout(expectedTo)));

checkError(expectedTo);
}
}

0 comments on commit 6d1e226

Please sign in to comment.