M harmony_changelog.md => harmony_changelog.md +2 -0
@@ 4,6 4,7 @@
### Fixed
* Fixed source clock frequency computation for PWM module
+* Fixed initial watchdog configuration
### Added
* Added setting onboarding year to build date year
@@ 11,6 12,7 @@
* Added low battery notification before using the application
* Added entering WFI when CPU is idle to reduce power consumption
* Added switching SDRAM to self-refresh before entering WFI for further power consumption reduction
+* Added watchdog protection to WFI mode
### Changed / Improved
M module-bsp/board/rt1051/bellpx/bsp/lpm/WfiController.cpp => module-bsp/board/rt1051/bellpx/bsp/lpm/WfiController.cpp +5 -5
@@ 4,12 4,12 @@
#include "WfiController.hpp"
#include "EnterSleepMode.h"
#include <fsl_gpc.h>
-#include <fsl_rtwdog.h>
#include <fsl_runtimestat_gpt.h>
#include <Utils.hpp>
#include <time/time_constants.hpp>
#include <ticks.hpp>
#include <timers.h>
+#include <watchdog/watchdog.hpp>
namespace bsp
{
@@ 19,8 19,8 @@ namespace bsp
* trigger after more than minute - this way no event will ever be missed */
constexpr auto timersInactivityTimeMs{60 * utils::time::milisecondsInSecond};
- bool wfiModeAllowed = false;
- std::uint32_t timeSpentInWFI;
+ bool wfiModeAllowed{false};
+ std::uint32_t timeSpentInWFI{0};
bool isTimerTaskScheduledSoon()
{
@@ 137,7 137,7 @@ namespace bsp
return 0;
}
- RTWDOG_Refresh(RTWDOG);
+ watchdog::refresh();
setWaitModeConfig();
peripheralEnterDozeMode();
@@ 163,7 163,7 @@ namespace bsp
enableSystick();
peripheralExitDozeMode();
- RTWDOG_Refresh(RTWDOG);
+ watchdog::refresh();
EnableGlobalIRQ(savedPrimask);
blockEnteringWfiMode();
M module-bsp/board/rt1051/bsp/watchdog/watchdog.cpp => module-bsp/board/rt1051/bsp/watchdog/watchdog.cpp +2 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "bsp/watchdog/watchdog.hpp"
@@ 23,7 23,7 @@ namespace bsp::watchdog
config.enableRtwdog = true;
config.clockSource = kRTWDOG_ClockSource1; // LPO_CLK clock (32.768kHz)
config.prescaler = kRTWDOG_ClockPrescalerDivide256; // 256 prescaler (effectively 128Hz clock)
- config.workMode.enableWait = false;
+ config.workMode.enableWait = true; // Keep RTWDOG enabled in WFI
config.workMode.enableStop = false;
config.workMode.enableDebug = false; // If true, RTWDOG will run when target is halted
config.testMode = kRTWDOG_TestModeDisabled;
M module-bsp/board/rt1051/common/system_MIMXRT1051.c => module-bsp/board/rt1051/common/system_MIMXRT1051.c +16 -12
@@ 108,22 108,27 @@ void SystemInit(void)
WDOG2->WCR &= ~WDOG_WCR_WDE_MASK;
}
+ /* Perform preliminary RTWDOG configuration */
#if defined(DISABLE_WATCHDOG)
- // Write watchdog update key to unlock
+ /* Write RTWDOG update key to unlock and wait for unlocking */
RTWDOG->CNT = 0xD928C520U;
- // Disable RTWDOG and allow configuration updates
+ while ((RTWDOG->CS & RTWDOG_CS_ULK_MASK) == 0) {}
+
+ /* Disable RTWDOG and allow configuration updates, wait until config is applied */
RTWDOG->TOVAL = 0xFFFF;
- RTWDOG->CS = (uint32_t)(((RTWDOG->CS) & ~RTWDOG_CS_EN_MASK) | RTWDOG_CS_UPDATE_MASK);
+ RTWDOG->CS = ((RTWDOG->CS & ~RTWDOG_CS_EN_MASK) | RTWDOG_CS_UPDATE_MASK);
+ while ((RTWDOG->CS & RTWDOG_CS_RCS_MASK) == 0) {}
#else
- //
- // Perform preliminary RTWDOG configuration
- //
- // Write RTWDOG update key to unlock
+ /* Write RTWDOG update key to unlock and wait for unlocking */
RTWDOG->CNT = 0xD928C520U;
- // Set timeout value (16s, assuming 128Hz clock - 32.768kHz after 256 prescaler)
- RTWDOG->TOVAL = 2048;
- // Enable RTWDOG, set 256 clock prescaler and allow configuration updates
- RTWDOG->CS = (uint32_t)((RTWDOG->CS) | RTWDOG_CS_EN_MASK | RTWDOG_CS_UPDATE_MASK | RTWDOG_CS_PRES_MASK);
+ while ((RTWDOG->CS & RTWDOG_CS_ULK_MASK) == 0) {}
+
+ /* Set timeout value to 16s (assuming 128Hz clock - 32.768kHz from LPO_CLK, with 256 prescaler) */
+ RTWDOG->TOVAL = 16 * 128;
+
+ /* Enable RTWDOG, set 256 clock prescaler and allow configuration updates, wait until config is applied */
+ RTWDOG->CS |= (RTWDOG_CS_EN_MASK | RTWDOG_CS_PRES_MASK | RTWDOG_CS_UPDATE_MASK);
+ while ((RTWDOG->CS & RTWDOG_CS_RCS_MASK) == 0) {}
#endif // (DISABLE_WATCHDOG)
/* Disable Systick which might be enabled by bootrom */
@@ 189,7 194,6 @@ void SystemCoreClockUpdate(void)
break;
case CCM_CBCMR_PERIPH_CLK2_SEL(3U):
- __attribute__((fallthrough));
default:
freq = 0U;
break;
M module-sys/SystemWatchdog/SystemWatchdog.cpp => module-sys/SystemWatchdog/SystemWatchdog.cpp +17 -5
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <SystemWatchdog/SystemWatchdog.hpp>
@@ 12,7 12,19 @@ namespace sys
{
using namespace cpp_freertos;
- static constexpr uint16_t stackDepthWords = 256;
+ namespace
+ {
+ // Watchdog thread stack size
+ constexpr std::uint16_t stackDepthWords = 256;
+ // Timeout period for refresh - 90s
+ constexpr TickType_t refreshTimeoutPeriod = pdMS_TO_TICKS(90000);
+ // Timeout period for the actual watchdog (has to be longer than maximum allowed WFI time 60s) - 64s
+ constexpr TickType_t watchdogTimeoutPeriod = pdMS_TO_TICKS(64000);
+ // Period of actual watchdog refresh - 16s
+ constexpr TickType_t checkPeriod = pdMS_TO_TICKS(16000);
+ // Timeout period for watchdog thread closure - 2s
+ constexpr TickType_t closurePeriod = pdMS_TO_TICKS(2000);
+ } // namespace
SystemWatchdog::SystemWatchdog()
: Thread(threadName, stackDepthWords, static_cast<UBaseType_t>(ServicePriority::High))
@@ 58,14 70,14 @@ namespace sys
while (enableRunLoop) {
Delay(checkPeriod);
- if (timeout_occurred) {
+ if (timeoutOccurred) {
continue;
}
// Critical section not required (atomic 32-bit reads)
- if (Ticks::GetTicks() - lastRefreshTimestamp >= refreshTimeoutPeriod) {
+ if ((Ticks::GetTicks() - lastRefreshTimestamp) >= refreshTimeoutPeriod) {
// Allow HW watchdog timeout to occur
- timeout_occurred = true;
+ timeoutOccurred = true;
LOG_FATAL("System watchdog timeout, system will be reset soon!");
}
else {
M module-sys/SystemWatchdog/include/SystemWatchdog/SystemWatchdog.hpp => module-sys/SystemWatchdog/include/SystemWatchdog/SystemWatchdog.hpp +2 -13
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 41,22 41,11 @@ namespace sys
private:
SystemWatchdog();
-
- // Timeout period for refresh
- static constexpr TickType_t refreshTimeoutPeriod = pdMS_TO_TICKS(90000);
- // Timeout period for the actual watchdog
- static constexpr TickType_t watchdogTimeoutPeriod = pdMS_TO_TICKS(16000);
- // Period of actual watchdog refresh
- static constexpr TickType_t checkPeriod = pdMS_TO_TICKS(8000);
- // Timeout period for watchdog thread closure
- static constexpr TickType_t closurePeriod = pdMS_TO_TICKS(2000);
-
void Run() final;
TickType_t lastRefreshTimestamp{0};
- bool timeout_occurred{false};
+ bool timeoutOccurred{false};
bool enableRunLoop{false};
cpp_freertos::BinarySemaphore taskEndedSem{false};
};
-
} // namespace sys