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