1*150812a8SEvalZero /*
2*150812a8SEvalZero * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
3*150812a8SEvalZero * All rights reserved.
4*150812a8SEvalZero *
5*150812a8SEvalZero * Redistribution and use in source and binary forms, with or without
6*150812a8SEvalZero * modification, are permitted provided that the following conditions are met:
7*150812a8SEvalZero *
8*150812a8SEvalZero * 1. Redistributions of source code must retain the above copyright notice, this
9*150812a8SEvalZero * list of conditions and the following disclaimer.
10*150812a8SEvalZero *
11*150812a8SEvalZero * 2. Redistributions in binary form must reproduce the above copyright
12*150812a8SEvalZero * notice, this list of conditions and the following disclaimer in the
13*150812a8SEvalZero * documentation and/or other materials provided with the distribution.
14*150812a8SEvalZero *
15*150812a8SEvalZero * 3. Neither the name of the copyright holder nor the names of its
16*150812a8SEvalZero * contributors may be used to endorse or promote products derived from this
17*150812a8SEvalZero * software without specific prior written permission.
18*150812a8SEvalZero *
19*150812a8SEvalZero * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*150812a8SEvalZero * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*150812a8SEvalZero * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*150812a8SEvalZero * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23*150812a8SEvalZero * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*150812a8SEvalZero * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*150812a8SEvalZero * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*150812a8SEvalZero * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*150812a8SEvalZero * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*150812a8SEvalZero * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*150812a8SEvalZero * POSSIBILITY OF SUCH DAMAGE.
30*150812a8SEvalZero */
31*150812a8SEvalZero
32*150812a8SEvalZero #ifndef NRFX_COMMON_H__
33*150812a8SEvalZero #define NRFX_COMMON_H__
34*150812a8SEvalZero
35*150812a8SEvalZero #include <stdint.h>
36*150812a8SEvalZero #include <stddef.h>
37*150812a8SEvalZero #include <stdbool.h>
38*150812a8SEvalZero
39*150812a8SEvalZero #include <nrf.h>
40*150812a8SEvalZero #include <nrf_peripherals.h>
41*150812a8SEvalZero
42*150812a8SEvalZero #ifdef __cplusplus
43*150812a8SEvalZero extern "C" {
44*150812a8SEvalZero #endif
45*150812a8SEvalZero
46*150812a8SEvalZero /**
47*150812a8SEvalZero * @defgroup nrfx_common Common module
48*150812a8SEvalZero * @{
49*150812a8SEvalZero * @ingroup nrfx
50*150812a8SEvalZero * @brief Common module.
51*150812a8SEvalZero */
52*150812a8SEvalZero
53*150812a8SEvalZero /**
54*150812a8SEvalZero * @brief Macro for checking if the specified identifier is defined and it has
55*150812a8SEvalZero * a non-zero value.
56*150812a8SEvalZero *
57*150812a8SEvalZero * Normally, preprocessors treat all undefined identifiers as having the value
58*150812a8SEvalZero * zero. However, some tools, like static code analyzers, may issue a warning
59*150812a8SEvalZero * when such identifier is evaluated. This macro gives the possibility to suppress
60*150812a8SEvalZero * such warnings only in places where this macro is used for evaluation, not in
61*150812a8SEvalZero * the whole analyzed code.
62*150812a8SEvalZero */
63*150812a8SEvalZero #define NRFX_CHECK(module_enabled) (module_enabled)
64*150812a8SEvalZero
65*150812a8SEvalZero /**
66*150812a8SEvalZero * @brief Macro for concatenating two tokens in macro expansion.
67*150812a8SEvalZero *
68*150812a8SEvalZero * @note This macro is expanded in two steps so that tokens given as macros
69*150812a8SEvalZero * themselves are fully expanded before they are merged.
70*150812a8SEvalZero *
71*150812a8SEvalZero * @param p1 First token.
72*150812a8SEvalZero * @param p2 Second token.
73*150812a8SEvalZero *
74*150812a8SEvalZero * @return The two tokens merged into one, unless they cannot together form
75*150812a8SEvalZero * a valid token (in such case, the preprocessor issues a warning and
76*150812a8SEvalZero * does not perform the concatenation).
77*150812a8SEvalZero *
78*150812a8SEvalZero * @sa NRFX_CONCAT_3
79*150812a8SEvalZero */
80*150812a8SEvalZero #define NRFX_CONCAT_2(p1, p2) NRFX_CONCAT_2_(p1, p2)
81*150812a8SEvalZero /**
82*150812a8SEvalZero * @brief Internal macro used by @ref NRFX_CONCAT_2 to perform the expansion
83*150812a8SEvalZero * in two steps.
84*150812a8SEvalZero */
85*150812a8SEvalZero #define NRFX_CONCAT_2_(p1, p2) p1 ## p2
86*150812a8SEvalZero
87*150812a8SEvalZero /**
88*150812a8SEvalZero * @brief Macro for concatenating three tokens in macro expansion.
89*150812a8SEvalZero *
90*150812a8SEvalZero * @note This macro is expanded in two steps so that tokens given as macros
91*150812a8SEvalZero * themselves are fully expanded before they are merged.
92*150812a8SEvalZero *
93*150812a8SEvalZero * @param p1 First token.
94*150812a8SEvalZero * @param p2 Second token.
95*150812a8SEvalZero * @param p3 Third token.
96*150812a8SEvalZero *
97*150812a8SEvalZero * @return The three tokens merged into one, unless they cannot together form
98*150812a8SEvalZero * a valid token (in such case, the preprocessor issues a warning and
99*150812a8SEvalZero * does not perform the concatenation).
100*150812a8SEvalZero *
101*150812a8SEvalZero * @sa NRFX_CONCAT_2
102*150812a8SEvalZero */
103*150812a8SEvalZero #define NRFX_CONCAT_3(p1, p2, p3) NRFX_CONCAT_3_(p1, p2, p3)
104*150812a8SEvalZero /**
105*150812a8SEvalZero * @brief Internal macro used by @ref NRFX_CONCAT_3 to perform the expansion
106*150812a8SEvalZero * in two steps.
107*150812a8SEvalZero */
108*150812a8SEvalZero #define NRFX_CONCAT_3_(p1, p2, p3) p1 ## p2 ## p3
109*150812a8SEvalZero
110*150812a8SEvalZero /**@brief Macro for performing rounded integer division (as opposed to
111*150812a8SEvalZero * truncating the result).
112*150812a8SEvalZero *
113*150812a8SEvalZero * @param a Numerator.
114*150812a8SEvalZero * @param b Denominator.
115*150812a8SEvalZero *
116*150812a8SEvalZero * @return Rounded (integer) result of dividing @c a by @c b.
117*150812a8SEvalZero */
118*150812a8SEvalZero #define NRFX_ROUNDED_DIV(a, b) (((a) + ((b) / 2)) / (b))
119*150812a8SEvalZero
120*150812a8SEvalZero /**@brief Macro for performing integer division, making sure the result is rounded up.
121*150812a8SEvalZero *
122*150812a8SEvalZero * @details A typical use case for this macro is to compute the number of objects
123*150812a8SEvalZero * with size @c b required to hold @c a number of bytes.
124*150812a8SEvalZero *
125*150812a8SEvalZero * @param a Numerator.
126*150812a8SEvalZero * @param b Denominator.
127*150812a8SEvalZero *
128*150812a8SEvalZero * @return Integer result of dividing @c a by @c b, rounded up.
129*150812a8SEvalZero */
130*150812a8SEvalZero #define NRFX_CEIL_DIV(a, b) ((((a) - 1) / (b)) + 1)
131*150812a8SEvalZero
132*150812a8SEvalZero /**
133*150812a8SEvalZero * @brief Macro for getting the number of elements in an array.
134*150812a8SEvalZero *
135*150812a8SEvalZero * @param array Name of the array.
136*150812a8SEvalZero *
137*150812a8SEvalZero * @return Array element count.
138*150812a8SEvalZero */
139*150812a8SEvalZero #define NRFX_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
140*150812a8SEvalZero
141*150812a8SEvalZero /**@brief Macro for checking if given lengths of EasyDMA transfers do not exceed
142*150812a8SEvalZero * the limit of the specified peripheral.
143*150812a8SEvalZero *
144*150812a8SEvalZero * @param peripheral Peripheral to check the lengths against.
145*150812a8SEvalZero * @param length1 First length to be checked.
146*150812a8SEvalZero * @param length2 Second length to be checked (pass 0 if not needed).
147*150812a8SEvalZero *
148*150812a8SEvalZero * @return
149*150812a8SEvalZero */
150*150812a8SEvalZero #define NRFX_EASYDMA_LENGTH_VALIDATE(peripheral, length1, length2) \
151*150812a8SEvalZero (((length1) < (1U << NRFX_CONCAT_2(peripheral, _EASYDMA_MAXCNT_SIZE))) && \
152*150812a8SEvalZero ((length2) < (1U << NRFX_CONCAT_2(peripheral, _EASYDMA_MAXCNT_SIZE))))
153*150812a8SEvalZero
154*150812a8SEvalZero /**@brief Macro for waiting until condition is met.
155*150812a8SEvalZero *
156*150812a8SEvalZero * @param[in] condition Condition to meet.
157*150812a8SEvalZero * @param[in] attempts Maximum number of condition checks. Must not be 0.
158*150812a8SEvalZero * @param[in] delay_us Delay between consecutive checks, in microseconds.
159*150812a8SEvalZero * @param[out] result Boolean variable to store the result of the wait process.
160*150812a8SEvalZero * Set to true if the condition is met or false otherwise.
161*150812a8SEvalZero */
162*150812a8SEvalZero #define NRFX_WAIT_FOR(condition, attempts, delay_us, result) \
163*150812a8SEvalZero do { \
164*150812a8SEvalZero result = false; \
165*150812a8SEvalZero uint32_t remaining_attempts = (attempts); \
166*150812a8SEvalZero do { \
167*150812a8SEvalZero if (condition) \
168*150812a8SEvalZero { \
169*150812a8SEvalZero result = true; \
170*150812a8SEvalZero break; \
171*150812a8SEvalZero } \
172*150812a8SEvalZero NRFX_DELAY_US(delay_us); \
173*150812a8SEvalZero } while (--remaining_attempts); \
174*150812a8SEvalZero } while(0)
175*150812a8SEvalZero
176*150812a8SEvalZero /**
177*150812a8SEvalZero * @brief Macro for getting the interrupt number assigned to a specific
178*150812a8SEvalZero * peripheral.
179*150812a8SEvalZero *
180*150812a8SEvalZero * In Nordic SoCs the IRQ number assigned to a peripheral is equal to the ID
181*150812a8SEvalZero * of this peripheral, and there is a direct relationship between this ID and
182*150812a8SEvalZero * the peripheral base address, i.e. the address of a fixed block of 0x1000
183*150812a8SEvalZero * bytes of address space assigned to this peripheral.
184*150812a8SEvalZero * See the chapter "Peripheral interface" (sections "Peripheral ID" and
185*150812a8SEvalZero * "Interrupts") in the product specification of a given SoC.
186*150812a8SEvalZero *
187*150812a8SEvalZero * @param[in] base_addr Peripheral base address or pointer.
188*150812a8SEvalZero *
189*150812a8SEvalZero * @return Interrupt number associated with the specified peripheral.
190*150812a8SEvalZero */
191*150812a8SEvalZero #define NRFX_IRQ_NUMBER_GET(base_addr) (uint8_t)((uint32_t)(base_addr) >> 12)
192*150812a8SEvalZero
193*150812a8SEvalZero /**
194*150812a8SEvalZero * @brief IRQ handler type.
195*150812a8SEvalZero */
196*150812a8SEvalZero typedef void (* nrfx_irq_handler_t)(void);
197*150812a8SEvalZero
198*150812a8SEvalZero /**
199*150812a8SEvalZero * @brief Driver state.
200*150812a8SEvalZero */
201*150812a8SEvalZero typedef enum
202*150812a8SEvalZero {
203*150812a8SEvalZero NRFX_DRV_STATE_UNINITIALIZED, ///< Uninitialized.
204*150812a8SEvalZero NRFX_DRV_STATE_INITIALIZED, ///< Initialized but powered off.
205*150812a8SEvalZero NRFX_DRV_STATE_POWERED_ON, ///< Initialized and powered on.
206*150812a8SEvalZero } nrfx_drv_state_t;
207*150812a8SEvalZero
208*150812a8SEvalZero
209*150812a8SEvalZero /**
210*150812a8SEvalZero * @brief Function for checking if an object is placed in the Data RAM region.
211*150812a8SEvalZero *
212*150812a8SEvalZero * Several peripherals (the ones using EasyDMA) require the transfer buffers
213*150812a8SEvalZero * to be placed in the Data RAM region. This function can be used to check if
214*150812a8SEvalZero * this condition is met.
215*150812a8SEvalZero *
216*150812a8SEvalZero * @param[in] p_object Pointer to an object whose location is to be checked.
217*150812a8SEvalZero *
218*150812a8SEvalZero * @retval true If the pointed object is located in the Data RAM region.
219*150812a8SEvalZero * @retval false Otherwise.
220*150812a8SEvalZero */
221*150812a8SEvalZero __STATIC_INLINE bool nrfx_is_in_ram(void const * p_object);
222*150812a8SEvalZero
223*150812a8SEvalZero
224*150812a8SEvalZero /**
225*150812a8SEvalZero * @brief Function for checking if an object is aligned to a 32-bit word
226*150812a8SEvalZero *
227*150812a8SEvalZero * Several peripherals (the ones using EasyDMA) require the transfer buffers
228*150812a8SEvalZero * to be aligned to a 32-bit word. This function can be used to check if
229*150812a8SEvalZero * this condition is met.
230*150812a8SEvalZero *
231*150812a8SEvalZero * @param[in] p_object Pointer to an object whose location is to be checked.
232*150812a8SEvalZero *
233*150812a8SEvalZero * @retval true if the pointed object is aligned to a 32-bit word.
234*150812a8SEvalZero * @retval false otherwise.
235*150812a8SEvalZero */
236*150812a8SEvalZero __STATIC_INLINE bool nrfx_is_word_aligned(void const * p_object);
237*150812a8SEvalZero
238*150812a8SEvalZero
239*150812a8SEvalZero /**
240*150812a8SEvalZero * @brief Function for getting the interrupt number for a specific peripheral.
241*150812a8SEvalZero *
242*150812a8SEvalZero * @param[in] p_reg Peripheral base pointer.
243*150812a8SEvalZero *
244*150812a8SEvalZero * @return Interrupt number associated with the pointed peripheral.
245*150812a8SEvalZero */
246*150812a8SEvalZero __STATIC_INLINE IRQn_Type nrfx_get_irq_number(void const * p_reg);
247*150812a8SEvalZero
248*150812a8SEvalZero /**
249*150812a8SEvalZero * @brief Function for converting an INTEN register bit position to the
250*150812a8SEvalZero * corresponding event identifier.
251*150812a8SEvalZero *
252*150812a8SEvalZero * The event identifier is the offset between the event register address and
253*150812a8SEvalZero * the peripheral base address, and is equal (thus, can be directly cast) to
254*150812a8SEvalZero * the corresponding value of the enumerated type from HAL (nrf_*_event_t).
255*150812a8SEvalZero
256*150812a8SEvalZero * @param bit INTEN register bit position.
257*150812a8SEvalZero *
258*150812a8SEvalZero * @return Event identifier.
259*150812a8SEvalZero *
260*150812a8SEvalZero * @sa nrfx_event_to_bitpos
261*150812a8SEvalZero */
262*150812a8SEvalZero __STATIC_INLINE uint32_t nrfx_bitpos_to_event(uint32_t bit);
263*150812a8SEvalZero
264*150812a8SEvalZero /**
265*150812a8SEvalZero * @brief Function for converting an event identifier to the corresponding
266*150812a8SEvalZero * INTEN register bit position.
267*150812a8SEvalZero *
268*150812a8SEvalZero * The event identifier is the offset between the event register address and
269*150812a8SEvalZero * the peripheral base address, and is equal (thus, can be directly cast) to
270*150812a8SEvalZero * the corresponding value of the enumerated type from HAL (nrf_*_event_t).
271*150812a8SEvalZero *
272*150812a8SEvalZero * @param event Event identifier.
273*150812a8SEvalZero *
274*150812a8SEvalZero * @return INTEN register bit position.
275*150812a8SEvalZero *
276*150812a8SEvalZero * @sa nrfx_bitpos_to_event
277*150812a8SEvalZero */
278*150812a8SEvalZero __STATIC_INLINE uint32_t nrfx_event_to_bitpos(uint32_t event);
279*150812a8SEvalZero
280*150812a8SEvalZero
281*150812a8SEvalZero #ifndef SUPPRESS_INLINE_IMPLEMENTATION
282*150812a8SEvalZero
nrfx_is_in_ram(void const * p_object)283*150812a8SEvalZero __STATIC_INLINE bool nrfx_is_in_ram(void const * p_object)
284*150812a8SEvalZero {
285*150812a8SEvalZero return ((((uint32_t)p_object) & 0xE0000000u) == 0x20000000u);
286*150812a8SEvalZero }
287*150812a8SEvalZero
nrfx_is_word_aligned(void const * p_object)288*150812a8SEvalZero __STATIC_INLINE bool nrfx_is_word_aligned(void const * p_object)
289*150812a8SEvalZero {
290*150812a8SEvalZero return ((((uint32_t)p_object) & 0x3u) == 0u);
291*150812a8SEvalZero }
292*150812a8SEvalZero
nrfx_get_irq_number(void const * p_reg)293*150812a8SEvalZero __STATIC_INLINE IRQn_Type nrfx_get_irq_number(void const * p_reg)
294*150812a8SEvalZero {
295*150812a8SEvalZero return (IRQn_Type)NRFX_IRQ_NUMBER_GET(p_reg);
296*150812a8SEvalZero }
297*150812a8SEvalZero
nrfx_bitpos_to_event(uint32_t bit)298*150812a8SEvalZero __STATIC_INLINE uint32_t nrfx_bitpos_to_event(uint32_t bit)
299*150812a8SEvalZero {
300*150812a8SEvalZero static const uint32_t event_reg_offset = 0x100u;
301*150812a8SEvalZero return event_reg_offset + (bit * sizeof(uint32_t));
302*150812a8SEvalZero }
303*150812a8SEvalZero
nrfx_event_to_bitpos(uint32_t event)304*150812a8SEvalZero __STATIC_INLINE uint32_t nrfx_event_to_bitpos(uint32_t event)
305*150812a8SEvalZero {
306*150812a8SEvalZero static const uint32_t event_reg_offset = 0x100u;
307*150812a8SEvalZero return (event - event_reg_offset) / sizeof(uint32_t);
308*150812a8SEvalZero }
309*150812a8SEvalZero
310*150812a8SEvalZero #endif
311*150812a8SEvalZero
312*150812a8SEvalZero /** @} */
313*150812a8SEvalZero
314*150812a8SEvalZero #ifdef __cplusplus
315*150812a8SEvalZero }
316*150812a8SEvalZero #endif
317*150812a8SEvalZero
318*150812a8SEvalZero #endif // NRFX_COMMON_H__
319