xref: /nrf52832-nimble/nordic/nrfx/drivers/nrfx_common.h (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
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