libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
esp_watchdog.cpp
1#include "esp_watchdog.hpp"
2
3#include <cstdint>
4
5#include "esp_private/periph_ctrl.h"
6#include "hal/mwdt_ll.h"
7#include "hal/timer_ll.h"
8
9namespace LibXR
10{
11namespace
12{
13
14constexpr uint32_t kWdtTickUs = 500;
15constexpr uint32_t kWdtTicksPerMs = 1000 / kWdtTickUs;
16
17bool GetMwdtGroupInfo(wdt_inst_t instance, int* group_id, periph_module_t* periph)
18{
19 if (instance == WDT_MWDT0)
20 {
21 *group_id = 0;
22 *periph = PERIPH_TIMG0_MODULE;
23 return true;
24 }
25
26#if SOC_TIMER_GROUPS >= 2
27 if (instance == WDT_MWDT1)
28 {
29 *group_id = 1;
30 *periph = PERIPH_TIMG1_MODULE;
31 return true;
32 }
33#endif
34
35 return false;
36}
37
38} // namespace
39
40ESP32Watchdog::ESP32Watchdog(uint32_t timeout_ms, uint32_t feed_ms)
41{
42 (void)SetConfig({timeout_ms, feed_ms});
43 (void)Start();
44}
45
46bool ESP32Watchdog::IsInstanceSupported(wdt_inst_t instance)
47{
48 switch (instance)
49 {
50 case WDT_MWDT0:
51 return true;
52#if SOC_TIMER_GROUPS >= 2
53 case WDT_MWDT1:
54 return true;
55#endif
56 case WDT_RWDT:
57 return true;
58 default:
59 return false;
60 }
61}
62
63ErrorCode ESP32Watchdog::InitializeHardware()
64{
65 if (initialized_)
66 {
67 return ErrorCode::OK;
68 }
69
70 if (!IsInstanceSupported(instance_))
71 {
73 }
74
75 if (instance_ != WDT_RWDT)
76 {
77 int group_id = 0;
78 periph_module_t periph = PERIPH_TIMG0_MODULE;
79 if (!GetMwdtGroupInfo(instance_, &group_id, &periph))
80 {
82 }
83
84 PERIPH_RCC_ACQUIRE_ATOMIC(periph, ref_count)
85 {
86 if (ref_count == 0)
87 {
88 timer_ll_enable_bus_clock(group_id, true);
89 timer_ll_reset_register(group_id);
90 }
91 }
92 }
93
94 const uint32_t prescaler = instance_ == WDT_RWDT ? 0U : MWDT_LL_DEFAULT_CLK_PRESCALER;
95 wdt_hal_init(&hal_, instance_, prescaler, false);
96 initialized_ = true;
97 return ErrorCode::OK;
98}
99
100ErrorCode ESP32Watchdog::ApplyConfiguration()
101{
102 if (!initialized_)
103 {
104 return ErrorCode::INIT_ERR;
105 }
106
107 const uint64_t ticks64 = static_cast<uint64_t>(timeout_ms_) * kWdtTicksPerMs;
108 if ((ticks64 == 0) || (ticks64 > UINT32_MAX))
109 {
111 }
112
113 const uint32_t stage0_ticks = static_cast<uint32_t>(ticks64);
114
115 wdt_hal_write_protect_disable(&hal_);
116 wdt_hal_config_stage(&hal_, WDT_STAGE0, stage0_ticks, WDT_STAGE_ACTION_RESET_SYSTEM);
117 wdt_hal_config_stage(&hal_, WDT_STAGE1, 0, WDT_STAGE_ACTION_OFF);
118 wdt_hal_config_stage(&hal_, WDT_STAGE2, 0, WDT_STAGE_ACTION_OFF);
119 wdt_hal_config_stage(&hal_, WDT_STAGE3, 0, WDT_STAGE_ACTION_OFF);
120 wdt_hal_write_protect_enable(&hal_);
121
122 return ErrorCode::OK;
123}
124
126{
127 if ((config.timeout_ms == 0) || (config.feed_ms == 0) ||
128 (config.feed_ms > config.timeout_ms))
129 {
130 return ErrorCode::ARG_ERR;
131 }
132
133 timeout_ms_ = config.timeout_ms;
135
136 ErrorCode ret = InitializeHardware();
137 if (ret != ErrorCode::OK)
138 {
139 return ret;
140 }
141
142 return ApplyConfiguration();
143}
144
146{
147 if (!initialized_ || !started_)
148 {
149 return ErrorCode::INIT_ERR;
150 }
151
152 wdt_hal_write_protect_disable(&hal_);
153 wdt_hal_feed(&hal_);
154 wdt_hal_write_protect_enable(&hal_);
155 return ErrorCode::OK;
156}
157
159{
160 ErrorCode ret = InitializeHardware();
161 if (ret != ErrorCode::OK)
162 {
163 return ret;
164 }
165
166 ret = ApplyConfiguration();
167 if (ret != ErrorCode::OK)
168 {
169 return ret;
170 }
171
172 wdt_hal_write_protect_disable(&hal_);
173 wdt_hal_enable(&hal_);
174 wdt_hal_feed(&hal_);
175 wdt_hal_write_protect_enable(&hal_);
176
177 auto_feed_ = true;
178 started_ = true;
179 return ErrorCode::OK;
180}
181
183{
184 if (!initialized_)
185 {
186 return ErrorCode::INIT_ERR;
187 }
188
189 wdt_hal_write_protect_disable(&hal_);
190 wdt_hal_disable(&hal_);
191 wdt_hal_write_protect_enable(&hal_);
192
193 auto_feed_ = false;
194 started_ = false;
195 return ErrorCode::OK;
196}
197
198} // namespace LibXR
ErrorCode Start() override
启动看门狗 / Start the watchdog
ErrorCode Stop() override
停止看门狗 / Stop the watchdog
ErrorCode Feed() override
立即手动喂狗 Feed the watchdog immediately
ErrorCode SetConfig(const Configuration &config) override
初始化硬件并设置超时时间 Initialize hardware and set overflow time
uint32_t auto_feed_interval_ms
自动喂狗间隔
Definition watchdog.hpp:110
bool auto_feed_
是否自动喂狗
Definition watchdog.hpp:111
uint32_t timeout_ms_
溢出时间
Definition watchdog.hpp:109
LibXR 命名空间
Definition ch32_can.hpp:14
ErrorCode
定义错误码枚举
Definition libxr_def.hpp:64
@ INIT_ERR
初始化错误 | Initialization error
@ NOT_SUPPORT
不支持 | Not supported
@ OK
操作成功 | Operation successful
@ ARG_ERR
参数错误 | Argument error
看门狗配置结构体 Configuration for the watchdog
Definition watchdog.hpp:27
uint32_t feed_ms
自动喂狗周期 Auto feed interval (ms, < timeout_ms)
Definition watchdog.hpp:29
uint32_t timeout_ms
看门狗溢出时间 Watchdog overflow time (ms)
Definition watchdog.hpp:28