Fri, 17 Nov 2017 10:13:31 +0100
proper configuration, homing and planner optimization
2 | 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 | static volatile 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(__AVR_ATmega32U4__) | |
51 | // I hate doing this, but the register assignment differs between the 1280/2560 | |
52 | // and the 32U4. Since avrlib defines registers PCMSK1 and PCMSK2 that aren't | |
53 | // even present on the 32U4 this is the only way to distinguish between them. | |
54 | case 0: | |
55 | EICRA = (EICRA & ~((1<<ISC00) | (1<<ISC01))) | (mode << ISC00); | |
56 | EIMSK |= (1<<INT0); | |
57 | break; | |
58 | case 1: | |
59 | EICRA = (EICRA & ~((1<<ISC10) | (1<<ISC11))) | (mode << ISC10); | |
60 | EIMSK |= (1<<INT1); | |
61 | break; | |
62 | #elif defined(EICRA) && defined(EICRB) && defined(EIMSK) | |
63 | case 2: | |
64 | EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); | |
65 | EIMSK |= (1 << INT0); | |
66 | break; | |
67 | case 3: | |
68 | EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); | |
69 | EIMSK |= (1 << INT1); | |
70 | break; | |
71 | case 4: | |
72 | EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20); | |
73 | EIMSK |= (1 << INT2); | |
74 | break; | |
75 | case 5: | |
76 | EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30); | |
77 | EIMSK |= (1 << INT3); | |
78 | break; | |
79 | case 0: | |
80 | EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40); | |
81 | EIMSK |= (1 << INT4); | |
82 | break; | |
83 | case 1: | |
84 | EICRB = (EICRB & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50); | |
85 | EIMSK |= (1 << INT5); | |
86 | break; | |
87 | case 6: | |
88 | EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60); | |
89 | EIMSK |= (1 << INT6); | |
90 | break; | |
91 | case 7: | |
92 | EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70); | |
93 | EIMSK |= (1 << INT7); | |
94 | break; | |
95 | #else | |
96 | case 0: | |
97 | #if defined(EICRA) && defined(ISC00) && defined(EIMSK) | |
98 | EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); | |
99 | EIMSK |= (1 << INT0); | |
100 | #elif defined(MCUCR) && defined(ISC00) && defined(GICR) | |
101 | MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); | |
102 | GICR |= (1 << INT0); | |
103 | #elif defined(MCUCR) && defined(ISC00) && defined(GIMSK) | |
104 | MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); | |
105 | GIMSK |= (1 << INT0); | |
106 | #else | |
107 | #error attachInterrupt not finished for this CPU (case 0) | |
108 | #endif | |
109 | break; | |
110 | ||
111 | case 1: | |
112 | #if defined(EICRA) && defined(ISC10) && defined(ISC11) && defined(EIMSK) | |
113 | EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); | |
114 | EIMSK |= (1 << INT1); | |
115 | #elif defined(MCUCR) && defined(ISC10) && defined(ISC11) && defined(GICR) | |
116 | MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); | |
117 | GICR |= (1 << INT1); | |
118 | #elif defined(MCUCR) && defined(ISC10) && defined(GIMSK) && defined(GIMSK) | |
119 | MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); | |
120 | GIMSK |= (1 << INT1); | |
121 | #else | |
122 | #warning attachInterrupt may need some more work for this cpu (case 1) | |
123 | #endif | |
124 | break; | |
125 | ||
126 | case 2: | |
127 | #if defined(EICRA) && defined(ISC20) && defined(ISC21) && defined(EIMSK) | |
128 | EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20); | |
129 | EIMSK |= (1 << INT2); | |
130 | #elif defined(MCUCR) && defined(ISC20) && defined(ISC21) && defined(GICR) | |
131 | MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20); | |
132 | GICR |= (1 << INT2); | |
133 | #elif defined(MCUCR) && defined(ISC20) && defined(GIMSK) && defined(GIMSK) | |
134 | MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20); | |
135 | GIMSK |= (1 << INT2); | |
136 | #endif | |
137 | break; | |
138 | #endif | |
139 | } | |
140 | } | |
141 | } | |
142 | ||
143 | void detachInterrupt(uint8_t interruptNum) { | |
144 | if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { | |
145 | // Disable the interrupt. (We can't assume that interruptNum is equal | |
146 | // to the number of the EIMSK bit to clear, as this isn't true on the | |
147 | // ATmega8. There, INT0 is 6 and INT1 is 7.) | |
148 | switch (interruptNum) { | |
149 | #if defined(__AVR_ATmega32U4__) | |
150 | case 0: | |
151 | EIMSK &= ~(1<<INT0); | |
152 | break; | |
153 | case 1: | |
154 | EIMSK &= ~(1<<INT1); | |
155 | break; | |
156 | #elif defined(EICRA) && defined(EICRB) && defined(EIMSK) | |
157 | case 2: | |
158 | EIMSK &= ~(1 << INT0); | |
159 | break; | |
160 | case 3: | |
161 | EIMSK &= ~(1 << INT1); | |
162 | break; | |
163 | case 4: | |
164 | EIMSK &= ~(1 << INT2); | |
165 | break; | |
166 | case 5: | |
167 | EIMSK &= ~(1 << INT3); | |
168 | break; | |
169 | case 0: | |
170 | EIMSK &= ~(1 << INT4); | |
171 | break; | |
172 | case 1: | |
173 | EIMSK &= ~(1 << INT5); | |
174 | break; | |
175 | case 6: | |
176 | EIMSK &= ~(1 << INT6); | |
177 | break; | |
178 | case 7: | |
179 | EIMSK &= ~(1 << INT7); | |
180 | break; | |
181 | #else | |
182 | case 0: | |
183 | #if defined(EIMSK) && defined(INT0) | |
184 | EIMSK &= ~(1 << INT0); | |
185 | #elif defined(GICR) && defined(ISC00) | |
186 | GICR &= ~(1 << INT0); // atmega32 | |
187 | #elif defined(GIMSK) && defined(INT0) | |
188 | GIMSK &= ~(1 << INT0); | |
189 | #else | |
190 | #error detachInterrupt not finished for this cpu | |
191 | #endif | |
192 | break; | |
193 | ||
194 | case 1: | |
195 | #if defined(EIMSK) && defined(INT1) | |
196 | EIMSK &= ~(1 << INT1); | |
197 | #elif defined(GICR) && defined(INT1) | |
198 | GICR &= ~(1 << INT1); // atmega32 | |
199 | #elif defined(GIMSK) && defined(INT1) | |
200 | GIMSK &= ~(1 << INT1); | |
201 | #else | |
202 | #warning detachInterrupt may need some more work for this cpu (case 1) | |
203 | #endif | |
204 | break; | |
205 | #endif | |
206 | } | |
207 | ||
208 | intFunc[interruptNum] = 0; | |
209 | } | |
210 | } | |
211 | ||
212 | /* | |
213 | void attachInterruptTwi(void (*userFunc)(void) ) { | |
214 | twiIntFunc = userFunc; | |
215 | } | |
216 | */ | |
217 | ||
218 | #if defined(__AVR_ATmega32U4__) | |
219 | SIGNAL(INT0_vect) { | |
220 | if(intFunc[EXTERNAL_INT_0]) | |
221 | intFunc[EXTERNAL_INT_0](); | |
222 | } | |
223 | ||
224 | SIGNAL(INT1_vect) { | |
225 | if(intFunc[EXTERNAL_INT_1]) | |
226 | intFunc[EXTERNAL_INT_1](); | |
227 | } | |
228 | ||
229 | #elif defined(EICRA) && defined(EICRB) | |
230 | ||
231 | SIGNAL(INT0_vect) { | |
232 | if(intFunc[EXTERNAL_INT_2]) | |
233 | intFunc[EXTERNAL_INT_2](); | |
234 | } | |
235 | ||
236 | SIGNAL(INT1_vect) { | |
237 | if(intFunc[EXTERNAL_INT_3]) | |
238 | intFunc[EXTERNAL_INT_3](); | |
239 | } | |
240 | ||
241 | SIGNAL(INT2_vect) { | |
242 | if(intFunc[EXTERNAL_INT_4]) | |
243 | intFunc[EXTERNAL_INT_4](); | |
244 | } | |
245 | ||
246 | SIGNAL(INT3_vect) { | |
247 | if(intFunc[EXTERNAL_INT_5]) | |
248 | intFunc[EXTERNAL_INT_5](); | |
249 | } | |
250 | ||
251 | SIGNAL(INT4_vect) { | |
252 | if(intFunc[EXTERNAL_INT_0]) | |
253 | intFunc[EXTERNAL_INT_0](); | |
254 | } | |
255 | ||
256 | SIGNAL(INT5_vect) { | |
257 | if(intFunc[EXTERNAL_INT_1]) | |
258 | intFunc[EXTERNAL_INT_1](); | |
259 | } | |
260 | ||
261 | SIGNAL(INT6_vect) { | |
262 | if(intFunc[EXTERNAL_INT_6]) | |
263 | intFunc[EXTERNAL_INT_6](); | |
264 | } | |
265 | ||
266 | SIGNAL(INT7_vect) { | |
267 | if(intFunc[EXTERNAL_INT_7]) | |
268 | intFunc[EXTERNAL_INT_7](); | |
269 | } | |
270 | ||
271 | #else | |
272 | ||
273 | SIGNAL(INT0_vect) { | |
274 | if(intFunc[EXTERNAL_INT_0]) | |
275 | intFunc[EXTERNAL_INT_0](); | |
276 | } | |
277 | ||
278 | SIGNAL(INT1_vect) { | |
279 | if(intFunc[EXTERNAL_INT_1]) | |
280 | intFunc[EXTERNAL_INT_1](); | |
281 | } | |
282 | ||
283 | #if defined(EICRA) && defined(ISC20) | |
284 | SIGNAL(INT2_vect) { | |
285 | if(intFunc[EXTERNAL_INT_2]) | |
286 | intFunc[EXTERNAL_INT_2](); | |
287 | } | |
288 | #endif | |
289 | ||
290 | #endif | |
291 | ||
292 | /* | |
293 | SIGNAL(SIG_2WIRE_SERIAL) { | |
294 | if(twiIntFunc) | |
295 | twiIntFunc(); | |
296 | } | |
297 | */ | |
298 |