1 /*
2  * Copyright (c) 2018, Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef NRFX_GLUE_H__
8 #define NRFX_GLUE_H__
9 
10 #if defined(CONFIG_CPU_CORTEX_M)
11 /* Workaround for missing __ICACHE_PRESENT and __DCACHE_PRESENT symbols in MDK
12  * SoC definitions. To be removed when this is fixed.
13  */
14 #include <cmsis_core_m_defaults.h>
15 #endif
16 
17 #include <zephyr/sys/__assert.h>
18 #include <zephyr/sys/atomic.h>
19 #include <zephyr/irq.h>
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /**
26  * @defgroup nrfx_glue nrfx_glue.h
27  * @{
28  * @ingroup nrfx
29  *
30  * @brief This file contains macros that should be implemented according to
31  *        the needs of the host environment into which @em nrfx is integrated.
32  */
33 
34 //------------------------------------------------------------------------------
35 
36 /**
37  * @brief Macro for placing a runtime assertion.
38  *
39  * @param expression Expression to be evaluated.
40  */
41 #ifndef NRFX_ASSERT
42 #define NRFX_ASSERT(expression)  __ASSERT_NO_MSG(expression)
43 #endif
44 
45 #if defined(CONFIG_RISCV)
46 /* included here due to dependency on NRFX_ASSERT definition */
47 #include <hal/nrf_vpr_clic.h>
48 #endif
49 
50 /**
51  * @brief Macro for placing a compile time assertion.
52  *
53  * @param expression Expression to be evaluated.
54  */
55 #define NRFX_STATIC_ASSERT(expression) \
56         BUILD_ASSERT(expression, "assertion failed")
57 
58 //------------------------------------------------------------------------------
59 
60 /**
61  * @brief Macro for setting the priority of a specific IRQ.
62  *
63  * @param irq_number IRQ number.
64  * @param priority   Priority to be set.
65  */
66 #define NRFX_IRQ_PRIORITY_SET(irq_number, priority)                                                \
67 	ARG_UNUSED(priority)                                                                       \
68 	/* Intentionally empty. Priorities of IRQs are set through IRQ_CONNECT. */
69 
70 /**
71  * @brief Macro for enabling a specific IRQ.
72  *
73  * @param irq_number IRQ number.
74  */
75 #define NRFX_IRQ_ENABLE(irq_number)  irq_enable(irq_number)
76 
77 /**
78  * @brief Macro for checking if a specific IRQ is enabled.
79  *
80  * @param irq_number IRQ number.
81  *
82  * @retval true  If the IRQ is enabled.
83  * @retval false Otherwise.
84  */
85 #define NRFX_IRQ_IS_ENABLED(irq_number)  irq_is_enabled(irq_number)
86 
87 /**
88  * @brief Macro for disabling a specific IRQ.
89  *
90  * @param irq_number IRQ number.
91  */
92 #define NRFX_IRQ_DISABLE(irq_number)  irq_disable(irq_number)
93 
94 /**
95  * @brief Macro for setting a specific IRQ as pending.
96  *
97  * @param irq_number IRQ number.
98  */
99 #if defined(CONFIG_RISCV)
100 #define NRFX_IRQ_PENDING_SET(irq_number) nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, irq_number)
101 #else
102 #define NRFX_IRQ_PENDING_SET(irq_number) NVIC_SetPendingIRQ(irq_number)
103 #endif
104 
105 /**
106  * @brief Macro for clearing the pending status of a specific IRQ.
107  *
108  * @param irq_number IRQ number.
109  */
110 #if defined(CONFIG_RISCV)
111 #define NRFX_IRQ_PENDING_CLEAR(irq_number) nrf_vpr_clic_int_pending_clear(NRF_VPRCLIC, irq_number)
112 #else
113 #define NRFX_IRQ_PENDING_CLEAR(irq_number) NVIC_ClearPendingIRQ(irq_number)
114 #endif
115 
116 /**
117  * @brief Macro for checking the pending status of a specific IRQ.
118  *
119  * @retval true  If the IRQ is pending.
120  * @retval false Otherwise.
121  */
122 #if defined(CONFIG_RISCV)
123 #define NRFX_IRQ_IS_PENDING(irq_number) nrf_vpr_clic_int_pending_check(NRF_VPRCLIC, irq_number)
124 #else
125 #define NRFX_IRQ_IS_PENDING(irq_number) (NVIC_GetPendingIRQ(irq_number) == 1)
126 #endif
127 
128 /** @brief Macro for entering into a critical section. */
129 #define NRFX_CRITICAL_SECTION_ENTER()  { unsigned int irq_lock_key = irq_lock();
130 
131 /** @brief Macro for exiting from a critical section. */
132 #define NRFX_CRITICAL_SECTION_EXIT()     irq_unlock(irq_lock_key); }
133 
134 //------------------------------------------------------------------------------
135 
136 /**
137  * @brief When set to a non-zero value, this macro specifies that
138  *        @ref nrfx_coredep_delay_us uses a precise DWT-based solution.
139  *        A compilation error is generated if the DWT unit is not present
140  *        in the SoC used.
141  */
142 #define NRFX_DELAY_DWT_BASED    0
143 
144 /**
145  * @brief Macro for delaying the code execution for at least the specified time.
146  *
147  * @param us_time Number of microseconds to wait.
148  */
149 #define NRFX_DELAY_US(us_time)  nrfx_busy_wait(us_time)
150 /* This is a k_busy_wait wrapper, added to avoid the inclusion of kernel.h */
151 void nrfx_busy_wait(uint32_t usec_to_wait);
152 
153 //------------------------------------------------------------------------------
154 
155 /** @brief Atomic 32-bit unsigned type. */
156 #define nrfx_atomic_t  atomic_t
157 
158 /**
159  * @brief Macro for storing a value to an atomic object and returning its previous value.
160  *
161  * @param[in] p_data Atomic memory pointer.
162  * @param[in] value  Value to store.
163  *
164  * @return Previous value of the atomic object.
165  */
166 #define NRFX_ATOMIC_FETCH_STORE(p_data, value)  atomic_set(p_data, value)
167 
168 /**
169  * @brief Macro for running a bitwise OR operation on an atomic object and returning its previous value.
170  *
171  * @param[in] p_data Atomic memory pointer.
172  * @param[in] value  Value of the second operand in the OR operation.
173  *
174  * @return Previous value of the atomic object.
175  */
176 #define NRFX_ATOMIC_FETCH_OR(p_data, value)  atomic_or(p_data, value)
177 
178 /**
179  * @brief Macro for running a bitwise AND operation on an atomic object
180  *        and returning its previous value.
181  *
182  * @param[in] p_data Atomic memory pointer.
183  * @param[in] value  Value of the second operand in the AND operation.
184  *
185  * @return Previous value of the atomic object.
186  */
187 #define NRFX_ATOMIC_FETCH_AND(p_data, value)  atomic_and(p_data, value)
188 
189 /**
190  * @brief Macro for running a bitwise XOR operation on an atomic object
191  *        and returning its previous value.
192  *
193  * @param[in] p_data Atomic memory pointer.
194  * @param[in] value  Value of the second operand in the XOR operation.
195  *
196  * @return Previous value of the atomic object.
197  */
198 #define NRFX_ATOMIC_FETCH_XOR(p_data, value)  atomic_xor(p_data, value)
199 
200 /**
201  * @brief Macro for running an addition operation on an atomic object
202  *        and returning its previous value.
203  *
204  * @param[in] p_data Atomic memory pointer.
205  * @param[in] value  Value of the second operand in the ADD operation.
206  *
207  * @return Previous value of the atomic object.
208  */
209 #define NRFX_ATOMIC_FETCH_ADD(p_data, value)  atomic_add(p_data, value)
210 
211 /**
212  * @brief Macro for running a subtraction operation on an atomic object
213  *        and returning its previous value.
214  *
215  * @param[in] p_data Atomic memory pointer.
216  * @param[in] value  Value of the second operand in the SUB operation.
217  *
218  * @return Previous value of the atomic object.
219  */
220 #define NRFX_ATOMIC_FETCH_SUB(p_data, value)  atomic_sub(p_data, value)
221 
222 /**
223  * @brief Macro for running compare and swap on an atomic object.
224  *
225  * Value is updated to the new value only if it previously equaled old value.
226  *
227  * @param[in,out] p_data      Atomic memory pointer.
228  * @param[in]     old_value Expected old value.
229  * @param[in]     new_value   New value.
230  *
231  * @retval true If value was updated.
232  * @retval false If value was not updated because location was not equal to @p old_value.
233  */
234 #define NRFX_ATOMIC_CAS(p_data, old_value, new_value) \
235 	atomic_cas(p_data, old_value, new_value)
236 
237 /**
238  * @brief Macro for counting leading zeros.
239  *
240  * @param[in] value A word value.
241  *
242  * @return Number of leading 0-bits in @p value, starting at the most significant bit position.
243  *         If x is 0, the result is undefined.
244  */
245 #define NRFX_CLZ(value) __builtin_clz(value)
246 
247 /**
248  * @brief Macro for counting trailing zeros.
249  *
250  * @param[in] value A word value.
251  *
252  * @return Number of trailing 0-bits in @p value, starting at the least significant bit position.
253  *         If x is 0, the result is undefined.
254  */
255 #define NRFX_CTZ(value) __builtin_ctz(value)
256 
257 //------------------------------------------------------------------------------
258 
259 /**
260  * @brief When set to a non-zero value, this macro specifies that the
261  *        @ref nrfx_error_codes and the @ref nrfx_err_t type itself are defined
262  *        in a customized way and the default definitions from @c <nrfx_error.h>
263  *        should not be used.
264  */
265 #define NRFX_CUSTOM_ERROR_CODES 0
266 
267 //------------------------------------------------------------------------------
268 
269 /**
270  * @brief When set to a non-zero value, this macro specifies that inside HALs
271  *        the event registers are read back after clearing, on devices that
272  *        otherwise could defer the actual register modification.
273  */
274 #define NRFX_EVENT_READBACK_ENABLED 1
275 
276 //------------------------------------------------------------------------------
277 
278 /**
279  * @brief Macro for writing back cache lines associated with the specified buffer.
280  *
281  * @param[in] p_buffer Pointer to the buffer.
282  * @param[in] size     Size of the buffer.
283  */
284 #define NRFY_CACHE_WB(p_buffer, size) \
285 	do {                          \
286 		(void)p_buffer;       \
287 		(void)size;           \
288 	} while (0)
289 
290 /**
291  * @brief Macro for invalidating cache lines associated with the specified buffer.
292  *
293  * @param[in] p_buffer Pointer to the buffer.
294  * @param[in] size     Size of the buffer.
295  */
296 #define NRFY_CACHE_INV(p_buffer, size) \
297 	do {                           \
298 		(void)p_buffer;        \
299 		(void)size;            \
300 	} while (0)
301 
302 /**
303  * @brief Macro for writing back and invalidating cache lines associated with
304  *        the specified buffer.
305  *
306  * @param[in] p_buffer Pointer to the buffer.
307  * @param[in] size     Size of the buffer.
308  */
309 #define NRFY_CACHE_WBINV(p_buffer, size) \
310 	do {                             \
311 		(void)p_buffer;          \
312 		(void)size;              \
313 	} while (0)
314 
315 /*------------------------------------------------------------------------------*/
316 
317 #ifdef CONFIG_NRFX_RESERVED_RESOURCES_HEADER
318 #include CONFIG_NRFX_RESERVED_RESOURCES_HEADER
319 #endif
320 
321 //------------------------------------------------------------------------------
322 
323 /**
324  * @brief Function helping to integrate nrfx IRQ handlers with IRQ_CONNECT.
325  *
326  * This function simply calls the nrfx IRQ handler supplied as the parameter.
327  * It is intended to be used in the following way:
328  * IRQ_CONNECT(IRQ_NUM, IRQ_PRI, nrfx_isr, nrfx_..._irq_handler, 0);
329  *
330  * @param[in] irq_handler  Pointer to the nrfx IRQ handler to be called.
331  */
332 void nrfx_isr(const void *irq_handler);
333 
334 #if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
335 #include "nrfx_glue_bsim.h"
336 #endif
337 
338 /** @} */
339 
340 #ifdef __cplusplus
341 }
342 #endif
343 
344 #endif // NRFX_GLUE_H__
345