1 /*
2 * Copyright 2020 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_cwt.h"
9
10 /*******************************************************************************
11 * Definitions
12 *******************************************************************************/
13
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.cwt"
17 #endif
18
19 /*******************************************************************************
20 * Prototypes
21 ******************************************************************************/
22
23 /*******************************************************************************
24 * Code
25 ******************************************************************************/
26
27 /*!
28 * brief Sets the default configuration of CWT
29 *
30 * This function initialize CWT config structure to default values.
31 *
32 * param conf CWT configuration structure
33 */
CWT_GetDefaultConfig(cwt_config_t * conf)34 void CWT_GetDefaultConfig(cwt_config_t *conf)
35 {
36 /* Default configuration after reset */
37 conf->lock = (uint8_t)kCDOG_LockCtrl_Unlock; /* Lock control */
38 conf->timeout = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Timeout control */
39 conf->miscompare = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Miscompare control */
40 conf->sequence = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Sequence control */
41 conf->control = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Control */
42 conf->state = (uint8_t)kCDOG_FaultCtrl_NoAction; /* State control */
43 conf->address = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Address control */
44 conf->irq_pause = (uint8_t)kCDOG_IrqPauseCtrl_Run; /* IRQ pause control */
45 conf->debug_halt = (uint8_t)kCDOG_DebugHaltCtrl_Run; /* Debug halt control */
46 return;
47 }
48
49 /*!
50 * brief Sets secure counter and instruction timer values
51 *
52 * This function sets value in RELOAD and START registers for instruction timer.
53 *
54 * param base CWT peripheral base address
55 * param reload reload value
56 * param start start value
57 */
CWT_Start(CDOG_Type * base,uint32_t reload,uint32_t start)58 void CWT_Start(CDOG_Type *base, uint32_t reload, uint32_t start)
59 {
60 base->RELOAD = reload;
61 base->START = start;
62 }
63
64 /*!
65 * brief Stops secure counter and instruction timer
66 *
67 * This function stops instruction timer and secure counter.
68 * This also change state of CWT to IDLE.
69 *
70 * param base CWT peripheral base address
71 * param stop expected value which will be compared with value of secure counter
72 */
CWT_Stop(CDOG_Type * base,uint32_t stop)73 void CWT_Stop(CDOG_Type *base, uint32_t stop)
74 {
75 base->STOP = stop;
76 }
77
78 /*!
79 * brief Sets secure counter and instruction timer values
80 *
81 * This function sets value in STOP, RELOAD and START registers
82 * for instruction timer and secure counter.
83 *
84 * param base CWT peripheral base address
85 * param stop expected value which will be compared with value of secure counter
86 * param reload reload value for instruction timer
87 * param start start value for secure timer
88 */
CWT_Set(CDOG_Type * base,uint32_t stop,uint32_t reload,uint32_t start)89 void CWT_Set(CDOG_Type *base, uint32_t stop, uint32_t reload, uint32_t start)
90 {
91 base->STOP = stop;
92 base->RELOAD = reload;
93 base->START = start;
94 }
95
96 /*!
97 * brief Add value to secure counter
98 *
99 * This function add specified value to secure counter.
100 *
101 * param base CWT peripheral base address.
102 * param add Value to be added.
103 */
CWT_Add(CDOG_Type * base,uint32_t add)104 void CWT_Add(CDOG_Type *base, uint32_t add)
105 {
106 base->ADD = (secure_counter_t)add;
107 }
108
109 /*!
110 * brief Add 1 to secure counter
111 *
112 * This function add 1 to secure counter.
113 *
114 * param base CWT peripheral base address.
115 * param add Value to be added.
116 */
CWT_Add1(CDOG_Type * base)117 void CWT_Add1(CDOG_Type *base)
118 {
119 base->ADD1 = (secure_counter_t)0x1U;
120 }
121
122 /*!
123 * brief Add 16 to secure counter
124 *
125 * This function add 16 to secure counter.
126 *
127 * param base CWT peripheral base address.
128 * param add Value to be added.
129 */
CWT_Add16(CDOG_Type * base)130 void CWT_Add16(CDOG_Type *base)
131 {
132 base->ADD16 = (secure_counter_t)0x1U;
133 }
134
135 /*!
136 * brief Add 256 to secure counter
137 *
138 * This function add 256 to secure counter.
139 *
140 * param base CWT peripheral base address.
141 * param add Value to be added.
142 */
CWT_Add256(CDOG_Type * base)143 void CWT_Add256(CDOG_Type *base)
144 {
145 base->ADD256 = (secure_counter_t)0x1U;
146 }
147
148 /*!
149 * brief Substract value to secure counter
150 *
151 * This function substract specified value to secure counter.
152 *
153 * param base CWT peripheral base address.
154 * param sub Value to be substracted.
155 */
CWT_Sub(CDOG_Type * base,uint32_t sub)156 void CWT_Sub(CDOG_Type *base, uint32_t sub)
157 {
158 base->SUB = (secure_counter_t)sub;
159 }
160
161 /*!
162 * brief Substract 1 from secure counter
163 *
164 * This function substract specified 1 from secure counter.
165 *
166 * param base CWT peripheral base address.
167 */
CWT_Sub1(CDOG_Type * base)168 void CWT_Sub1(CDOG_Type *base)
169 {
170 base->SUB1 = (secure_counter_t)0x1U;
171 }
172
173 /*!
174 * brief Substract 16 from secure counter
175 *
176 * This function substract specified 16 from secure counter.
177 *
178 * param base CWT peripheral base address.
179 */
CWT_Sub16(CDOG_Type * base)180 void CWT_Sub16(CDOG_Type *base)
181 {
182 base->SUB16 = (secure_counter_t)0x1U;
183 }
184
185 /*!
186 * brief Substract 256 from secure counter
187 *
188 * This function substract specified 256 from secure counter.
189 *
190 * param base CWT peripheral base address.
191 */
CWT_Sub256(CDOG_Type * base)192 void CWT_Sub256(CDOG_Type *base)
193 {
194 base->SUB256 = (secure_counter_t)0x1U;
195 }
196
197 /*!
198 * brief Checks secure counter.
199 *
200 * This function compares stop value with secure counter value
201 * by writting to RELOAD refister.
202 *
203 * param base CWT peripheral base address
204 * param check expected (stop) value.
205 */
CWT_Check(CDOG_Type * base,uint32_t check)206 void CWT_Check(CDOG_Type *base, uint32_t check)
207 {
208 base->RESTART = check;
209 }
210
211 /*!
212 * brief Set the CWT persistent word.
213 *
214 * param base CWT peripheral base address.
215 * param value The value to be written.
216 */
CWT_WritePersistent(CDOG_Type * base,uint32_t value)217 void CWT_WritePersistent(CDOG_Type *base, uint32_t value)
218 {
219 base->PERSISTENT = value;
220 }
221
222 /*!
223 * brief Get the CWT persistent word.
224 *
225 * param base CWT peripheral base address.
226 * return The persistent word.
227 */
CWT_ReadPersistent(CDOG_Type * base)228 uint32_t CWT_ReadPersistent(CDOG_Type *base)
229 {
230 return base->PERSISTENT;
231 }
232
233 /*!
234 * brief Initialize CWT
235 *
236 * This function initializes CWT block and setting.
237 *
238 * param base CWT peripheral base address
239 * param conf CWT configuration structure
240 * return Status of the init operation
241 */
CWT_Init(CDOG_Type * base,cwt_config_t * conf)242 status_t CWT_Init(CDOG_Type *base, cwt_config_t *conf)
243 {
244 /* Ungate clock to CWT engine and reset it */
245 CLOCK_EnableClock(kCLOCK_Cwt);
246 RESET_PeripheralReset(kCWT_RST_SHIFT_RSTn);
247
248 if (base->CONTROL == 0x0U)
249 {
250 /* CWT is not in IDLE mode, which may be cause after SW reset. */
251 /* Writing to CONTROL register will trigger fault. */
252 return kStatus_Fail;
253 }
254
255 /* Clear pending errors, otherwise the device will reset */
256 /* itself immediately after enable Code Watchdog */
257 if ((uint32_t)kCDOG_LockCtrl_Lock ==
258 ((base->CONTROL & CDOG_CONTROL_LOCK_CTRL_MASK) >> CDOG_CONTROL_LOCK_CTRL_SHIFT))
259
260 {
261 CDOG->FLAGS = CDOG_FLAGS_TO_FLAG(1U) | CDOG_FLAGS_MISCOM_FLAG(1U) | CDOG_FLAGS_SEQ_FLAG(1U) |
262 CDOG_FLAGS_CNT_FLAG(1U) | CDOG_FLAGS_STATE_FLAG(1U) | CDOG_FLAGS_ADDR_FLAG(1U) |
263 CDOG_FLAGS_POR_FLAG(1U);
264 }
265 else
266 {
267 CDOG->FLAGS = CDOG_FLAGS_TO_FLAG(0U) | CDOG_FLAGS_MISCOM_FLAG(0U) | CDOG_FLAGS_SEQ_FLAG(0U) |
268 CDOG_FLAGS_CNT_FLAG(0U) | CDOG_FLAGS_STATE_FLAG(0U) | CDOG_FLAGS_ADDR_FLAG(0U) |
269 CDOG_FLAGS_POR_FLAG(0U);
270 }
271
272 base->CONTROL =
273 CDOG_CONTROL_TIMEOUT_CTRL(conf->timeout) | /* Action if the timeout event is triggered */
274 CDOG_CONTROL_MISCOMPARE_CTRL(conf->miscompare) | /* Action if the miscompare error event is triggered */
275 CDOG_CONTROL_SEQUENCE_CTRL(conf->sequence) | /* Action if the sequence error event is triggered */
276 CDOG_CONTROL_CONTROL_CTRL(conf->control) | /* Action if the control error event is triggered */
277 CDOG_CONTROL_STATE_CTRL(conf->state) | /* Action if the state error event is triggered */
278 CDOG_CONTROL_ADDRESS_CTRL(conf->address) | /* Action if the address error event is triggered */
279 CDOG_CONTROL_IRQ_PAUSE(conf->irq_pause) | /* Pause running during interrupts setup */
280 CDOG_CONTROL_DEBUG_HALT_CTRL(
281 conf->debug_halt) | /* Halt CWT timer during debug so we have chance to debug code */
282 CDOG_CONTROL_LOCK_CTRL(conf->lock); /* Lock control register */
283
284 NVIC_EnableIRQ(CodeWDG_IRQn);
285
286 return kStatus_Success;
287 }
288
289 /*!
290 * brief Deinitialize CWT
291 *
292 * This function stops CWT secure counter.
293 *
294 * param base CWT peripheral base address
295 */
CWT_Deinit(CDOG_Type * base)296 void CWT_Deinit(CDOG_Type *base)
297 {
298 NVIC_DisableIRQ(CodeWDG_IRQn);
299
300 RESET_SetPeripheralReset(kCWT_RST_SHIFT_RSTn);
301 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
302 CLOCK_DisableClock(kCLOCK_Cwt);
303 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
304 }
305