72 |
|
|
73 |
/*@}*/ |
/*@}*/ |
74 |
|
|
75 |
#ifdef __cplusplus |
/** \name Macros for writing interrupt handler functions */ |
|
extern "C" { |
|
|
#endif |
|
76 |
|
|
77 |
/** \name Allowing specific system-wide interrupts |
/*@{*/ |
78 |
|
|
79 |
In addition to globally enabling interrupts, each device's particular |
/** \def ISR(vector) |
80 |
interrupt needs to be enabled separately if interrupts for this device are |
\ingroup avr_interrupts |
|
desired. While some devices maintain their interrupt enable bit inside |
|
|
the device's register set, external and timer interrupts have system-wide |
|
|
configuration registers. |
|
81 |
|
|
82 |
Example: |
\code#include <avr/interrupt.h>\endcode |
83 |
|
|
84 |
\code |
Introduces an interrupt handler function (interrupt service |
85 |
// Enable timer 1 overflow interrupts. |
routine) that runs with global interrupts initially disabled. |
|
timer_enable_int(_BV(TOIE1)); |
|
|
|
|
|
// Do some work... |
|
|
|
|
|
// Disable all timer interrupts. |
|
|
timer_enable_int(0); |
|
|
\endcode |
|
|
|
|
|
\note Be careful when you use these functions. If you already have a |
|
|
different interrupt enabled, you could inadvertantly disable it by |
|
|
enabling another intterupt. */ |
|
86 |
|
|
87 |
/*@{*/ |
\c vector must be one of the interrupt vector names that are |
88 |
|
valid for the particular MCU type. |
89 |
|
*/ |
90 |
|
|
91 |
/** \ingroup avr_interrupts |
#ifdef __cplusplus |
92 |
\def enable_external_int(mask) |
#define ISR(vector) \ |
93 |
\code#include <avr/interrupt.h>\endcode |
extern "C" void vector(void); \ |
94 |
|
void vector (void) __attribute__ ((signal)); \ |
95 |
This macro gives access to the \c GIMSK register (or \c EIMSK register |
void vector (void) |
96 |
if using an AVR Mega device or \c GICR register for others). Although this |
#else |
97 |
macro is essentially the same as assigning to the register, it does |
#define ISR(vector) \ |
98 |
adapt slightly to the type of device being used. This macro is |
void vector (void) __attribute__ ((signal)); \ |
99 |
unavailable if none of the registers listed above are defined. */ |
void vector (void) |
|
|
|
|
/* Define common register definition if available. */ |
|
|
#if defined(EIMSK) |
|
|
# define __EICR EIMSK |
|
|
#elif defined(GIMSK) |
|
|
# define __EICR GIMSK |
|
|
#elif defined(GICR) |
|
|
# define __EICR GICR |
|
100 |
#endif |
#endif |
101 |
|
|
102 |
/* If common register defined, define macro. */ |
/** \def SIGNAL(signame) |
103 |
#if defined(__EICR) || defined(__DOXYGEN__) |
\ingroup avr_interrupts |
|
#define enable_external_int(mask) (__EICR = mask) |
|
|
#endif |
|
104 |
|
|
105 |
|
\code#include <avr/interrupt.h>\endcode |
106 |
|
|
107 |
|
Introduces an interrupt handler function that runs with global interrupts |
108 |
|
initially disabled. |
109 |
|
|
110 |
/** \ingroup avr_interrupts |
This is the same as the ISR macro. |
111 |
|
\note Do not use anymore in new code, it will be deprecated |
112 |
|
in a future release. |
113 |
|
*/ |
114 |
|
|
115 |
|
#ifdef __cplusplus |
116 |
|
#define SIGNAL(signame) \ |
117 |
|
extern "C" void signame(void); \ |
118 |
|
void signame (void) __attribute__ ((signal)); \ |
119 |
|
void signame (void) |
120 |
|
#else |
121 |
|
#define SIGNAL(signame) \ |
122 |
|
void signame (void) __attribute__ ((signal)); \ |
123 |
|
void signame (void) |
124 |
|
#endif |
125 |
|
|
126 |
|
/** \def EMPTY_INTERRUPT(signame) |
127 |
|
\ingroup avr_interrupts |
128 |
|
|
129 |
\code#include <avr/interrupt.h>\endcode |
\code#include <avr/interrupt.h>\endcode |
130 |
|
|
131 |
This function modifies the \c timsk register. |
Defines an empty interrupt handler function. This will not generate |
132 |
The value you pass via \c ints is device specific. */ |
any prolog or epilog code and will only return from the ISR. Do not |
133 |
|
define a function body as this will define it for you. |
134 |
|
Example: |
135 |
|
\code EMPTY_INTERRUPT(ADC_vect);\endcode */ |
136 |
|
|
137 |
static __inline__ void timer_enable_int (unsigned char ints) |
#ifdef __cplusplus |
138 |
{ |
#define EMPTY_INTERRUPT(vector) \ |
139 |
#ifdef TIMSK |
extern "C" void vector(void); \ |
140 |
TIMSK = ints; |
void vector (void) __attribute__ ((naked)); \ |
141 |
|
void vector (void) { __asm__ __volatile__ ("reti" ::); } |
142 |
|
#else |
143 |
|
#define EMPTY_INTERRUPT(vector) \ |
144 |
|
void vector (void) __attribute__ ((naked)); \ |
145 |
|
void vector (void) { __asm__ __volatile__ ("reti" ::); } |
146 |
#endif |
#endif |
147 |
} |
|
148 |
|
|
149 |
|
|
150 |
/*@}*/ |
/*@}*/ |
151 |
|
|
152 |
#ifdef __cplusplus |
#ifdef __cplusplus |
153 |
|
extern "C" { |
154 |
|
#endif |
155 |
|
|
156 |
|
#ifdef __cplusplus |
157 |
} |
} |
158 |
#endif |
#endif |
159 |
|
|