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_wdog.h" |
10 | |
11 | /* Component ID definition, used by tools. */ |
12 | #ifndef FSL_COMPONENT_ID |
13 | #define FSL_COMPONENT_ID "platform.drivers.wdog01" |
14 | #endif |
15 | |
16 | /******************************************************************************* |
17 | * Variables |
18 | ******************************************************************************/ |
19 | static WDOG_Type *const s_wdogBases[] = WDOG_BASE_PTRS; |
20 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
21 | /* Array of WDOG clock name. */ |
22 | static const clock_ip_name_t s_wdogClock[] = WDOG_CLOCKS; |
23 | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
24 | |
25 | static const IRQn_Type s_wdogIRQ[] = WDOG_IRQS; |
26 | |
27 | /******************************************************************************* |
28 | * Code |
29 | ******************************************************************************/ |
30 | static uint32_t WDOG_GetInstance(WDOG_Type *base) |
31 | { |
32 | uint32_t instance; |
33 | |
34 | /* Find the instance index from base address mappings. */ |
35 | for (instance = 0; instance < ARRAY_SIZE(s_wdogBases); instance++) |
36 | { |
37 | if (s_wdogBases[instance] == base) |
38 | { |
39 | break; |
40 | } |
41 | } |
42 | |
43 | assert(instance < ARRAY_SIZE(s_wdogBases)); |
44 | |
45 | return instance; |
46 | } |
47 | |
48 | /*! |
49 | * brief Initializes the WDOG configuration structure. |
50 | * |
51 | * This function initializes the WDOG configuration structure to default values. The default |
52 | * values are as follows. |
53 | * code |
54 | * wdogConfig->enableWdog = true; |
55 | * wdogConfig->workMode.enableWait = true; |
56 | * wdogConfig->workMode.enableStop = false; |
57 | * wdogConfig->workMode.enableDebug = false; |
58 | * wdogConfig->enableInterrupt = false; |
59 | * wdogConfig->enablePowerdown = false; |
60 | * wdogConfig->resetExtension = flase; |
61 | * wdogConfig->timeoutValue = 0xFFU; |
62 | * wdogConfig->interruptTimeValue = 0x04u; |
63 | * endcode |
64 | * |
65 | * param config Pointer to the WDOG configuration structure. |
66 | * see wdog_config_t |
67 | */ |
68 | void WDOG_GetDefaultConfig(wdog_config_t *config) |
69 | { |
70 | assert(NULL != config); |
71 | |
72 | /* Initializes the configure structure to zero. */ |
73 | (void)memset(config, 0, sizeof(*config)); |
74 | |
75 | config->enableWdog = true; |
76 | config->workMode.enableWait = false; |
77 | config->workMode.enableStop = false; |
78 | config->workMode.enableDebug = false; |
79 | config->enableInterrupt = false; |
80 | config->softwareResetExtension = false; |
81 | config->enablePowerDown = false; |
82 | config->timeoutValue = 0xffu; |
83 | config->interruptTimeValue = 0x04u; |
84 | config->enableTimeOutAssert = false; |
85 | } |
86 | |
87 | /*! |
88 | * brief Initializes the WDOG. |
89 | * |
90 | * This function initializes the WDOG. When called, the WDOG runs according to the configuration. |
91 | * |
92 | * This is an example. |
93 | * code |
94 | * wdog_config_t config; |
95 | * WDOG_GetDefaultConfig(&config); |
96 | * config.timeoutValue = 0xffU; |
97 | * config->interruptTimeValue = 0x04u; |
98 | * WDOG_Init(wdog_base,&config); |
99 | * endcode |
100 | * |
101 | * param base WDOG peripheral base address |
102 | * param config The configuration of WDOG |
103 | */ |
104 | void WDOG_Init(WDOG_Type *base, const wdog_config_t *config) |
105 | { |
106 | assert(NULL != config); |
107 | |
108 | uint16_t value = 0u; |
109 | uint32_t primaskValue = 0U; |
110 | |
111 | value = WDOG_WCR_WDE(config->enableWdog) | WDOG_WCR_WDW(config->workMode.enableWait) | |
112 | WDOG_WCR_WDZST(config->workMode.enableStop) | WDOG_WCR_WDBG(config->workMode.enableDebug) | |
113 | WDOG_WCR_SRE(config->softwareResetExtension) | WDOG_WCR_WT(config->timeoutValue) | |
114 | WDOG_WCR_WDT(config->enableTimeOutAssert) | WDOG_WCR_SRS_MASK | WDOG_WCR_WDA_MASK; |
115 | |
116 | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
117 | /* Set configuration */ |
118 | CLOCK_EnableClock(s_wdogClock[WDOG_GetInstance(base)]); |
119 | #endif |
120 | |
121 | primaskValue = DisableGlobalIRQ(); |
122 | base->WICR = WDOG_WICR_WICT(config->interruptTimeValue) | WDOG_WICR_WIE(config->enableInterrupt); |
123 | base->WMCR = WDOG_WMCR_PDE(config->enablePowerDown); |
124 | base->WCR = value; |
125 | EnableGlobalIRQ(primaskValue); |
126 | if (config->enableInterrupt) |
127 | { |
128 | (void)EnableIRQ(s_wdogIRQ[WDOG_GetInstance(base)]); |
129 | } |
130 | } |
131 | |
132 | /*! |
133 | * brief Shuts down the WDOG. |
134 | * |
135 | * This function shuts down the WDOG. |
136 | * Watchdog Enable bit is a write one once only bit. It is not |
137 | * possible to clear this bit by a software write, once the bit is set. |
138 | * This bit(WDE) can be set/reset only in debug mode(exception). |
139 | */ |
140 | void WDOG_Deinit(WDOG_Type *base) |
141 | { |
142 | if (0U != (base->WCR & WDOG_WCR_WDBG_MASK)) |
143 | { |
144 | WDOG_Disable(base); |
145 | } |
146 | } |
147 | |
148 | /*! |
149 | * brief Gets the WDOG all reset status flags. |
150 | * |
151 | * This function gets all reset status flags. |
152 | * |
153 | * code |
154 | * uint16_t status; |
155 | * status = WDOG_GetStatusFlags (wdog_base); |
156 | * endcode |
157 | * param base WDOG peripheral base address |
158 | * return State of the status flag: asserted (true) or not-asserted (false).see _wdog_status_flags |
159 | * - true: a related status flag has been set. |
160 | * - false: a related status flag is not set. |
161 | */ |
162 | uint16_t WDOG_GetStatusFlags(WDOG_Type *base) |
163 | { |
164 | uint16_t status_flag = 0U; |
165 | |
166 | status_flag |= (base->WCR & WDOG_WCR_WDE_MASK); |
167 | status_flag |= (base->WRSR & WDOG_WRSR_POR_MASK); |
168 | status_flag |= (base->WRSR & WDOG_WRSR_TOUT_MASK); |
169 | status_flag |= (base->WRSR & WDOG_WRSR_SFTW_MASK); |
170 | status_flag |= (base->WICR & WDOG_WICR_WTIS_MASK); |
171 | |
172 | return status_flag; |
173 | } |
174 | |
175 | /*! |
176 | * brief Clears the WDOG flag. |
177 | * |
178 | * This function clears the WDOG status flag. |
179 | * |
180 | * This is an example for clearing the interrupt flag. |
181 | * code |
182 | * WDOG_ClearStatusFlags(wdog_base,KWDOG_InterruptFlag); |
183 | * endcode |
184 | * param base WDOG peripheral base address |
185 | * param mask The status flags to clear. |
186 | * The parameter could be any combination of the following values. |
187 | * kWDOG_TimeoutFlag |
188 | */ |
189 | void WDOG_ClearInterruptStatus(WDOG_Type *base, uint16_t mask) |
190 | { |
191 | if (0U != (mask & (uint16_t)kWDOG_InterruptFlag)) |
192 | { |
193 | base->WICR |= WDOG_WICR_WTIS_MASK; |
194 | } |
195 | } |
196 | |
197 | /*! |
198 | * brief Refreshes the WDOG timer. |
199 | * |
200 | * This function feeds the WDOG. |
201 | * This function should be called before the WDOG timer is in timeout. Otherwise, a reset is asserted. |
202 | * |
203 | * param base WDOG peripheral base address |
204 | */ |
205 | void WDOG_Refresh(WDOG_Type *base) |
206 | { |
207 | uint32_t primaskValue = 0U; |
208 | |
209 | /* Disable the global interrupt to protect refresh sequence */ |
210 | primaskValue = DisableGlobalIRQ(); |
211 | base->WSR = WDOG_REFRESH_KEY & 0xFFFFU; |
212 | base->WSR = (WDOG_REFRESH_KEY >> 16U) & 0xFFFFU; |
213 | EnableGlobalIRQ(primaskValue); |
214 | } |
215 | |