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/cpu.cpp b/src/hal/avr/cpu.cpp index 96d539d..7bef056 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(watchdog::configuration::compute(0)); //quickest watchdog reset + 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 new file mode 100644 index 0000000..26b32aa --- /dev/null +++ b/src/hal/avr/watchdog.cpp @@ -0,0 +1,20 @@ +#include "../watchdog.h" +#include + +namespace hal { +namespace watchdog { + +void Enable(const configuration &config) { + wdt_enable(config.prescalerBits); +} + +void Disable() { + wdt_disable(); +} + +void Reset() { + wdt_reset(); +} + +} // namespace watchdog +} // namespace hal 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 c57d373..a560c14 100644 --- a/src/hal/watchdog.h +++ b/src/hal/watchdog.h @@ -1,13 +1,55 @@ #pragma once +#include 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 = 6; //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(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 = 1; + switch (timeout) { + case 8000: + prescalerBits = 9; + } + + configuration config = { prescalerBits, static_cast(ticks - 1) }; + return config; + } +}; + /// watchdog interface -void ConfigureWatchDog(uint16_t period); -void ResetWatchDog(); +void Enable(const configuration &config); +void Disable(); +void Reset(); } // namespace watchdog } // namespace hal diff --git a/src/main.cpp b/src/main.cpp index 9fedbe2..2544f4d 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(); + watchdog::Enable(watchdog::configuration::compute(8000)); //set 8s timeout + mg::globals.Init(); // watchdog init @@ -291,12 +294,13 @@ 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::cpu::Reset(); + 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: @@ -363,7 +367,8 @@ void loop() { ms::selector.Step(); mui::userInput.Step(); currentCommand->Step(); - // add a watchdog reset + + hal::watchdog::Reset(); } int main() {