Statistics
| Branch: | Revision:

root / arduino-1.0 / hardware / arduino / cores / arduino / WInterrupts.c @ 58d82c77

History | View | Annotate | Download (6.53 KB)

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

    
35
volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
36
// volatile static voidFuncPtr twiIntFunc;
37

    
38
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
39
  if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
40
    intFunc[interruptNum] = userFunc;
41
    
42
    // Configure the interrupt mode (trigger on low input, any change, rising
43
    // edge, or falling edge).  The mode constants were chosen to correspond
44
    // to the configuration bits in the hardware register, so we simply shift
45
    // the mode into place.
46
      
47
    // Enable the interrupt.
48
      
49
    switch (interruptNum) {
50
#if defined(EICRA) && defined(EICRB) && defined(EIMSK)
51
    case 2:
52
      EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
53
      EIMSK |= (1 << INT0);
54
      break;
55
    case 3:
56
      EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
57
      EIMSK |= (1 << INT1);
58
      break;
59
    case 4:
60
      EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
61
      EIMSK |= (1 << INT2);
62
      break;
63
    case 5:
64
      EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30);
65
      EIMSK |= (1 << INT3);
66
      break;
67
    case 0:
68
      EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40);
69
      EIMSK |= (1 << INT4);
70
      break;
71
    case 1:
72
      EICRB = (EICRB & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50);
73
      EIMSK |= (1 << INT5);
74
      break;
75
    case 6:
76
      EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60);
77
      EIMSK |= (1 << INT6);
78
      break;
79
    case 7:
80
      EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
81
      EIMSK |= (1 << INT7);
82
      break;
83
#else
84
    case 0:
85
    #if defined(EICRA) && defined(ISC00) && defined(EIMSK)
86
      EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
87
      EIMSK |= (1 << INT0);
88
    #elif defined(MCUCR) && defined(ISC00) && defined(GICR)
89
      MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
90
      GICR |= (1 << INT0);
91
    #elif defined(MCUCR) && defined(ISC00) && defined(GIMSK)
92
      MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
93
      GIMSK |= (1 << INT0);
94
    #else
95
      #error attachInterrupt not finished for this CPU (case 0)
96
    #endif
97
      break;
98

    
99
    case 1:
100
    #if defined(EICRA) && defined(ISC10) && defined(ISC11) && defined(EIMSK)
101
      EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
102
      EIMSK |= (1 << INT1);
103
    #elif defined(MCUCR) && defined(ISC10) && defined(ISC11) && defined(GICR)
104
      MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
105
      GICR |= (1 << INT1);
106
    #elif defined(MCUCR) && defined(ISC10) && defined(GIMSK) && defined(GIMSK)
107
      MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
108
      GIMSK |= (1 << INT1);
109
    #else
110
      #warning attachInterrupt may need some more work for this cpu (case 1)
111
    #endif
112
      break;
113
#endif
114
    }
115
  }
116
}
117

    
118
void detachInterrupt(uint8_t interruptNum) {
119
  if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
120
    // Disable the interrupt.  (We can't assume that interruptNum is equal
121
    // to the number of the EIMSK bit to clear, as this isn't true on the 
122
    // ATmega8.  There, INT0 is 6 and INT1 is 7.)
123
    switch (interruptNum) {
124
#if defined(EICRA) && defined(EICRB) && defined(EIMSK)
125
    case 2:
126
      EIMSK &= ~(1 << INT0);
127
      break;
128
    case 3:
129
      EIMSK &= ~(1 << INT1);
130
      break;
131
    case 4:
132
      EIMSK &= ~(1 << INT2);
133
      break;
134
    case 5:
135
      EIMSK &= ~(1 << INT3);
136
      break;
137
    case 0:
138
      EIMSK &= ~(1 << INT4);
139
      break;
140
    case 1:
141
      EIMSK &= ~(1 << INT5);
142
      break;
143
    case 6:
144
      EIMSK &= ~(1 << INT6);
145
      break;
146
    case 7:
147
      EIMSK &= ~(1 << INT7);
148
      break;
149
#else
150
    case 0:
151
    #if defined(EIMSK) && defined(INT0)
152
      EIMSK &= ~(1 << INT0);
153
    #elif defined(GICR) && defined(ISC00)
154
      GICR &= ~(1 << INT0); // atmega32
155
    #elif defined(GIMSK) && defined(INT0)
156
      GIMSK &= ~(1 << INT0);
157
    #else
158
      #error detachInterrupt not finished for this cpu
159
    #endif
160
      break;
161

    
162
    case 1:
163
    #if defined(EIMSK) && defined(INT1)
164
      EIMSK &= ~(1 << INT1);
165
    #elif defined(GICR) && defined(INT1)
166
      GICR &= ~(1 << INT1); // atmega32
167
    #elif defined(GIMSK) && defined(INT1)
168
      GIMSK &= ~(1 << INT1);
169
    #else
170
      #warning detachInterrupt may need some more work for this cpu (case 1)
171
    #endif
172
      break;
173
#endif
174
    }
175
      
176
    intFunc[interruptNum] = 0;
177
  }
178
}
179

    
180
/*
181
void attachInterruptTwi(void (*userFunc)(void) ) {
182
  twiIntFunc = userFunc;
183
}
184
*/
185

    
186
#if defined(EICRA) && defined(EICRB)
187

    
188
SIGNAL(INT0_vect) {
189
  if(intFunc[EXTERNAL_INT_2])
190
    intFunc[EXTERNAL_INT_2]();
191
}
192

    
193
SIGNAL(INT1_vect) {
194
  if(intFunc[EXTERNAL_INT_3])
195
    intFunc[EXTERNAL_INT_3]();
196
}
197

    
198
SIGNAL(INT2_vect) {
199
  if(intFunc[EXTERNAL_INT_4])
200
    intFunc[EXTERNAL_INT_4]();
201
}
202

    
203
SIGNAL(INT3_vect) {
204
  if(intFunc[EXTERNAL_INT_5])
205
    intFunc[EXTERNAL_INT_5]();
206
}
207

    
208
SIGNAL(INT4_vect) {
209
  if(intFunc[EXTERNAL_INT_0])
210
    intFunc[EXTERNAL_INT_0]();
211
}
212

    
213
SIGNAL(INT5_vect) {
214
  if(intFunc[EXTERNAL_INT_1])
215
    intFunc[EXTERNAL_INT_1]();
216
}
217

    
218
SIGNAL(INT6_vect) {
219
  if(intFunc[EXTERNAL_INT_6])
220
    intFunc[EXTERNAL_INT_6]();
221
}
222

    
223
SIGNAL(INT7_vect) {
224
  if(intFunc[EXTERNAL_INT_7])
225
    intFunc[EXTERNAL_INT_7]();
226
}
227

    
228
#else
229

    
230
SIGNAL(INT0_vect) {
231
  if(intFunc[EXTERNAL_INT_0])
232
    intFunc[EXTERNAL_INT_0]();
233
}
234

    
235
SIGNAL(INT1_vect) {
236
  if(intFunc[EXTERNAL_INT_1])
237
    intFunc[EXTERNAL_INT_1]();
238
}
239

    
240
#endif
241

    
242
/*
243
SIGNAL(SIG_2WIRE_SERIAL) {
244
  if(twiIntFunc)
245
    twiIntFunc();
246
}
247
*/
248