1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2019 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_rtwdog.h"
10 
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.rtwdog"
14 #endif
15 
16 /*******************************************************************************
17  * Code
18  ******************************************************************************/
19 
20 /*!
21  * brief Clears the RTWDOG flag.
22  *
23  * This function clears the RTWDOG status flag.
24  *
25  * Example to clear an interrupt flag:
26  * code
27  *   RTWDOG_ClearStatusFlags(wdog_base,kRTWDOG_InterruptFlag);
28  * endcode
29  * param base        RTWDOG peripheral base address.
30  * param mask        The status flags to clear.
31  *                    The parameter can be any combination of the following values:
32  *                    arg kRTWDOG_InterruptFlag
33  */
RTWDOG_ClearStatusFlags(RTWDOG_Type * base,uint32_t mask)34 void RTWDOG_ClearStatusFlags(RTWDOG_Type *base, uint32_t mask)
35 {
36     if ((mask & (uint32_t)kRTWDOG_InterruptFlag) != 0U)
37     {
38         base->CS |= RTWDOG_CS_FLG_MASK;
39     }
40 }
41 
42 /*!
43  * brief Initializes the RTWDOG configuration structure.
44  *
45  * This function initializes the RTWDOG configuration structure to default values. The default
46  * values are:
47  * code
48  *   rtwdogConfig->enableRtwdog = true;
49  *   rtwdogConfig->clockSource = kRTWDOG_ClockSource1;
50  *   rtwdogConfig->prescaler = kRTWDOG_ClockPrescalerDivide1;
51  *   rtwdogConfig->workMode.enableWait = true;
52  *   rtwdogConfig->workMode.enableStop = false;
53  *   rtwdogConfig->workMode.enableDebug = false;
54  *   rtwdogConfig->testMode = kRTWDOG_TestModeDisabled;
55  *   rtwdogConfig->enableUpdate = true;
56  *   rtwdogConfig->enableInterrupt = false;
57  *   rtwdogConfig->enableWindowMode = false;
58  *   rtwdogConfig->windowValue = 0U;
59  *   rtwdogConfig->timeoutValue = 0xFFFFU;
60  * endcode
61  *
62  * param config Pointer to the RTWDOG configuration structure.
63  * see rtwdog_config_t
64  */
RTWDOG_GetDefaultConfig(rtwdog_config_t * config)65 void RTWDOG_GetDefaultConfig(rtwdog_config_t *config)
66 {
67     assert(config != NULL);
68 
69     /* Initializes the configure structure to zero. */
70     (void)memset(config, 0, sizeof(*config));
71 
72     config->enableRtwdog         = true;
73     config->clockSource          = kRTWDOG_ClockSource1;
74     config->prescaler            = kRTWDOG_ClockPrescalerDivide1;
75     config->workMode.enableWait  = true;
76     config->workMode.enableStop  = false;
77     config->workMode.enableDebug = false;
78     config->testMode             = kRTWDOG_TestModeDisabled;
79     config->enableUpdate         = true;
80     config->enableInterrupt      = false;
81     config->enableWindowMode     = false;
82     config->windowValue          = 0U;
83     config->timeoutValue         = 0xFFFFU;
84 }
85 
86 /*!
87  * brief Initializes the RTWDOG module.
88  *
89  * This function initializes the RTWDOG.
90  * To reconfigure the RTWDOG without forcing a reset first, enableUpdate must be set to true
91  * in the configuration.
92  *
93  * Example:
94  * code
95  *   rtwdog_config_t config;
96  *   RTWDOG_GetDefaultConfig(&config);
97  *   config.timeoutValue = 0x7ffU;
98  *   config.enableUpdate = true;
99  *   RTWDOG_Init(wdog_base,&config);
100  * endcode
101  *
102  * param base   RTWDOG peripheral base address.
103  * param config The configuration of the RTWDOG.
104  */
RTWDOG_Init(RTWDOG_Type * base,const rtwdog_config_t * config)105 void RTWDOG_Init(RTWDOG_Type *base, const rtwdog_config_t *config)
106 {
107     assert(NULL != config);
108 
109     uint32_t value        = 0U;
110     uint32_t primaskValue = 0U;
111 
112     value = RTWDOG_CS_EN(config->enableRtwdog) | RTWDOG_CS_CLK(config->clockSource) |
113             RTWDOG_CS_INT(config->enableInterrupt) | RTWDOG_CS_WIN(config->enableWindowMode) |
114             RTWDOG_CS_UPDATE(config->enableUpdate) | RTWDOG_CS_DBG(config->workMode.enableDebug) |
115             RTWDOG_CS_STOP(config->workMode.enableStop) | RTWDOG_CS_WAIT(config->workMode.enableWait) |
116             RTWDOG_CS_PRES(config->prescaler) | RTWDOG_CS_CMD32EN(1U) | RTWDOG_CS_TST(config->testMode);
117 
118     /* Disable the global interrupts. Otherwise, an interrupt could effectively invalidate the unlock sequence
119      * and the WCT may expire. After the configuration finishes, re-enable the global interrupts. */
120     primaskValue = DisableGlobalIRQ();
121     RTWDOG_Unlock(base);
122     base->WIN   = config->windowValue;
123     base->TOVAL = config->timeoutValue;
124     base->CS    = value;
125     while ((base->CS & RTWDOG_CS_RCS_MASK) == 0U)
126     {
127     }
128     EnableGlobalIRQ(primaskValue);
129 }
130 
131 /*!
132  * brief De-initializes the RTWDOG module.
133  *
134  * This function shuts down the RTWDOG.
135  * Ensure that the WDOG_CS.UPDATE is 1, which means that the register update is enabled.
136  *
137  * param base   RTWDOG peripheral base address.
138  */
RTWDOG_Deinit(RTWDOG_Type * base)139 void RTWDOG_Deinit(RTWDOG_Type *base)
140 {
141     uint32_t primaskValue = 0U;
142 
143     /* Disable the global interrupts */
144     primaskValue = DisableGlobalIRQ();
145     RTWDOG_Unlock(base);
146     RTWDOG_Disable(base);
147     EnableGlobalIRQ(primaskValue);
148 }
149