• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // The LL layer for Timer Group register operations.
16 // Note that most of the register operations in this layer are non-atomic operations.
17 
18 #pragma once
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 #include <stdlib.h>
25 #include <stdbool.h>
26 #include "hal/wdt_types.h"
27 #include "soc/rtc_cntl_periph.h"
28 #include "esp_attr.h"
29 
30 //Type check wdt_stage_action_t
31 _Static_assert(WDT_STAGE_ACTION_OFF == RTC_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
32 _Static_assert(WDT_STAGE_ACTION_INT == RTC_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
33 _Static_assert(WDT_STAGE_ACTION_RESET_CPU == RTC_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
34 _Static_assert(WDT_STAGE_ACTION_RESET_SYSTEM == RTC_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
35 _Static_assert(WDT_STAGE_ACTION_RESET_RTC == RTC_WDT_STG_SEL_RESET_RTC, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
36 //Type check wdt_reset_sig_length_t
37 _Static_assert(WDT_RESET_SIG_LENGTH_100ns == RTC_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
38 _Static_assert(WDT_RESET_SIG_LENGTH_200ns == RTC_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
39 _Static_assert(WDT_RESET_SIG_LENGTH_300ns == RTC_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
40 _Static_assert(WDT_RESET_SIG_LENGTH_400ns == RTC_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
41 _Static_assert(WDT_RESET_SIG_LENGTH_500ns == RTC_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
42 _Static_assert(WDT_RESET_SIG_LENGTH_800ns == RTC_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
43 _Static_assert(WDT_RESET_SIG_LENGTH_1_6us == RTC_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
44 _Static_assert(WDT_RESET_SIG_LENGTH_3_2us == RTC_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
45 
46 
47 /**
48  * @brief Enable the RWDT
49  *
50  * @param hw Start address of the peripheral registers.
51  */
rwdt_ll_enable(rtc_cntl_dev_t * hw)52 FORCE_INLINE_ATTR void rwdt_ll_enable(rtc_cntl_dev_t *hw)
53 {
54     hw->wdt_config0.en = 1;
55 }
56 
57 /**
58  * @brief Disable the RWDT
59  *
60  * @param hw Start address of the peripheral registers.
61  * @note This function does not disable the flashboot mode. Therefore, given that
62  *       the MWDT is disabled using this function, a timeout can still occur
63  *       if the flashboot mode is simultaneously enabled.
64  */
rwdt_ll_disable(rtc_cntl_dev_t * hw)65 FORCE_INLINE_ATTR void rwdt_ll_disable(rtc_cntl_dev_t *hw)
66 {
67     hw->wdt_config0.en = 0;
68 }
69 
70 /**
71  * @brief Check if the RWDT is enabled
72  *
73  * @param hw Start address of the peripheral registers.
74  * @return True if RTC WDT is enabled
75  */
rwdt_ll_check_if_enabled(rtc_cntl_dev_t * hw)76 FORCE_INLINE_ATTR bool rwdt_ll_check_if_enabled(rtc_cntl_dev_t *hw)
77 {
78     return (hw->wdt_config0.en) ? true : false;
79 }
80 
81 /**
82  * @brief Configure a particular stage of the RWDT
83  *
84  * @param hw Start address of the peripheral registers.
85  * @param stage Which stage to configure
86  * @param timeout Number of timer ticks for the stage to timeout
87  * @param behavior What action to take when the stage times out
88  */
rwdt_ll_config_stage(rtc_cntl_dev_t * hw,wdt_stage_t stage,uint32_t timeout_ticks,wdt_stage_action_t behavior)89 FORCE_INLINE_ATTR void rwdt_ll_config_stage(rtc_cntl_dev_t *hw, wdt_stage_t stage, uint32_t timeout_ticks, wdt_stage_action_t behavior)
90 {
91     switch (stage) {
92         case WDT_STAGE0:
93             hw->wdt_config0.stg0 = behavior;
94             hw->wdt_config1 = timeout_ticks;
95             break;
96         case WDT_STAGE1:
97             hw->wdt_config0.stg1 = behavior;
98             hw->wdt_config2 = timeout_ticks;
99             break;
100         case WDT_STAGE2:
101             hw->wdt_config0.stg2 = behavior;
102             hw->wdt_config3 = timeout_ticks;
103             break;
104         case WDT_STAGE3:
105             hw->wdt_config0.stg3 = behavior;
106             hw->wdt_config4 = timeout_ticks;
107             break;
108         default:
109             abort();
110     }
111 }
112 
113 /**
114  * @brief Disable a particular stage of the RWDT
115  *
116  * @param hw Start address of the peripheral registers.
117  * @param stage Which stage to disable
118  */
rwdt_ll_disable_stage(rtc_cntl_dev_t * hw,wdt_stage_t stage)119 FORCE_INLINE_ATTR void rwdt_ll_disable_stage(rtc_cntl_dev_t *hw, wdt_stage_t stage)
120 {
121     switch (stage) {
122         case WDT_STAGE0:
123             hw->wdt_config0.stg0 = WDT_STAGE_ACTION_OFF;
124             break;
125         case WDT_STAGE1:
126             hw->wdt_config0.stg1 = WDT_STAGE_ACTION_OFF;
127             break;
128         case WDT_STAGE2:
129             hw->wdt_config0.stg2 = WDT_STAGE_ACTION_OFF;
130             break;
131         case WDT_STAGE3:
132             hw->wdt_config0.stg3 = WDT_STAGE_ACTION_OFF;
133             break;
134         default:
135             abort();
136     }
137 }
138 
139 /**
140  * @brief Enable or disable RWDT edge interrupt
141  *
142  * @param hw Start address of the peripheral registers.
143  * @param enable Whether to enable edge interrupt
144  */
rwdt_ll_set_edge_intr(rtc_cntl_dev_t * hw,bool enable)145 FORCE_INLINE_ATTR void rwdt_ll_set_edge_intr(rtc_cntl_dev_t *hw, bool enable)
146 {
147     hw->wdt_config0.edge_int_en = (enable) ? 1 : 0;
148 }
149 
150 /**
151  * @brief Enable or disable RWDT level interrupt
152  *
153  * @param hw Start address of the peripheral registers.
154  * @param enable Whether to enable level interrupt
155  */
rwdt_ll_set_level_intr(rtc_cntl_dev_t * hw,bool enable)156 FORCE_INLINE_ATTR void rwdt_ll_set_level_intr(rtc_cntl_dev_t *hw, bool enable)
157 {
158     hw->wdt_config0.level_int_en = (enable) ? 1 : 0;
159 }
160 
161 /**
162  * @brief Set the length of the CPU reset action
163  *
164  * @param hw Start address of the peripheral registers.
165  * @param length Length of CPU reset signal
166  */
rwdt_ll_set_cpu_reset_length(rtc_cntl_dev_t * hw,wdt_reset_sig_length_t length)167 FORCE_INLINE_ATTR void rwdt_ll_set_cpu_reset_length(rtc_cntl_dev_t *hw, wdt_reset_sig_length_t length)
168 {
169     hw->wdt_config0.cpu_reset_length = length;
170 }
171 
172 /**
173  * @brief Set the length of the system reset action
174  *
175  * @param hw Start address of the peripheral registers.
176  * @param length Length of system reset signal
177  */
rwdt_ll_set_sys_reset_length(rtc_cntl_dev_t * hw,wdt_reset_sig_length_t length)178 FORCE_INLINE_ATTR void rwdt_ll_set_sys_reset_length(rtc_cntl_dev_t *hw, wdt_reset_sig_length_t length)
179 {
180     hw->wdt_config0.sys_reset_length = length;
181 }
182 
183 /**
184  * @brief Enable/Disable the RWDT flashboot mode.
185  *
186  * @param hw Start address of the peripheral registers.
187  * @param enable True to enable RWDT flashboot mode, false to disable RWDT flashboot mode.
188  *
189  * @note Flashboot mode is independent and can trigger a WDT timeout event if the
190  *       WDT's enable bit is set to 0. Flashboot mode for RWDT is automatically enabled
191  *       on flashboot, and should be disabled by software when flashbooting completes.
192  */
rwdt_ll_set_flashboot_en(rtc_cntl_dev_t * hw,bool enable)193 FORCE_INLINE_ATTR void rwdt_ll_set_flashboot_en(rtc_cntl_dev_t* hw, bool enable)
194 {
195     hw->wdt_config0.flashboot_mod_en = (enable) ? 1 : 0;
196 }
197 
198 /**
199  * @brief Enable/Disable the CPU0 to be reset on WDT_STAGE_ACTION_RESET_CPU
200  *
201  * @param hw Start address of the peripheral registers.
202  * @param enable True to enable CPU0 to be reset, false to disable.
203  */
rwdt_ll_set_procpu_reset_en(rtc_cntl_dev_t * hw,bool enable)204 FORCE_INLINE_ATTR void rwdt_ll_set_procpu_reset_en(rtc_cntl_dev_t* hw, bool enable)
205 {
206     hw->wdt_config0.procpu_reset_en = (enable) ? 1 : 0;
207 }
208 
209 /**
210  * @brief Enable/Disable the CPU1 to be reset on WDT_STAGE_ACTION_RESET_CPU
211  *
212  * @param hw Start address of the peripheral registers.
213  * @param enable True to enable CPU1 to be reset, false to disable.
214  */
rwdt_ll_set_appcpu_reset_en(rtc_cntl_dev_t * hw,bool enable)215 FORCE_INLINE_ATTR void rwdt_ll_set_appcpu_reset_en(rtc_cntl_dev_t* hw, bool enable)
216 {
217     hw->wdt_config0.appcpu_reset_en = (enable) ? 1 : 0;
218 }
219 
220 /**
221  * @brief Enable/Disable the RWDT pause during sleep functionality
222  *
223  * @param hw Start address of the peripheral registers.
224  * @param enable True to enable, false to disable.
225  */
rwdt_ll_set_pause_in_sleep_en(rtc_cntl_dev_t * hw,bool enable)226 FORCE_INLINE_ATTR void rwdt_ll_set_pause_in_sleep_en(rtc_cntl_dev_t* hw, bool enable)
227 {
228     hw->wdt_config0.pause_in_slp = (enable) ? 1 : 0;
229 }
230 
231 /**
232  * @brief Feed the RWDT
233  *
234  * Resets the current timer count and current stage.
235  *
236  * @param hw Start address of the peripheral registers.
237  */
rwdt_ll_feed(rtc_cntl_dev_t * hw)238 FORCE_INLINE_ATTR void rwdt_ll_feed(rtc_cntl_dev_t *hw)
239 {
240     hw->wdt_feed.feed = 1;
241 }
242 
243 /**
244  * @brief Enable write protection of the RWDT registers
245  *
246  * @param hw Start address of the peripheral registers.
247  */
rwdt_ll_write_protect_enable(rtc_cntl_dev_t * hw)248 FORCE_INLINE_ATTR void rwdt_ll_write_protect_enable(rtc_cntl_dev_t *hw)
249 {
250     hw->wdt_wprotect = 0;
251 }
252 
253 /**
254  * @brief Disable write protection of the RWDT registers
255  *
256  * @param hw Start address of the peripheral registers.
257  */
rwdt_ll_write_protect_disable(rtc_cntl_dev_t * hw)258 FORCE_INLINE_ATTR void rwdt_ll_write_protect_disable(rtc_cntl_dev_t *hw)
259 {
260     hw->wdt_wprotect = RTC_CNTL_WDT_WKEY_VALUE;
261 }
262 
263 /**
264  * @brief Enable the RWDT interrupt.
265  *
266  * @param hw Start address of the peripheral registers.
267  * @param enable True to enable RWDT interrupt, false to disable.
268  */
rwdt_ll_set_intr_enable(rtc_cntl_dev_t * hw,bool enable)269 FORCE_INLINE_ATTR void rwdt_ll_set_intr_enable(rtc_cntl_dev_t* hw, bool enable)
270 {
271     hw->int_ena.rtc_wdt = (enable) ? 1 : 0;
272 }
273 
274 /**
275  * @brief Check if the RWDT interrupt has been triggered
276  *
277  * @param hw Start address of the peripheral registers.
278  * @return True if the RWDT interrupt was triggered
279  */
rwdt_ll_check_intr_status(rtc_cntl_dev_t * hw)280 FORCE_INLINE_ATTR bool rwdt_ll_check_intr_status(rtc_cntl_dev_t *hw)
281 {
282     return (hw->int_st.rtc_wdt) ? true : false;
283 }
284 
285 /**
286  * @brief Clear the RWDT interrupt status.
287  *
288  * @param hw Start address of the peripheral registers.
289  */
rwdt_ll_clear_intr_status(rtc_cntl_dev_t * hw)290 FORCE_INLINE_ATTR void rwdt_ll_clear_intr_status(rtc_cntl_dev_t* hw)
291 {
292     hw->int_clr.rtc_wdt = 1;
293 }
294 
295 #ifdef __cplusplus
296 }
297 #endif
298