From 324ced6807019fee1b89fad996f8ad696c239694 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Tue, 20 Jul 2021 07:16:59 +0200 Subject: [PATCH 01/15] Add watchdog implementation + use it in main() --- src/hal/CMakeLists.txt | 1 + src/hal/avr/watchdog.cpp | 15 +++++++++++++++ src/hal/watchdog.h | 1 + src/main.cpp | 6 +++++- 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/hal/avr/watchdog.cpp diff --git a/src/hal/CMakeLists.txt b/src/hal/CMakeLists.txt index 77c7d99..fd0029d 100644 --- a/src/hal/CMakeLists.txt +++ b/src/hal/CMakeLists.txt @@ -8,4 +8,5 @@ target_sources( tmc2130.cpp adc.cpp avr/spi.cpp + avr/watchdog.cpp ) diff --git a/src/hal/avr/watchdog.cpp b/src/hal/avr/watchdog.cpp new file mode 100644 index 0000000..a707047 --- /dev/null +++ b/src/hal/avr/watchdog.cpp @@ -0,0 +1,15 @@ +#include "../watchdog.h" + +namespace hal { +namespace watchdog { + +void ConfigureWatchDog(uint16_t period) { + // @@TODO +} + +void ResetWatchDog() { + asm("wdr"); +} + +} // namespace watchdog +} // namespace hal diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index c57d373..90c3f10 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -1,4 +1,5 @@ #pragma once +#include namespace hal { diff --git a/src/main.cpp b/src/main.cpp index 9fedbe2..8dcbf77 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,7 @@ #include "hal/shr16.h" #include "hal/spi.h" #include "hal/usart.h" +#include "hal/watchdog.h" #include "pins.h" #include @@ -96,6 +97,8 @@ void setup() { mt::timebase.Init(); + hal::watchdog::ConfigureWatchDog(8); + mg::globals.Init(); // watchdog init @@ -363,7 +366,8 @@ void loop() { ms::selector.Step(); mui::userInput.Step(); currentCommand->Step(); - // add a watchdog reset + + hal::watchdog::ResetWatchDog(); } int main() { From 3b46c3559568f537ba5d6e24b9adfdcd28675555 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Tue, 20 Jul 2021 07:28:43 +0200 Subject: [PATCH 02/15] Add handling of the X0 message (restart the MMU) via Watchdog --- src/main.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8dcbf77..08713da 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -294,12 +294,15 @@ void ProcessRequestMsg(const mp::RequestMsg &rq) { break; case mp::RequestMsgCodes::Reset: // immediately reset the board - there is no response in this case - break; // @@TODO + hal::watchdog::ConfigureWatchDog(1); // set the watchdog to the lowest possible timeout + for (;;) + ; // cycle indefinitely (i.e. let the watchdog reset the CPU) + break; case mp::RequestMsgCodes::Version: ReportVersion(rq); break; case mp::RequestMsgCodes::Wait: - break; // @@TODO + break; // @@TODO - not used anywhere yet case mp::RequestMsgCodes::Cut: case mp::RequestMsgCodes::Eject: case mp::RequestMsgCodes::Load: From 56eee8dcfbced98dfebb490acc10a16434c69306 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Jul 2021 13:47:36 +0300 Subject: [PATCH 03/15] Reset the board using the cpu hal instead of the watchdog hal Also some naming changes --- src/hal/avr/cpu.cpp | 9 +++++++++ src/hal/avr/watchdog.cpp | 4 ++-- src/hal/cpu.h | 1 + src/hal/watchdog.h | 4 ++-- src/main.cpp | 8 +++----- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/hal/avr/cpu.cpp b/src/hal/avr/cpu.cpp index 96d539d..110e8be 100644 --- a/src/hal/avr/cpu.cpp +++ b/src/hal/avr/cpu.cpp @@ -1,4 +1,6 @@ #include "../cpu.h" +#include +#include "../watchdog.h" namespace hal { namespace cpu { @@ -6,5 +8,12 @@ namespace cpu { void Init() { } +void Reset() { + cli(); + watchdog::Enable(0); //minimum amount of watchdog + for (;;) + ; //endless loop while waiting for the watchdog to reset +} + } // namespace CPU } // namespace hal diff --git a/src/hal/avr/watchdog.cpp b/src/hal/avr/watchdog.cpp index a707047..86f1b52 100644 --- a/src/hal/avr/watchdog.cpp +++ b/src/hal/avr/watchdog.cpp @@ -3,11 +3,11 @@ namespace hal { namespace watchdog { -void ConfigureWatchDog(uint16_t period) { +void Enable(uint16_t period) { // @@TODO } -void ResetWatchDog() { +void Reset() { asm("wdr"); } diff --git a/src/hal/cpu.h b/src/hal/cpu.h index 604c7b9..ace6a9e 100644 --- a/src/hal/cpu.h +++ b/src/hal/cpu.h @@ -12,6 +12,7 @@ namespace cpu { /// CPU init routines (not really necessary for the AVR) void Init(); +void Reset(); } // namespace cpu } // namespace hal diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index 90c3f10..c585281 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -7,8 +7,8 @@ namespace hal { namespace watchdog { /// watchdog interface -void ConfigureWatchDog(uint16_t period); -void ResetWatchDog(); +void Enable(uint16_t period); +void Reset(); } // namespace watchdog } // namespace hal diff --git a/src/main.cpp b/src/main.cpp index 08713da..c24082c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -97,7 +97,7 @@ void setup() { mt::timebase.Init(); - hal::watchdog::ConfigureWatchDog(8); + watchdog::Enable(8000); //8s timeout mg::globals.Init(); @@ -294,9 +294,7 @@ void ProcessRequestMsg(const mp::RequestMsg &rq) { break; case mp::RequestMsgCodes::Reset: // immediately reset the board - there is no response in this case - hal::watchdog::ConfigureWatchDog(1); // set the watchdog to the lowest possible timeout - for (;;) - ; // cycle indefinitely (i.e. let the watchdog reset the CPU) + hal::cpu::Reset(); break; case mp::RequestMsgCodes::Version: ReportVersion(rq); @@ -370,7 +368,7 @@ void loop() { mui::userInput.Step(); currentCommand->Step(); - hal::watchdog::ResetWatchDog(); + hal::watchdog::Reset(); } int main() { From a433db5648716c63d07dbd269bf10cd4982ec22a Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Jul 2021 13:57:27 +0300 Subject: [PATCH 04/15] Add Disable and use the avrlibc wdt functions --- src/hal/avr/watchdog.cpp | 7 ++++++- src/hal/watchdog.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hal/avr/watchdog.cpp b/src/hal/avr/watchdog.cpp index 86f1b52..7717b58 100644 --- a/src/hal/avr/watchdog.cpp +++ b/src/hal/avr/watchdog.cpp @@ -1,4 +1,5 @@ #include "../watchdog.h" +#include namespace hal { namespace watchdog { @@ -7,8 +8,12 @@ void Enable(uint16_t period) { // @@TODO } +void Disable() { + wdt_disable(); +} + void Reset() { - asm("wdr"); + wdt_reset(); } } // namespace watchdog diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index c585281..592f6f3 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -8,6 +8,7 @@ namespace watchdog { /// watchdog interface void Enable(uint16_t period); +void Disable(); void Reset(); } // namespace watchdog From 06b959bb6628a072253452f817212ef1f40bd23b Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Jul 2021 17:13:20 +0300 Subject: [PATCH 05/15] 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 c24082c..e06a034 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -97,7 +97,7 @@ void setup() { mt::timebase.Init(); - watchdog::Enable(8000); //8s timeout + watchdog::Enable(watchdog::configuration::compute(8)); //set 8s timeout mg::globals.Init(); From cf636ec095f94f451436599eddc836c2783053e2 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Jul 2021 18:23:42 +0300 Subject: [PATCH 06/15] Fix configuration compute() math --- src/hal/watchdog.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index 84a839e..9a3edde 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -14,7 +14,7 @@ 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 maxPrescaler = 6; //the maximum value prescalerBits can take constexpr uint8_t reloadBits = 12; //number of bits in the reload register #endif @@ -24,16 +24,15 @@ struct configuration { 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) { + uint32_t ticks = timeout * F_WDT / (basePrescaler * (1 << prescalerBits)); + while ((ticks >= (1 << reloadBits)) && (prescalerBits < maxPrescaler)) { prescalerBits++; + ticks = timeout * F_WDT / (basePrescaler * (1 << prescalerBits)); } - if (timeout) - reload = static_cast(((timeout * (1 << reloadBits)) / (tickPeriod * (basePrescaler << prescalerBits)))) - 1; - - configuration config = { prescalerBits, reload }; + if ((prescalerBits == 0) && (ticks == 0)) + ticks = 1; //1 tick is minimum + configuration config = { prescalerBits, static_cast(ticks - 1) }; return config; } }; From 7fe6f6c9ebe4d474c3b11f567ddc6554b019cb03 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Jul 2021 19:14:33 +0300 Subject: [PATCH 07/15] Simplify logic --- src/hal/watchdog.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index 9a3edde..f737cb7 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -28,7 +28,7 @@ public: uint32_t ticks = timeout * F_WDT / (basePrescaler * (1 << prescalerBits)); while ((ticks >= (1 << reloadBits)) && (prescalerBits < maxPrescaler)) { prescalerBits++; - ticks = timeout * F_WDT / (basePrescaler * (1 << prescalerBits)); + ticks >>= 1; } if ((prescalerBits == 0) && (ticks == 0)) ticks = 1; //1 tick is minimum From d1fd815e0c3473b31df1cdf6690e7963083283ce Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Mon, 20 Sep 2021 16:36:44 +0200 Subject: [PATCH 08/15] Quick and dirty workaround --- src/hal/watchdog.h | 23 ++++++++++++++++------- src/main.cpp | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index f737cb7..31edb81 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -23,15 +23,24 @@ struct configuration { uint16_t reload; public: - static constexpr configuration compute(float timeout) { + static constexpr configuration compute(uint16_t timeout) { + // uint8_t prescalerBits = 0; + // uint32_t ticks = timeout * F_WDT / (basePrescaler * (1 << prescalerBits)); + // while ((ticks >= (1 << reloadBits)) && (prescalerBits < maxPrescaler)) { + // prescalerBits++; + // ticks >>= 1; + // } + // if ((prescalerBits == 0) && (ticks == 0)) + // ticks = 1; //1 tick is minimum + // configuration config = { prescalerBits, static_cast(ticks - 1) }; + // return config; uint8_t prescalerBits = 0; - uint32_t ticks = timeout * F_WDT / (basePrescaler * (1 << prescalerBits)); - while ((ticks >= (1 << reloadBits)) && (prescalerBits < maxPrescaler)) { - prescalerBits++; - ticks >>= 1; + uint32_t ticks = 1; + switch (timeout) { + case 8000: + prescalerBits = 9; } - if ((prescalerBits == 0) && (ticks == 0)) - ticks = 1; //1 tick is minimum + configuration config = { prescalerBits, static_cast(ticks - 1) }; return config; } diff --git a/src/main.cpp b/src/main.cpp index e06a034..2544f4d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -97,7 +97,7 @@ void setup() { mt::timebase.Init(); - watchdog::Enable(watchdog::configuration::compute(8)); //set 8s timeout + watchdog::Enable(watchdog::configuration::compute(8000)); //set 8s timeout mg::globals.Init(); From a23ed5e1bff44bbe6ed0b5c7c57a0bf1c49ede09 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Tue, 20 Jul 2021 07:16:59 +0200 Subject: [PATCH 09/15] Add watchdog implementation + use it in main() --- src/hal/CMakeLists.txt | 1 + src/hal/avr/watchdog.cpp | 15 +++++++++++++++ src/hal/watchdog.h | 1 + src/main.cpp | 5 ++++- 4 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/hal/avr/watchdog.cpp diff --git a/src/hal/CMakeLists.txt b/src/hal/CMakeLists.txt index 77c7d99..fd0029d 100644 --- a/src/hal/CMakeLists.txt +++ b/src/hal/CMakeLists.txt @@ -8,4 +8,5 @@ target_sources( tmc2130.cpp adc.cpp avr/spi.cpp + avr/watchdog.cpp ) diff --git a/src/hal/avr/watchdog.cpp b/src/hal/avr/watchdog.cpp new file mode 100644 index 0000000..a707047 --- /dev/null +++ b/src/hal/avr/watchdog.cpp @@ -0,0 +1,15 @@ +#include "../watchdog.h" + +namespace hal { +namespace watchdog { + +void ConfigureWatchDog(uint16_t period) { + // @@TODO +} + +void ResetWatchDog() { + asm("wdr"); +} + +} // namespace watchdog +} // namespace hal diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index c57d373..90c3f10 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -1,4 +1,5 @@ #pragma once +#include namespace hal { diff --git a/src/main.cpp b/src/main.cpp index 9fedbe2..4a4eac5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,7 @@ #include "hal/shr16.h" #include "hal/spi.h" #include "hal/usart.h" +#include "hal/watchdog.h" #include "pins.h" #include @@ -95,6 +96,7 @@ void setup() { cpu::Init(); mt::timebase.Init(); + hal::watchdog::ConfigureWatchDog(8); mg::globals.Init(); @@ -363,7 +365,8 @@ void loop() { ms::selector.Step(); mui::userInput.Step(); currentCommand->Step(); - // add a watchdog reset + + hal::watchdog::ResetWatchDog(); } int main() { From 4ba6c6e67988995d201a2eff7fde52f1111eb51b Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Tue, 20 Jul 2021 07:28:43 +0200 Subject: [PATCH 10/15] Add handling of the X0 message (restart the MMU) via Watchdog --- src/main.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 4a4eac5..26e1b9c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -293,12 +293,15 @@ void ProcessRequestMsg(const mp::RequestMsg &rq) { break; case mp::RequestMsgCodes::Reset: // immediately reset the board - there is no response in this case - break; // @@TODO + hal::watchdog::ConfigureWatchDog(1); // set the watchdog to the lowest possible timeout + for (;;) + ; // cycle indefinitely (i.e. let the watchdog reset the CPU) + break; case mp::RequestMsgCodes::Version: ReportVersion(rq); break; case mp::RequestMsgCodes::Wait: - break; // @@TODO + break; // @@TODO - not used anywhere yet case mp::RequestMsgCodes::Cut: case mp::RequestMsgCodes::Eject: case mp::RequestMsgCodes::Load: From 954ef2fb8ddf2c9c3c27431522359a43f4db5191 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Jul 2021 13:47:36 +0300 Subject: [PATCH 11/15] Reset the board using the cpu hal instead of the watchdog hal Also some naming changes --- src/hal/avr/cpu.cpp | 9 +++++++++ src/hal/avr/watchdog.cpp | 4 ++-- src/hal/cpu.h | 1 + src/hal/watchdog.h | 4 ++-- src/main.cpp | 8 +++----- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/hal/avr/cpu.cpp b/src/hal/avr/cpu.cpp index 96d539d..110e8be 100644 --- a/src/hal/avr/cpu.cpp +++ b/src/hal/avr/cpu.cpp @@ -1,4 +1,6 @@ #include "../cpu.h" +#include +#include "../watchdog.h" namespace hal { namespace cpu { @@ -6,5 +8,12 @@ namespace cpu { void Init() { } +void Reset() { + cli(); + watchdog::Enable(0); //minimum amount of watchdog + for (;;) + ; //endless loop while waiting for the watchdog to reset +} + } // namespace CPU } // namespace hal diff --git a/src/hal/avr/watchdog.cpp b/src/hal/avr/watchdog.cpp index a707047..86f1b52 100644 --- a/src/hal/avr/watchdog.cpp +++ b/src/hal/avr/watchdog.cpp @@ -3,11 +3,11 @@ namespace hal { namespace watchdog { -void ConfigureWatchDog(uint16_t period) { +void Enable(uint16_t period) { // @@TODO } -void ResetWatchDog() { +void Reset() { asm("wdr"); } diff --git a/src/hal/cpu.h b/src/hal/cpu.h index 604c7b9..ace6a9e 100644 --- a/src/hal/cpu.h +++ b/src/hal/cpu.h @@ -12,6 +12,7 @@ namespace cpu { /// CPU init routines (not really necessary for the AVR) void Init(); +void Reset(); } // namespace cpu } // namespace hal diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index 90c3f10..c585281 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -7,8 +7,8 @@ namespace hal { namespace watchdog { /// watchdog interface -void ConfigureWatchDog(uint16_t period); -void ResetWatchDog(); +void Enable(uint16_t period); +void Reset(); } // namespace watchdog } // namespace hal diff --git a/src/main.cpp b/src/main.cpp index 26e1b9c..b0aeb8f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -96,7 +96,7 @@ void setup() { cpu::Init(); mt::timebase.Init(); - hal::watchdog::ConfigureWatchDog(8); + watchdog::Enable(8000); //8s timeout mg::globals.Init(); @@ -293,9 +293,7 @@ void ProcessRequestMsg(const mp::RequestMsg &rq) { break; case mp::RequestMsgCodes::Reset: // immediately reset the board - there is no response in this case - hal::watchdog::ConfigureWatchDog(1); // set the watchdog to the lowest possible timeout - for (;;) - ; // cycle indefinitely (i.e. let the watchdog reset the CPU) + hal::cpu::Reset(); break; case mp::RequestMsgCodes::Version: ReportVersion(rq); @@ -369,7 +367,7 @@ void loop() { mui::userInput.Step(); currentCommand->Step(); - hal::watchdog::ResetWatchDog(); + hal::watchdog::Reset(); } int main() { From e86def99f9bd5d6dd14c20e41bef4f14b8df6de3 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Jul 2021 13:57:27 +0300 Subject: [PATCH 12/15] Add Disable and use the avrlibc wdt functions --- src/hal/avr/watchdog.cpp | 7 ++++++- src/hal/watchdog.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hal/avr/watchdog.cpp b/src/hal/avr/watchdog.cpp index 86f1b52..7717b58 100644 --- a/src/hal/avr/watchdog.cpp +++ b/src/hal/avr/watchdog.cpp @@ -1,4 +1,5 @@ #include "../watchdog.h" +#include namespace hal { namespace watchdog { @@ -7,8 +8,12 @@ void Enable(uint16_t period) { // @@TODO } +void Disable() { + wdt_disable(); +} + void Reset() { - asm("wdr"); + wdt_reset(); } } // namespace watchdog diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index c585281..592f6f3 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -8,6 +8,7 @@ namespace watchdog { /// watchdog interface void Enable(uint16_t period); +void Disable(); void Reset(); } // namespace watchdog From 0e9802c4cd72465d91efe5171ae3ddd90f8f295c Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Jul 2021 17:13:20 +0300 Subject: [PATCH 13/15] 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(); From 89a2bdc7e46733dfac3aca0ddee0f0cfa6fcfc09 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Jul 2021 18:23:42 +0300 Subject: [PATCH 14/15] Fix configuration compute() math --- src/hal/watchdog.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index 84a839e..9a3edde 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -14,7 +14,7 @@ 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 maxPrescaler = 6; //the maximum value prescalerBits can take constexpr uint8_t reloadBits = 12; //number of bits in the reload register #endif @@ -24,16 +24,15 @@ struct configuration { 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) { + uint32_t ticks = timeout * F_WDT / (basePrescaler * (1 << prescalerBits)); + while ((ticks >= (1 << reloadBits)) && (prescalerBits < maxPrescaler)) { prescalerBits++; + ticks = timeout * F_WDT / (basePrescaler * (1 << prescalerBits)); } - if (timeout) - reload = static_cast(((timeout * (1 << reloadBits)) / (tickPeriod * (basePrescaler << prescalerBits)))) - 1; - - configuration config = { prescalerBits, reload }; + if ((prescalerBits == 0) && (ticks == 0)) + ticks = 1; //1 tick is minimum + configuration config = { prescalerBits, static_cast(ticks - 1) }; return config; } }; From fbe8d3d6cd81df06f84da0fb505cb309346f18bf Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Jul 2021 19:14:33 +0300 Subject: [PATCH 15/15] Simplify logic --- src/hal/watchdog.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hal/watchdog.h b/src/hal/watchdog.h index 9a3edde..f737cb7 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -28,7 +28,7 @@ public: uint32_t ticks = timeout * F_WDT / (basePrescaler * (1 << prescalerBits)); while ((ticks >= (1 << reloadBits)) && (prescalerBits < maxPrescaler)) { prescalerBits++; - ticks = timeout * F_WDT / (basePrescaler * (1 << prescalerBits)); + ticks >>= 1; } if ((prescalerBits == 0) && (ticks == 0)) ticks = 1; //1 tick is minimum