~aleteoryx/muditaos

1d51c5c4bc23b862760de490f3320f2c649db8d6 — Lefucjusz 1 year, 10 months ago f3f98bb
[BH-1833] Enable RTWDOG in WFI mode

* Fixed initial RTWDOG config procedure, which
put watchdog module in some non-deterministic
state due to not waiting after unlock request
and config change, what prevented the watchdog
to be reconfigured later in the OS.
* Configured RTWDOG to continue running in
WFI to prevent potential freezes caused by
CPU not being woken up by periodic RTC
interrupt.
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