1 /*
2 * Copyright (c) 2021 - 2023, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef NRFY_WDT_H__
35 #define NRFY_WDT_H__
36
37 #include <nrfx.h>
38 #include <hal/nrf_wdt.h>
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 NRFY_STATIC_INLINE bool __nrfy_internal_wdt_event_handle(NRF_WDT_Type * p_reg,
45 uint32_t mask,
46 nrf_wdt_event_t event,
47 uint32_t * p_evt_mask);
48
49 NRFY_STATIC_INLINE uint32_t __nrfy_internal_wdt_events_process(NRF_WDT_Type * p_reg, uint32_t mask);
50
51 NRFY_STATIC_INLINE void __nrfy_internal_wdt_event_enabled_clear(NRF_WDT_Type * p_reg,
52 uint32_t mask,
53 nrf_wdt_event_t event);
54
55 /**
56 * @defgroup nrfy_wdt WDT HALY
57 * @{
58 * @ingroup nrf_wdt
59 * @brief Hardware access layer with cache and barrier support for managing the WDT peripheral.
60 */
61
62 #if NRF_WDT_HAS_STOP || defined(__NRFX_DOXYGEN__)
63 /** @refhal{NRF_WDT_HAS_STOP} */
64 #define NRFY_WDT_HAS_STOP 1
65 #else
66 #define NRFY_WDT_HAS_STOP 0
67 #endif
68
69 /** @brief WDT configuration structure. */
70 typedef struct
71 {
72 uint32_t behaviour; ///< Watchdog behaviour flags bitmask, constructed from @ref nrf_wdt_behaviour_mask_t.
73 uint32_t reload_value; ///< Watchdog counter initial value.
74 } nrfy_wdt_config_t;
75
76 /**
77 * @brief Function for configuring the WDT.
78 *
79 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
80 * @param[in] p_config Pointer to the peripheral configuration structure.
81 */
nrfy_wdt_periph_configure(NRF_WDT_Type * p_reg,nrfy_wdt_config_t const * p_config)82 NRFY_STATIC_INLINE void nrfy_wdt_periph_configure(NRF_WDT_Type * p_reg,
83 nrfy_wdt_config_t const * p_config)
84 {
85 nrf_wdt_behaviour_set(p_reg, p_config->behaviour);
86 nrf_wdt_reload_value_set(p_reg, p_config->reload_value);
87 nrf_barrier_w();
88 }
89
90 /**
91 * @brief Function for initializing the specified WDT interrupts.
92 *
93 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
94 * @param[in] mask Mask of interrupts to be initialized.
95 * @param[in] irq_priority Interrupt priority.
96 * @param[in] enable True if interrupts are to be enabled, false otherwise.
97 */
nrfy_wdt_int_init(NRF_WDT_Type * p_reg,uint32_t mask,uint8_t irq_priority,bool enable)98 NRFY_STATIC_INLINE void nrfy_wdt_int_init(NRF_WDT_Type * p_reg,
99 uint32_t mask,
100 uint8_t irq_priority,
101 bool enable)
102 {
103 __nrfy_internal_wdt_event_enabled_clear(p_reg, mask, NRF_WDT_EVENT_TIMEOUT);
104 #if NRFY_WDT_HAS_STOP
105 __nrfy_internal_wdt_event_enabled_clear(p_reg, mask, NRF_WDT_EVENT_STOPPED);
106 #endif
107 nrf_barrier_w();
108
109 NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_reg), irq_priority);
110 NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_reg));
111
112 if (enable)
113 {
114 nrf_wdt_int_enable(p_reg, mask);
115 }
116 nrf_barrier_w();
117 }
118
119 /**
120 * @brief Function for uninitializing the WDT interrupts.
121 *
122 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
123 */
nrfy_wdt_int_uninit(NRF_WDT_Type * p_reg)124 NRFY_STATIC_INLINE void nrfy_wdt_int_uninit(NRF_WDT_Type * p_reg)
125 {
126 NRFX_IRQ_DISABLE(nrfx_get_irq_number(p_reg));
127 nrf_barrier_w();
128 }
129
130 /**
131 * @brief Function for processing the specified WDT events.
132 *
133 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
134 * @param[in] mask Mask of events to be processed, created by @ref NRFY_EVENT_TO_INT_BITMASK.
135 *
136 * @return Mask of events that were generated and processed.
137 * To be checked against the result of @ref NRFY_EVENT_TO_INT_BITMASK().
138 */
nrfy_wdt_events_process(NRF_WDT_Type * p_reg,uint32_t mask)139 NRFY_STATIC_INLINE uint32_t nrfy_wdt_events_process(NRF_WDT_Type * p_reg, uint32_t mask)
140 {
141 uint32_t evt_mask = __nrfy_internal_wdt_events_process(p_reg, mask);
142 nrf_barrier_w();
143 return evt_mask;
144 }
145
146 /** @refhal{nrf_wdt_task_trigger} */
nrfy_wdt_task_trigger(NRF_WDT_Type * p_reg,nrf_wdt_task_t task)147 NRFY_STATIC_INLINE void nrfy_wdt_task_trigger(NRF_WDT_Type * p_reg, nrf_wdt_task_t task)
148 {
149 nrf_wdt_task_trigger(p_reg, task);
150 nrf_barrier_w();
151 }
152
153 /** @refhal{nrf_wdt_task_address_get} */
nrfy_wdt_task_address_get(NRF_WDT_Type const * p_reg,nrf_wdt_task_t task)154 NRFY_STATIC_INLINE uint32_t nrfy_wdt_task_address_get(NRF_WDT_Type const * p_reg,
155 nrf_wdt_task_t task)
156 {
157 return nrf_wdt_task_address_get(p_reg, task);
158 }
159
160 /** @refhal{nrf_wdt_event_clear} */
nrfy_wdt_event_clear(NRF_WDT_Type * p_reg,nrf_wdt_event_t event)161 NRFY_STATIC_INLINE void nrfy_wdt_event_clear(NRF_WDT_Type * p_reg, nrf_wdt_event_t event)
162 {
163 nrf_wdt_event_clear(p_reg, event);
164 nrf_barrier_w();
165 }
166
167 /** @refhal{nrf_wdt_event_check} */
nrfy_wdt_event_check(NRF_WDT_Type const * p_reg,nrf_wdt_event_t event)168 NRFY_STATIC_INLINE bool nrfy_wdt_event_check(NRF_WDT_Type const * p_reg, nrf_wdt_event_t event)
169 {
170 nrf_barrier_r();
171 bool check = nrf_wdt_event_check(p_reg, event);
172 nrf_barrier_r();
173 return check;
174 }
175
176 /** @refhal{nrf_wdt_event_address_get} */
nrfy_wdt_event_address_get(NRF_WDT_Type const * p_reg,nrf_wdt_event_t event)177 NRFY_STATIC_INLINE uint32_t nrfy_wdt_event_address_get(NRF_WDT_Type const * p_reg,
178 nrf_wdt_event_t event)
179 {
180 return nrf_wdt_event_address_get(p_reg, event);
181 }
182
183 /** @refhal{nrf_wdt_int_enable} */
nrfy_wdt_int_enable(NRF_WDT_Type * p_reg,uint32_t mask)184 NRFY_STATIC_INLINE void nrfy_wdt_int_enable(NRF_WDT_Type * p_reg, uint32_t mask)
185 {
186 nrf_wdt_int_enable(p_reg, mask);
187 nrf_barrier_w();
188 }
189
190 /** @refhal{nrf_wdt_int_enable_check} */
nrfy_wdt_int_enable_check(NRF_WDT_Type const * p_reg,uint32_t mask)191 NRFY_STATIC_INLINE uint32_t nrfy_wdt_int_enable_check(NRF_WDT_Type const * p_reg, uint32_t mask)
192 {
193 nrf_barrier_rw();
194 uint32_t check = nrf_wdt_int_enable_check(p_reg, mask);
195 nrf_barrier_r();
196 return check;
197 }
198
199 /** @refhal{nrf_wdt_int_disable} */
nrfy_wdt_int_disable(NRF_WDT_Type * p_reg,uint32_t mask)200 NRFY_STATIC_INLINE void nrfy_wdt_int_disable(NRF_WDT_Type * p_reg, uint32_t mask)
201 {
202 nrf_wdt_int_disable(p_reg, mask);
203 nrf_barrier_w();
204 }
205
206 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
207 /** @refhal{nrf_wdt_subscribe_set} */
nrfy_wdt_subscribe_set(NRF_WDT_Type * p_reg,nrf_wdt_task_t task,uint8_t channel)208 NRFY_STATIC_INLINE void nrfy_wdt_subscribe_set(NRF_WDT_Type * p_reg,
209 nrf_wdt_task_t task,
210 uint8_t channel)
211 {
212 nrf_wdt_subscribe_set(p_reg, task, channel);
213 nrf_barrier_w();
214 }
215
216 /** @refhal{nrf_wdt_subscribe_clear} */
nrfy_wdt_subscribe_clear(NRF_WDT_Type * p_reg,nrf_wdt_task_t task)217 NRFY_STATIC_INLINE void nrfy_wdt_subscribe_clear(NRF_WDT_Type * p_reg, nrf_wdt_task_t task)
218 {
219 nrf_wdt_subscribe_clear(p_reg, task);
220 nrf_barrier_w();
221 }
222
223 /** @refhal{nrf_wdt_publish_set} */
nrfy_wdt_publish_set(NRF_WDT_Type * p_reg,nrf_wdt_event_t event,uint8_t channel)224 NRFY_STATIC_INLINE void nrfy_wdt_publish_set(NRF_WDT_Type * p_reg,
225 nrf_wdt_event_t event,
226 uint8_t channel)
227 {
228 nrf_wdt_publish_set(p_reg, event, channel);
229 nrf_barrier_w();
230 }
231
232 /** @refhal{nrf_wdt_publish_clear} */
nrfy_wdt_publish_clear(NRF_WDT_Type * p_reg,nrf_wdt_event_t event)233 NRFY_STATIC_INLINE void nrfy_wdt_publish_clear(NRF_WDT_Type * p_reg, nrf_wdt_event_t event)
234 {
235 nrf_wdt_publish_clear(p_reg, event);
236 nrf_barrier_w();
237 }
238 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
239
240 /** @refhal{nrf_wdt_behaviour_set} */
nrfy_wdt_behaviour_set(NRF_WDT_Type * p_reg,uint32_t mask)241 NRFY_STATIC_INLINE void nrfy_wdt_behaviour_set(NRF_WDT_Type * p_reg, uint32_t mask)
242 {
243 nrf_wdt_behaviour_set(p_reg, mask);
244 nrf_barrier_w();
245 }
246
247 /** @refhal{nrf_wdt_started_check} */
nrfy_wdt_started_check(NRF_WDT_Type const * p_reg)248 NRFY_STATIC_INLINE bool nrfy_wdt_started_check(NRF_WDT_Type const * p_reg)
249 {
250 nrf_barrier_r();
251 bool check = nrf_wdt_started_check(p_reg);
252 nrf_barrier_r();
253 return check;
254 }
255
256 /** @refhal{nrf_wdt_request_status_check} */
nrfy_wdt_request_status_check(NRF_WDT_Type const * p_reg,nrf_wdt_rr_register_t rr_register)257 NRFY_STATIC_INLINE bool nrfy_wdt_request_status_check(NRF_WDT_Type const * p_reg,
258 nrf_wdt_rr_register_t rr_register)
259 {
260 nrf_barrier_r();
261 bool check = nrf_wdt_request_status_check(p_reg, rr_register);
262 nrf_barrier_r();
263 return check;
264 }
265
266 /** @refhal{nrf_wdt_request_status_get} */
nrfy_wdt_request_status_get(NRF_WDT_Type const * p_reg)267 NRFY_STATIC_INLINE uint32_t nrfy_wdt_request_status_get(NRF_WDT_Type const * p_reg)
268 {
269 nrf_barrier_r();
270 uint32_t ret = nrf_wdt_request_status_get(p_reg);
271 nrf_barrier_r();
272 return ret;
273 }
274
275 /** @refhal{nrf_wdt_reload_value_set} */
nrfy_wdt_reload_value_set(NRF_WDT_Type * p_reg,uint32_t reload_value)276 NRFY_STATIC_INLINE void nrfy_wdt_reload_value_set(NRF_WDT_Type * p_reg, uint32_t reload_value)
277 {
278 nrf_wdt_reload_value_set(p_reg, reload_value);
279 nrf_barrier_w();
280 }
281
282 /** @refhal{nrf_wdt_reload_value_get} */
nrfy_wdt_reload_value_get(NRF_WDT_Type const * p_reg)283 NRFY_STATIC_INLINE uint32_t nrfy_wdt_reload_value_get(NRF_WDT_Type const * p_reg)
284 {
285 nrf_barrier_rw();
286 uint32_t ret = nrf_wdt_reload_value_get(p_reg);
287 nrf_barrier_r();
288 return ret;
289 }
290
291 /** @refhal{nrf_wdt_reload_request_enable} */
nrfy_wdt_reload_request_enable(NRF_WDT_Type * p_reg,nrf_wdt_rr_register_t rr_register)292 NRFY_STATIC_INLINE void nrfy_wdt_reload_request_enable(NRF_WDT_Type * p_reg,
293 nrf_wdt_rr_register_t rr_register)
294 {
295 nrf_wdt_reload_request_enable(p_reg, rr_register);
296 nrf_barrier_w();
297 }
298
299 /** @refhal{nrf_wdt_reload_request_disable} */
nrfy_wdt_reload_request_disable(NRF_WDT_Type * p_reg,nrf_wdt_rr_register_t rr_register)300 NRFY_STATIC_INLINE void nrfy_wdt_reload_request_disable(NRF_WDT_Type * p_reg,
301 nrf_wdt_rr_register_t rr_register)
302 {
303 nrf_wdt_reload_request_disable(p_reg, rr_register);
304 nrf_barrier_w();
305 }
306
307 /** @refhal{nrf_wdt_reload_request_enable_check} */
nrfy_wdt_reload_request_enable_check(NRF_WDT_Type const * p_reg,nrf_wdt_rr_register_t rr_register)308 NRFY_STATIC_INLINE bool nrfy_wdt_reload_request_enable_check(NRF_WDT_Type const * p_reg,
309 nrf_wdt_rr_register_t rr_register)
310 {
311 nrf_barrier_rw();
312 bool check = nrf_wdt_reload_request_enable_check(p_reg, rr_register);
313 nrf_barrier_r();
314 return check;
315 }
316
317 /** @refhal{nrf_wdt_reload_request_set} */
nrfy_wdt_reload_request_set(NRF_WDT_Type * p_reg,nrf_wdt_rr_register_t rr_register)318 NRFY_STATIC_INLINE void nrfy_wdt_reload_request_set(NRF_WDT_Type * p_reg,
319 nrf_wdt_rr_register_t rr_register)
320 {
321 nrf_wdt_reload_request_set(p_reg, rr_register);
322 nrf_barrier_w();
323 }
324
325 #if NRFY_WDT_HAS_STOP
326 /** @refhal{nrf_wdt_task_stop_enable_set} */
nrfy_wdt_task_stop_enable_set(NRF_WDT_Type * p_reg,bool enable)327 NRFY_STATIC_INLINE void nrfy_wdt_task_stop_enable_set(NRF_WDT_Type * p_reg, bool enable)
328 {
329 nrf_wdt_task_stop_enable_set(p_reg, enable);
330 nrf_barrier_w();
331 }
332 #endif
333
334 /** @} */
335
__nrfy_internal_wdt_event_handle(NRF_WDT_Type * p_reg,uint32_t mask,nrf_wdt_event_t event,uint32_t * p_evt_mask)336 NRFY_STATIC_INLINE bool __nrfy_internal_wdt_event_handle(NRF_WDT_Type * p_reg,
337 uint32_t mask,
338 nrf_wdt_event_t event,
339 uint32_t * p_evt_mask)
340 {
341 if ((mask & NRFY_EVENT_TO_INT_BITMASK(event)) && nrf_wdt_event_check(p_reg, event))
342 {
343 nrf_wdt_event_clear(p_reg, event);
344 if (p_evt_mask)
345 {
346 *p_evt_mask |= NRFY_EVENT_TO_INT_BITMASK(event);
347 }
348 return true;
349 }
350 return false;
351 }
352
__nrfy_internal_wdt_events_process(NRF_WDT_Type * p_reg,uint32_t mask)353 NRFY_STATIC_INLINE uint32_t __nrfy_internal_wdt_events_process(NRF_WDT_Type * p_reg, uint32_t mask)
354 {
355 uint32_t evt_mask = 0;
356
357 nrf_barrier_r();
358 (void)__nrfy_internal_wdt_event_handle(p_reg, mask, NRF_WDT_EVENT_TIMEOUT, &evt_mask);
359 #if NRFY_WDT_HAS_STOP
360 (void)__nrfy_internal_wdt_event_handle(p_reg, mask, NRF_WDT_EVENT_STOPPED, &evt_mask);
361 #endif
362
363 return evt_mask;
364 }
365
__nrfy_internal_wdt_event_enabled_clear(NRF_WDT_Type * p_reg,uint32_t mask,nrf_wdt_event_t event)366 NRFY_STATIC_INLINE void __nrfy_internal_wdt_event_enabled_clear(NRF_WDT_Type * p_reg,
367 uint32_t mask,
368 nrf_wdt_event_t event)
369 {
370 if (mask & NRFY_EVENT_TO_INT_BITMASK(event))
371 {
372 nrf_wdt_event_clear(p_reg, event);
373 }
374 }
375
376 #ifdef __cplusplus
377 }
378 #endif
379
380 #endif // NRFY_WDT_H__
381