blob: 734797b04439eb320c08daf9ff5232f650f6a91b [file] [log] [blame]
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2011, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are 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_
/*
* Peripherals registers definitions
*/
#include "include/samv7/samv71.h"
//_____ D E C L A R A T I O N S ____________________________________________
#ifndef __ASSEMBLY__
#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
/* 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_