/* ---------------------------------------------------------------------------- */ /* Atmel Microcontroller Software Support */ /* SAM Software Package License */ /* ---------------------------------------------------------------------------- */ /* Copyright (c) 2015, Atmel Corporation */ /* */ /* All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following condition is met: */ /* */ /* - Redistributions of source code must retain the above copyright notice, */ /* this list of conditions and the disclaimer below. */ /* */ /* Atmel's name may not be used to endorse or promote products derived from */ /* this software without specific prior written permission. */ /* */ /* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ /* DISCLAIMED. IN NO EVENT SHALL ATMEL 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. */ /* ---------------------------------------------------------------------------- */ #ifndef _COMPILER_H_ #define _COMPILER_H_ #ifdef __rtems__ #include #endif /* __rtems__ */ /* * Peripherals registers definitions */ #if defined __SAMV71J19__ \ || defined __SAMV71J20__ \ || defined __SAMV71J21__ \ || defined __SAMV71N19__ \ || defined __SAMV71N20__ \ || defined __SAMV71N21__ \ || defined __SAMV71Q19__ \ || defined __SAMV71Q20__ \ || defined __SAMV71Q21__ #include "include/samv71/samv71.h" #elif defined __SAMS70J19__ \ || defined __SAMS70J20__ \ || defined __SAMS70J21__ \ || defined __SAMS70N19__ \ || defined __SAMS70N20__ \ || defined __SAMS70N21__ \ || defined __SAMS70Q19__ \ || defined __SAMS70Q20__ \ || defined __SAMS70Q21__ #include "include/sams70/sams70.h" #elif defined __SAME70J19__ \ || defined __SAME70J20__ \ || defined __SAME70J21__ \ || defined __SAME70N19__ \ || defined __SAME70N20__ \ || defined __SAME70N21__ \ || defined __SAME70Q19__ \ || defined __SAME70Q20__ \ || defined __SAME70Q21__ #include "include/same70/same70.h" #else #error "please define correct macro for the chip first!" #endif //_____ D E C L A R A T I O N S ____________________________________________ #ifndef __ASSEMBLY__ #include #include #include #include /* Define WEAK attribute */ #if defined (__CC_ARM) #define WEAK __attribute__ ((weak)) #elif defined (__ICCARM__) #define WEAK __weak #elif defined (__GNUC__) #define WEAK __attribute__ ((weak)) #endif /* Define Compiler name of tool chains */ #if defined (__CC_ARM) #define COMPILER_NAME "KEIL" #elif defined (__ICCARM__) #define COMPILER_NAME "IAR" #elif defined (__GNUC__) #define COMPILER_NAME "GCC" #endif /* Define NO_INIT attribute */ #if defined (__CC_ARM) #define NO_INIT #elif defined (__ICCARM__) #define NO_INIT __no_init #elif defined (__GNUC__) #define NO_INIT #endif /* Define memory sync for tool chains */ #if defined (__CC_ARM) #define memory_sync() __dsb(15);__isb(15); #elif defined (__ICCARM__) #define memory_sync() __DSB();__ISB(); #elif defined (__GNUC__) #define memory_sync() __DSB();__ISB(); #endif /* Define memory barrier for tool chains */ #if defined (__CC_ARM) #define memory_barrier() __dmb(15); #elif defined (__ICCARM__) #define memory_barrier() __DMB(); #elif defined (__GNUC__) #define memory_barrier() __DMB(); #endif /*! \name Token Paste * * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. * * May be used only within macros with the tokens passed as arguments if the tokens are \#defined. * * For example, writing TPASTE2(U, WIDTH) within a macro \#defined by * UTYPE(WIDTH) and invoked as UTYPE(UL_WIDTH) with UL_WIDTH \#defined as 32 is * equivalent to writing U32. */ //! @{ #define TPASTE2(a, b) a##b #define TPASTE3(a, b, c) a##b##c //! @} /*! \name Absolute Token Paste * * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. * * No restriction of use if the tokens are \#defined. * * For example, writing ATPASTE2(U, UL_WIDTH) anywhere with UL_WIDTH \#defined * as 32 is equivalent to writing U32. */ //! @{ #define ATPASTE2(a, b) TPASTE2(a, b) #define ATPASTE3(a, b, c) TPASTE3(a, b, c) //! @} /** * \brief Emit the compiler pragma \a arg. * * \param arg The pragma directive as it would appear after \e \#pragma * (i.e. not stringified). */ #define COMPILER_PRAGMA(arg) _Pragma(#arg) /** * \def COMPILER_PACK_SET(alignment) * \brief Set maximum alignment for subsequent structure and union * definitions to \a alignment. */ #define COMPILER_PACK_SET(alignment) COMPILER_PRAGMA(pack(alignment)) /** * \def COMPILER_PACK_RESET() * \brief Set default alignment for subsequent structure and union * definitions. */ #define COMPILER_PACK_RESET() COMPILER_PRAGMA(pack()) /** * \brief Set user-defined section. * Place a data object or a function in a user-defined section. */ #if defined (__CC_ARM) #define COMPILER_SECTION(a) __attribute__((__section__(a))) #elif defined (__ICCARM__) #define COMPILER_SECTION(a) COMPILER_PRAGMA(location = a) #elif defined (__GNUC__) #define COMPILER_SECTION(a) __attribute__((__section__(a))) #endif /** * \brief Set aligned boundary. */ #if defined (__CC_ARM) #define COMPILER_ALIGNED(a) __attribute__((__aligned__(a))) #elif defined (__ICCARM__) #define COMPILER_ALIGNED(a) COMPILER_PRAGMA(data_alignment = a) #elif defined (__GNUC__) #define COMPILER_ALIGNED(a) __attribute__((__aligned__(a))) #endif /** * \brief Set word-aligned boundary. */ #if defined (__CC_ARM) #define COMPILER_WORD_ALIGNED __attribute__((__aligned__(4))) #elif defined (__ICCARM__) #define COMPILER_WORD_ALIGNED COMPILER_PRAGMA(data_alignment = 4) #elif defined (__GNUC__) #define COMPILER_WORD_ALIGNED __attribute__((__aligned__(4))) #endif /*! \name Mathematics * * The same considerations as for clz and ctz apply here but GCC does not * provide built-in functions to access the assembly instructions abs, min and * max and it does not produce them by itself in most cases, so two sets of * macros are defined here: * - Abs, Min and Max to apply to constant expressions (values known at * compile time); * - abs, min and max to apply to non-constant expressions (values unknown at * compile time), abs is found in stdlib.h. */ //! @{ /*! \brief Takes the absolute value of \a a. * * \param a Input value. * * \return Absolute value of \a a. * * \note More optimized if only used with values known at compile time. */ #define Abs(a) (((a) < 0) ? -(a) : (a)) /*! \brief Takes the minimal value of \a a and \a b. * * \param a Input value. * \param b Input value. * * \return Minimal value of \a a and \a b. * * \note More optimized if only used with values known at compile time. */ #define Min(a, b) (((a) < (b)) ? (a) : (b)) /*! \brief Takes the maximal value of \a a and \a b. * * \param a Input value. * \param b Input value. * * \return Maximal value of \a a and \a b. * * \note More optimized if only used with values known at compile time. */ #define Max(a, b) (((a) > (b)) ? (a) : (b)) // abs() is already defined by stdlib.h /*! \brief Takes the minimal value of \a a and \a b. * * \param a Input value. * \param b Input value. * * \return Minimal value of \a a and \a b. * * \note More optimized if only used with values unknown at compile time. */ #define min(a, b) Min(a, b) /*! \brief Takes the maximal value of \a a and \a b. * * \param a Input value. * \param b Input value. * * \return Maximal value of \a a and \a b. * * \note More optimized if only used with values unknown at compile time. */ #define max(a, b) Max(a, b) //! @} #define be32_to_cpu(x) __REV(x) #define cpu_to_be32(x) __REV(x) #define BE32_TO_CPU(x) __REV(x) #define CPU_TO_BE32(x) __REV(x) /** * \def UNUSED * \brief Marking \a v as a unused parameter or value. */ #define UNUSED(v) (void)(v) /** * \weakgroup interrupt_group * * @{ */ /** * \name Interrupt Service Routine definition * * @{ */ /** * \brief Initialize interrupt vectors * * For NVIC the interrupt vectors are put in vector table. So nothing * to do to initialize them, except defined the vector function with * right name. * * This must be called prior to \ref irq_register_handler. */ # define irq_initialize_vectors() \ do { \ } while (0) /** * \brief Register handler for interrupt * * For NVIC the interrupt vectors are put in vector table. So nothing * to do to register them, except defined the vector function with * right name. * * Usage: * \code irq_initialize_vectors(); irq_register_handler(foo_irq_handler); \endcode * * \note The function \a func must be defined with the \ref ISR macro. * \note The functions prototypes can be found in the device exception header * files (exceptions.h). */ # define irq_register_handler(int_num, int_prio) \ NVIC_ClearPendingIRQ((IRQn_Type)int_num); \ NVIC_SetPriority((IRQn_Type)int_num, int_prio); \ NVIC_EnableIRQ((IRQn_Type)int_num); \ //@} # define cpu_irq_enable() \ do { \ /*g_interrupt_enabled = true; */ \ __DMB(); \ __enable_irq(); \ } while (0) # define cpu_irq_disable() \ do { \ __disable_irq(); \ __DMB(); \ /*g_interrupt_enabled = false; */ \ } while (0) typedef uint32_t irqflags_t; #if !defined(__DOXYGEN__) extern volatile bool g_interrupt_enabled; #endif #define cpu_irq_is_enabled() (__get_PRIMASK() == 0) static volatile uint32_t cpu_irq_critical_section_counter; static volatile bool cpu_irq_prev_interrupt_state; static inline irqflags_t cpu_irq_save(void) { irqflags_t flags = cpu_irq_is_enabled(); cpu_irq_disable(); return flags; } static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) { return (flags); } static inline void cpu_irq_restore(irqflags_t flags) { if (cpu_irq_is_enabled_flags(flags)) cpu_irq_enable(); } /* void cpu_irq_enter_critical(void); void cpu_irq_leave_critical(void);*/ /** * \weakgroup interrupt_deprecated_group * @{ */ #define Enable_global_interrupt() cpu_irq_enable() #define Disable_global_interrupt() cpu_irq_disable() #define Is_global_interrupt_enabled() cpu_irq_is_enabled() //_____ M A C R O S ________________________________________________________ /*! \name Usual Constants */ //! @{ #define DISABLE 0 #define ENABLE 1 #define DISABLED 0 #define ENABLED 1 #define OFF 0 #define ON 1 #define FALSE 0 #define TRUE 1 #ifndef __cplusplus #if !defined(__bool_true_false_are_defined) #define false FALSE #define true TRUE #endif #endif #define KO 0 #define OK 1 #define PASS 0 #define FAIL 1 #define LOW 0 #define HIGH 1 #define CLR 0 #define SET 1 //! @} /*! \brief Counts the trailing zero bits of the given value considered as a 32-bit integer. * * \param u Value of which to count the trailing zero bits. * * \return The count of trailing zero bits in \a u. */ #define ctz(u) ((u) & (1ul << 0) ? 0 : \ (u) & (1ul << 1) ? 1 : \ (u) & (1ul << 2) ? 2 : \ (u) & (1ul << 3) ? 3 : \ (u) & (1ul << 4) ? 4 : \ (u) & (1ul << 5) ? 5 : \ (u) & (1ul << 6) ? 6 : \ (u) & (1ul << 7) ? 7 : \ (u) & (1ul << 8) ? 8 : \ (u) & (1ul << 9) ? 9 : \ (u) & (1ul << 10) ? 10 : \ (u) & (1ul << 11) ? 11 : \ (u) & (1ul << 12) ? 12 : \ (u) & (1ul << 13) ? 13 : \ (u) & (1ul << 14) ? 14 : \ (u) & (1ul << 15) ? 15 : \ (u) & (1ul << 16) ? 16 : \ (u) & (1ul << 17) ? 17 : \ (u) & (1ul << 18) ? 18 : \ (u) & (1ul << 19) ? 19 : \ (u) & (1ul << 20) ? 20 : \ (u) & (1ul << 21) ? 21 : \ (u) & (1ul << 22) ? 22 : \ (u) & (1ul << 23) ? 23 : \ (u) & (1ul << 24) ? 24 : \ (u) & (1ul << 25) ? 25 : \ (u) & (1ul << 26) ? 26 : \ (u) & (1ul << 27) ? 27 : \ (u) & (1ul << 28) ? 28 : \ (u) & (1ul << 29) ? 29 : \ (u) & (1ul << 30) ? 30 : \ (u) & (1ul << 31) ? 31 : \ 32) #endif // __ASSEMBLY__ #endif // _COMPILER_H_