/* * Copyright (c) 2015-2016 Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP * All rights reserved. * * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * */ /*! * @file s32_core_cm0.h * * @page misra_violations MISRA-C:2012 violations * * @section [global] * Violates MISRA 2012 Advisory Directive 4.9, Function-like macro * Function-like macros are used instead of inline functions in order to ensure * that the performance will not be decreased if the functions will not be * inlined by the compiler. * * @section [global] * Violates MISRA 2012 Advisory Rule 2.5, Global macro not referenced. * The macros defined are used only on some of the drivers, so this might be reported * when the analysis is made only on one driver. */ /* * Tool Chains: * GNUC flag is defined also by ARM compiler - it shows the current major version of the compatible GCC version * __GNUC__ : GNU Compiler Collection * __ghs__ : Green Hills ARM Compiler * __ICCARM__ : IAR ARM Compiler * __DCC__ : Wind River Diab Compiler * __ARMCC_VERSION : ARM Compiler */ #if !defined (CORE_CM0_H) #define CORE_CM0_H #ifdef __cplusplus extern "C" { #endif /** \brief BKPT_ASM * * Macro to be used to trigger an debug interrupt */ #if defined ( __DCC__ ) #define BKPT_ASM __asm ("BKPT 0\n\t") #else #define BKPT_ASM __asm ("BKPT #0\n\t") #endif /** \brief Enable interrupts */ #if defined (__GNUC__) #define ENABLE_INTERRUPTS() __asm volatile ("cpsie i" : : : "memory"); #elif defined ( __DCC__ ) #define ENABLE_INTERRUPTS() __asm (".short 0xb662"); #else #define ENABLE_INTERRUPTS() __asm("cpsie i") #endif /** \brief Disable interrupts */ #if defined (__GNUC__) #define DISABLE_INTERRUPTS() __asm volatile ("cpsid i" : : : "memory"); #elif defined ( __DCC__ ) #define DISABLE_INTERRUPTS() __asm (".short 0xb672"); #else #define DISABLE_INTERRUPTS() __asm("cpsid i") #endif /** \brief Enter low-power standby state * WFI (Wait For Interrupt) makes the processor suspend execution (Clock is stopped) until an IRQ interrupts. */ #if defined (__GNUC__) #define STANDBY() __asm volatile ("wfi") #elif defined ( __DCC__ ) #define STANDBY() __asm (".short 0xbf30"); #else #define STANDBY() __asm ("wfi") #endif /** \brief No-op */ #define NOP() __asm volatile ("nop") /** \brief Reverse byte order in a word. * ARM Documentation Cortex-M0 Devices Generic User Guide * Accordingly to 3.5.7. REV, REV16, and REVSH * Restriction "This function requires low registers R0-R7 register" */ #if defined (__GNUC__) || defined (__ICCARM__) || defined (__ARMCC_VERSION) #define REV_BYTES_32(a, b) __asm volatile ("rev %0, %1" : "=l" (b) : "l" (a)) #elif defined (__ghs__) #define REV_BYTES_32(a, b) __asm volatile ("rev %0, %1" : "=r" (b) : "r" (a)) #else #define REV_BYTES_32(a, b) (b = ((a & 0xFF000000U) >> 24U) | ((a & 0xFF0000U) >> 8U) \ | ((a & 0xFF00U) << 8U) | ((a & 0xFFU) << 24U)) #endif /** \brief Reverse byte order in each halfword independently. * ARM Documentation Cortex-M0 Devices Generic User Guide * Accordingly to 3.5.7. REV, REV16, and REVSH * Restriction "This function requires low registers R0-R7 register" */ #if defined (__GNUC__) || defined (__ICCARM__) || defined (__ARMCC_VERSION) #define REV_BYTES_16(a, b) __asm volatile ("rev16 %0, %1" : "=l" (b) : "l" (a)) #elif defined (__ghs__) #define REV_BYTES_16(a, b) __asm volatile ("rev16 %0, %1" : "=r" (b) : "r" (a)) #else #define REV_BYTES_16(a, b) (b = ((a & 0xFF000000U) >> 8U) | ((a & 0xFF0000U) << 8U) \ | ((a & 0xFF00U) >> 8U) | ((a & 0xFFU) << 8U)) #endif /** \brief Places a function in RAM. */ #if defined ( __GNUC__ ) || defined (__ARMCC_VERSION) #define START_FUNCTION_DECLARATION_RAMSECTION #define END_FUNCTION_DECLARATION_RAMSECTION __attribute__((section (".code_ram"))); #elif defined ( __ghs__ ) #define START_FUNCTION_DECLARATION_RAMSECTION _Pragma("ghs callmode=far") #define END_FUNCTION_DECLARATION_RAMSECTION __attribute__((section (".code_ram")));\ _Pragma("ghs callmode=default") #elif defined ( __ICCARM__ ) #define START_FUNCTION_DECLARATION_RAMSECTION __ramfunc #define END_FUNCTION_DECLARATION_RAMSECTION ; #elif defined ( __DCC__ ) #define START_FUNCTION_DECLARATION_RAMSECTION _Pragma("section CODE \".code_ram\" \"\" far-absolute") \ _Pragma("use_section CODE") #define END_FUNCTION_DECLARATION_RAMSECTION ; \ _Pragma("section CODE \".text\"") #else /* Keep compatibility with software analysis tools */ #define START_FUNCTION_DECLARATION_RAMSECTION #define END_FUNCTION_DECLARATION_RAMSECTION ; #endif /* For GCC, IAR, GHS, Diab and ARMC there is no need to specify the section when defining a function, it is enough to specify it at the declaration. This also enables compatibility with software analysis tools. */ #define START_FUNCTION_DEFINITION_RAMSECTION #define END_FUNCTION_DEFINITION_RAMSECTION #if defined (__ICCARM__) #define DISABLE_CHECK_RAMSECTION_FUNCTION_CALL _Pragma("diag_suppress=Ta022") #define ENABLE_CHECK_RAMSECTION_FUNCTION_CALL _Pragma("diag_default=Ta022") #else #define DISABLE_CHECK_RAMSECTION_FUNCTION_CALL #define ENABLE_CHECK_RAMSECTION_FUNCTION_CALL #endif /** \brief Get Core ID * * GET_CORE_ID returns the processor identification number for cm0 */ #define GET_CORE_ID() 0U /** \brief Data alignment. */ #if defined ( __GNUC__ ) || defined ( __ghs__ ) || defined ( __DCC__ ) || defined (__ARMCC_VERSION) #define ALIGNED(x) __attribute__((aligned(x))) #elif defined ( __ICCARM__ ) #define stringify(s) tostring(s) #define tostring(s) #s #define ALIGNED(x) _Pragma(stringify(data_alignment=x)) #else /* Keep compatibility with software analysis tools */ #define ALIGNED(x) #endif /** \brief Endianness. */ #define CORE_LITTLE_ENDIAN #ifdef __cplusplus } #endif #endif /* CORE_CM0_H */ /******************************************************************************* * EOF ******************************************************************************/