1 /*
2  * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /* Recommendation of using API RTC_WDT.
8 1) Setting and enabling rtc_wdt:
9 @code
10     rtc_wdt_protect_off();
11     rtc_wdt_disable();
12     rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us);
13     rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_SYSTEM); //RTC_WDT_STAGE_ACTION_RESET_SYSTEM or RTC_WDT_STAGE_ACTION_RESET_RTC
14     rtc_wdt_set_time(RTC_WDT_STAGE0, 7000);     // timeout rtd_wdt 7000ms.
15     rtc_wdt_enable();
16     rtc_wdt_protect_on();
17  @endcode
18 
19 * If you use this option RTC_WDT_STAGE_ACTION_RESET_SYSTEM then after reset you can see these messages.
20 They can help to understand where the CPUs were when the WDT was triggered.
21     W (30) boot: PRO CPU has been reset by WDT.
22 	W (30) boot: WDT reset info: PRO CPU PC=0x400xxxxx
23 	... function where it happened
24 
25 	W (31) boot: WDT reset info: APP CPU PC=0x400xxxxx
26 	... function where it happened
27 
28 * If you use this option RTC_WDT_STAGE_ACTION_RESET_RTC then you will see message (rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT))
29 without description where were CPUs when it happened.
30 
31 2) Reset counter of rtc_wdt:
32 @code
33     rtc_wdt_feed();
34 @endcode
35 
36 3) Disable rtc_wdt:
37 @code
38     rtc_wdt_disable();
39 @endcode
40  */
41 
42 #pragma once
43 #include <stdint.h>
44 #include <stdbool.h>
45 #include "soc/rtc_periph.h"
46 #include "esp_err.h"
47 
48 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
49 
50 #ifdef __cplusplus
51 extern "C"
52 {
53 #endif
54 
55 /// List of stage of rtc watchdog. WDT has 4 stage.
56 typedef enum {
57     RTC_WDT_STAGE0 = 0,     /*!< Stage 0 */
58     RTC_WDT_STAGE1 = 1,     /*!< Stage 1 */
59     RTC_WDT_STAGE2 = 2,     /*!< Stage 2 */
60     RTC_WDT_STAGE3 = 3      /*!< Stage 3 */
61 } rtc_wdt_stage_t;
62 
63 /// List of action. When the time of stage expires this action will be triggered.
64 typedef enum {
65     RTC_WDT_STAGE_ACTION_OFF            = RTC_WDT_STG_SEL_OFF,          /*!< Disabled. This stage will have no effects on the system. */
66     RTC_WDT_STAGE_ACTION_INTERRUPT      = RTC_WDT_STG_SEL_INT,          /*!< Trigger an interrupt. When the stage expires an interrupt is triggered. */
67     RTC_WDT_STAGE_ACTION_RESET_CPU      = RTC_WDT_STG_SEL_RESET_CPU,    /*!< Reset a CPU core. */
68     RTC_WDT_STAGE_ACTION_RESET_SYSTEM   = RTC_WDT_STG_SEL_RESET_SYSTEM, /*!< Reset the main system includes the CPU and all peripherals. The RTC is an exception to this, and it will not be reset. */
69     RTC_WDT_STAGE_ACTION_RESET_RTC      = RTC_WDT_STG_SEL_RESET_RTC     /*!< Reset the main system and the RTC. */
70 } rtc_wdt_stage_action_t;
71 
72 /// Type of reset signal
73 typedef enum {
74     RTC_WDT_SYS_RESET_SIG = 0,     /*!< System reset signal length selection */
75     RTC_WDT_CPU_RESET_SIG = 1      /*!< CPU reset signal length selection */
76 } rtc_wdt_reset_sig_t;
77 
78 /// Length of reset signal
79 typedef enum {
80     RTC_WDT_LENGTH_100ns = 0,     /*!< 100 ns */
81     RTC_WDT_LENGTH_200ns = 1,     /*!< 200 ns */
82     RTC_WDT_LENGTH_300ns = 2,     /*!< 300 ns */
83     RTC_WDT_LENGTH_400ns = 3,     /*!< 400 ns */
84     RTC_WDT_LENGTH_500ns = 4,     /*!< 500 ns */
85     RTC_WDT_LENGTH_800ns = 5,     /*!< 800 ns */
86     RTC_WDT_LENGTH_1_6us = 6,     /*!< 1.6 us */
87     RTC_WDT_LENGTH_3_2us = 7      /*!< 3.2 us */
88 } rtc_wdt_length_sig_t;
89 
90 /**
91  * @brief Get status of protect of rtc_wdt.
92  *
93  * @return
94  *         - True if the protect of RTC_WDT is set
95  */
96 bool rtc_wdt_get_protect_status(void);
97 
98 /**
99  * @brief Set protect of rtc_wdt.
100  */
101 void rtc_wdt_protect_on(void);
102 
103 /**
104  * @brief Reset protect of rtc_wdt.
105  */
106 void rtc_wdt_protect_off(void);
107 
108 /**
109  * @brief Enable rtc_wdt.
110  */
111 void rtc_wdt_enable(void);
112 
113 /**
114  * @brief Enable the flash boot protection procedure for WDT.
115  *
116  * Do not recommend to use it in the app.
117  * This function was added to be compatibility with the old bootloaders.
118  * This mode is disabled in bootloader or using rtc_wdt_disable() function.
119  */
120 void rtc_wdt_flashboot_mode_enable(void);
121 
122 /**
123  * @brief Disable rtc_wdt.
124  */
125 void rtc_wdt_disable(void);
126 
127 /**
128  * @brief Reset counter rtc_wdt.
129  *
130  * It returns to stage 0 and its expiry counter restarts from 0.
131  */
132 void rtc_wdt_feed(void);
133 
134 /**
135  * @brief Set time for required stage.
136  *
137  * @param[in] stage Stage of rtc_wdt.
138  * @param[in] timeout_ms Timeout for this stage.
139  *
140  * @return
141  *         - ESP_OK In case of success
142  *         - ESP_ERR_INVALID_ARG If stage has invalid value
143  */
144 esp_err_t rtc_wdt_set_time(rtc_wdt_stage_t stage, unsigned int timeout_ms);
145 
146 /**
147  * @brief Get the timeout set for the required stage.
148  *
149  * @param[in]  stage Stage of rtc_wdt.
150  * @param[out] timeout_ms Timeout set for this stage. (not elapsed time).
151  *
152  * @return
153  *         - ESP_OK In case of success
154  *         - ESP_ERR_INVALID_ARG If stage has invalid value
155  */
156 esp_err_t rtc_wdt_get_timeout(rtc_wdt_stage_t stage, unsigned int* timeout_ms);
157 
158 /**
159  * @brief Set an action for required stage.
160  *
161  * @param[in] stage Stage of rtc_wdt.
162  * @param[in] stage_sel Action for this stage. When the time of stage expires this action will be triggered.
163  *
164  * @return
165  *         - ESP_OK In case of success
166  *         - ESP_ERR_INVALID_ARG If stage or stage_sel have invalid value
167  */
168 esp_err_t rtc_wdt_set_stage(rtc_wdt_stage_t stage, rtc_wdt_stage_action_t stage_sel);
169 
170 /**
171  * @brief Set a length of reset signal.
172  *
173  * @param[in] reset_src Type of reset signal.
174  * @param[in] reset_signal_length A length of reset signal.
175  *
176  * @return
177  *         - ESP_OK In case of success
178  *         - ESP_ERR_INVALID_ARG If reset_src  or reset_signal_length have invalid value
179  */
180 esp_err_t rtc_wdt_set_length_of_reset_signal(rtc_wdt_reset_sig_t reset_src, rtc_wdt_length_sig_t reset_signal_length);
181 
182 /**
183  * @brief Return true if rtc_wdt is enabled.
184  *
185  * @return
186  *         - True rtc_wdt is enabled
187  */
188 bool rtc_wdt_is_on(void);
189 
190 #ifdef __cplusplus
191 }
192 #endif
193 
194 #endif // CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
195