Index

auto-plow / c7eae65

A wheelchair motor-propelled battery-powered ESP32-driven remote control snow plow.

Latest Commit

{#}TimeHashSubjectAuthor#(+)(-)GPG?
630 Nov 2018 18:364a63c8cInclude Arduino core filesJoshua13240N

Blob @ auto-plow / include / arduino / WInterrupts.c

text/plain9409 bytesdownload raw
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
325