From 0e9802c4cd72465d91efe5171ae3ddd90f8f295c Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Jul 2021 17:13:20 +0300 Subject: [PATCH] watchdog configuration --- src/hal/avr/cpu.cpp | 2 +- src/hal/avr/watchdog.cpp | 4 ++-- src/hal/watchdog.h | 34 +++++++++++++++++++++++++++++++++- src/main.cpp | 2 +- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/hal/avr/cpu.cpp b/src/hal/avr/cpu.cpp index 110e8be..7bef056 100644 --- a/src/hal/avr/cpu.cpp +++ b/src/hal/avr/cpu.cpp @@ -10,7 +10,7 @@ void Init() { void Reset() { cli(); - watchdog::Enable(0); //minimum amount of watchdog + watchdog::Enable(watchdog::configuration::compute(0)); //quickest watchdog reset for (;;) ; //endless loop while waiting for the watchdog to reset } diff --git a/src/hal/avr/watchdog.cpp b/src/hal/avr/watchdog.cpp index 7717b58..26b32aa 100644 --- a/src/hal/avr/watchdog.cpp +++ b/src/hal/avr/watchdog.cpp @@ -4,8 +4,8 @@ namespace hal { namespace watchdog { -void Enable(uint16_t period) { - // @@TODO +void Enable(const configuration &config) { + wdt_enable(config.prescalerBits); } void Disable() { diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index 592f6f3..84a839e 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -6,8 +6,40 @@ namespace hal { /// Hardware Abstraction Layer for the CPU's internal watchdog namespace watchdog { +#if defined(__AVR__) +constexpr uint32_t F_WDT = 128000; //frequency of the watchdog unit in Hz +constexpr uint32_t basePrescaler = 2048; //what prescalerBits==0 actually does. +constexpr uint8_t maxPrescaler = 9; //the maximum value prescalerBits can take +constexpr uint8_t reloadBits = 0; //number of bits in the reload register +#elif defined(__STM32__) //@todo to be changed to the final form +constexpr uint32_t F_WDT = 32000; //frequency of the watchdog unit in Hz +constexpr uint32_t basePrescaler = 4; //what prescalerBits==0 actually does. +constexpr uint8_t maxPrescaler = 7; //the maximum value prescalerBits can take +constexpr uint8_t reloadBits = 12; //number of bits in the reload register +#endif + +struct configuration { + uint8_t prescalerBits; + uint16_t reload; + +public: + static constexpr configuration compute(float timeout) { + constexpr float tickPeriod = 1 / (float)F_WDT; + uint8_t prescalerBits = 0; + uint16_t reload = 0; + while (tickPeriod * (basePrescaler << prescalerBits) < timeout) { + prescalerBits++; + } + if (timeout) + reload = static_cast(((timeout * (1 << reloadBits)) / (tickPeriod * (basePrescaler << prescalerBits)))) - 1; + + configuration config = { prescalerBits, reload }; + return config; + } +}; + /// watchdog interface -void Enable(uint16_t period); +void Enable(const configuration &config); void Disable(); void Reset(); diff --git a/src/main.cpp b/src/main.cpp index b0aeb8f..d506cf6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -96,7 +96,7 @@ void setup() { cpu::Init(); mt::timebase.Init(); - watchdog::Enable(8000); //8s timeout + watchdog::Enable(watchdog::configuration::compute(8)); //set 8s timeout mg::globals.Init();