• 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 <stdint.h>
25 #include <stdbool.h>
26 #include "soc/timer_periph.h"
27 #include "hal/wdt_types.h"
28 #include "esp_attr.h"
29 
30 //Type check wdt_stage_action_t
31 _Static_assert(WDT_STAGE_ACTION_OFF == TIMG_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 == TIMG_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 == TIMG_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 == TIMG_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 //Type check wdt_reset_sig_length_t
36 _Static_assert(WDT_RESET_SIG_LENGTH_100ns == TIMG_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");
37 _Static_assert(WDT_RESET_SIG_LENGTH_200ns == TIMG_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");
38 _Static_assert(WDT_RESET_SIG_LENGTH_300ns == TIMG_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");
39 _Static_assert(WDT_RESET_SIG_LENGTH_400ns == TIMG_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");
40 _Static_assert(WDT_RESET_SIG_LENGTH_500ns == TIMG_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");
41 _Static_assert(WDT_RESET_SIG_LENGTH_800ns == TIMG_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");
42 _Static_assert(WDT_RESET_SIG_LENGTH_1_6us == TIMG_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");
43 _Static_assert(WDT_RESET_SIG_LENGTH_3_2us == TIMG_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");
44 
45 /**
46  * @brief Enable the MWDT
47  *
48  * @param hw Start address of the peripheral registers.
49  */
mwdt_ll_enable(timg_dev_t * hw)50 FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw)
51 {
52     hw->wdt_config0.en = 1;
53 }
54 
55 /**
56  * @brief Disable the MWDT
57  *
58  * @param hw Start address of the peripheral registers.
59  * @note This function does not disable the flashboot mode. Therefore, given that
60  *       the MWDT is disabled using this function, a timeout can still occur
61  *       if the flashboot mode is simultaneously enabled.
62  */
mwdt_ll_disable(timg_dev_t * hw)63 FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw)
64 {
65     hw->wdt_config0.en = 0;
66 }
67 
68 /**
69  * Check if the MWDT is enabled
70  *
71  * @param hw Start address of the peripheral registers.
72  * @return True if the MWDT is enabled, false otherwise
73  */
mwdt_ll_check_if_enabled(timg_dev_t * hw)74 FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw)
75 {
76     return (hw->wdt_config0.en) ? true : false;
77 }
78 
79 /**
80  * @brief Configure a particular stage of the MWDT
81  *
82  * @param hw Start address of the peripheral registers.
83  * @param stage Which stage to configure
84  * @param timeout Number of timer ticks for the stage to timeout
85  * @param behavior What action to take when the stage times out
86  */
mwdt_ll_config_stage(timg_dev_t * hw,wdt_stage_t stage,uint32_t timeout,wdt_stage_action_t behavior)87 FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, uint32_t timeout, wdt_stage_action_t behavior)
88 {
89     switch (stage) {
90         case WDT_STAGE0:
91             hw->wdt_config0.stg0 = behavior;
92             hw->wdt_config2 = timeout;
93             break;
94         case WDT_STAGE1:
95             hw->wdt_config0.stg1 = behavior;
96             hw->wdt_config3 = timeout;
97             break;
98         case WDT_STAGE2:
99             hw->wdt_config0.stg2 = behavior;
100             hw->wdt_config4 = timeout;
101             break;
102         case WDT_STAGE3:
103             hw->wdt_config0.stg3 = behavior;
104             hw->wdt_config5 = timeout;
105             break;
106         default:
107             break;
108     }
109 }
110 
111 /**
112  * @brief Disable a particular stage of the MWDT
113  *
114  * @param hw Start address of the peripheral registers.
115  * @param stage Which stage to disable
116  */
mwdt_ll_disable_stage(timg_dev_t * hw,uint32_t stage)117 FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
118 {
119     switch (stage) {
120         case WDT_STAGE0:
121             hw->wdt_config0.stg0 = WDT_STAGE_ACTION_OFF;
122             break;
123         case WDT_STAGE1:
124             hw->wdt_config0.stg1 = WDT_STAGE_ACTION_OFF;
125             break;
126         case WDT_STAGE2:
127             hw->wdt_config0.stg2 = WDT_STAGE_ACTION_OFF;
128             break;
129         case WDT_STAGE3:
130             hw->wdt_config0.stg3 = WDT_STAGE_ACTION_OFF;
131             break;
132         default:
133             break;
134     }
135 }
136 
137 /**
138  * @brief Enable or disable MWDT edge interrupt
139  *
140  * @param hw Start address of the peripheral registers.
141  * @param enable Whether to enable edge interrupt
142  */
mwdt_ll_set_edge_intr(timg_dev_t * hw,bool enable)143 FORCE_INLINE_ATTR void mwdt_ll_set_edge_intr(timg_dev_t *hw, bool enable)
144 {
145     hw->wdt_config0.edge_int_en = (enable) ? 1 : 0;
146 }
147 
148 /**
149  * @brief Enable or disable MWDT level interrupt
150  *
151  * @param hw Start address of the peripheral registers.
152  * @param enable Whether to enable level interrupt
153  */
mwdt_ll_set_level_intr(timg_dev_t * hw,bool enable)154 FORCE_INLINE_ATTR void mwdt_ll_set_level_intr(timg_dev_t *hw, bool enable)
155 {
156     hw->wdt_config0.level_int_en = (enable) ? 1 : 0;
157 }
158 
159 /**
160  * @brief Set the length of the CPU reset action
161  *
162  * @param hw Start address of the peripheral registers.
163  * @param length Length of CPU reset signal
164  */
mwdt_ll_set_cpu_reset_length(timg_dev_t * hw,wdt_reset_sig_length_t length)165 FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
166 {
167     hw->wdt_config0.cpu_reset_length = length;
168 }
169 
170 /**
171  * @brief Set the length of the system reset action
172  *
173  * @param hw Start address of the peripheral registers.
174  * @param length Length of system reset signal
175  */
mwdt_ll_set_sys_reset_length(timg_dev_t * hw,wdt_reset_sig_length_t length)176 FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
177 {
178     hw->wdt_config0.sys_reset_length = length;
179 }
180 
181 /**
182  * @brief Enable/Disable the MWDT flashboot mode.
183  *
184  * @param hw Beginning address of the peripheral registers.
185  * @param enable True to enable WDT flashboot mode, false to disable WDT flashboot mode.
186  *
187  * @note Flashboot mode is independent and can trigger a WDT timeout event if the
188  *       WDT's enable bit is set to 0. Flashboot mode for TG0 is automatically enabled
189  *       on flashboot, and should be disabled by software when flashbooting completes.
190  */
mwdt_ll_set_flashboot_en(timg_dev_t * hw,bool enable)191 FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t* hw, bool enable)
192 {
193     hw->wdt_config0.flashboot_mod_en = (enable) ? 1 : 0;
194 }
195 
196 /**
197  * @brief Set the clock prescaler of the MWDT
198  *
199  * @param hw Start address of the peripheral registers.
200  * @param prescaler Prescaler value between 1 to 65535
201  */
mwdt_ll_set_prescaler(timg_dev_t * hw,uint32_t prescaler)202 FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler)
203 {
204     hw->wdt_config1.clk_prescale = prescaler;
205 }
206 
207 /**
208  * @brief Feed the MWDT
209  *
210  * Resets the current timer count and current stage.
211  *
212  * @param hw Start address of the peripheral registers.
213  */
mwdt_ll_feed(timg_dev_t * hw)214 FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw)
215 {
216     hw->wdt_feed = 1;
217 }
218 
219 /**
220  * @brief Enable write protection of the MWDT registers
221  *
222  * @param hw Start address of the peripheral registers.
223  */
mwdt_ll_write_protect_enable(timg_dev_t * hw)224 FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw)
225 {
226     hw->wdt_wprotect = 0;
227 }
228 
229 /**
230  * @brief Disable write protection of the MWDT registers
231  *
232  * @param hw Start address of the peripheral registers.
233  */
mwdt_ll_write_protect_disable(timg_dev_t * hw)234 FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw)
235 {
236     hw->wdt_wprotect = TIMG_WDT_WKEY_VALUE;
237 }
238 
239 /**
240  * @brief Clear the MWDT interrupt status.
241  *
242  * @param hw Start address of the peripheral registers.
243  */
mwdt_ll_clear_intr_status(timg_dev_t * hw)244 FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t* hw)
245 {
246     hw->int_clr_timers.wdt = 1;
247 }
248 
249 /**
250  * @brief Set the interrupt enable bit for the MWDT interrupt.
251  *
252  * @param hw Beginning address of the peripheral registers.
253  * @param enable Whether to enable the MWDT interrupt
254  */
mwdt_ll_set_intr_enable(timg_dev_t * hw,bool enable)255 FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t* hw, bool enable)
256 {
257     hw->int_ena.wdt = (enable) ? 1 : 0;
258 }
259 
260 #ifdef __cplusplus
261 }
262 #endif
263