123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671 |
- /*
- * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
- * Copyright 2016-2021 NXP
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #ifndef _FSL_COMMON_ARM_H_
- #define _FSL_COMMON_ARM_H_
- /*
- * For CMSIS pack RTE.
- * CMSIS pack RTE generates "RTC_Components.h" which contains the statements
- * of the related <RTE_Components_h> element for all selected software components.
- */
- #ifdef _RTE_
- #include "RTE_Components.h"
- #endif
- /*!
- * @addtogroup ksdk_common
- * @{
- */
- /*! @name Atomic modification
- *
- * These macros are used for atomic access, such as read-modify-write
- * to the peripheral registers.
- *
- * - SDK_ATOMIC_LOCAL_ADD
- * - SDK_ATOMIC_LOCAL_SET
- * - SDK_ATOMIC_LOCAL_CLEAR
- * - SDK_ATOMIC_LOCAL_TOGGLE
- * - SDK_ATOMIC_LOCAL_CLEAR_AND_SET
- *
- * Take SDK_ATOMIC_LOCAL_CLEAR_AND_SET as an example: the parameter @c addr
- * means the address of the peripheral register or variable you want to modify
- * atomically, the parameter @c clearBits is the bits to clear, the parameter
- * @c setBits it the bits to set.
- * For example, to set a 32-bit register bit1:bit0 to 0b10, use like this:
- *
- * @code
- volatile uint32_t * reg = (volatile uint32_t *)REG_ADDR;
- SDK_ATOMIC_LOCAL_CLEAR_AND_SET(reg, 0x03, 0x02);
- @endcode
- *
- * In this example, the register bit1:bit0 are cleared and bit1 is set, as a result,
- * register bit1:bit0 = 0b10.
- *
- * @note For the platforms don't support exclusive load and store, these macros
- * disable the global interrupt to pretect the modification.
- *
- * @note These macros only guarantee the local processor atomic operations. For
- * the multi-processor devices, use hardware semaphore such as SEMA42 to
- * guarantee exclusive access if necessary.
- *
- * @{
- */
- /* clang-format off */
- #if ((defined(__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
- (defined(__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
- (defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
- (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ == 1)))
- /* clang-format on */
- /* If the LDREX and STREX are supported, use them. */
- #define _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, val, ops) \
- do \
- { \
- (val) = __LDREXB(addr); \
- (ops); \
- } while (0UL != __STREXB((val), (addr)))
- #define _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, val, ops) \
- do \
- { \
- (val) = __LDREXH(addr); \
- (ops); \
- } while (0UL != __STREXH((val), (addr)))
- #define _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, val, ops) \
- do \
- { \
- (val) = __LDREXW(addr); \
- (ops); \
- } while (0UL != __STREXW((val), (addr)))
- static inline void _SDK_AtomicLocalAdd1Byte(volatile uint8_t *addr, uint8_t val)
- {
- uint8_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val += val);
- }
- static inline void _SDK_AtomicLocalAdd2Byte(volatile uint16_t *addr, uint16_t val)
- {
- uint16_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val += val);
- }
- static inline void _SDK_AtomicLocalAdd4Byte(volatile uint32_t *addr, uint32_t val)
- {
- uint32_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val += val);
- }
- static inline void _SDK_AtomicLocalSub1Byte(volatile uint8_t *addr, uint8_t val)
- {
- uint8_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val -= val);
- }
- static inline void _SDK_AtomicLocalSub2Byte(volatile uint16_t *addr, uint16_t val)
- {
- uint16_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val -= val);
- }
- static inline void _SDK_AtomicLocalSub4Byte(volatile uint32_t *addr, uint32_t val)
- {
- uint32_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val -= val);
- }
- static inline void _SDK_AtomicLocalSet1Byte(volatile uint8_t *addr, uint8_t bits)
- {
- uint8_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val |= bits);
- }
- static inline void _SDK_AtomicLocalSet2Byte(volatile uint16_t *addr, uint16_t bits)
- {
- uint16_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val |= bits);
- }
- static inline void _SDK_AtomicLocalSet4Byte(volatile uint32_t *addr, uint32_t bits)
- {
- uint32_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val |= bits);
- }
- static inline void _SDK_AtomicLocalClear1Byte(volatile uint8_t *addr, uint8_t bits)
- {
- uint8_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val &= ~bits);
- }
- static inline void _SDK_AtomicLocalClear2Byte(volatile uint16_t *addr, uint16_t bits)
- {
- uint16_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val &= ~bits);
- }
- static inline void _SDK_AtomicLocalClear4Byte(volatile uint32_t *addr, uint32_t bits)
- {
- uint32_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val &= ~bits);
- }
- static inline void _SDK_AtomicLocalToggle1Byte(volatile uint8_t *addr, uint8_t bits)
- {
- uint8_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val ^= bits);
- }
- static inline void _SDK_AtomicLocalToggle2Byte(volatile uint16_t *addr, uint16_t bits)
- {
- uint16_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val ^= bits);
- }
- static inline void _SDK_AtomicLocalToggle4Byte(volatile uint32_t *addr, uint32_t bits)
- {
- uint32_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val ^= bits);
- }
- static inline void _SDK_AtomicLocalClearAndSet1Byte(volatile uint8_t *addr, uint8_t clearBits, uint8_t setBits)
- {
- uint8_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_1BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
- }
- static inline void _SDK_AtomicLocalClearAndSet2Byte(volatile uint16_t *addr, uint16_t clearBits, uint16_t setBits)
- {
- uint16_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_2BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
- }
- static inline void _SDK_AtomicLocalClearAndSet4Byte(volatile uint32_t *addr, uint32_t clearBits, uint32_t setBits)
- {
- uint32_t s_val;
- _SDK_ATOMIC_LOCAL_OPS_4BYTE(addr, s_val, s_val = (s_val & ~clearBits) | setBits);
- }
- #define SDK_ATOMIC_LOCAL_ADD(addr, val) \
- ((1UL == sizeof(*(addr))) ? \
- _SDK_AtomicLocalAdd1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(val)) : \
- ((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalAdd2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(val)) : \
- _SDK_AtomicLocalAdd4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(val))))
- #define SDK_ATOMIC_LOCAL_SET(addr, bits) \
- ((1UL == sizeof(*(addr))) ? \
- _SDK_AtomicLocalSet1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(bits)) : \
- ((2UL == sizeof(*(addr))) ? _SDK_AtomicLocalSet2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(bits)) : \
- _SDK_AtomicLocalSet4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(bits))))
- #define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \
- ((1UL == sizeof(*(addr))) ? \
- _SDK_AtomicLocalClear1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(bits)) : \
- ((2UL == sizeof(*(addr))) ? \
- _SDK_AtomicLocalClear2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(bits)) : \
- _SDK_AtomicLocalClear4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(bits))))
- #define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \
- ((1UL == sizeof(*(addr))) ? \
- _SDK_AtomicLocalToggle1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(bits)) : \
- ((2UL == sizeof(*(addr))) ? \
- _SDK_AtomicLocalToggle2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(bits)) : \
- _SDK_AtomicLocalToggle4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(bits))))
- #define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \
- ((1UL == sizeof(*(addr))) ? \
- _SDK_AtomicLocalClearAndSet1Byte((volatile uint8_t *)(volatile void *)(addr), (uint8_t)(clearBits), (uint8_t)(setBits)) : \
- ((2UL == sizeof(*(addr))) ? \
- _SDK_AtomicLocalClearAndSet2Byte((volatile uint16_t *)(volatile void *)(addr), (uint16_t)(clearBits), (uint16_t)(setBits)) : \
- _SDK_AtomicLocalClearAndSet4Byte((volatile uint32_t *)(volatile void *)(addr), (uint32_t)(clearBits), (uint32_t)(setBits))))
- #else
- #define SDK_ATOMIC_LOCAL_ADD(addr, val) \
- do \
- { \
- uint32_t s_atomicOldInt; \
- s_atomicOldInt = DisableGlobalIRQ(); \
- *(addr) += (val); \
- EnableGlobalIRQ(s_atomicOldInt); \
- } while (0)
- #define SDK_ATOMIC_LOCAL_SET(addr, bits) \
- do \
- { \
- uint32_t s_atomicOldInt; \
- s_atomicOldInt = DisableGlobalIRQ(); \
- *(addr) |= (bits); \
- EnableGlobalIRQ(s_atomicOldInt); \
- } while (0)
- #define SDK_ATOMIC_LOCAL_CLEAR(addr, bits) \
- do \
- { \
- uint32_t s_atomicOldInt; \
- s_atomicOldInt = DisableGlobalIRQ(); \
- *(addr) &= ~(bits); \
- EnableGlobalIRQ(s_atomicOldInt); \
- } while (0)
- #define SDK_ATOMIC_LOCAL_TOGGLE(addr, bits) \
- do \
- { \
- uint32_t s_atomicOldInt; \
- s_atomicOldInt = DisableGlobalIRQ(); \
- *(addr) ^= (bits); \
- EnableGlobalIRQ(s_atomicOldInt); \
- } while (0)
- #define SDK_ATOMIC_LOCAL_CLEAR_AND_SET(addr, clearBits, setBits) \
- do \
- { \
- uint32_t s_atomicOldInt; \
- s_atomicOldInt = DisableGlobalIRQ(); \
- *(addr) = (*(addr) & ~(clearBits)) | (setBits); \
- EnableGlobalIRQ(s_atomicOldInt); \
- } while (0)
- #endif
- /* @} */
- /*! @name Timer utilities */
- /* @{ */
- /*! Macro to convert a microsecond period to raw count value */
- #define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)(((uint64_t)(us) * (clockFreqInHz)) / 1000000U)
- /*! Macro to convert a raw count value to microsecond */
- #define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count)*1000000U / (clockFreqInHz))
- /*! Macro to convert a millisecond period to raw count value */
- #define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)(ms) * (clockFreqInHz) / 1000U)
- /*! Macro to convert a raw count value to millisecond */
- #define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)(count)*1000U / (clockFreqInHz))
- /* @} */
- /*! @name ISR exit barrier
- * @{
- *
- * ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
- * exception return operation might vector to incorrect interrupt.
- * For Cortex-M7, if core speed much faster than peripheral register write speed,
- * the peripheral interrupt flags may be still set after exiting ISR, this results to
- * the same error similar with errata 83869.
- */
- #if (defined __CORTEX_M) && ((__CORTEX_M == 4U) || (__CORTEX_M == 7U))
- #define SDK_ISR_EXIT_BARRIER __DSB()
- #else
- #define SDK_ISR_EXIT_BARRIER
- #endif
- /* @} */
- /*! @name Alignment variable definition macros */
- /* @{ */
- #if (defined(__ICCARM__))
- /*
- * Workaround to disable MISRA C message suppress warnings for IAR compiler.
- * http:/ /supp.iar.com/Support/?note=24725
- */
- _Pragma("diag_suppress=Pm120")
- #define SDK_PRAGMA(x) _Pragma(#x)
- _Pragma("diag_error=Pm120")
- /*! Macro to define a variable with alignbytes alignment */
- #define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
- #elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
- /*! Macro to define a variable with alignbytes alignment */
- #define SDK_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
- #elif defined(__GNUC__)
- /*! Macro to define a variable with alignbytes alignment */
- #define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
- #else
- #error Toolchain not supported
- #endif
- /*! Macro to define a variable with L1 d-cache line size alignment */
- #if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
- #define SDK_L1DCACHE_ALIGN(var) SDK_ALIGN(var, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
- #endif
- /*! Macro to define a variable with L2 cache line size alignment */
- #if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
- #define SDK_L2CACHE_ALIGN(var) SDK_ALIGN(var, FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
- #endif
- /*! Macro to change a value to a given size aligned value */
- #define SDK_SIZEALIGN(var, alignbytes) \
- ((unsigned int)((var) + ((alignbytes)-1U)) & (unsigned int)(~(unsigned int)((alignbytes)-1U)))
- /* @} */
- /*! @name Non-cacheable region definition macros */
- /* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or
- * "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable
- * variables, please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them,
- * these zero-inited variables will be initialized to zero in system startup.
- */
- /* @{ */
- #if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && \
- defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
- #if (defined(__ICCARM__))
- #define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable"
- #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable"
- #define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init"
- #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
- SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init"
- #elif (defined(__CC_ARM) || defined(__ARMCC_VERSION))
- #define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
- #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
- __attribute__((section("NonCacheable.init"))) __attribute__((aligned(alignbytes))) var
- #if (defined(__CC_ARM))
- #define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var
- #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
- __attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var
- #else
- #define AT_NONCACHEABLE_SECTION(var) __attribute__((section(".bss.NonCacheable"))) var
- #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
- __attribute__((section(".bss.NonCacheable"))) __attribute__((aligned(alignbytes))) var
- #endif
- #elif (defined(__GNUC__))
- /* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA"
- * in your projects to make sure the non-cacheable section variables will be initialized in system startup.
- */
- #define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
- #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
- __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
- #define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var
- #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
- __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes)))
- #else
- #error Toolchain not supported.
- #endif
- #else
- #define AT_NONCACHEABLE_SECTION(var) var
- #define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_ALIGN(var, alignbytes)
- #define AT_NONCACHEABLE_SECTION_INIT(var) var
- #define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_ALIGN(var, alignbytes)
- #endif
- /* @} */
- /*!
- * @name Time sensitive region
- * @{
- */
- #if (defined(__ICCARM__))
- #define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess"
- #define AT_QUICKACCESS_SECTION_DATA(var) var @"DataQuickAccess"
- #define AT_QUICKACCESS_SECTION_DATA_ALIGN(var, alignbytes) \
- SDK_PRAGMA(data_alignment = alignbytes) var @"DataQuickAccess"
- #elif (defined(__CC_ARM) || defined(__ARMCC_VERSION))
- #define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
- #define AT_QUICKACCESS_SECTION_DATA(var) __attribute__((section("DataQuickAccess"))) var
- #define AT_QUICKACCESS_SECTION_DATA_ALIGN(var, alignbytes) \
- __attribute__((section("DataQuickAccess"))) __attribute__((aligned(alignbytes))) var
- #elif (defined(__GNUC__))
- #define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
- #define AT_QUICKACCESS_SECTION_DATA(var) __attribute__((section("DataQuickAccess"))) var
- #define AT_QUICKACCESS_SECTION_DATA_ALIGN(var, alignbytes) \
- __attribute__((section("DataQuickAccess"))) var __attribute__((aligned(alignbytes)))
- #else
- #error Toolchain not supported.
- #endif /* defined(__ICCARM__) */
- /*! @name Ram Function */
- #if (defined(__ICCARM__))
- #define RAMFUNCTION_SECTION_CODE(func) func @"RamFunction"
- #elif (defined(__CC_ARM) || defined(__ARMCC_VERSION))
- #define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
- #elif (defined(__GNUC__))
- #define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
- #else
- #error Toolchain not supported.
- #endif /* defined(__ICCARM__) */
- /* @} */
- #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
- void DefaultISR(void);
- #endif
- /*
- * The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
- * defined in previous of this file.
- */
- #include "fsl_clock.h"
- /*
- * Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
- */
- #if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
- (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
- #include "fsl_reset.h"
- #endif
- /*******************************************************************************
- * API
- ******************************************************************************/
- #if defined(__cplusplus)
- extern "C" {
- #endif /* __cplusplus*/
- /*!
- * @brief Enable specific interrupt.
- *
- * Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt
- * levels. For example, there are NVIC and intmux. Here the interrupts connected
- * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
- * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
- * to NVIC first then routed to core.
- *
- * This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts
- * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
- *
- * @param interrupt The IRQ number.
- * @retval kStatus_Success Interrupt enabled successfully
- * @retval kStatus_Fail Failed to enable the interrupt
- */
- static inline status_t EnableIRQ(IRQn_Type interrupt)
- {
- status_t status = kStatus_Success;
- if (NotAvail_IRQn == interrupt)
- {
- status = kStatus_Fail;
- }
- #if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
- else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
- {
- status = kStatus_Fail;
- }
- #endif
- else
- {
- #if defined(__GIC_PRIO_BITS)
- GIC_EnableIRQ(interrupt);
- #else
- NVIC_EnableIRQ(interrupt);
- #endif
- }
- return status;
- }
- /*!
- * @brief Disable specific interrupt.
- *
- * Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt
- * levels. For example, there are NVIC and intmux. Here the interrupts connected
- * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
- * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
- * to NVIC first then routed to core.
- *
- * This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts
- * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
- *
- * @param interrupt The IRQ number.
- * @retval kStatus_Success Interrupt disabled successfully
- * @retval kStatus_Fail Failed to disable the interrupt
- */
- static inline status_t DisableIRQ(IRQn_Type interrupt)
- {
- status_t status = kStatus_Success;
- if (NotAvail_IRQn == interrupt)
- {
- status = kStatus_Fail;
- }
- #if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
- else if ((int32_t)interrupt >= (int32_t)FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
- {
- status = kStatus_Fail;
- }
- #endif
- else
- {
- #if defined(__GIC_PRIO_BITS)
- GIC_DisableIRQ(interrupt);
- #else
- NVIC_DisableIRQ(interrupt);
- #endif
- }
- return status;
- }
- /*!
- * @brief Disable the global IRQ
- *
- * Disable the global interrupt and return the current primask register. User is required to provided the primask
- * register for the EnableGlobalIRQ().
- *
- * @return Current primask value.
- */
- static inline uint32_t DisableGlobalIRQ(void)
- {
- #if defined(CPSR_I_Msk)
- uint32_t cpsr = __get_CPSR() & CPSR_I_Msk;
- __disable_irq();
- return cpsr;
- #else
- uint32_t regPrimask = __get_PRIMASK();
- __disable_irq();
- return regPrimask;
- #endif
- }
- /*!
- * @brief Enable the global IRQ
- *
- * Set the primask register with the provided primask value but not just enable the primask. The idea is for the
- * convenience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to
- * use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair.
- *
- * @param primask value of primask register to be restored. The primask value is supposed to be provided by the
- * DisableGlobalIRQ().
- */
- static inline void EnableGlobalIRQ(uint32_t primask)
- {
- #if defined(CPSR_I_Msk)
- __set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
- #else
- __set_PRIMASK(primask);
- #endif
- }
- #if defined(ENABLE_RAM_VECTOR_TABLE)
- /*!
- * @brief install IRQ handler
- *
- * @param irq IRQ number
- * @param irqHandler IRQ handler address
- * @return The old IRQ handler address
- */
- uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
- #endif /* ENABLE_RAM_VECTOR_TABLE. */
- #if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
- /*
- * When FSL_FEATURE_POWERLIB_EXTEND is defined to non-zero value,
- * powerlib should be used instead of these functions.
- */
- #if !(defined(FSL_FEATURE_POWERLIB_EXTEND) && (FSL_FEATURE_POWERLIB_EXTEND != 0))
- /*!
- * @brief Enable specific interrupt for wake-up from deep-sleep mode.
- *
- * Enable the interrupt for wake-up from deep sleep mode.
- * Some interrupts are typically used in sleep mode only and will not occur during
- * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
- * those clocks (significantly increasing power consumption in the reduced power mode),
- * making these wake-ups possible.
- *
- * @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internaly).
- *
- * @param interrupt The IRQ number.
- */
- void EnableDeepSleepIRQ(IRQn_Type interrupt);
- /*!
- * @brief Disable specific interrupt for wake-up from deep-sleep mode.
- *
- * Disable the interrupt for wake-up from deep sleep mode.
- * Some interrupts are typically used in sleep mode only and will not occur during
- * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
- * those clocks (significantly increasing power consumption in the reduced power mode),
- * making these wake-ups possible.
- *
- * @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internaly).
- *
- * @param interrupt The IRQ number.
- */
- void DisableDeepSleepIRQ(IRQn_Type interrupt);
- #endif /* FSL_FEATURE_POWERLIB_EXTEND */
- #endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
- #if defined(__cplusplus)
- }
- #endif /* __cplusplus*/
- /*! @} */
- #endif /* _FSL_COMMON_ARM_H_ */
|