/**
* \file
*
* \brief Commonly used includes, types and macros.
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* EXPRESSLY AND SPECIFICALLY 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit Atmel Support
*/
#ifndef UTILS_COMPILER_H
#define UTILS_COMPILER_H
#if defined(__GNUC__)
# include
#elif defined(__ICCAVR__)
# include
# include
#else
# error "Unsupported compiler."
#endif
#include
#include
#include
#include
#include
#ifdef __ICCAVR__
/*! \name Compiler Keywords
*
* Port of some keywords from GCC to IAR Embedded Workbench.
*/
//! @{
#define __asm__ asm
#define __inline__ inline
#define __volatile__
//! @}
#endif
/**
* \def UNUSED
* \brief Marking \a v as a unused parameter or value.
*/
#define UNUSED(v) (void)(v)
/**
* \def unused
* \brief Marking \a v as a unused parameter or value.
*/
#define unused(v) do { (void)(v); } while(0)
/**
* \def barrier
* \brief Memory barrier
*/
#ifdef __GNUC__
# define barrier() asm volatile("" ::: "memory")
#else
# define barrier() asm ("")
#endif
/*
* AVR arch does not care about alignment anyway.
*/
#define COMPILER_PACK_RESET(alignment)
#define COMPILER_PACK_SET(alignment)
//_____ M A C R O S ________________________________________________________
/**
* \def __always_inline
* \brief The function should always be inlined.
*
* This annotation instructs the compiler to ignore its inlining
* heuristics and inline the function no matter how big it thinks it
* becomes.
*/
#if (defined __GNUC__)
# define __always_inline inline __attribute__((__always_inline__))
#elif (defined __ICCAVR__)
# define __always_inline _Pragma("inline=forced")
#endif
/**
* \def __always_optimize
* \brief The function should always be optimized.
*
* This annotation instructs the compiler to ignore global optimization
* settings and always compile the function with a high level of
* optimization.
*/
#if (defined __GNUC__)
#define __always_optimize __attribute__((optimize(3)))
#elif (defined __ICCAVR__)
#define __always_optimize _Pragma("optimize=high")
#endif
/*! \brief This macro is used to test fatal errors.
*
* The macro tests if the expression is false. If it is, a fatal error is
* detected and the application hangs up. If TEST_SUITE_DEFINE_ASSERT_MACRO
* is defined, a unit test version of the macro is used, to allow execution
* of further tests after a false expression.
*
* \param expr Expression to evaluate and supposed to be nonzero.
*/
#if defined(_ASSERT_ENABLE_)
# if defined(TEST_SUITE_DEFINE_ASSERT_MACRO)
// Assert() is defined in unit_test/suite.h
# include "unit_test/suite.h"
# else
# define Assert(expr) \
{\
if (!(expr)) while (true);\
}
# endif
#else
# define Assert(expr) ((void) 0)
#endif
/*! \name MCU Endianism Handling
*/
//! @{
#define MSB(u16) (((uint8_t* )&u16)[1])
#define LSB(u16) (((uint8_t* )&u16)[0])
//! @}
#include "interrupt.h"
#include "progmem.h"
#if (defined __GNUC__)
#define SHORTENUM __attribute__ ((packed))
#elif (defined __ICCAVR__)
#define SHORTENUM /**/
#endif
#if (defined __GNUC__)
#define FUNC_PTR void *
#elif (defined __ICCAVR__)
#if (FLASHEND > 0x1FFFF) // Required for program code larger than 128K
#define FUNC_PTR void __farflash *
#else
#define FUNC_PTR void *
#endif /* ENABLE_FAR_FLASH */
#endif
#if (defined __GNUC__)
#define FLASH_DECLARE(x) const x __attribute__((__progmem__))
#elif (defined __ICCAVR__)
#define FLASH_DECLARE(x) const __flash x
#endif
#if (defined __GNUC__)
#define FLASH_EXTERN(x) extern const x
#elif (defined __ICCAVR__)
#define FLASH_EXTERN(x) extern const __flash x
#endif
/*Defines the Flash Storage for the request and response of MAC*/
#define CMD_ID_OCTET (0)
/* Converting of values from CPU endian to little endian. */
#define CPU_ENDIAN_TO_LE16(x) (x)
#define CPU_ENDIAN_TO_LE32(x) (x)
#define CPU_ENDIAN_TO_LE64(x) (x)
/* Converting of values from little endian to CPU endian. */
#define LE16_TO_CPU_ENDIAN(x) (x)
#define LE32_TO_CPU_ENDIAN(x) (x)
#define LE64_TO_CPU_ENDIAN(x) (x)
/* Converting of constants from little endian to CPU endian. */
#define CLE16_TO_CPU_ENDIAN(x) (x)
#define CLE32_TO_CPU_ENDIAN(x) (x)
#define CLE64_TO_CPU_ENDIAN(x) (x)
/* Converting of constants from CPU endian to little endian. */
#define CCPU_ENDIAN_TO_LE16(x) (x)
#define CCPU_ENDIAN_TO_LE32(x) (x)
#define CCPU_ENDIAN_TO_LE64(x) (x)
#if (defined __GNUC__)
#define ADDR_COPY_DST_SRC_16(dst, src) memcpy((&(dst)), (&(src)), sizeof(uint16_t))
#define ADDR_COPY_DST_SRC_64(dst, src) memcpy((&(dst)), (&(src)), sizeof(uint64_t))
/* Converts a 2 Byte array into a 16-Bit value */
#define convert_byte_array_to_16_bit(data) \
(*(uint16_t *)(data))
/* Converts a 4 Byte array into a 32-Bit value */
#define convert_byte_array_to_32_bit(data) \
(*(uint32_t *)(data))
/* Converts a 8 Byte array into a 64-Bit value */
#define convert_byte_array_to_64_bit(data) \
(*(uint64_t *)(data))
/* Converts a 16-Bit value into a 2 Byte array */
#define convert_16_bit_to_byte_array(value, data) \
((*(uint16_t *)(data)) = (uint16_t)(value))
/* Converts spec 16-Bit value into a 2 Byte array */
#define convert_spec_16_bit_to_byte_array(value, data) \
((*(uint16_t *)(data)) = (uint16_t)(value))
/* Converts spec 16-Bit value into a 2 Byte array */
#define convert_16_bit_to_byte_address(value, data) \
((*(uint16_t *)(data)) = (uint16_t)(value))
/* Converts a 32-Bit value into a 4 Byte array */
#define convert_32_bit_to_byte_array(value, data) \
((*(uint32_t *)(data)) = (uint32_t)(value))
/* Converts a 64-Bit value into a 8 Byte array */
/* Here memcpy requires much less footprint */
#define convert_64_bit_to_byte_array(value, data) \
memcpy((data), (&(value)), sizeof(uint64_t))
#elif (defined __ICCAVR__)
#define ADDR_COPY_DST_SRC_16(dst, src) ((dst) = (src))
#define ADDR_COPY_DST_SRC_64(dst, src) ((dst) = (src))
/* Converts a 2 Byte array into a 16-Bit value */
#define convert_byte_array_to_16_bit(data) \
(*(uint16_t *)(data))
/* Converts a 4 Byte array into a 32-Bit value */
#define convert_byte_array_to_32_bit(data) \
(*(uint32_t *)(data))
/* Converts a 8 Byte array into a 64-Bit value */
#define convert_byte_array_to_64_bit(data) \
(*(uint64_t *)(data))
/* Converts a 16-Bit value into a 2 Byte array */
#define convert_16_bit_to_byte_array(value, data) \
((*(uint16_t *)(data)) = (uint16_t)(value))
/* Converts spec 16-Bit value into a 2 Byte array */
#define convert_spec_16_bit_to_byte_array(value, data) \
((*(uint16_t *)(data)) = (uint16_t)(value))
/* Converts spec 16-Bit value into a 2 Byte array */
#define convert_16_bit_to_byte_address(value, data) \
((*(uint16_t *)(data)) = (uint16_t)(value))
/* Converts a 32-Bit value into a 4 Byte array */
#define convert_32_bit_to_byte_array(value, data) \
((*(uint32_t *)(data)) = (uint32_t)(value))
/* Converts a 64-Bit value into a 8 Byte array */
#define convert_64_bit_to_byte_array(value, data) \
((*(uint64_t *)(data)) = (uint64_t)(value))
#endif
#define MEMCPY_ENDIAN memcpy
#define PGM_READ_BLOCK(dst, src, len) memcpy_P((dst), (src), (len))
#if (defined __GNUC__)
#define PGM_READ_BYTE(x) pgm_read_byte(x)
#define PGM_READ_WORD(x) pgm_read_word(x)
#elif (defined __ICCAVR__)
#define PGM_READ_BYTE(x) *(x)
#define PGM_READ_WORD(x) *(x)
#endif
typedef uint8_t U8 ; //!< 8-bit unsigned integer.
typedef uint16_t U16; //!< 16-bit unsigned integer.
typedef uint32_t U32; //!< 32-bit unsigned integer.
typedef unsigned long long int U64; //!< 64-bit unsigned integer.
/*! \brief Toggles the endianism of \a u16 (by swapping its bytes).
*
* \param u16 U16 of which to toggle the endianism.
*
* \return Value resulting from \a u16 with toggled endianism.
*
* \note More optimized if only used with values known at compile time.
*/
#define Swap16(u16) ((U16)(((U16)(u16) >> 8) |\
((U16)(u16) << 8)))
/*! \brief Toggles the endianism of \a u32 (by swapping its bytes).
*
* \param u32 U32 of which to toggle the endianism.
*
* \return Value resulting from \a u32 with toggled endianism.
*
* \note More optimized if only used with values known at compile time.
*/
#define Swap32(u32) ((U32)(((U32)Swap16((U32)(u32) >> 16)) |\
((U32)Swap16((U32)(u32)) << 16)))
/*! \brief Toggles the endianism of \a u64 (by swapping its bytes).
*
* \param u64 U64 of which to toggle the endianism.
*
* \return Value resulting from \a u64 with toggled endianism.
*
* \note More optimized if only used with values known at compile time.
*/
#define Swap64(u64) ((U64)(((U64)Swap32((U64)(u64) >> 32)) |\
((U64)Swap32((U64)(u64)) << 32)))
#if (defined __GNUC__)
#define nop() do { __asm__ __volatile__ ("nop"); } while (0)
#elif (defined __ICCAVR__)
#define nop() __no_operation()
#endif
#if (defined __GNUC__)
#define FORCE_INLINE(type, name, ...) \
static inline type name(__VA_ARGS__) __attribute__((always_inline)); \
static inline type name(__VA_ARGS__)
#elif (defined __ICCAVR__)
#define FORCE_INLINE(type, name, ...) \
PRAGMA(inline=forced) \
static inline type name(__VA_ARGS__)
#endif
#endif // UTILS_COMPILER_H