/** * @file gpTimer.hpp * @author Gustice * @brief ESP-hardware-timer class * * @copyright Copyright (c) 2024 */ #pragma once #include "driver/gptimer.h" #include "esp_attr.h" #include "esp_log.h" #include "portBase.hpp" /** * @brief Base class for tasks */ class HwTimerBase : public PortBase { public: enum Mode { OneShot = 0, Periodic }; void setup(int thresh, Mode mode); void start(); void stop(); protected: gptimer_handle_t gpTimer{}; HwTimerBase(gptimer_alarm_cb_t callback); ~HwTimerBase(); }; /** * @brief Simple Timer without callback */ class HwTimer : public HwTimerBase { public: using CallSignature = bool (*)(HwTimer &); HwTimer(CallSignature call) : HwTimerBase(CallFrame), _call{call} { } private: CallSignature _call; static bool IRAM_ATTR CallFrame(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *_this) { auto &tmr = *reinterpret_cast(_this); return tmr._call(tmr); } }; /** * @brief Timer with callback parameter * @tparam T Type of task parameter on call */ template class HwTimerT : public HwTimerBase { using CallSignatureT = bool (*)(HwTimerT &, T); public: HwTimerT(CallSignatureT call, const T ¶m) : HwTimerBase(CallFrame), _param(call, param) { } private: template struct Param { CallSignatureT call; const TS &arg; }; static bool IRAM_ATTR CallFrame(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *_this) { auto &tmr = *reinterpret_cast(_this); auto ¶m = tmr._param; return param.call(tmr, param.arg); } Param _param; };