summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/avr/avr/interrupt.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/cpu/avr/avr/interrupt.h')
-rw-r--r--cpukit/score/cpu/avr/avr/interrupt.h344
1 files changed, 344 insertions, 0 deletions
diff --git a/cpukit/score/cpu/avr/avr/interrupt.h b/cpukit/score/cpu/avr/avr/interrupt.h
new file mode 100644
index 0000000000..e4077c16bc
--- /dev/null
+++ b/cpukit/score/cpu/avr/avr/interrupt.h
@@ -0,0 +1,344 @@
+/* Copyright (c) 2002,2005,2007 Marek Michalkiewicz
+ Copyright (c) 2007, Dean Camera
+
+ 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 following disclaimer.
+
+ * 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.
+
+ * Neither the name of the copyright holders nor the names of
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 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. */
+
+/* $Id$ */
+
+#ifndef _AVR_INTERRUPT_H_
+#define _AVR_INTERRUPT_H_
+
+#include <avr/io.h>
+
+#if !defined(__DOXYGEN__) && !defined(__STRINGIFY)
+/* Auxiliary macro for ISR_ALIAS(). */
+#define __STRINGIFY(x) #x
+#endif /* !defined(__DOXYGEN__) */
+
+/**
+\file
+\@{
+*/
+
+
+/** \name Global manipulation of the interrupt flag
+
+ The global interrupt flag is maintained in the I bit of the status
+ register (SREG).
+*/
+
+#if defined(__DOXYGEN__)
+/** \def sei()
+ \ingroup avr_interrupts
+
+ \code #include <avr/interrupt.h> \endcode
+
+ Enables interrupts by setting the global interrupt mask. This function
+ actually compiles into a single line of assembly, so there is no function
+ call overhead. */
+#define sei()
+#else /* !DOXYGEN */
+# define sei() __asm__ __volatile__ ("sei" ::)
+#endif /* DOXYGEN */
+
+#if defined(__DOXYGEN__)
+/** \def cli()
+ \ingroup avr_interrupts
+
+ \code #include <avr/interrupt.h> \endcode
+
+ Disables all interrupts by clearing the global interrupt mask. This function
+ actually compiles into a single line of assembly, so there is no function
+ call overhead. */
+#define cli()
+#else /* !DOXYGEN */
+# define cli() __asm__ __volatile__ ("cli" ::)
+#endif /* DOXYGEN */
+
+
+/** \name Macros for writing interrupt handler functions */
+
+
+#if defined(__DOXYGEN__)
+/** \def ISR(vector [, attributes])
+ \ingroup avr_interrupts
+
+ \code #include <avr/interrupt.h> \endcode
+
+ Introduces an interrupt handler function (interrupt service
+ routine) that runs with global interrupts initially disabled
+ by default with no attributes specified.
+
+ The attributes are optional and alter the behaviour and resultant
+ generated code of the interrupt routine. Multiple attributes may
+ be used for a single function, with a space seperating each
+ attribute.
+
+ Valid attributes are ISR_BLOCK, ISR_NOBLOCK, ISR_NAKED and
+ ISR_ALIASOF(vect).
+
+ \c vector must be one of the interrupt vector names that are
+ valid for the particular MCU type.
+*/
+# define ISR(vector, [attributes])
+#else /* real code */
+
+#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+# define __INTR_ATTRS used, externally_visible
+#else /* GCC < 4.1 */
+# define __INTR_ATTRS used
+#endif
+
+#ifdef __cplusplus
+# define ISR(vector, ...) \
+ extern "C" void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
+ void vector (void)
+#else
+# define ISR(vector, ...) \
+ void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
+ void vector (void)
+#endif
+
+#endif /* DOXYGEN */
+
+#if defined(__DOXYGEN__)
+/** \def SIGNAL(vector)
+ \ingroup avr_interrupts
+
+ \code #include <avr/interrupt.h> \endcode
+
+ Introduces an interrupt handler function that runs with global interrupts
+ initially disabled.
+
+ This is the same as the ISR macro without optional attributes.
+ \deprecated Do not use SIGNAL() in new code. Use ISR() instead.
+*/
+# define SIGNAL(vector)
+#else /* real code */
+
+#ifdef __cplusplus
+# define SIGNAL(vector) \
+ extern "C" void vector(void) __attribute__ ((signal, __INTR_ATTRS)); \
+ void vector (void)
+#else
+# define SIGNAL(vector) \
+ void vector (void) __attribute__ ((signal, __INTR_ATTRS)); \
+ void vector (void)
+#endif
+
+#endif /* DOXYGEN */
+
+#if defined(__DOXYGEN__)
+/** \def EMPTY_INTERRUPT(vector)
+ \ingroup avr_interrupts
+
+ \code #include <avr/interrupt.h> \endcode
+
+ Defines an empty interrupt handler function. This will not generate
+ any prolog or epilog code and will only return from the ISR. Do not
+ define a function body as this will define it for you.
+ Example:
+ \code EMPTY_INTERRUPT(ADC_vect);\endcode */
+# define EMPTY_INTERRUPT(vector)
+#else /* real code */
+
+#ifdef __cplusplus
+# define EMPTY_INTERRUPT(vector) \
+ extern "C" void vector(void) __attribute__ ((signal,naked,__INTR_ATTRS)); \
+ void vector (void) { __asm__ __volatile__ ("reti" ::); }
+#else
+# define EMPTY_INTERRUPT(vector) \
+ void vector (void) __attribute__ ((signal,naked,__INTR_ATTRS)); \
+ void vector (void) { __asm__ __volatile__ ("reti" ::); }
+#endif
+
+#endif /* DOXYGEN */
+
+#if defined(__DOXYGEN__)
+/** \def ISR_ALIAS(vector, target_vector)
+ \ingroup avr_interrupts
+
+ \code #include <avr/interrupt.h> \endcode
+
+ Aliases a given vector to another one in the same manner as the
+ ISR_ALIASOF attribute for the ISR() macro. Unlike the ISR_ALIASOF
+ attribute macro however, this is compatible for all versions of
+ GCC rather than just GCC version 4.2 onwards.
+
+ \note This macro creates a trampoline function for the aliased
+ macro. This will result in a two cycle penalty for the aliased
+ vector compared to the ISR the vector is aliased to, due to the
+ JMP/RJMP opcode used.
+
+ \deprecated
+ For new code, the use of ISR(..., ISR_ALIASOF(...)) is
+ recommended.
+
+ Example:
+ \code
+ ISR(INT0_vect)
+ {
+ PORTB = 42;
+ }
+
+ ISR_ALIAS(INT1_vect, INT0_vect);
+ \endcode
+*/
+# define ISR_ALIAS(vector, target_vector)
+#else /* real code */
+
+#ifdef __cplusplus
+# if defined(__AVR_MEGA__) && __AVR_MEGA__
+# define ISR_ALIAS(vector, tgt) extern "C" void vector (void) \
+ __attribute__((signal, naked, __INTR_ATTRS)); \
+ void vector (void) { __asm__ volatile ("jmp " __STRINGIFY(tgt) ::); }
+# else /* !__AVR_MEGA */
+# define ISR_ALIAS(vector, tgt) extern "C" void vector (void) \
+ __attribute__((signal, naked, __INTR_ATTRS)); \
+ void vector (void) { __asm__ volatile ("rjmp " __STRINGIFY(tgt) ::); }
+# endif /* __AVR_MEGA__ */
+#else /* !__cplusplus */
+# if defined(__AVR_MEGA__) && __AVR_MEGA__
+# define ISR_ALIAS(vector, tgt) void vector (void) \
+ __attribute__((signal, naked, __INTR_ATTRS)); \
+ void vector (void) { __asm__ volatile ("jmp " __STRINGIFY(tgt) ::); }
+# else /* !__AVR_MEGA */
+# define ISR_ALIAS(vector, tgt) void vector (void) \
+ __attribute__((signal, naked, __INTR_ATTRS)); \
+ void vector (void) { __asm__ volatile ("rjmp " __STRINGIFY(tgt) ::); }
+# endif /* __AVR_MEGA__ */
+#endif /* __cplusplus */
+
+#endif /* DOXYGEN */
+
+#if defined(__DOXYGEN__)
+/** \def reti()
+ \ingroup avr_interrupts
+
+ \code #include <avr/interrupt.h> \endcode
+
+ Returns from an interrupt routine, enabling global interrupts. This should
+ be the last command executed before leaving an ISR defined with the ISR_NAKED
+ attribute.
+
+ This macro actually compiles into a single line of assembly, so there is
+ no function call overhead.
+*/
+# define reti()
+#else /* !DOXYGEN */
+# define reti() __asm__ __volatile__ ("reti" ::)
+#endif /* DOXYGEN */
+
+#if defined(__DOXYGEN__)
+/** \def BADISR_vect
+ \ingroup avr_interrupts
+
+ \code #include <avr/interrupt.h> \endcode
+
+ This is a vector which is aliased to __vector_default, the vector
+ executed when an ISR fires with no accompanying ISR handler. This
+ may be used along with the ISR() macro to create a catch-all for
+ undefined but used ISRs for debugging purposes.
+*/
+# define BADISR_vect
+#else /* !DOXYGEN */
+# define BADISR_vect __vector_default
+#endif /* DOXYGEN */
+
+/** \name ISR attributes */
+
+#if defined(__DOXYGEN__)
+/** \def ISR_BLOCK
+ \ingroup avr_interrupts
+
+ \code# include <avr/interrupt.h> \endcode
+
+ Identical to an ISR with no attributes specified. Global
+ interrupts are initially disabled by the AVR hardware when
+ entering the ISR, without the compiler modifying this state.
+
+ Use this attribute in the attributes parameter of the ISR macro.
+*/
+# define ISR_BLOCK
+
+/** \def ISR_NOBLOCK
+ \ingroup avr_interrupts
+
+ \code# include <avr/interrupt.h> \endcode
+
+ ISR runs with global interrupts initially enabled. The interrupt
+ enable flag is activated by the compiler as early as possible
+ within the ISR to ensure minimal processing delay for nested
+ interrupts.
+
+ This may be used to create nested ISRs, however care should be
+ taken to avoid stack overflows, or to avoid infinitely entering
+ the ISR for those cases where the AVR hardware does not clear the
+ respective interrupt flag before entering the ISR.
+
+ Use this attribute in the attributes parameter of the ISR macro.
+*/
+# define ISR_NOBLOCK
+
+/** \def ISR_NAKED
+ \ingroup avr_interrupts
+
+ \code# include <avr/interrupt.h> \endcode
+
+ ISR is created with no prologue or epilogue code. The user code is
+ responsible for preservation of the machine state including the
+ SREG register, as well as placing a reti() at the end of the
+ interrupt routine.
+
+ Use this attribute in the attributes parameter of the ISR macro.
+*/
+# define ISR_NAKED
+
+/** \def ISR_ALIASOF(target_vector)
+ \ingroup avr_interrupts
+
+ \code#include <avr/interrupt.h>\endcode
+
+ The ISR is linked to another ISR, specified by the vect parameter.
+ This is compatible with GCC 4.2 and greater only.
+
+ Use this attribute in the attributes parameter of the ISR macro.
+*/
+# define ISR_ALIASOF(target_vector)
+#else /* !DOXYGEN */
+# define ISR_BLOCK
+# define ISR_NOBLOCK __attribute__((interrupt))
+# define ISR_NAKED __attribute__((naked))
+# define ISR_ALIASOF(v) __attribute__((alias(__STRINGIFY(v))))
+#endif /* DOXYGEN */
+
+/* \@} */
+
+#endif