1 /*
2 * Copyright (c) 2019 - 2024, 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 NRF_MWU_H__
35 #define NRF_MWU_H__
36
37 #include <nrfx.h>
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /**
44 * @defgroup nrf_mwu_hal MWU HAL
45 * @{
46 * @ingroup nrf_mwu
47 * @brief Hardware access layer for managing the Memory Watch Unit (MWU) peripheral.
48 */
49
50 /** @brief MWU events. */
51 typedef enum
52 {
53 NRF_MWU_EVENT_REGION0_WRITE = offsetof(NRF_MWU_Type, EVENTS_REGION[0].WA), ///< Write access to region 0 detected.
54 NRF_MWU_EVENT_REGION0_READ = offsetof(NRF_MWU_Type, EVENTS_REGION[0].RA), ///< Read access to region 0 detected.
55 NRF_MWU_EVENT_REGION1_WRITE = offsetof(NRF_MWU_Type, EVENTS_REGION[1].WA), ///< Write access to region 1 detected.
56 NRF_MWU_EVENT_REGION1_READ = offsetof(NRF_MWU_Type, EVENTS_REGION[1].RA), ///< Read access to region 1 detected.
57 NRF_MWU_EVENT_REGION2_WRITE = offsetof(NRF_MWU_Type, EVENTS_REGION[2].WA), ///< Write access to region 2 detected.
58 NRF_MWU_EVENT_REGION2_READ = offsetof(NRF_MWU_Type, EVENTS_REGION[2].RA), ///< Read access to region 2 detected.
59 NRF_MWU_EVENT_REGION3_WRITE = offsetof(NRF_MWU_Type, EVENTS_REGION[3].WA), ///< Write access to region 3 detected.
60 NRF_MWU_EVENT_REGION3_READ = offsetof(NRF_MWU_Type, EVENTS_REGION[3].RA), ///< Read access to region 3 detected.
61 NRF_MWU_EVENT_PREGION0_WRITE = offsetof(NRF_MWU_Type, EVENTS_PREGION[0].WA), ///< Write access to peripheral region 0 detected.
62 NRF_MWU_EVENT_PREGION0_READ = offsetof(NRF_MWU_Type, EVENTS_PREGION[0].RA), ///< Read access to peripheral region 0 detected.
63 NRF_MWU_EVENT_PREGION1_WRITE = offsetof(NRF_MWU_Type, EVENTS_PREGION[1].WA), ///< Write access to peripheral region 1 detected.
64 NRF_MWU_EVENT_PREGION1_READ = offsetof(NRF_MWU_Type, EVENTS_PREGION[1].RA), ///< Read access to peripheral region 1 detected.
65 } nrf_mwu_event_t;
66
67 /** @brief MWU interrupt masks. */
68 typedef enum
69 {
70 NRF_MWU_INT_REGION0_WRITE_MASK = MWU_INTEN_REGION0WA_Msk, ///< Interrupt on REGION[0].WA event.
71 NRF_MWU_INT_REGION0_READ_MASK = MWU_INTEN_REGION0RA_Msk, ///< Interrupt on REGION[0].RA event.
72 NRF_MWU_INT_REGION1_WRITE_MASK = MWU_INTEN_REGION1WA_Msk, ///< Interrupt on REGION[1].WA event.
73 NRF_MWU_INT_REGION1_READ_MASK = MWU_INTEN_REGION1RA_Msk, ///< Interrupt on REGION[1].RA event.
74 NRF_MWU_INT_REGION2_WRITE_MASK = MWU_INTEN_REGION2WA_Msk, ///< Interrupt on REGION[2].WA event.
75 NRF_MWU_INT_REGION2_READ_MASK = MWU_INTEN_REGION2RA_Msk, ///< Interrupt on REGION[2].RA event.
76 NRF_MWU_INT_REGION3_WRITE_MASK = MWU_INTEN_REGION3WA_Msk, ///< Interrupt on REGION[3].WA event.
77 NRF_MWU_INT_REGION3_READ_MASK = MWU_INTEN_REGION3RA_Msk, ///< Interrupt on REGION[3].RA event.
78 NRF_MWU_INT_PREGION0_WRITE_MASK = MWU_INTEN_PREGION0WA_Msk, ///< Interrupt on PREGION[0].WA event.
79 NRF_MWU_INT_PREGION0_READ_MASK = MWU_INTEN_PREGION0RA_Msk, ///< Interrupt on PREGION[0].RA event.
80 NRF_MWU_INT_PREGION1_WRITE_MASK = MWU_INTEN_PREGION1WA_Msk, ///< Interrupt on PREGION[1].WA event.
81 NRF_MWU_INT_PREGION1_READ_MASK = MWU_INTEN_PREGION1RA_Msk, ///< Interrupt on PREGION[1].RA event.
82 } nrf_mwu_int_mask_t;
83
84 /** @brief MWU region watch masks. */
85 typedef enum
86 {
87 NRF_MWU_WATCH_REGION0_WRITE = MWU_REGIONEN_RGN0WA_Msk, ///< Region 0 write access watch mask.
88 NRF_MWU_WATCH_REGION0_READ = MWU_REGIONEN_RGN0RA_Msk, ///< Region 0 read access watch mask.
89 NRF_MWU_WATCH_REGION1_WRITE = MWU_REGIONEN_RGN1WA_Msk, ///< Region 1 write access watch mask.
90 NRF_MWU_WATCH_REGION1_READ = MWU_REGIONEN_RGN1RA_Msk, ///< Region 1 read access watch mask.
91 NRF_MWU_WATCH_REGION2_WRITE = MWU_REGIONEN_RGN2WA_Msk, ///< Region 2 write access watch mask.
92 NRF_MWU_WATCH_REGION2_READ = MWU_REGIONEN_RGN2RA_Msk, ///< Region 2 read access watch mask.
93 NRF_MWU_WATCH_REGION3_WRITE = MWU_REGIONEN_RGN3WA_Msk, ///< Region 3 write access watch mask.
94 NRF_MWU_WATCH_REGION3_READ = MWU_REGIONEN_RGN3RA_Msk, ///< Region 3 read access watch mask.
95 NRF_MWU_WATCH_PREGION0_WRITE = MWU_REGIONEN_PRGN0WA_Msk, ///< Peripheral region 0 write access watch mask.
96 NRF_MWU_WATCH_PREGION0_READ = MWU_REGIONEN_PRGN0RA_Msk, ///< Peripheral region 0 read access watch mask.
97 NRF_MWU_WATCH_PREGION1_WRITE = MWU_REGIONEN_PRGN1WA_Msk, ///< Peripheral region 1 write access watch mask.
98 NRF_MWU_WATCH_PREGION1_READ = MWU_REGIONEN_PRGN1RA_Msk, ///< Peripheral region 1 read access watch mask.
99 } nrf_mwu_region_watch_t;
100
101 /**
102 * @brief Function for retrieving the state of the MWU event.
103 *
104 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
105 * @param[in] event Event to be checked.
106 *
107 * @retval true The event has been generated.
108 * @retval false The event has not been generated.
109 */
110 NRF_STATIC_INLINE bool nrf_mwu_event_check(NRF_MWU_Type const * p_reg,
111 nrf_mwu_event_t event);
112
113 /**
114 * @brief Function for clearing a specific MWU event.
115 *
116 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
117 * @param[in] event Event to clear.
118 */
119 NRF_STATIC_INLINE void nrf_mwu_event_clear(NRF_MWU_Type * p_reg,
120 nrf_mwu_event_t event);
121
122 /**
123 * @brief Function for getting the address of a specific MWU event register.
124 *
125 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
126 * @param[in] event Requested event.
127 *
128 * @return Address of the specified event register.
129 */
130 NRF_STATIC_INLINE uint32_t nrf_mwu_event_address_get(NRF_MWU_Type const * p_reg,
131 nrf_mwu_event_t event);
132
133 /**
134 * @brief Function for enabling specified interrupts.
135 *
136 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
137 * @param[in] mask Mask of interrupts to be enabled.
138 * Use @ref nrf_mwu_int_mask_t values for bit masking.
139 */
140 NRF_STATIC_INLINE void nrf_mwu_int_enable(NRF_MWU_Type * p_reg, uint32_t mask);
141
142 /**
143 * @brief Function for checking if the specified interrupts are enabled.
144 *
145 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
146 * @param[in] mask Mask of interrupts to be checked.
147 * Use @ref nrf_mwu_int_mask_t values for bit masking.
148 *
149 * @return Mask of enabled interrupts.
150 */
151 NRF_STATIC_INLINE uint32_t nrf_mwu_int_enable_check(NRF_MWU_Type const * p_reg, uint32_t mask);
152
153 /**
154 * @brief Function for disabling specified interrupts.
155 *
156 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
157 * @param[in] mask Mask of interrupts to be disabled.
158 * Use @ref nrf_mwu_int_mask_t values for bit masking.
159 */
160 NRF_STATIC_INLINE void nrf_mwu_int_disable(NRF_MWU_Type * p_reg, uint32_t mask);
161
162 /**
163 * @brief Function for enabling specified non-maskable interrupts.
164 *
165 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
166 * @param[in] mask Mask of interrupts to be enabled.
167 */
168 NRF_STATIC_INLINE void nrf_mwu_nmi_enable(NRF_MWU_Type * p_reg, uint32_t mask);
169
170 /**
171 * @brief Function for checking if the specified non-maskable interrupts are enabled.
172 *
173 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
174 * @param[in] mask Mask of interrupts to be checked.
175 *
176 * @return Mask of enabled interrupts.
177 */
178 NRF_STATIC_INLINE uint32_t nrf_mwu_nmi_enable_check(NRF_MWU_Type const * p_reg, uint32_t mask);
179
180 /**
181 * @brief Function for disabling specified non-maskable interrupts.
182 *
183 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
184 * @param[in] mask Mask of interrupts to be disabled.
185 */
186 NRF_STATIC_INLINE void nrf_mwu_nmi_disable(NRF_MWU_Type * p_reg, uint32_t mask);
187
188 /**
189 * @brief Function for setting address range of the specified user region.
190 *
191 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
192 * @param[in] region_idx Region number to configure.
193 * @param[in] start_addr Memory address defining the beginning of the region.
194 * @param[in] end_addr Memory address defining the end of the region.
195 */
196 NRF_STATIC_INLINE void nrf_mwu_user_region_range_set(NRF_MWU_Type * p_reg,
197 uint8_t region_idx,
198 uint32_t start_addr,
199 uint32_t end_addr);
200
201 /**
202 * @brief Function for enabling memory access watch mechanism.
203 *
204 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
205 * @param[in] reg_watch_mask Mask that defines regions and access types to watch.
206 * Compose this mask from @ref nrf_mwu_region_watch_t values.
207 */
208 NRF_STATIC_INLINE void nrf_mwu_region_watch_enable(NRF_MWU_Type * p_reg, uint32_t reg_watch_mask);
209
210 /**
211 * @brief Function for disabling memory access watch mechanism.
212 *
213 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
214 * @param[in] reg_watch_mask Mask that defines regions and access types to stop watching.
215 * Compose this mask from @ref nrf_mwu_region_watch_t values.
216 */
217 NRF_STATIC_INLINE void nrf_mwu_region_watch_disable(NRF_MWU_Type * p_reg, uint32_t reg_watch_mask);
218
219 /**
220 * @brief Function for getting memory access watch configuration mask.
221 *
222 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
223 *
224 * @return Mask that defines regions and access types being watched.
225 */
226 NRF_STATIC_INLINE uint32_t nrf_mwu_region_watch_get(NRF_MWU_Type const * p_reg);
227
228 /**
229 * @brief Function for configuring peripheral subregions for watching.
230 *
231 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
232 * @param[in] per_reg_idx Peripheral region containing specified subregions.
233 * @param[in] subregion_mask Mask that defines subregions to include into the specified peripheral region.
234 */
235 NRF_STATIC_INLINE void nrf_mwu_subregions_configure(NRF_MWU_Type * p_reg,
236 uint8_t per_reg_idx,
237 uint32_t subregion_mask);
238
239 /**
240 * @brief Function for getting the mask of the write access flags of peripheral subregions
241 *
242 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
243 * @param[in] per_reg_idx Peripheral region containing subregions to be checked.
244 *
245 * @return Mask specifying subregions that were write accessed.
246 */
247 NRF_STATIC_INLINE uint32_t nrf_mwu_subregions_write_accesses_get(NRF_MWU_Type const * p_reg,
248 uint8_t per_reg_idx);
249
250 /**
251 * @brief Function for clearing write access flags of peripheral subregions.
252 *
253 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
254 * @param[in] per_reg_idx Peripheral region containing subregion accesses to clear.
255 * @param[in] subregion_mask Mask that defines subregion write accesses to clear.
256 */
257 NRF_STATIC_INLINE void nrf_mwu_subregions_write_accesses_clear(NRF_MWU_Type * p_reg,
258 uint8_t per_reg_idx,
259 uint32_t subregion_mask);
260
261 /**
262 * @brief Function for getting the mask of the read access flags of peripheral subregions
263 *
264 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
265 * @param[in] per_reg_idx Peripheral region containing subregions to be checked.
266 *
267 * @return Mask specifying subregions that were read accessed.
268 */
269 NRF_STATIC_INLINE uint32_t nrf_mwu_subregions_read_accesses_get(NRF_MWU_Type const * p_reg,
270 uint8_t per_reg_idx);
271
272 /**
273 * @brief Function for clearing read access flags of peripheral subregions.
274 *
275 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
276 * @param[in] per_reg_idx Peripheral region containing subregion accesses to clear.
277 * @param[in] subregion_mask Mask that defines subregion read accesses to clear.
278 */
279 NRF_STATIC_INLINE void nrf_mwu_subregions_read_accesses_clear(NRF_MWU_Type * p_reg,
280 uint8_t per_reg_idx,
281 uint32_t subregion_mask);
282
283 #ifndef NRF_DECLARE_ONLY
284
nrf_mwu_event_check(NRF_MWU_Type const * p_reg,nrf_mwu_event_t event)285 NRF_STATIC_INLINE bool nrf_mwu_event_check(NRF_MWU_Type const * p_reg,
286 nrf_mwu_event_t event)
287 {
288 return nrf_event_check(p_reg, event);
289 }
290
nrf_mwu_event_clear(NRF_MWU_Type * p_reg,nrf_mwu_event_t event)291 NRF_STATIC_INLINE void nrf_mwu_event_clear(NRF_MWU_Type * p_reg,
292 nrf_mwu_event_t event)
293 {
294 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0;
295 nrf_event_readback((uint8_t *)p_reg + (uint32_t)event);
296 }
297
nrf_mwu_event_address_get(NRF_MWU_Type const * p_reg,nrf_mwu_event_t event)298 NRF_STATIC_INLINE uint32_t nrf_mwu_event_address_get(NRF_MWU_Type const * p_reg,
299 nrf_mwu_event_t event)
300 {
301 return nrf_task_event_address_get(p_reg, event);
302 }
303
nrf_mwu_int_enable(NRF_MWU_Type * p_reg,uint32_t mask)304 NRF_STATIC_INLINE void nrf_mwu_int_enable(NRF_MWU_Type * p_reg, uint32_t mask)
305 {
306 p_reg->INTENSET = mask;
307 }
308
nrf_mwu_int_enable_check(NRF_MWU_Type const * p_reg,uint32_t mask)309 NRF_STATIC_INLINE uint32_t nrf_mwu_int_enable_check(NRF_MWU_Type const * p_reg, uint32_t mask)
310 {
311 return p_reg->INTENSET & mask;
312 }
313
nrf_mwu_int_disable(NRF_MWU_Type * p_reg,uint32_t mask)314 NRF_STATIC_INLINE void nrf_mwu_int_disable(NRF_MWU_Type * p_reg, uint32_t mask)
315 {
316 p_reg->INTENCLR = mask;
317 }
318
nrf_mwu_nmi_enable(NRF_MWU_Type * p_reg,uint32_t mask)319 NRF_STATIC_INLINE void nrf_mwu_nmi_enable(NRF_MWU_Type * p_reg, uint32_t mask)
320 {
321 p_reg->NMIENSET = mask;
322 }
323
nrf_mwu_nmi_enable_check(NRF_MWU_Type const * p_reg,uint32_t mask)324 NRF_STATIC_INLINE uint32_t nrf_mwu_nmi_enable_check(NRF_MWU_Type const * p_reg, uint32_t mask)
325 {
326 return p_reg->NMIENSET & mask;
327 }
328
nrf_mwu_nmi_disable(NRF_MWU_Type * p_reg,uint32_t mask)329 NRF_STATIC_INLINE void nrf_mwu_nmi_disable(NRF_MWU_Type * p_reg, uint32_t mask)
330 {
331 p_reg->NMIENCLR = mask;
332 }
333
nrf_mwu_user_region_range_set(NRF_MWU_Type * p_reg,uint8_t region_idx,uint32_t start_addr,uint32_t end_addr)334 NRF_STATIC_INLINE void nrf_mwu_user_region_range_set(NRF_MWU_Type * p_reg,
335 uint8_t region_idx,
336 uint32_t start_addr,
337 uint32_t end_addr)
338 {
339 NRFX_ASSERT(end_addr >= start_addr);
340
341 p_reg->REGION[region_idx].START = start_addr;
342 p_reg->REGION[region_idx].END = end_addr;
343 }
344
nrf_mwu_region_watch_enable(NRF_MWU_Type * p_reg,uint32_t reg_watch_mask)345 NRF_STATIC_INLINE void nrf_mwu_region_watch_enable(NRF_MWU_Type * p_reg, uint32_t reg_watch_mask)
346 {
347 p_reg->REGIONENSET = reg_watch_mask;
348 }
349
nrf_mwu_region_watch_disable(NRF_MWU_Type * p_reg,uint32_t reg_watch_mask)350 NRF_STATIC_INLINE void nrf_mwu_region_watch_disable(NRF_MWU_Type * p_reg, uint32_t reg_watch_mask)
351 {
352 p_reg->REGIONENCLR = reg_watch_mask;
353 }
354
nrf_mwu_region_watch_get(NRF_MWU_Type const * p_reg)355 NRF_STATIC_INLINE uint32_t nrf_mwu_region_watch_get(NRF_MWU_Type const * p_reg)
356 {
357 return p_reg->REGIONENSET;
358 }
359
nrf_mwu_subregions_configure(NRF_MWU_Type * p_reg,uint8_t per_reg_idx,uint32_t subregion_mask)360 NRF_STATIC_INLINE void nrf_mwu_subregions_configure(NRF_MWU_Type * p_reg,
361 uint8_t per_reg_idx,
362 uint32_t subregion_mask)
363 {
364 p_reg->PREGION[per_reg_idx].SUBS = subregion_mask;
365 }
366
nrf_mwu_subregions_write_accesses_get(NRF_MWU_Type const * p_reg,uint8_t per_reg_idx)367 NRF_STATIC_INLINE uint32_t nrf_mwu_subregions_write_accesses_get(NRF_MWU_Type const * p_reg,
368 uint8_t per_reg_idx)
369 {
370 return p_reg->PERREGION[per_reg_idx].SUBSTATWA;
371 }
372
nrf_mwu_subregions_write_accesses_clear(NRF_MWU_Type * p_reg,uint8_t per_reg_idx,uint32_t subregion_mask)373 NRF_STATIC_INLINE void nrf_mwu_subregions_write_accesses_clear(NRF_MWU_Type * p_reg,
374 uint8_t per_reg_idx,
375 uint32_t subregion_mask)
376 {
377 p_reg->PERREGION[per_reg_idx].SUBSTATWA = subregion_mask;
378 }
379
nrf_mwu_subregions_read_accesses_get(NRF_MWU_Type const * p_reg,uint8_t per_reg_idx)380 NRF_STATIC_INLINE uint32_t nrf_mwu_subregions_read_accesses_get(NRF_MWU_Type const * p_reg,
381 uint8_t per_reg_idx)
382 {
383 return p_reg->PERREGION[per_reg_idx].SUBSTATRA;
384 }
385
nrf_mwu_subregions_read_accesses_clear(NRF_MWU_Type * p_reg,uint8_t per_reg_idx,uint32_t subregion_mask)386 NRF_STATIC_INLINE void nrf_mwu_subregions_read_accesses_clear(NRF_MWU_Type * p_reg,
387 uint8_t per_reg_idx,
388 uint32_t subregion_mask)
389 {
390 p_reg->PERREGION[per_reg_idx].SUBSTATRA = subregion_mask;
391 }
392
393 #endif // NRF_DECLARE_ONLY
394
395 /** @} */
396
397 #ifdef __cplusplus
398 }
399 #endif
400
401 #endif // NRF_MWU_H__
402