Add build tests to verify correct compilation of as many modules as possible under...
[pub/USBasp.git] / LUFA / Common / Common.h
index 69c4ff2..4c9aa49 100644 (file)
@@ -1,13 +1,13 @@
 /*
              LUFA Library
 /*
              LUFA Library
-     Copyright (C) Dean Camera, 2011.
+     Copyright (C) Dean Camera, 2012.
 
   dean [at] fourwalledcubicle [dot] com
            www.lufa-lib.org
 */
 
 /*
 
   dean [at] fourwalledcubicle [dot] com
            www.lufa-lib.org
 */
 
 /*
-  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+  Copyright 2012  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 
   Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
 
   Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
  *  @{
  */
 
  *  @{
  */
 
-/** \defgroup Group_Debugging Debugging Macros
- *  \brief Convenience macros to aid in debugging applications.
- *
- *  Macros to aid debugging of a user application.
- */
 /** \defgroup Group_GlobalInt Global Interrupt Macros
  *  \brief Convenience macros for the management of interrupts globally within the device.
  *
 /** \defgroup Group_GlobalInt Global Interrupt Macros
  *  \brief Convenience macros for the management of interrupts globally within the device.
  *
 
        /* Macros: */
                #define __INCLUDE_FROM_COMMON_H
 
        /* Macros: */
                #define __INCLUDE_FROM_COMMON_H
-               
+
        /* Includes: */
                #include <stdint.h>
                #include <stdbool.h>
                #include <string.h>
                #include <stddef.h>
        /* Includes: */
                #include <stdint.h>
                #include <stdbool.h>
                #include <string.h>
                #include <stddef.h>
-               
+
+               #if defined(USE_LUFA_CONFIG_HEADER)
+                       #include "LUFAConfig.h"
+               #endif
+
                #include "Architectures.h"
                #include "Architectures.h"
-               #include "Attributes.h"
                #include "BoardTypes.h"
                #include "BoardTypes.h"
-               
+               #include "ArchitectureSpecific.h"
+               #include "CompilerSpecific.h"
+               #include "Attributes.h"
+
+       /* Enable C linkage for C++ Compilers: */
+               #if defined(__cplusplus)
+                       extern "C" {
+               #endif
+
        /* Architecture specific utility includes: */
                #if defined(__DOXYGEN__)
                        /** Type define for an unsigned integer the same width as the selected architecture's machine register.
        /* Architecture specific utility includes: */
                #if defined(__DOXYGEN__)
                        /** Type define for an unsigned integer the same width as the selected architecture's machine register.
                        #include <avr/pgmspace.h>
                        #include <avr/eeprom.h>
                        #include <avr/boot.h>
                        #include <avr/pgmspace.h>
                        #include <avr/eeprom.h>
                        #include <avr/boot.h>
+                       #include <math.h>
                        #include <util/delay.h>
                        #include <util/delay.h>
-                       
+
                        typedef uint8_t uint_reg_t;
                        typedef uint8_t uint_reg_t;
-                       
+
                        #define ARCH_HAS_EEPROM_ADDRESS_SPACE
                        #define ARCH_HAS_FLASH_ADDRESS_SPACE
                        #define ARCH_HAS_MULTI_ADDRESS_SPACE
                        #define ARCH_HAS_EEPROM_ADDRESS_SPACE
                        #define ARCH_HAS_FLASH_ADDRESS_SPACE
                        #define ARCH_HAS_MULTI_ADDRESS_SPACE
                        // =================================================
 
                        typedef uint32_t uint_reg_t;
                        // =================================================
 
                        typedef uint32_t uint_reg_t;
-                       
+
                        #define ARCH_BIG_ENDIAN
 
                        #include "Endianness.h"
                        #define ARCH_BIG_ENDIAN
 
                        #include "Endianness.h"
+               #elif (ARCH == ARCH_XMEGA)
+                       #include <avr/io.h>
+                       #include <avr/interrupt.h>
+                       #include <avr/pgmspace.h>
+                       #include <avr/eeprom.h>
+                       #include <math.h>
+                       #include <util/delay.h>
+
+                       typedef uint8_t uint_reg_t;
+
+                       #define ARCH_HAS_EEPROM_ADDRESS_SPACE
+                       #define ARCH_HAS_FLASH_ADDRESS_SPACE
+                       #define ARCH_HAS_MULTI_ADDRESS_SPACE
+                       #define ARCH_LITTLE_ENDIAN
+
+                       #include "Endianness.h"
                #else
                        #error Unknown device architecture specified.
                #endif
                #else
                        #error Unknown device architecture specified.
                #endif
                         *  \return The larger of the two input parameters
                         */
                        #if !defined(MAX) || defined(__DOXYGEN__)
                         *  \return The larger of the two input parameters
                         */
                        #if !defined(MAX) || defined(__DOXYGEN__)
-                               #define MAX(x, y)               ((x > y) ? x : y)
+                               #define MAX(x, y)               (((x) > (y)) ? (x) : (y))
                        #endif
 
                        /** Convenience macro to determine the smaller of two values.
                        #endif
 
                        /** Convenience macro to determine the smaller of two values.
                         *  \return The smaller of the two input parameters
                         */
                        #if !defined(MIN) || defined(__DOXYGEN__)
                         *  \return The smaller of the two input parameters
                         */
                        #if !defined(MIN) || defined(__DOXYGEN__)
-                               #define MIN(x, y)               ((x < y) ? x : y)
+                               #define MIN(x, y)               (((x) < (y)) ? (x) : (y))
                        #endif
 
                        #endif
 
-                       #if (ARCH == ARCH_AVR8) || defined(__DOXYGEN__)
-                               /** Defines a volatile \c NOP statement which cannot be optimized out by the compiler, and thus can always
-                                *  be set as a breakpoint in the resulting code. Useful for debugging purposes, where the optimiser
-                                *  removes/reorders code to the point where break points cannot reliably be set.
-                                *
-                                *  \note This macro is not available for all architectures.
-                                *
-                                *  \ingroup Group_Debugging
-                                */
-                               #define JTAG_DEBUG_POINT()      __asm__ __volatile__ ("NOP" ::)
-
-                               /** Defines an explicit JTAG break point in the resulting binary via the assembly \c BREAK statement. When
-                                *  a JTAG is used, this causes the program execution to halt when reached until manually resumed.
+                       #if !defined(STRINGIFY) || defined(__DOXYGEN__)
+                               /** Converts the given input into a string, via the C Preprocessor. This macro puts literal quotation
+                                *  marks around the input, converting the source into a string literal.
                                 *
                                 *
-                                *  \note This macro is not available for all architectures.
+                                *  \param[in] x  Input to convert into a string literal.
                                 *
                                 *
-                                *  \ingroup Group_Debugging
+                                *  \return String version of the input.
                                 */
                                 */
-                               #define JTAG_DEBUG_BREAK()      __asm__ __volatile__ ("BREAK" ::)
-
-                               /** Macro for testing condition "x" and breaking via \ref JTAG_DEBUG_BREAK() if the condition is false.
-                                *
-                                *  \note This macro is not available for all architectures.
-                                *
-                                *  \param[in] Condition  Condition that will be evaluated.
-                                *
-                                *  \ingroup Group_Debugging
-                               */
-                               #define JTAG_DEBUG_ASSERT(Condition)    MACROS{ if (!(Condition)) { JTAG_DEBUG_BREAK(); } }MACROE
+                               #define STRINGIFY(x)            #x
 
 
-                               /** Macro for testing condition "x" and writing debug data to the stdout stream if \c false. The stdout stream
-                                *  must be pre-initialized before this macro is run and linked to an output device, such as the microcontroller's
-                                *  USART peripheral.
-                                *
-                                *  The output takes the form "{FILENAME}: Function {FUNCTION NAME}, Line {LINE NUMBER}: Assertion {Condition} failed."
-                                *
-                                *  \note This macro is not available for all architectures.
+                               /** Converts the given input into a string after macro expansion, via the C Preprocessor. This macro puts
+                                *  literal quotation marks around the expanded input, converting the source into a string literal.
                                 *
                                 *
-                                *  \param[in] Condition  Condition that will be evaluated,
+                                *  \param[in] x  Input to expand and convert into a string literal.
                                 *
                                 *
-                                *  \ingroup Group_Debugging
+                                *  \return String version of the expanded input.
                                 */
                                 */
-                               #define STDOUT_ASSERT(Condition)        MACROS{ if (!(x)) { printf_P(PSTR("%s: Function \"%s\", Line %d: "   \
-                                                                               "Assertion \"%s\" failed.\r\n"),     \
-                                                                               __FILE__, __func__, __LINE__, #Condition); } }MACROE
-
-                               #if !defined(pgm_read_ptr) || defined(__DOXYGEN__)
-                                       /** Reads a pointer out of PROGMEM space on the AVR8 architecture. This is currently a wrapper for the
-                                        *  avr-libc \c pgm_read_ptr() macro with a \c void* cast, so that its value can be assigned directly
-                                        *  to a pointer variable or used in pointer arithmetic without further casting in C. In a future
-                                        *  avr-libc distribution this will be part of the standard API and will be implemented in a more formal
-                                        *  manner.
-                                        *
-                                        *  \note This macro is not available for all architectures.
-                                        *
-                                        *  \param[in] Address  Address of the pointer to read.
-                                        *
-                                        *  \return Pointer retrieved from PROGMEM space.
-                                        */
-                                       #define pgm_read_ptr(Address)        (void*)pgm_read_word(Address)
-                               #endif
+                               #define STRINGIFY_EXPANDED(x)   STRINGIFY(x)
                        #endif
                        #endif
-                       
-                       /** Forces GCC to use pointer indirection (via the device's pointer register pairs) when accessing the given
-                        *  struct pointer. In some cases GCC will emit non-optimal assembly code when accessing a structure through
-                        *  a pointer, resulting in a larger binary. When this macro is used on a (non \c const) structure pointer before
-                        *  use, it will force GCC to use pointer indirection on the elements rather than direct store and load
-                        *  instructions.
-                        *
-                        *  \param[in, out] StructPtr  Pointer to a structure which is to be forced into indirect access mode.
-                        */
-                       #define GCC_FORCE_POINTER_ACCESS(StructPtr) __asm__ __volatile__("" : "=b" (StructPtr) : "0" (StructPtr))
-
-                       /** Forces GCC to create a memory barrier, ensuring that memory accesses are not reordered past the barrier point.
-                        *  This can be used before ordering-critical operations, to ensure that the compiler does not re-order the resulting
-                        *  assembly output in an unexpected manner on sections of code that are ordering-specific.
-                        */
-                       #define GCC_MEMORY_BARRIER()                __asm__ __volatile__("" ::: "memory");
-                       
-                       /** Evaluates to boolean true if the specified value can be determined at compile time to be a constant value
-                        *  when compiling under GCC.
-                        *
-                        *  \param[in] x  Value to check compile time constantness of.
-                        *
-                        *  \return Boolean true if the given value is known to be a compile time constant.
-                        */
-                       #define GCC_IS_COMPILE_CONST(x)             __builtin_constant_p(x)
 
                        #if !defined(ISR) || defined(__DOXYGEN__)
                                /** Macro for the definition of interrupt service routines, so that the compiler can insert the required
 
                        #if !defined(ISR) || defined(__DOXYGEN__)
                                /** Macro for the definition of interrupt service routines, so that the compiler can insert the required
                                 *
                                 *  \param Name  Unique name of the interrupt service routine.
                                 */
                                 *
                                 *  \param Name  Unique name of the interrupt service routine.
                                 */
-                               #define ISR(Name, ...)                  void Name (void) __attribute__((__interrupt__)) __VA_ARGS__; void Name (void)
+                               #define ISR(Name, ...)          void Name (void) __attribute__((__interrupt__)) __VA_ARGS__; void Name (void)
                        #endif
 
                /* Inline Functions: */
                        #endif
 
                /* Inline Functions: */
                         *  etc.
                         *
                         *  \param[in] Byte  Byte of data whose bits are to be reversed.
                         *  etc.
                         *
                         *  \param[in] Byte  Byte of data whose bits are to be reversed.
+                        *
+                        *  \return Input data with the individual bits reversed (mirrored).
                         */
                        static inline uint8_t BitReverse(uint8_t Byte) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
                        static inline uint8_t BitReverse(uint8_t Byte)
                         */
                        static inline uint8_t BitReverse(uint8_t Byte) ATTR_WARN_UNUSED_RESULT ATTR_CONST;
                        static inline uint8_t BitReverse(uint8_t Byte)
                         *
                         *  \param[in] Milliseconds  Number of milliseconds to delay
                         */
                         *
                         *  \param[in] Milliseconds  Number of milliseconds to delay
                         */
-                       static inline void Delay_MS(uint8_t Milliseconds) ATTR_ALWAYS_INLINE;
-                       static inline void Delay_MS(uint8_t Milliseconds)
+                       static inline void Delay_MS(uint16_t Milliseconds) ATTR_ALWAYS_INLINE;
+                       static inline void Delay_MS(uint16_t Milliseconds)
                        {
                                #if (ARCH == ARCH_AVR8)
                                if (GCC_IS_COMPILE_CONST(Milliseconds))
                        {
                                #if (ARCH == ARCH_AVR8)
                                if (GCC_IS_COMPILE_CONST(Milliseconds))
                                while (Milliseconds--)
                                {
                                        __builtin_mtsr(AVR32_COUNT, 0);
                                while (Milliseconds--)
                                {
                                        __builtin_mtsr(AVR32_COUNT, 0);
-                                       while (__builtin_mfsr(AVR32_COUNT) < (F_CPU / 1000));                           
+                                       while ((uint32_t)__builtin_mfsr(AVR32_COUNT) < (F_CPU / 1000));
+                               }
+                               #elif (ARCH == ARCH_XMEGA)
+                               if (GCC_IS_COMPILE_CONST(Milliseconds))
+                               {
+                                       _delay_ms(Milliseconds);
+                               }
+                               else
+                               {
+                                       while (Milliseconds--)
+                                         _delay_ms(1);
                                }
                                #endif
                        }
                                }
                                #endif
                        }
                                #if (ARCH == ARCH_AVR8)
                                return SREG;
                                #elif (ARCH == ARCH_UC3)
                                #if (ARCH == ARCH_AVR8)
                                return SREG;
                                #elif (ARCH == ARCH_UC3)
-                               return __builtin_mfsr(AVR32_SR);                                
+                               return __builtin_mfsr(AVR32_SR);
+                               #elif (ARCH == ARCH_XMEGA)
+                               return SREG;
                                #endif
 
                                GCC_MEMORY_BARRIER();
                                #endif
 
                                GCC_MEMORY_BARRIER();
                                  __builtin_ssrf(AVR32_SR_GM_OFFSET);
                                else
                                  __builtin_csrf(AVR32_SR_GM_OFFSET);
                                  __builtin_ssrf(AVR32_SR_GM_OFFSET);
                                else
                                  __builtin_csrf(AVR32_SR_GM_OFFSET);
+                               #elif (ARCH == ARCH_XMEGA)
+                               SREG = GlobalIntState;
                                #endif
                                #endif
-                               
+
                                GCC_MEMORY_BARRIER();
                        }
                                GCC_MEMORY_BARRIER();
                        }
-               
+
                        /** Enables global interrupt handling for the device, allowing interrupts to be handled.
                         *
                         *  \ingroup Group_GlobalInt
                        /** Enables global interrupt handling for the device, allowing interrupts to be handled.
                         *
                         *  \ingroup Group_GlobalInt
                                sei();
                                #elif (ARCH == ARCH_UC3)
                                __builtin_csrf(AVR32_SR_GM_OFFSET);
                                sei();
                                #elif (ARCH == ARCH_UC3)
                                __builtin_csrf(AVR32_SR_GM_OFFSET);
+                               #elif (ARCH == ARCH_XMEGA)
+                               sei();
                                #endif
 
                                GCC_MEMORY_BARRIER();
                                #endif
 
                                GCC_MEMORY_BARRIER();
-                       }               
+                       }
 
                        /** Disabled global interrupt handling for the device, preventing interrupts from being handled.
                         *
 
                        /** Disabled global interrupt handling for the device, preventing interrupts from being handled.
                         *
                                cli();
                                #elif (ARCH == ARCH_UC3)
                                __builtin_ssrf(AVR32_SR_GM_OFFSET);
                                cli();
                                #elif (ARCH == ARCH_UC3)
                                __builtin_ssrf(AVR32_SR_GM_OFFSET);
+                               #elif (ARCH == ARCH_XMEGA)
+                               cli();
                                #endif
 
                                GCC_MEMORY_BARRIER();
                        }
 
                                #endif
 
                                GCC_MEMORY_BARRIER();
                        }
 
+       /* Disable C linkage for C++ Compilers: */
+               #if defined(__cplusplus)
+                       }
+               #endif
+
 #endif
 
 /** @} */
 #endif
 
 /** @} */