/***************************************************************************//**
* @file
* @brief Core interrupt handling API (Generic)
*******************************************************************************
* # License
* Copyright 2023 Silicon Laboratories Inc. www.silabs.com
*******************************************************************************
*
* SPDX-License-Identifier: Zlib
*
* The licensor of this software is Silicon Laboratories Inc.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
******************************************************************************/
#ifndef EM_CORE_GENERIC_H
#define EM_CORE_GENERIC_H
#include
#include
/***************************************************************************//**
* @addtogroup core
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** Use PRIMASK register to disable interrupts in ATOMIC sections. */
#define CORE_ATOMIC_METHOD_PRIMASK 0
/** Use BASEPRI register to disable interrupts in ATOMIC sections. */
#define CORE_ATOMIC_METHOD_BASEPRI 1
#if !defined(CORE_ATOMIC_BASE_PRIORITY_LEVEL)
/** The interrupt priority level disabled within ATOMIC regions. Interrupts
* with priority level equal to or lower than this definition will be disabled
* within ATOMIC regions. */
#define CORE_ATOMIC_BASE_PRIORITY_LEVEL 3
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
************************ MACRO API ***************************************
******************************************************************************/
//
// CRITICAL section macro API.
//
/** Allocate storage for PRIMASK or BASEPRI value for use by
* CORE_ENTER/EXIT_ATOMIC() and CORE_ENTER/EXIT_CRITICAL() macros. */
#define CORE_DECLARE_IRQ_STATE CORE_irqState_t irqState
/** CRITICAL style interrupt disable. */
#define CORE_CRITICAL_IRQ_DISABLE() CORE_CriticalDisableIrq()
/** CRITICAL style interrupt enable. */
#define CORE_CRITICAL_IRQ_ENABLE() CORE_CriticalEnableIrq()
/** Convenience macro for implementing a CRITICAL section. */
#define CORE_CRITICAL_SECTION(yourcode) \
{ \
CORE_DECLARE_IRQ_STATE; \
CORE_ENTER_CRITICAL(); \
{ \
yourcode \
} \
CORE_EXIT_CRITICAL(); \
}
/** Enter CRITICAL section. Assumes that a @ref CORE_DECLARE_IRQ_STATE exist in
* scope. */
#define CORE_ENTER_CRITICAL() irqState = CORE_EnterCritical()
/** Exit CRITICAL section. Assumes that a @ref CORE_DECLARE_IRQ_STATE exist in
* scope. */
#define CORE_EXIT_CRITICAL() CORE_ExitCritical(irqState)
/** CRITICAL style yield. */
#define CORE_YIELD_CRITICAL() CORE_YieldCritical()
//
// ATOMIC section macro API.
//
/** ATOMIC style interrupt disable. */
#define CORE_ATOMIC_IRQ_DISABLE() CORE_AtomicDisableIrq()
/** ATOMIC style interrupt enable. */
#define CORE_ATOMIC_IRQ_ENABLE() CORE_AtomicEnableIrq()
/** Convenience macro for implementing an ATOMIC section. */
#define CORE_ATOMIC_SECTION(yourcode) \
{ \
CORE_DECLARE_IRQ_STATE; \
CORE_ENTER_ATOMIC(); \
{ \
yourcode \
} \
CORE_EXIT_ATOMIC(); \
}
/** Enter ATOMIC section. Assumes that a @ref CORE_DECLARE_IRQ_STATE exist in
* scope. */
#define CORE_ENTER_ATOMIC() irqState = CORE_EnterAtomic()
/** Exit ATOMIC section. Assumes that a @ref CORE_DECLARE_IRQ_STATE exist in
* scope. */
#define CORE_EXIT_ATOMIC() CORE_ExitAtomic(irqState)
/** ATOMIC style yield. */
#define CORE_YIELD_ATOMIC() CORE_YieldAtomic()
/** Check if IRQ is disabled. */
#define CORE_IRQ_DISABLED() CORE_IrqIsDisabled()
/** Check if inside an IRQ handler. */
#define CORE_IN_IRQ_CONTEXT() CORE_InIrqContext()
/*******************************************************************************
************************* TYPEDEFS ****************************************
******************************************************************************/
/** Storage for PRIMASK or BASEPRI value. */
typedef uint32_t CORE_irqState_t;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void CORE_CriticalDisableIrq(void);
void CORE_CriticalEnableIrq(void);
void CORE_ExitCritical(CORE_irqState_t irqState);
void CORE_YieldCritical(void);
CORE_irqState_t CORE_EnterCritical(void);
void CORE_AtomicDisableIrq(void);
void CORE_AtomicEnableIrq(void);
void CORE_ExitAtomic(CORE_irqState_t irqState);
void CORE_YieldAtomic(void);
CORE_irqState_t CORE_EnterAtomic(void);
bool CORE_InIrqContext(void);
bool CORE_IrqIsDisabled(void);
#ifdef __cplusplus
}
#endif
/** @} (end addtogroup core) */
#endif /* EM_CORE_GENERIC_H */