1*150812a8SEvalZero /* 2*150812a8SEvalZero * Copyright (c) 2016 - 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_ATOMIC_H__ 33*150812a8SEvalZero #define NRFX_ATOMIC_H__ 34*150812a8SEvalZero 35*150812a8SEvalZero #include <nrfx.h> 36*150812a8SEvalZero 37*150812a8SEvalZero #ifdef __cplusplus 38*150812a8SEvalZero extern "C" { 39*150812a8SEvalZero #endif 40*150812a8SEvalZero 41*150812a8SEvalZero /** 42*150812a8SEvalZero * @defgroup nrfx_atomic Atomic operations API 43*150812a8SEvalZero * @ingroup nrfx 44*150812a8SEvalZero * @{ 45*150812a8SEvalZero * 46*150812a8SEvalZero * @brief This module implements C11 stdatomic.h simplified API. 47*150812a8SEvalZero * 48*150812a8SEvalZero * At this point, only Cortex-M3 and M4 cores are supported (LDREX/STREX instructions). 49*150812a8SEvalZero * Atomic types are limited to @ref nrfx_atomic_u32_t and @ref nrfx_atomic_flag_t. 50*150812a8SEvalZero */ 51*150812a8SEvalZero 52*150812a8SEvalZero 53*150812a8SEvalZero /** 54*150812a8SEvalZero * @brief Atomic 32-bit unsigned type. 55*150812a8SEvalZero */ 56*150812a8SEvalZero typedef volatile uint32_t nrfx_atomic_u32_t; 57*150812a8SEvalZero 58*150812a8SEvalZero /** 59*150812a8SEvalZero * @brief Atomic 1-bit flag type (technically 32-bit). 60*150812a8SEvalZero */ 61*150812a8SEvalZero typedef volatile uint32_t nrfx_atomic_flag_t; 62*150812a8SEvalZero 63*150812a8SEvalZero /** 64*150812a8SEvalZero * @brief Function for storing a value to an atomic object and returning its previous value. 65*150812a8SEvalZero * 66*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 67*150812a8SEvalZero * @param[in] value Value to store. 68*150812a8SEvalZero * 69*150812a8SEvalZero * @return Previous value stored in the atomic object. 70*150812a8SEvalZero */ 71*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_store(nrfx_atomic_u32_t * p_data, uint32_t value); 72*150812a8SEvalZero 73*150812a8SEvalZero /** 74*150812a8SEvalZero * @brief Function for storing a value to an atomic object and returning its new value. 75*150812a8SEvalZero * 76*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 77*150812a8SEvalZero * @param[in] value Value to store. 78*150812a8SEvalZero * 79*150812a8SEvalZero * @return New value stored in the atomic object. 80*150812a8SEvalZero */ 81*150812a8SEvalZero uint32_t nrfx_atomic_u32_store(nrfx_atomic_u32_t * p_data, uint32_t value); 82*150812a8SEvalZero 83*150812a8SEvalZero /** 84*150812a8SEvalZero * @brief Function for running a logical OR operation on an atomic object 85*150812a8SEvalZero * and returning its previous value. 86*150812a8SEvalZero * 87*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 88*150812a8SEvalZero * @param[in] value Value of the second operand in the OR operation. 89*150812a8SEvalZero * 90*150812a8SEvalZero * @return Previous value stored in the atomic object. 91*150812a8SEvalZero */ 92*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_or(nrfx_atomic_u32_t * p_data, uint32_t value); 93*150812a8SEvalZero 94*150812a8SEvalZero /** 95*150812a8SEvalZero * @brief Function for running a logical OR operation on an atomic object 96*150812a8SEvalZero * and returning its new value. 97*150812a8SEvalZero * 98*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 99*150812a8SEvalZero * @param[in] value Value of the second operand in the OR operation. 100*150812a8SEvalZero * 101*150812a8SEvalZero * @return New value stored in the atomic object. 102*150812a8SEvalZero */ 103*150812a8SEvalZero uint32_t nrfx_atomic_u32_or(nrfx_atomic_u32_t * p_data, uint32_t value); 104*150812a8SEvalZero 105*150812a8SEvalZero /** 106*150812a8SEvalZero * @brief Function for running a logical AND operation on an atomic object 107*150812a8SEvalZero * and returning its previous value. 108*150812a8SEvalZero * 109*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 110*150812a8SEvalZero * @param[in] value Value of the second operand in the AND operation. 111*150812a8SEvalZero * 112*150812a8SEvalZero * @return Previous value stored in the atomic object. 113*150812a8SEvalZero */ 114*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_and(nrfx_atomic_u32_t * p_data, uint32_t value); 115*150812a8SEvalZero 116*150812a8SEvalZero /** 117*150812a8SEvalZero * @brief Function for running a logical AND operation on an atomic object 118*150812a8SEvalZero * and returning its new value. 119*150812a8SEvalZero * 120*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 121*150812a8SEvalZero * @param[in] value Value of the second operand in the AND operation. 122*150812a8SEvalZero * 123*150812a8SEvalZero * @return New value stored in the atomic object. 124*150812a8SEvalZero */ 125*150812a8SEvalZero uint32_t nrfx_atomic_u32_and(nrfx_atomic_u32_t * p_data, uint32_t value); 126*150812a8SEvalZero 127*150812a8SEvalZero /** 128*150812a8SEvalZero * @brief Function for running a logical XOR operation on an atomic object 129*150812a8SEvalZero * and returning its previous value. 130*150812a8SEvalZero * 131*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 132*150812a8SEvalZero * @param[in] value Value of the second operand in the XOR operation. 133*150812a8SEvalZero * 134*150812a8SEvalZero * @return Previous value stored in the atomic object. 135*150812a8SEvalZero */ 136*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_xor(nrfx_atomic_u32_t * p_data, uint32_t value); 137*150812a8SEvalZero 138*150812a8SEvalZero /** 139*150812a8SEvalZero * @brief Function for running a logical XOR operation on an atomic object 140*150812a8SEvalZero * and returning its new value. 141*150812a8SEvalZero * 142*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 143*150812a8SEvalZero * @param[in] value Value of the second operand in the XOR operation. 144*150812a8SEvalZero * 145*150812a8SEvalZero * @return New value stored in the atomic object. 146*150812a8SEvalZero */ 147*150812a8SEvalZero uint32_t nrfx_atomic_u32_xor(nrfx_atomic_u32_t * p_data, uint32_t value); 148*150812a8SEvalZero 149*150812a8SEvalZero /** 150*150812a8SEvalZero * @brief Function for running an arithmetic ADD operation on an atomic object 151*150812a8SEvalZero * and returning its previous value. 152*150812a8SEvalZero * 153*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 154*150812a8SEvalZero * @param[in] value Value of the second operand in the ADD operation. 155*150812a8SEvalZero * 156*150812a8SEvalZero * @return Previous value stored in the atomic object. 157*150812a8SEvalZero */ 158*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_add(nrfx_atomic_u32_t * p_data, uint32_t value); 159*150812a8SEvalZero 160*150812a8SEvalZero /** 161*150812a8SEvalZero * @brief Function for running an arithmetic ADD operation on an atomic object 162*150812a8SEvalZero * and returning its new value. 163*150812a8SEvalZero * 164*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 165*150812a8SEvalZero * @param[in] value Value of the second operand in the ADD operation. 166*150812a8SEvalZero * 167*150812a8SEvalZero * @return New value stored in the atomic object. 168*150812a8SEvalZero */ 169*150812a8SEvalZero uint32_t nrfx_atomic_u32_add(nrfx_atomic_u32_t * p_data, uint32_t value); 170*150812a8SEvalZero 171*150812a8SEvalZero /** 172*150812a8SEvalZero * @brief Function for running an arithmetic SUB operation on an atomic object 173*150812a8SEvalZero * and returning its previous value. 174*150812a8SEvalZero * 175*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 176*150812a8SEvalZero * @param[in] value Value of the second operand in the SUB operation. 177*150812a8SEvalZero * 178*150812a8SEvalZero * @return Old value stored in the atomic object. 179*150812a8SEvalZero */ 180*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_sub(nrfx_atomic_u32_t * p_data, uint32_t value); 181*150812a8SEvalZero 182*150812a8SEvalZero /** 183*150812a8SEvalZero * @brief Function for running an arithmetic SUB operation on an atomic object 184*150812a8SEvalZero * and returning its new value. 185*150812a8SEvalZero * 186*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 187*150812a8SEvalZero * @param[in] value Value of the second operand in the SUB operation. 188*150812a8SEvalZero * 189*150812a8SEvalZero * @return New value stored in the atomic object. 190*150812a8SEvalZero */ 191*150812a8SEvalZero uint32_t nrfx_atomic_u32_sub(nrfx_atomic_u32_t * p_data, uint32_t value); 192*150812a8SEvalZero 193*150812a8SEvalZero /** 194*150812a8SEvalZero * @brief Function for atomic conditional value replacement. 195*150812a8SEvalZero * 196*150812a8SEvalZero * Atomically compares the value pointed to by @p p_data with the value pointed to by @p p_expected. 197*150812a8SEvalZero * If those are equal, replaces the former with desired. Otherwise, loads the actual value 198*150812a8SEvalZero * pointed to by @p p_data into @p *p_expected. 199*150812a8SEvalZero * 200*150812a8SEvalZero * @param p_data Atomic memory pointer to test and modify. 201*150812a8SEvalZero * @param p_expected Pointer to the test value. 202*150812a8SEvalZero * @param desired Value to be stored to atomic memory. 203*150812a8SEvalZero * 204*150812a8SEvalZero * @retval true @p *p_data was equal to @p *p_expected. 205*150812a8SEvalZero * @retval false @p *p_data was not equal to @p *p_expected. 206*150812a8SEvalZero */ 207*150812a8SEvalZero bool nrfx_atomic_u32_cmp_exch(nrfx_atomic_u32_t * p_data, 208*150812a8SEvalZero uint32_t * p_expected, 209*150812a8SEvalZero uint32_t desired); 210*150812a8SEvalZero 211*150812a8SEvalZero /** 212*150812a8SEvalZero * @brief Function for running an arithmetic SUB operation on an atomic object 213*150812a8SEvalZero * if object >= value, and returning its previous value. 214*150812a8SEvalZero * 215*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 216*150812a8SEvalZero * @param[in] value Value of the second operand in the SUB operation. 217*150812a8SEvalZero * 218*150812a8SEvalZero * @return Previous value stored in the atomic object. 219*150812a8SEvalZero */ 220*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_sub_hs(nrfx_atomic_u32_t * p_data, uint32_t value); 221*150812a8SEvalZero 222*150812a8SEvalZero /** 223*150812a8SEvalZero * @brief Function for running an arithmetic SUB operation on an atomic object 224*150812a8SEvalZero * if object >= value, and returning its new value. 225*150812a8SEvalZero * 226*150812a8SEvalZero * @param[in] p_data Atomic memory pointer. 227*150812a8SEvalZero * @param[in] value Value of the second operand in the SUB operation. 228*150812a8SEvalZero * 229*150812a8SEvalZero * @return New value stored in the atomic object. 230*150812a8SEvalZero */ 231*150812a8SEvalZero uint32_t nrfx_atomic_u32_sub_hs(nrfx_atomic_u32_t * p_data, uint32_t value); 232*150812a8SEvalZero 233*150812a8SEvalZero /** 234*150812a8SEvalZero * @brief Function for running a logical one bit flag set operation 235*150812a8SEvalZero * on an atomic object and returning its previous value. 236*150812a8SEvalZero * 237*150812a8SEvalZero * @param[in] p_data Atomic flag memory pointer. 238*150812a8SEvalZero * 239*150812a8SEvalZero * @return Previous flag value. 240*150812a8SEvalZero */ 241*150812a8SEvalZero uint32_t nrfx_atomic_flag_set_fetch(nrfx_atomic_flag_t * p_data); 242*150812a8SEvalZero 243*150812a8SEvalZero /** 244*150812a8SEvalZero * @brief Function for running a logical one bit flag set operation 245*150812a8SEvalZero * on an atomic object and returning its new value. 246*150812a8SEvalZero * 247*150812a8SEvalZero * @param[in] p_data Atomic flag memory pointer. 248*150812a8SEvalZero * 249*150812a8SEvalZero * @return New flag value. 250*150812a8SEvalZero */ 251*150812a8SEvalZero uint32_t nrfx_atomic_flag_set(nrfx_atomic_flag_t * p_data); 252*150812a8SEvalZero 253*150812a8SEvalZero /** 254*150812a8SEvalZero * @brief Function for running a logical one bit flag clear operation 255*150812a8SEvalZero * on an atomic object and returning its previous value. 256*150812a8SEvalZero * 257*150812a8SEvalZero * @param[in] p_data Atomic flag memory pointer. 258*150812a8SEvalZero * 259*150812a8SEvalZero * @return Previous flag value. 260*150812a8SEvalZero */ 261*150812a8SEvalZero uint32_t nrfx_atomic_flag_clear_fetch(nrfx_atomic_flag_t * p_data); 262*150812a8SEvalZero 263*150812a8SEvalZero /** 264*150812a8SEvalZero * @brief Function for running a logical one bit flag clear operation 265*150812a8SEvalZero * on an atomic object and returning its new value. 266*150812a8SEvalZero * 267*150812a8SEvalZero * @param[in] p_data Atomic flag memory pointer. 268*150812a8SEvalZero * 269*150812a8SEvalZero * @return New flag value. 270*150812a8SEvalZero */ 271*150812a8SEvalZero uint32_t nrfx_atomic_flag_clear(nrfx_atomic_flag_t * p_data); 272*150812a8SEvalZero 273*150812a8SEvalZero /** @} */ 274*150812a8SEvalZero 275*150812a8SEvalZero #ifdef __cplusplus 276*150812a8SEvalZero } 277*150812a8SEvalZero #endif 278*150812a8SEvalZero 279*150812a8SEvalZero #endif // NRFX_ATOMIC_H__ 280