| 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 |
|
|