1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef _FSL_RTWDOG_H_
9 #define _FSL_RTWDOG_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup rtwdog
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  *******************************************************************************/
21 /*! @name Unlock sequence */
22 /*@{*/
23 #define WDOG_FIRST_WORD_OF_UNLOCK  (RTWDOG_UPDATE_KEY & 0xFFFFU)          /*!< First word of unlock sequence */
24 #define WDOG_SECOND_WORD_OF_UNLOCK ((RTWDOG_UPDATE_KEY >> 16U) & 0xFFFFU) /*!< Second word of unlock sequence */
25 /*@}*/
26 
27 /*! @name Refresh sequence */
28 /*@{*/
29 #define WDOG_FIRST_WORD_OF_REFRESH  (RTWDOG_REFRESH_KEY & 0xFFFFU)          /*!< First word of refresh sequence */
30 #define WDOG_SECOND_WORD_OF_REFRESH ((RTWDOG_REFRESH_KEY >> 16U) & 0xFFFFU) /*!< Second word of refresh sequence */
31 /*@}*/
32 /*! @name Driver version */
33 /*@{*/
34 /*! @brief RTWDOG driver version 2.1.2. */
35 #define FSL_RTWDOG_DRIVER_VERSION (MAKE_VERSION(2, 1, 2))
36 /*@}*/
37 
38 /*! @brief Describes RTWDOG clock source. */
39 typedef enum _rtwdog_clock_source
40 {
41     kRTWDOG_ClockSource0 = 0U, /*!< Clock source 0 */
42     kRTWDOG_ClockSource1 = 1U, /*!< Clock source 1 */
43     kRTWDOG_ClockSource2 = 2U, /*!< Clock source 2 */
44     kRTWDOG_ClockSource3 = 3U, /*!< Clock source 3 */
45 } rtwdog_clock_source_t;
46 
47 /*! @brief Describes the selection of the clock prescaler. */
48 typedef enum _rtwdog_clock_prescaler
49 {
50     kRTWDOG_ClockPrescalerDivide1   = 0x0U, /*!< Divided by 1 */
51     kRTWDOG_ClockPrescalerDivide256 = 0x1U, /*!< Divided by 256 */
52 } rtwdog_clock_prescaler_t;
53 
54 /*! @brief Defines RTWDOG work mode. */
55 typedef struct _rtwdog_work_mode
56 {
57     bool enableWait;  /*!< Enables or disables RTWDOG in wait mode */
58     bool enableStop;  /*!< Enables or disables RTWDOG in stop mode */
59     bool enableDebug; /*!< Enables or disables RTWDOG in debug mode */
60 } rtwdog_work_mode_t;
61 
62 /*! @brief Describes RTWDOG test mode. */
63 typedef enum _rtwdog_test_mode
64 {
65     kRTWDOG_TestModeDisabled = 0U, /*!< Test Mode disabled */
66     kRTWDOG_UserModeEnabled  = 1U, /*!< User Mode enabled */
67     kRTWDOG_LowByteTest      = 2U, /*!< Test Mode enabled, only low byte is used */
68     kRTWDOG_HighByteTest     = 3U, /*!< Test Mode enabled, only high byte is used */
69 } rtwdog_test_mode_t;
70 
71 /*! @brief Describes RTWDOG configuration structure. */
72 typedef struct _rtwdog_config
73 {
74     bool enableRtwdog;                  /*!< Enables or disables RTWDOG */
75     rtwdog_clock_source_t clockSource;  /*!< Clock source select */
76     rtwdog_clock_prescaler_t prescaler; /*!< Clock prescaler value */
77     rtwdog_work_mode_t workMode;        /*!< Configures RTWDOG work mode in debug stop and wait mode */
78     rtwdog_test_mode_t testMode;        /*!< Configures RTWDOG test mode */
79     bool enableUpdate;                  /*!< Update write-once register enable */
80     bool enableInterrupt;               /*!< Enables or disables RTWDOG interrupt */
81     bool enableWindowMode;              /*!< Enables or disables RTWDOG window mode */
82     uint16_t windowValue;               /*!< Window value */
83     uint16_t timeoutValue;              /*!< Timeout value */
84 } rtwdog_config_t;
85 
86 /*!
87  * @brief RTWDOG interrupt configuration structure.
88  *
89  * This structure contains the settings for all of the RTWDOG interrupt configurations.
90  */
91 enum _rtwdog_interrupt_enable_t
92 {
93     kRTWDOG_InterruptEnable = RTWDOG_CS_INT_MASK, /*!< Interrupt is generated before forcing a reset */
94 };
95 
96 /*!
97  * @brief RTWDOG status flags.
98  *
99  * This structure contains the RTWDOG status flags for use in the RTWDOG functions.
100  */
101 enum _rtwdog_status_flags_t
102 {
103     kRTWDOG_RunningFlag   = RTWDOG_CS_EN_MASK,  /*!< Running flag, set when RTWDOG is enabled */
104     kRTWDOG_InterruptFlag = RTWDOG_CS_FLG_MASK, /*!< Interrupt flag, set when interrupt occurs */
105 };
106 
107 /*******************************************************************************
108  * API
109  *******************************************************************************/
110 
111 #if defined(__cplusplus)
112 extern "C" {
113 #endif /* __cplusplus */
114 
115 /*!
116  * @name RTWDOG Initialization and De-initialization
117  * @{
118  */
119 
120 /*!
121  * @brief Initializes the RTWDOG configuration structure.
122  *
123  * This function initializes the RTWDOG configuration structure to default values. The default
124  * values are:
125  * @code
126  *   rtwdogConfig->enableRtwdog = true;
127  *   rtwdogConfig->clockSource = kRTWDOG_ClockSource1;
128  *   rtwdogConfig->prescaler = kRTWDOG_ClockPrescalerDivide1;
129  *   rtwdogConfig->workMode.enableWait = true;
130  *   rtwdogConfig->workMode.enableStop = false;
131  *   rtwdogConfig->workMode.enableDebug = false;
132  *   rtwdogConfig->testMode = kRTWDOG_TestModeDisabled;
133  *   rtwdogConfig->enableUpdate = true;
134  *   rtwdogConfig->enableInterrupt = false;
135  *   rtwdogConfig->enableWindowMode = false;
136  *   rtwdogConfig->windowValue = 0U;
137  *   rtwdogConfig->timeoutValue = 0xFFFFU;
138  * @endcode
139  *
140  * @param config Pointer to the RTWDOG configuration structure.
141  * @see rtwdog_config_t
142  */
143 void RTWDOG_GetDefaultConfig(rtwdog_config_t *config);
144 
145 /*!
146  * @brief Initializes the RTWDOG module.
147  *
148  * This function initializes the RTWDOG.
149  * To reconfigure the RTWDOG without forcing a reset first, enableUpdate must be set to true
150  * in the configuration.
151  *
152  * Example:
153  * @code
154  *   rtwdog_config_t config;
155  *   RTWDOG_GetDefaultConfig(&config);
156  *   config.timeoutValue = 0x7ffU;
157  *   config.enableUpdate = true;
158  *   RTWDOG_Init(wdog_base,&config);
159  * @endcode
160  *
161  * @param base   RTWDOG peripheral base address.
162  * @param config The configuration of the RTWDOG.
163  */
164 
165 #if defined(DOXYGEN_OUTPUT) && DOXYGEN_OUTPUT
166 void RTWDOG_Init(RTWDOG_Type *base, const rtwdog_config_t *config);
167 #else
168 AT_QUICKACCESS_SECTION_CODE(void RTWDOG_Init(RTWDOG_Type *base, const rtwdog_config_t *config));
169 #endif
170 
171 /*!
172  * @brief De-initializes the RTWDOG module.
173  *
174  * This function shuts down the RTWDOG.
175  * Ensure that the WDOG_CS.UPDATE is 1, which means that the register update is enabled.
176  *
177  * @param base   RTWDOG peripheral base address.
178  */
179 void RTWDOG_Deinit(RTWDOG_Type *base);
180 
181 /* @} */
182 
183 /*!
184  * @name RTWDOG functional Operation
185  * @{
186  */
187 
188 /*!
189  * @brief Enables the RTWDOG module.
190  *
191  * This function writes a value into the WDOG_CS register to enable the RTWDOG.
192  * The WDOG_CS register is a write-once register. Ensure that the WCT window is still open and
193  * this register has not been written in this WCT while the function is called.
194  *
195  * @param base RTWDOG peripheral base address.
196  */
RTWDOG_Enable(RTWDOG_Type * base)197 static inline void RTWDOG_Enable(RTWDOG_Type *base)
198 {
199     base->CS |= RTWDOG_CS_EN_MASK;
200 }
201 
202 /*!
203  * @brief Disables the RTWDOG module.
204  *
205  * This function writes a value into the WDOG_CS register to disable the RTWDOG.
206  * The WDOG_CS register is a write-once register. Ensure that the WCT window is still open and
207  * this register has not been written in this WCT while the function is called.
208  *
209  * @param base RTWDOG peripheral base address
210  */
RTWDOG_Disable(RTWDOG_Type * base)211 static inline void RTWDOG_Disable(RTWDOG_Type *base)
212 {
213     base->CS &= ~RTWDOG_CS_EN_MASK;
214 }
215 
216 /*!
217  * @brief Enables the RTWDOG interrupt.
218  *
219  * This function writes a value into the WDOG_CS register to enable the RTWDOG interrupt.
220  * The WDOG_CS register is a write-once register. Ensure that the WCT window is still open and
221  * this register has not been written in this WCT while the function is called.
222  *
223  * @param base RTWDOG peripheral base address.
224  * @param mask The interrupts to enable.
225  *        The parameter can be a combination of the following source if defined:
226  *        @arg kRTWDOG_InterruptEnable
227  */
RTWDOG_EnableInterrupts(RTWDOG_Type * base,uint32_t mask)228 static inline void RTWDOG_EnableInterrupts(RTWDOG_Type *base, uint32_t mask)
229 {
230     base->CS |= mask;
231 }
232 
233 /*!
234  * @brief Disables the RTWDOG interrupt.
235  *
236  * This function writes a value into the WDOG_CS register to disable the RTWDOG interrupt.
237  * The WDOG_CS register is a write-once register. Ensure that the WCT window is still open and
238  * this register has not been written in this WCT while the function is called.
239  *
240  * @param base RTWDOG peripheral base address.
241  * @param mask The interrupts to disabled.
242  *        The parameter can be a combination of the following source if defined:
243  *        @arg kRTWDOG_InterruptEnable
244  */
RTWDOG_DisableInterrupts(RTWDOG_Type * base,uint32_t mask)245 static inline void RTWDOG_DisableInterrupts(RTWDOG_Type *base, uint32_t mask)
246 {
247     base->CS &= ~mask;
248 }
249 
250 /*!
251  * @brief Gets the RTWDOG all status flags.
252  *
253  * This function gets all status flags.
254  *
255  * Example to get the running flag:
256  * @code
257  *   uint32_t status;
258  *   status = RTWDOG_GetStatusFlags(wdog_base) & kRTWDOG_RunningFlag;
259  * @endcode
260  * @param base        RTWDOG peripheral base address
261  * @return            State of the status flag: asserted (true) or not-asserted (false). @see _rtwdog_status_flags_t
262  *                    - true: related status flag has been set.
263  *                    - false: related status flag is not set.
264  */
RTWDOG_GetStatusFlags(RTWDOG_Type * base)265 static inline uint32_t RTWDOG_GetStatusFlags(RTWDOG_Type *base)
266 {
267     return (base->CS & (RTWDOG_CS_EN_MASK | RTWDOG_CS_FLG_MASK));
268 }
269 
270 /*!
271  * @brief Enables/disables the window mode.
272  *
273  * @param base   RTWDOG peripheral base address.
274  * @param enable Enables(true) or disables(false) the feature.
275  */
RTWDOG_EnableWindowMode(RTWDOG_Type * base,bool enable)276 static inline void RTWDOG_EnableWindowMode(RTWDOG_Type *base, bool enable)
277 {
278     if (enable)
279     {
280         base->CS |= RTWDOG_CS_WIN_MASK;
281     }
282     else
283     {
284         base->CS &= ~RTWDOG_CS_WIN_MASK;
285     }
286 }
287 
288 /*!
289  * @brief Converts raw count value to millisecond.
290  *
291  * Note that if the clock frequency is too high the timeout period can be less than 1 ms.
292  * In this case this api will return 0 value.
293  *
294  * @param base          RTWDOG peripheral base address.
295  * @param count         Raw count value.
296  * @param clockFreqInHz The frequency of the clock source RTWDOG uses.
297  */
RTWDOG_CountToMesec(RTWDOG_Type * base,uint32_t count,uint32_t clockFreqInHz)298 static inline uint32_t RTWDOG_CountToMesec(RTWDOG_Type *base, uint32_t count, uint32_t clockFreqInHz)
299 {
300     if ((base->CS & RTWDOG_CS_PRES_MASK) != 0U)
301     {
302         clockFreqInHz /= 256U;
303     }
304     return count * 1000U / clockFreqInHz;
305 }
306 
307 /*!
308  * @brief Clears the RTWDOG flag.
309  *
310  * This function clears the RTWDOG status flag.
311  *
312  * Example to clear an interrupt flag:
313  * @code
314  *   RTWDOG_ClearStatusFlags(wdog_base,kRTWDOG_InterruptFlag);
315  * @endcode
316  * @param base        RTWDOG peripheral base address.
317  * @param mask        The status flags to clear.
318  *                    The parameter can be any combination of the following values:
319  *                    @arg kRTWDOG_InterruptFlag
320  */
321 void RTWDOG_ClearStatusFlags(RTWDOG_Type *base, uint32_t mask);
322 
323 /*!
324  * @brief Sets the RTWDOG timeout value.
325  *
326  * This function writes a timeout value into the WDOG_TOVAL register.
327  * The WDOG_TOVAL register is a write-once register. Ensure that the WCT window is still open and
328  * this register has not been written in this WCT while the function is called.
329  *
330  * @param base RTWDOG peripheral base address
331  * @param timeoutCount RTWDOG timeout value, count of RTWDOG clock ticks.
332  */
RTWDOG_SetTimeoutValue(RTWDOG_Type * base,uint16_t timeoutCount)333 static inline void RTWDOG_SetTimeoutValue(RTWDOG_Type *base, uint16_t timeoutCount)
334 {
335     base->TOVAL = timeoutCount;
336 }
337 
338 /*!
339  * @brief Sets the RTWDOG window value.
340  *
341  * This function writes a window value into the WDOG_WIN register.
342  * The WDOG_WIN register is a write-once register. Ensure that the WCT window is still open and
343  * this register has not been written in this WCT while the function is called.
344  *
345  * @param base RTWDOG peripheral base address.
346  * @param windowValue RTWDOG window value.
347  */
RTWDOG_SetWindowValue(RTWDOG_Type * base,uint16_t windowValue)348 static inline void RTWDOG_SetWindowValue(RTWDOG_Type *base, uint16_t windowValue)
349 {
350     base->WIN = windowValue;
351 }
352 
353 /*!
354  * @brief Unlocks the RTWDOG register written.
355  *
356  * This function unlocks the RTWDOG register written.
357  *
358  * Before starting the unlock sequence and following the configuration, disable the global interrupts.
359  * Otherwise, an interrupt could effectively invalidate the unlock sequence and the WCT may expire.
360  * After the configuration finishes, re-enable the global interrupts.
361  *
362  * @param base RTWDOG peripheral base address
363  */
RTWDOG_Unlock(RTWDOG_Type * base)364 __STATIC_FORCEINLINE void RTWDOG_Unlock(RTWDOG_Type *base)
365 {
366     if (((base->CS) & RTWDOG_CS_CMD32EN_MASK) != 0U)
367     {
368         base->CNT = RTWDOG_UPDATE_KEY;
369     }
370     else
371     {
372         base->CNT = WDOG_FIRST_WORD_OF_UNLOCK;
373         base->CNT = WDOG_SECOND_WORD_OF_UNLOCK;
374     }
375     while ((base->CS & RTWDOG_CS_ULK_MASK) == 0U)
376     {
377     }
378 }
379 
380 /*!
381  * @brief Refreshes the RTWDOG timer.
382  *
383  * This function feeds the RTWDOG.
384  * This function should be called before the Watchdog timer is in timeout. Otherwise, a reset is asserted.
385  *
386  * @param base RTWDOG peripheral base address
387  */
RTWDOG_Refresh(RTWDOG_Type * base)388 static inline void RTWDOG_Refresh(RTWDOG_Type *base)
389 {
390     uint32_t primaskValue = 0U;
391     primaskValue          = DisableGlobalIRQ();
392     if (((base->CS) & RTWDOG_CS_CMD32EN_MASK) != 0U)
393     {
394         base->CNT = RTWDOG_REFRESH_KEY;
395     }
396     else
397     {
398         base->CNT = WDOG_FIRST_WORD_OF_REFRESH;
399         base->CNT = WDOG_SECOND_WORD_OF_REFRESH;
400     }
401     EnableGlobalIRQ(primaskValue);
402 }
403 
404 /*!
405  * @brief Gets the RTWDOG counter value.
406  *
407  * This function gets the RTWDOG counter value.
408  *
409  * @param base RTWDOG peripheral base address.
410  * @return     Current RTWDOG counter value.
411  */
RTWDOG_GetCounterValue(RTWDOG_Type * base)412 static inline uint16_t RTWDOG_GetCounterValue(RTWDOG_Type *base)
413 {
414     return (uint16_t)base->CNT;
415 }
416 
417 /*@}*/
418 
419 #if defined(__cplusplus)
420 }
421 #endif /* __cplusplus */
422 
423 /*! @}*/
424 
425 #endif /* _FSL_RTWDOG_H_ */
426