1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2020 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_wdog32.h"
10
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.wdog32"
14 #endif
15
16 /*
17 * $Coverage Justification Reference$
18 *
19 * $Justification wdog32_c_ref_1$
20 * Function not covered. Test unfeasible, the reset state is too short to catch.
21 *
22 */
23
24 /*******************************************************************************
25 * Code
26 ******************************************************************************/
WDOG32_ClearStatusFlags(WDOG_Type * base,uint32_t mask)27 void WDOG32_ClearStatusFlags(WDOG_Type *base, uint32_t mask)
28 {
29
30 /* $Line Coverage Justification$ $ref wdog32_c_ref_1$. */
31 /* $Branch Coverage Justification$ $ref wdog32_c_ref_1$. */
32 if (0U != (mask & (uint32_t)kWDOG32_InterruptFlag))
33 {
34 base->CS |= WDOG_CS_FLG_MASK;
35 }
36 }
37
38 /*!
39 * brief Initializes the WDOG32 configuration structure.
40 *
41 * This function initializes the WDOG32 configuration structure to default values. The default
42 * values are:
43 * code
44 * wdog32Config->enableWdog32 = true;
45 * wdog32Config->clockSource = kWDOG32_ClockSource1;
46 * wdog32Config->prescaler = kWDOG32_ClockPrescalerDivide1;
47 * wdog32Config->workMode.enableWait = true;
48 * wdog32Config->workMode.enableStop = false;
49 * wdog32Config->workMode.enableDebug = false;
50 * wdog32Config->testMode = kWDOG32_TestModeDisabled;
51 * wdog32Config->enableUpdate = true;
52 * wdog32Config->enableInterrupt = false;
53 * wdog32Config->enableWindowMode = false;
54 * wdog32Config->windowValue = 0U;
55 * wdog32Config->timeoutValue = 0xFFFFU;
56 * endcode
57 *
58 * param config Pointer to the WDOG32 configuration structure.
59 * see wdog32_config_t
60 */
WDOG32_GetDefaultConfig(wdog32_config_t * config)61 void WDOG32_GetDefaultConfig(wdog32_config_t *config)
62 {
63 assert(NULL != config);
64
65 /* Initializes the configure structure to zero. */
66 (void)memset(config, 0, sizeof(*config));
67
68 config->enableWdog32 = true;
69 config->clockSource = kWDOG32_ClockSource1;
70 config->prescaler = kWDOG32_ClockPrescalerDivide1;
71 config->workMode.enableWait = true;
72 config->workMode.enableStop = false;
73 config->workMode.enableDebug = false;
74 config->testMode = kWDOG32_TestModeDisabled;
75 config->enableUpdate = true;
76 config->enableInterrupt = false;
77 config->enableWindowMode = false;
78 config->windowValue = 0U;
79 config->timeoutValue = 0xFFFFU;
80 }
81
WDOG32_Init(WDOG_Type * base,const wdog32_config_t * config)82 void WDOG32_Init(WDOG_Type *base, const wdog32_config_t *config)
83 {
84 assert(NULL != config);
85
86 register uint32_t value = 0U;
87 uint32_t primaskValue = 0U;
88 register WDOG_Type *regBase = base;
89 register const wdog32_config_t *regConfig = config;
90 uint32_t tempPrescaler = (uint32_t)regConfig->prescaler;
91
92 value = WDOG_CS_EN((uint32_t)regConfig->enableWdog32) | WDOG_CS_CLK((uint32_t)regConfig->clockSource) |
93 WDOG_CS_INT((uint32_t)regConfig->enableInterrupt) | WDOG_CS_WIN((uint32_t)regConfig->enableWindowMode) |
94 WDOG_CS_UPDATE((uint32_t)regConfig->enableUpdate) | WDOG_CS_DBG((uint32_t)regConfig->workMode.enableDebug) |
95 WDOG_CS_STOP((uint32_t)regConfig->workMode.enableStop) |
96 WDOG_CS_WAIT((uint32_t)regConfig->workMode.enableWait) | WDOG_CS_PRES(tempPrescaler) |
97 WDOG_CS_CMD32EN(1UL) | WDOG_CS_TST((uint32_t)regConfig->testMode);
98
99 /* Disable the global interrupts. Otherwise, an interrupt could effectively invalidate the unlock sequence
100 * and the WCT may expire. After the configuration finishes, re-enable the global interrupts. */
101 primaskValue = DisableGlobalIRQ();
102 WDOG32_Unlock(base);
103 regBase->WIN = regConfig->windowValue;
104 regBase->TOVAL = regConfig->timeoutValue;
105 regBase->CS = value;
106 #ifdef WDOG_CS_RCS_MASK
107 /* Waits until for new configuration to take effect. */
108 while (0U == ((base->CS) & WDOG_CS_RCS_MASK))
109 {
110 ;
111 }
112 #else
113 /* When switches clock sources during reconfiguration, the watchdog hardware holds the counter at
114 zero for 2.5 periods of the previous clock source and 2.5 periods of the new clock source
115 after the configuration time period (128 bus clocks) ends.
116 This delay ensures a smooth transition before restarting the counter with the new configuration. */
117 for (uint8_t timeDelay = 0U; timeDelay < 128U; timeDelay++)
118 {
119 (void)base->CNT;
120 }
121 #endif /* WDOG_CS_RCS_MASK */
122
123 EnableGlobalIRQ(primaskValue);
124 }
125
126 /*!
127 * brief De-initializes the WDOG32 module.
128 *
129 * This function shuts down the WDOG32.
130 * Ensure that the WDOG_CS.UPDATE is 1, which means that the register update is enabled.
131 *
132 * param base WDOG32 peripheral base address.
133 */
WDOG32_Deinit(WDOG_Type * base)134 void WDOG32_Deinit(WDOG_Type *base)
135 {
136 uint32_t primaskValue = 0U;
137
138 /* Disable the global interrupts */
139 primaskValue = DisableGlobalIRQ();
140 WDOG32_Unlock(base);
141 WDOG32_Disable(base);
142 EnableGlobalIRQ(primaskValue);
143 }
144
145 /*!
146 * brief Unlocks the WDOG32 register written.
147 *
148 * This function unlocks the WDOG32 register written.
149 *
150 * Before starting the unlock sequence and following the configuration, disable the global interrupts.
151 * Otherwise, an interrupt could effectively invalidate the unlock sequence and the WCT may expire.
152 * After the configuration finishes, re-enable the global interrupts.
153 *
154 * param base WDOG32 peripheral base address
155 */
WDOG32_Unlock(WDOG_Type * base)156 void WDOG32_Unlock(WDOG_Type *base)
157 {
158 if (0U != ((base->CS) & WDOG_CS_CMD32EN_MASK))
159 {
160 base->CNT = WDOG_UPDATE_KEY;
161 }
162 else
163 {
164 base->CNT = WDOG_FIRST_WORD_OF_UNLOCK;
165 base->CNT = WDOG_SECOND_WORD_OF_UNLOCK;
166 }
167 #ifdef WDOG_CS_ULK_MASK
168 /* Waited until for registers to be unlocked. */
169 while (0U == ((base->CS) & WDOG_CS_ULK_MASK))
170 {
171 ;
172 }
173 #endif /* WDOG_CS_ULK_MASK */
174 }
175
176 /*!
177 * brief Enables the WDOG32 module.
178 *
179 * This function writes a value into the WDOG_CS register to enable the WDOG32.
180 * The WDOG_CS register is a write-once register. Please check the enableUpdate is set to true for calling WDOG32_Init
181 * to do wdog initialize, before call the re-configuration APIs, ensure that the WCT window is still open and
182 * this register has not been written in this WCT while the function is called.
183 *
184 * param base WDOG32 peripheral base address.
185 */
WDOG32_Enable(WDOG_Type * base)186 void WDOG32_Enable(WDOG_Type *base)
187 {
188 base->CS |= WDOG_CS_EN_MASK;
189 }
190
191 /*!
192 * brief Disables the WDOG32 module.
193 *
194 * This function writes a value into the WDOG_CS register to disable the WDOG32.
195 * The WDOG_CS register is a write-once register. Please check the enableUpdate is set to true for calling WDOG32_Init
196 * to do wdog initialize, before call the re-configuration APIs, ensure that the WCT window is still open and
197 * this register has not been written in this WCT while the function is called.
198 *
199 * param base WDOG32 peripheral base address
200 */
WDOG32_Disable(WDOG_Type * base)201 void WDOG32_Disable(WDOG_Type *base)
202 {
203 base->CS &= ~WDOG_CS_EN_MASK;
204 }
205
206 /*!
207 * brief Enables the WDOG32 interrupt.
208 *
209 * This function writes a value into the WDOG_CS register to enable the WDOG32 interrupt.
210 * The WDOG_CS register is a write-once register. Please check the enableUpdate is set to true for calling WDOG32_Init
211 * to do wdog initialize, before call the re-configuration APIs, ensure that the WCT window is still open and
212 * this register has not been written in this WCT while the function is called.
213 *
214 * param base WDOG32 peripheral base address.
215 * param mask The interrupts to enable.
216 * The parameter can be a combination of the following source if defined:
217 * arg kWDOG32_InterruptEnable
218 */
WDOG32_EnableInterrupts(WDOG_Type * base,uint32_t mask)219 void WDOG32_EnableInterrupts(WDOG_Type *base, uint32_t mask)
220 {
221 base->CS |= mask;
222 }
223
224 /*!
225 * brief Disables the WDOG32 interrupt.
226 *
227 * This function writes a value into the WDOG_CS register to disable the WDOG32 interrupt.
228 * The WDOG_CS register is a write-once register. Please check the enableUpdate is set to true for calling WDOG32_Init
229 * to do wdog initialize, before call the re-configuration APIs, ensure that the WCT window is still open and
230 * this register has not been written in this WCT while the function is called.
231 *
232 * param base WDOG32 peripheral base address.
233 * param mask The interrupts to disabled.
234 * The parameter can be a combination of the following source if defined:
235 * arg kWDOG32_InterruptEnable
236 */
WDOG32_DisableInterrupts(WDOG_Type * base,uint32_t mask)237 void WDOG32_DisableInterrupts(WDOG_Type *base, uint32_t mask)
238 {
239 base->CS &= ~mask;
240 }
241
242 /*!
243 * brief Sets the WDOG32 timeout value.
244 *
245 * This function writes a timeout value into the WDOG_TOVAL register.
246 * The WDOG_TOVAL register is a write-once register. To ensure the reconfiguration fits the timing of WCT, unlock
247 * function will be called in the function.
248 *
249 * param base WDOG32 peripheral base address
250 * param timeoutCount WDOG32 timeout value, count of WDOG32 clock ticks.
251 */
WDOG32_SetTimeoutValue(WDOG_Type * base,uint16_t timeoutCount)252 void WDOG32_SetTimeoutValue(WDOG_Type *base, uint16_t timeoutCount)
253 {
254 base->TOVAL = timeoutCount;
255 }
256
257 /*!
258 * brief Sets the WDOG32 window value.
259 *
260 * This function writes a window value into the WDOG_WIN register.
261 * The WDOG_WIN register is a write-once register. Ensure that the WCT window is still open and
262 * this register has not been written in this WCT while the function is called.
263 *
264 * param base WDOG32 peripheral base address.
265 * param windowValue WDOG32 window value.
266 */
WDOG32_SetWindowValue(WDOG_Type * base,uint16_t windowValue)267 void WDOG32_SetWindowValue(WDOG_Type *base, uint16_t windowValue)
268 {
269 base->WIN = windowValue;
270 }
271