Add build tests to verify correct compilation of as many modules as possible under...
[pub/USBasp.git] / LUFA / Common / Common.h
index 87fc08c..4c9aa49 100644 (file)
@@ -1,13 +1,13 @@
 /*
              LUFA Library
-     Copyright (C) Dean Camera, 2011.
+     Copyright (C) Dean Camera, 2012.
 
   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
  *  @{
  */
 
-/** \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.
  *
 
        /* Macros: */
                #define __INCLUDE_FROM_COMMON_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 "CompilerSpecific.h"
                #include "Architectures.h"
-               #include "Attributes.h"
                #include "BoardTypes.h"
-               
+               #include "ArchitectureSpecific.h"
+               #include "CompilerSpecific.h"
+               #include "Attributes.h"
+
        /* Enable C linkage for C++ Compilers: */
                #if defined(__cplusplus)
                        extern "C" {
                        #include <avr/pgmspace.h>
                        #include <avr/eeprom.h>
                        #include <avr/boot.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
                        // =================================================
 
                        typedef uint32_t uint_reg_t;
-                       
+
                        #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
                         *  \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.
                         *  \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
 
-                       #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 optimizer
-                                *  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.
+                               /** 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.
                                 *
-                                *  The output takes the form "{FILENAME}: Function {FUNCTION NAME}, Line {LINE NUMBER}: Assertion {Condition} failed."
+                                *  \param[in] x  Input to expand and convert into a string literal.
                                 *
-                                *  \note This macro is not available for all architectures.
-                                *
-                                *  \param[in] Condition  Condition that will be evaluated,
-                                *
-                                *  \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
 
                        #if !defined(ISR) || defined(__DOXYGEN__)
                                 *
                                 *  \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: */
                         *  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)
                         *
                         *  \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))
                                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
                        }
                                #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();
                                  __builtin_ssrf(AVR32_SR_GM_OFFSET);
                                else
                                  __builtin_csrf(AVR32_SR_GM_OFFSET);
+                               #elif (ARCH == ARCH_XMEGA)
+                               SREG = GlobalIntState;
                                #endif
-                               
+
                                GCC_MEMORY_BARRIER();
                        }
-               
+
                        /** 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);
+                               #elif (ARCH == ARCH_XMEGA)
+                               sei();
                                #endif
 
                                GCC_MEMORY_BARRIER();
-                       }               
+                       }
 
                        /** Disabled global interrupt handling for the device, preventing interrupts from being handled.
                         *
                                cli();
                                #elif (ARCH == ARCH_UC3)
                                __builtin_ssrf(AVR32_SR_GM_OFFSET);
+                               #elif (ARCH == ARCH_XMEGA)
+                               cli();
                                #endif
 
                                GCC_MEMORY_BARRIER();