source: arduino-1-6-7/trunk/fuentes/arduino-ide-amd64/hardware/arduino/avr/cores/arduino/WInterrupts.c @ 4837

Last change on this file since 4837 was 4837, checked in by daduve, 3 years ago

Adding new version

File size: 9.2 KB
Line 
1/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
3/*
4  Part of the Wiring project - http://wiring.uniandes.edu.co
5
6  Copyright (c) 2004-05 Hernando Barragan
7
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  Lesser General Public License for more details.
17
18  You should have received a copy of the GNU Lesser General
19  Public License along with this library; if not, write to the
20  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
21  Boston, MA  02111-1307  USA
22 
23  Modified 24 November 2006 by David A. Mellis
24  Modified 1 August 2010 by Mark Sproul
25*/
26
27#include <inttypes.h>
28#include <avr/io.h>
29#include <avr/interrupt.h>
30#include <avr/pgmspace.h>
31#include <stdio.h>
32
33#include "wiring_private.h"
34
35static void nothing(void) {
36}
37
38static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS] = {
39#if EXTERNAL_NUM_INTERRUPTS > 8
40    #warning There are more than 8 external interrupts. Some callbacks may not be initialized.
41    nothing,
42#endif
43#if EXTERNAL_NUM_INTERRUPTS > 7
44    nothing,
45#endif
46#if EXTERNAL_NUM_INTERRUPTS > 6
47    nothing,
48#endif
49#if EXTERNAL_NUM_INTERRUPTS > 5
50    nothing,
51#endif
52#if EXTERNAL_NUM_INTERRUPTS > 4
53    nothing,
54#endif
55#if EXTERNAL_NUM_INTERRUPTS > 3
56    nothing,
57#endif
58#if EXTERNAL_NUM_INTERRUPTS > 2
59    nothing,
60#endif
61#if EXTERNAL_NUM_INTERRUPTS > 1
62    nothing,
63#endif
64#if EXTERNAL_NUM_INTERRUPTS > 0
65    nothing,
66#endif
67};
68// volatile static voidFuncPtr twiIntFunc;
69
70void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
71  if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
72    intFunc[interruptNum] = userFunc;
73   
74    // Configure the interrupt mode (trigger on low input, any change, rising
75    // edge, or falling edge).  The mode constants were chosen to correspond
76    // to the configuration bits in the hardware register, so we simply shift
77    // the mode into place.
78     
79    // Enable the interrupt.
80     
81    switch (interruptNum) {
82#if defined(__AVR_ATmega32U4__)
83        // I hate doing this, but the register assignment differs between the 1280/2560
84        // and the 32U4.  Since avrlib defines registers PCMSK1 and PCMSK2 that aren't
85        // even present on the 32U4 this is the only way to distinguish between them.
86    case 0:
87        EICRA = (EICRA & ~((1<<ISC00) | (1<<ISC01))) | (mode << ISC00);
88        EIMSK |= (1<<INT0);
89        break;
90    case 1:
91        EICRA = (EICRA & ~((1<<ISC10) | (1<<ISC11))) | (mode << ISC10);
92        EIMSK |= (1<<INT1);
93        break; 
94    case 2:
95        EICRA = (EICRA & ~((1<<ISC20) | (1<<ISC21))) | (mode << ISC20);
96        EIMSK |= (1<<INT2);
97        break;
98    case 3:
99        EICRA = (EICRA & ~((1<<ISC30) | (1<<ISC31))) | (mode << ISC30);
100        EIMSK |= (1<<INT3);
101        break;
102    case 4:
103        EICRB = (EICRB & ~((1<<ISC60) | (1<<ISC61))) | (mode << ISC60);
104        EIMSK |= (1<<INT6);
105        break;
106#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
107    case 2:
108      EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
109      EIMSK |= (1 << INT0);
110      break;
111    case 3:
112      EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
113      EIMSK |= (1 << INT1);
114      break;
115    case 4:
116      EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
117      EIMSK |= (1 << INT2);
118      break;
119    case 5:
120      EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30);
121      EIMSK |= (1 << INT3);
122      break;
123    case 0:
124      EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40);
125      EIMSK |= (1 << INT4);
126      break;
127    case 1:
128      EICRB = (EICRB & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50);
129      EIMSK |= (1 << INT5);
130      break;
131    case 6:
132      EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60);
133      EIMSK |= (1 << INT6);
134      break;
135    case 7:
136      EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
137      EIMSK |= (1 << INT7);
138      break;
139#else           
140    case 0:
141    #if defined(EICRA) && defined(ISC00) && defined(EIMSK)
142      EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
143      EIMSK |= (1 << INT0);
144    #elif defined(MCUCR) && defined(ISC00) && defined(GICR)
145      MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
146      GICR |= (1 << INT0);
147    #elif defined(MCUCR) && defined(ISC00) && defined(GIMSK)
148      MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
149      GIMSK |= (1 << INT0);
150    #else
151      #error attachInterrupt not finished for this CPU (case 0)
152    #endif
153      break;
154
155    case 1:
156    #if defined(EICRA) && defined(ISC10) && defined(ISC11) && defined(EIMSK)
157      EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
158      EIMSK |= (1 << INT1);
159    #elif defined(MCUCR) && defined(ISC10) && defined(ISC11) && defined(GICR)
160      MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
161      GICR |= (1 << INT1);
162    #elif defined(MCUCR) && defined(ISC10) && defined(GIMSK) && defined(GIMSK)
163      MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
164      GIMSK |= (1 << INT1);
165    #else
166      #warning attachInterrupt may need some more work for this cpu (case 1)
167    #endif
168      break;
169   
170    case 2:
171    #if defined(EICRA) && defined(ISC20) && defined(ISC21) && defined(EIMSK)
172      EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
173      EIMSK |= (1 << INT2);
174    #elif defined(MCUCR) && defined(ISC20) && defined(ISC21) && defined(GICR)
175      MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
176      GICR |= (1 << INT2);
177    #elif defined(MCUCR) && defined(ISC20) && defined(GIMSK) && defined(GIMSK)
178      MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
179      GIMSK |= (1 << INT2);
180    #endif
181      break;
182#endif
183    }
184  }
185}
186
187void detachInterrupt(uint8_t interruptNum) {
188  if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
189    // Disable the interrupt.  (We can't assume that interruptNum is equal
190    // to the number of the EIMSK bit to clear, as this isn't true on the
191    // ATmega8.  There, INT0 is 6 and INT1 is 7.)
192    switch (interruptNum) {
193#if defined(__AVR_ATmega32U4__)
194    case 0:
195        EIMSK &= ~(1<<INT0);
196        break;
197    case 1:
198        EIMSK &= ~(1<<INT1);
199        break;
200    case 2:
201        EIMSK &= ~(1<<INT2);
202        break;
203    case 3:
204        EIMSK &= ~(1<<INT3);
205        break; 
206    case 4:
207        EIMSK &= ~(1<<INT6);
208        break; 
209#elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
210    case 2:
211      EIMSK &= ~(1 << INT0);
212      break;
213    case 3:
214      EIMSK &= ~(1 << INT1);
215      break;
216    case 4:
217      EIMSK &= ~(1 << INT2);
218      break;
219    case 5:
220      EIMSK &= ~(1 << INT3);
221      break;
222    case 0:
223      EIMSK &= ~(1 << INT4);
224      break;
225    case 1:
226      EIMSK &= ~(1 << INT5);
227      break;
228    case 6:
229      EIMSK &= ~(1 << INT6);
230      break;
231    case 7:
232      EIMSK &= ~(1 << INT7);
233      break;
234#else
235    case 0:
236    #if defined(EIMSK) && defined(INT0)
237      EIMSK &= ~(1 << INT0);
238    #elif defined(GICR) && defined(ISC00)
239      GICR &= ~(1 << INT0); // atmega32
240    #elif defined(GIMSK) && defined(INT0)
241      GIMSK &= ~(1 << INT0);
242    #else
243      #error detachInterrupt not finished for this cpu
244    #endif
245      break;
246
247    case 1:
248    #if defined(EIMSK) && defined(INT1)
249      EIMSK &= ~(1 << INT1);
250    #elif defined(GICR) && defined(INT1)
251      GICR &= ~(1 << INT1); // atmega32
252    #elif defined(GIMSK) && defined(INT1)
253      GIMSK &= ~(1 << INT1);
254    #else
255      #warning detachInterrupt may need some more work for this cpu (case 1)
256    #endif
257      break;
258     
259    case 2:
260    #if defined(EIMSK) && defined(INT2)
261      EIMSK &= ~(1 << INT2);
262    #elif defined(GICR) && defined(INT2)
263      GICR &= ~(1 << INT2); // atmega32
264    #elif defined(GIMSK) && defined(INT2)
265      GIMSK &= ~(1 << INT2);
266    #elif defined(INT2)
267      #warning detachInterrupt may need some more work for this cpu (case 2)
268    #endif
269      break;       
270#endif
271    }
272     
273    intFunc[interruptNum] = nothing;
274  }
275}
276
277/*
278void attachInterruptTwi(void (*userFunc)(void) ) {
279  twiIntFunc = userFunc;
280}
281*/
282
283#define IMPLEMENT_ISR(vect, interrupt) \
284  ISR(vect) { \
285    intFunc[interrupt](); \
286  }
287
288#if defined(__AVR_ATmega32U4__)
289
290IMPLEMENT_ISR(INT0_vect, EXTERNAL_INT_0)
291IMPLEMENT_ISR(INT1_vect, EXTERNAL_INT_1)
292IMPLEMENT_ISR(INT2_vect, EXTERNAL_INT_2)
293IMPLEMENT_ISR(INT3_vect, EXTERNAL_INT_3)
294IMPLEMENT_ISR(INT6_vect, EXTERNAL_INT_4)
295
296#elif defined(EICRA) && defined(EICRB)
297
298IMPLEMENT_ISR(INT0_vect, EXTERNAL_INT_2)
299IMPLEMENT_ISR(INT1_vect, EXTERNAL_INT_3)
300IMPLEMENT_ISR(INT2_vect, EXTERNAL_INT_4)
301IMPLEMENT_ISR(INT3_vect, EXTERNAL_INT_5)
302IMPLEMENT_ISR(INT4_vect, EXTERNAL_INT_0)
303IMPLEMENT_ISR(INT5_vect, EXTERNAL_INT_1)
304IMPLEMENT_ISR(INT6_vect, EXTERNAL_INT_6)
305IMPLEMENT_ISR(INT7_vect, EXTERNAL_INT_7)
306
307#else
308
309IMPLEMENT_ISR(INT0_vect, EXTERNAL_INT_0)
310IMPLEMENT_ISR(INT1_vect, EXTERNAL_INT_1)
311
312#if defined(EICRA) && defined(ISC20)
313IMPLEMENT_ISR(INT2_vect, EXTERNAL_INT_2)
314#endif
315
316#endif
317
318/*
319ISR(TWI_vect) {
320  if(twiIntFunc)
321    twiIntFunc();
322}
323*/
324
Note: See TracBrowser for help on using the repository browser.