1 /***************************************************************************//** 2 * @file 3 * @brief Core interrupt handling API (Generic) 4 ******************************************************************************* 5 * # License 6 * <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b> 7 ******************************************************************************* 8 * 9 * SPDX-License-Identifier: Zlib 10 * 11 * The licensor of this software is Silicon Laboratories Inc. 12 * 13 * This software is provided 'as-is', without any express or implied 14 * warranty. In no event will the authors be held liable for any damages 15 * arising from the use of this software. 16 * 17 * Permission is granted to anyone to use this software for any purpose, 18 * including commercial applications, and to alter it and redistribute it 19 * freely, subject to the following restrictions: 20 * 21 * 1. The origin of this software must not be misrepresented; you must not 22 * claim that you wrote the original software. If you use this software 23 * in a product, an acknowledgment in the product documentation would be 24 * appreciated but is not required. 25 * 2. Altered source versions must be plainly marked as such, and must not be 26 * misrepresented as being the original software. 27 * 3. This notice may not be removed or altered from any source distribution. 28 * 29 ******************************************************************************/ 30 31 #ifndef EM_CORE_GENERIC_H 32 #define EM_CORE_GENERIC_H 33 34 #include <stdbool.h> 35 #include <stdint.h> 36 37 /***************************************************************************//** 38 * @addtogroup core 39 * @{ 40 ******************************************************************************/ 41 42 /******************************************************************************* 43 ******************************* DEFINES *********************************** 44 ******************************************************************************/ 45 46 /** Use PRIMASK register to disable interrupts in ATOMIC sections. */ 47 #define CORE_ATOMIC_METHOD_PRIMASK 0 48 49 /** Use BASEPRI register to disable interrupts in ATOMIC sections. */ 50 #define CORE_ATOMIC_METHOD_BASEPRI 1 51 52 #if !defined(CORE_ATOMIC_BASE_PRIORITY_LEVEL) 53 /** The interrupt priority level disabled within ATOMIC regions. Interrupts 54 * with priority level equal to or lower than this definition will be disabled 55 * within ATOMIC regions. */ 56 #define CORE_ATOMIC_BASE_PRIORITY_LEVEL 3 57 #endif 58 59 #ifdef __cplusplus 60 extern "C" { 61 #endif 62 63 /******************************************************************************* 64 ************************ MACRO API *************************************** 65 ******************************************************************************/ 66 67 // 68 // CRITICAL section macro API. 69 // 70 71 /** Allocate storage for PRIMASK or BASEPRI value for use by 72 * CORE_ENTER/EXIT_ATOMIC() and CORE_ENTER/EXIT_CRITICAL() macros. */ 73 #define CORE_DECLARE_IRQ_STATE CORE_irqState_t irqState 74 75 /** CRITICAL style interrupt disable. */ 76 #define CORE_CRITICAL_IRQ_DISABLE() CORE_CriticalDisableIrq() 77 78 /** CRITICAL style interrupt enable. */ 79 #define CORE_CRITICAL_IRQ_ENABLE() CORE_CriticalEnableIrq() 80 81 /** Convenience macro for implementing a CRITICAL section. */ 82 #define CORE_CRITICAL_SECTION(yourcode) \ 83 { \ 84 CORE_DECLARE_IRQ_STATE; \ 85 CORE_ENTER_CRITICAL(); \ 86 { \ 87 yourcode \ 88 } \ 89 CORE_EXIT_CRITICAL(); \ 90 } 91 92 /** Enter CRITICAL section. Assumes that a @ref CORE_DECLARE_IRQ_STATE exist in 93 * scope. */ 94 #define CORE_ENTER_CRITICAL() irqState = CORE_EnterCritical() 95 96 /** Exit CRITICAL section. Assumes that a @ref CORE_DECLARE_IRQ_STATE exist in 97 * scope. */ 98 #define CORE_EXIT_CRITICAL() CORE_ExitCritical(irqState) 99 100 /** CRITICAL style yield. */ 101 #define CORE_YIELD_CRITICAL() CORE_YieldCritical() 102 103 // 104 // ATOMIC section macro API. 105 // 106 107 /** ATOMIC style interrupt disable. */ 108 #define CORE_ATOMIC_IRQ_DISABLE() CORE_AtomicDisableIrq() 109 110 /** ATOMIC style interrupt enable. */ 111 #define CORE_ATOMIC_IRQ_ENABLE() CORE_AtomicEnableIrq() 112 113 /** Convenience macro for implementing an ATOMIC section. */ 114 #define CORE_ATOMIC_SECTION(yourcode) \ 115 { \ 116 CORE_DECLARE_IRQ_STATE; \ 117 CORE_ENTER_ATOMIC(); \ 118 { \ 119 yourcode \ 120 } \ 121 CORE_EXIT_ATOMIC(); \ 122 } 123 124 /** Enter ATOMIC section. Assumes that a @ref CORE_DECLARE_IRQ_STATE exist in 125 * scope. */ 126 #define CORE_ENTER_ATOMIC() irqState = CORE_EnterAtomic() 127 128 /** Exit ATOMIC section. Assumes that a @ref CORE_DECLARE_IRQ_STATE exist in 129 * scope. */ 130 #define CORE_EXIT_ATOMIC() CORE_ExitAtomic(irqState) 131 132 /** ATOMIC style yield. */ 133 #define CORE_YIELD_ATOMIC() CORE_YieldAtomic() 134 135 /** Check if IRQ is disabled. */ 136 #define CORE_IRQ_DISABLED() CORE_IrqIsDisabled() 137 138 /** Check if inside an IRQ handler. */ 139 #define CORE_IN_IRQ_CONTEXT() CORE_InIrqContext() 140 141 /******************************************************************************* 142 ************************* TYPEDEFS **************************************** 143 ******************************************************************************/ 144 145 /** Storage for PRIMASK or BASEPRI value. */ 146 typedef uint32_t CORE_irqState_t; 147 148 /******************************************************************************* 149 ***************************** PROTOTYPES ********************************** 150 ******************************************************************************/ 151 152 void CORE_CriticalDisableIrq(void); 153 void CORE_CriticalEnableIrq(void); 154 void CORE_ExitCritical(CORE_irqState_t irqState); 155 void CORE_YieldCritical(void); 156 CORE_irqState_t CORE_EnterCritical(void); 157 158 void CORE_AtomicDisableIrq(void); 159 void CORE_AtomicEnableIrq(void); 160 void CORE_ExitAtomic(CORE_irqState_t irqState); 161 void CORE_YieldAtomic(void); 162 CORE_irqState_t CORE_EnterAtomic(void); 163 164 bool CORE_InIrqContext(void); 165 bool CORE_IrqIsDisabled(void); 166 167 #ifdef __cplusplus 168 } 169 #endif 170 171 /** @} (end addtogroup core) */ 172 173 #endif /* EM_CORE_GENERIC_H */ 174