Browse Source

[LPC176x] Endstop Interrupts Feature (#11202)

Enable the endstop interrupts feature for LPC176x boards. Although Smoothieboard chose to use non-interrupt capable pins for their endstops, and this has been copied by clones, so they can't use it.
Chris Pepper 7 years ago
parent
commit
55f4744e54

+ 35
- 62
Marlin/src/HAL/HAL_LPC1768/WInterrupts.cpp View File

@@ -19,29 +19,20 @@
19 19
 #ifdef TARGET_LPC1768
20 20
 
21 21
 #include "../../inc/MarlinConfig.h"
22
-#include <Arduino.h>
23
-#include <pinmapping.h>
24
-//#include "HAL_timers.h"
25
-#include "fastio.h"
26 22
 
27 23
 #define GNUM 31
28 24
 
29 25
 typedef void (*interruptCB)(void);
30 26
 
31
-static interruptCB callbacksP0[GNUM];
32
-static interruptCB callbacksP2[GNUM];
27
+static interruptCB callbacksP0[GNUM] = {};
28
+static interruptCB callbacksP2[GNUM] = {};
33 29
 
34 30
 extern "C" void GpioEnableInt(const uint32_t port, const uint32_t pin, const uint32_t mode);
35 31
 extern "C" void GpioDisableInt(const uint32_t port, const uint32_t pin);
36 32
 
37
-//void deadloop(void) {}
38 33
 
39
-/* Configure PIO interrupt sources */
40 34
 static void __initialize() {
41
-  for (uint8_t i = 0; i < GNUM; i++) {
42
-    callbacksP0[i] = 0;
43
-    callbacksP2[i] = 0;
44
-  }
35
+  NVIC_SetPriority(EINT3_IRQn, NVIC_EncodePriority(0, 1, 0));
45 36
   NVIC_EnableIRQ(EINT3_IRQn);
46 37
 }
47 38
 
@@ -54,6 +45,7 @@ void attachInterrupt(const pin_t pin, void (*callback)(void), uint32_t mode) {
54 45
     __initialize();
55 46
     ++enabled;
56 47
   }
48
+
57 49
   uint8_t myport = LPC1768_PIN_PORT(pin),
58 50
           mypin = LPC1768_PIN_PIN(pin);
59 51
 
@@ -130,60 +122,41 @@ extern "C" void GpioDisableInt(const uint32_t port, const uint32_t pin) {
130 122
   }
131 123
 }
132 124
 
133
-constexpr bool isPowerOf2(const uint16_t n) {
134
-  return IS_POWER_OF_2(n);
135
-}
136
-
137
-#if 0
138
-  extern "C" void EINT3_IRQHandler () {
139
-    LPC_GPIOINT->IO0IntClr = LPC_GPIOINT->IO2IntClr = 0xFFFFFFFF;
140
-    TOGGLE(13);
141
-    //NVIC_ClearPendingIRQ(EINT3_IRQn);
125
+extern "C" void EINT3_IRQHandler(void) {
126
+  // Read in all current interrupt registers. We do this once as the
127
+  // GPIO interrupt registers are on the APB bus, and this is slow.
128
+  uint32_t rise0 = LPC_GPIOINT->IO0IntStatR,
129
+           fall0 = LPC_GPIOINT->IO0IntStatF,
130
+           rise2 = LPC_GPIOINT->IO2IntStatR,
131
+           fall2 = LPC_GPIOINT->IO2IntStatF;
132
+
133
+  // Clear the interrupts ASAP
134
+  LPC_GPIOINT->IO0IntClr = LPC_GPIOINT->IO2IntClr = 0xFFFFFFFF;
135
+  NVIC_ClearPendingIRQ(EINT3_IRQn);
136
+
137
+  while (rise0 > 0) {                                       // If multiple pins changes happened continue as long as there are interrupts pending
138
+    const uint8_t bitloc = 31 - __CLZ(rise0);               // CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
139
+    if (callbacksP0[bitloc] != NULL) callbacksP0[bitloc]();
140
+    rise0 -= _BV(bitloc);
142 141
   }
143
-#else
144
-
145
-  extern "C" void EINT3_IRQHandler(void) {
146
-    // Read in all current interrupt registers. We do this once as the
147
-    // GPIO interrupt registers are on the APB bus, and this is slow.
148
-    uint32_t rise0 = LPC_GPIOINT->IO0IntStatR,
149
-             fall0 = LPC_GPIOINT->IO0IntStatF,
150
-             rise2 = LPC_GPIOINT->IO2IntStatR,
151
-             fall2 = LPC_GPIOINT->IO2IntStatF;
152
-    // Clear the interrupts ASAP
153
-    LPC_GPIOINT->IO0IntClr = LPC_GPIOINT->IO2IntClr = 0xFFFFFFFF;
154
-    NVIC_ClearPendingIRQ(EINT3_IRQn);
155
-
156
-    /* multiple pins changes happened.*/
157
-    if (rise0) while (rise0 > 0) {      // Continue as long as there are interrupts pending
158
-      const uint8_t bitloc = 31 - __CLZ(rise0); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
159
-      if (callbacksP0[bitloc] != NULL) callbacksP0[bitloc]();
160
-      rise0 -= _BV(bitloc);
161
-    }
162
-
163
-    if (fall0) while (fall0 > 0) {
164
-      const uint8_t bitloc = 31 - __CLZ(fall0);
165
-      if (callbacksP0[bitloc] != NULL) callbacksP0[bitloc]();
166
-      fall0 -= _BV(bitloc);
167
-    }
168 142
 
169
-    if (rise2) while(rise2 > 0) {
170
-      const uint8_t bitloc = 31 - __CLZ(rise2);
171
-      if (callbacksP2[bitloc] != NULL) callbacksP2[bitloc]();
172
-      //LPC_GPIOINT->IO2IntClr = 1 << bitloc;
173
-      rise2 -= _BV(bitloc);
174
-    }
143
+  while (fall0 > 0) {
144
+    const uint8_t bitloc = 31 - __CLZ(fall0);
145
+    if (callbacksP0[bitloc] != NULL) callbacksP0[bitloc]();
146
+    fall0 -= _BV(bitloc);
147
+  }
175 148
 
176
-    if (fall2) while (fall2 > 0) {
177
-      const uint8_t bitloc = 31 - __CLZ(fall2);
178
-      if (callbacksP2[bitloc] != NULL) callbacksP2[bitloc]();
179
-      //LPC_GPIOINT->IO2IntClr = 1 << bitloc;
180
-      fall2 -= _BV(bitloc);
181
-    }
182
-    //NVIC_ClearPendingIRQ(EINT3_IRQn);
183
-    //LPC_GPIOINT->IO0IntClr = LPC_GPIOINT->IO2IntClr = 0xFFFFFFFF;
184
-    //NVIC_ClearPendingIRQ(EINT3_IRQn);
149
+  while(rise2 > 0) {
150
+    const uint8_t bitloc = 31 - __CLZ(rise2);
151
+    if (callbacksP2[bitloc] != NULL) callbacksP2[bitloc]();
152
+    rise2 -= _BV(bitloc);
185 153
   }
186 154
 
187
-#endif
155
+  while (fall2 > 0) {
156
+    const uint8_t bitloc = 31 - __CLZ(fall2);
157
+    if (callbacksP2[bitloc] != NULL) callbacksP2[bitloc]();
158
+    fall2 -= _BV(bitloc);
159
+  }
160
+}
188 161
 
189 162
 #endif // TARGET_LPC1768

+ 28
- 4
Marlin/src/HAL/HAL_LPC1768/endstop_interrupts.h View File

@@ -37,9 +37,6 @@
37 37
 #ifndef _ENDSTOP_INTERRUPTS_H_
38 38
 #define _ENDSTOP_INTERRUPTS_H_
39 39
 
40
-//Currently this is untested and broken
41
-#error "Please disable Endstop Interrupts LPC176x is currently an unsupported platform"
42
-
43 40
 #include "../../module/endstops.h"
44 41
 
45 42
 // One ISR for all EXT-Interrupts
@@ -47,30 +44,57 @@ void endstop_ISR(void) { endstops.update(); }
47 44
 
48 45
 void setup_endstop_interrupts(void) {
49 46
   #if HAS_X_MAX
50
-    attachInterrupt(digitalPinToInterrupt(X_MAX_PIN), endstop_ISR, CHANGE); // assign it
47
+    #if !LPC1768_PIN_INTERRUPT_M(X_MAX_PIN)
48
+      #error "X_MAX_PIN is not an INTERRUPT capable pin."
49
+    #endif
50
+    attachInterrupt(digitalPinToInterrupt(X_MAX_PIN), endstop_ISR, CHANGE);
51 51
   #endif
52 52
   #if HAS_X_MIN
53
+    #if !LPC1768_PIN_INTERRUPT_M(X_MIN_PIN)
54
+      #error "X_MIN_PIN is not an INTERRUPT capable pin."
55
+    #endif
53 56
     attachInterrupt(digitalPinToInterrupt(X_MIN_PIN), endstop_ISR, CHANGE);
54 57
   #endif
55 58
   #if HAS_Y_MAX
59
+    #if !LPC1768_PIN_INTERRUPT_M(Y_MAX_PIN)
60
+      #error "Y_MAX_PIN is not an INTERRUPT capable pin."
61
+    #endif
56 62
     attachInterrupt(digitalPinToInterrupt(Y_MAX_PIN), endstop_ISR, CHANGE);
57 63
   #endif
58 64
   #if HAS_Y_MIN
65
+    #if !LPC1768_PIN_INTERRUPT_M(Y_MIN_PIN)
66
+      #error "Y_MIN_PIN is not an INTERRUPT capable pin."
67
+    #endif
59 68
     attachInterrupt(digitalPinToInterrupt(Y_MIN_PIN), endstop_ISR, CHANGE);
60 69
   #endif
61 70
   #if HAS_Z_MAX
71
+    #if !LPC1768_PIN_INTERRUPT_M(Z_MAX_PIN)
72
+      #error "Z_MAX_PIN is not an INTERRUPT capable pin."
73
+    #endif
62 74
     attachInterrupt(digitalPinToInterrupt(Z_MAX_PIN), endstop_ISR, CHANGE);
63 75
   #endif
64 76
   #if HAS_Z_MIN
77
+    #if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PIN)
78
+      #error "Z_MIN_PIN is not an INTERRUPT capable pin."
79
+    #endif
65 80
      attachInterrupt(digitalPinToInterrupt(Z_MIN_PIN), endstop_ISR, CHANGE);
66 81
   #endif
67 82
   #if HAS_Z2_MAX
83
+    #if !LPC1768_PIN_INTERRUPT_M(Z2_MAX_PIN)
84
+      #error "Z2_MAX_PIN is not an INTERRUPT capable pin."
85
+    #endif
68 86
     attachInterrupt(digitalPinToInterrupt(Z2_MAX_PIN), endstop_ISR, CHANGE);
69 87
   #endif
70 88
   #if HAS_Z2_MIN
89
+    #if !LPC1768_PIN_INTERRUPT_M(Z2_MIN_PIN)
90
+      #error "Z2_MIN_PIN is not an INTERRUPT capable pin."
91
+    #endif
71 92
     attachInterrupt(digitalPinToInterrupt(Z2_MIN_PIN), endstop_ISR, CHANGE);
72 93
   #endif
73 94
   #if HAS_Z_MIN_PROBE_PIN
95
+    #if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PROBE_PIN)
96
+      #error "Z_MIN_PROBE_PIN is not an INTERRUPT capable pin."
97
+    #endif
74 98
     attachInterrupt(digitalPinToInterrupt(Z_MIN_PROBE_PIN), endstop_ISR, CHANGE);
75 99
   #endif
76 100
 }

+ 2
- 1
Marlin/src/HAL/HAL_LPC1768/include/pinmapping.h View File

@@ -267,7 +267,7 @@ constexpr pin_t adc_pin_table[] = {
267 267
 
268 268
 // Get the digital pin for an analog index
269 269
 pin_t analogInputToDigitalPin(const int8_t p);
270
-
270
+#define digitalPinToInterrupt(pin) (pin)
271 271
 // Return the index of a pin number
272 272
 // The pin number given here is in the form ppp:nnnnn
273 273
 int16_t GET_PIN_MAP_INDEX(const pin_t pin);
@@ -283,6 +283,7 @@ bool PWM_PIN(const pin_t p);
283 283
 
284 284
 // Test whether the pin is interruptable
285 285
 bool INTERRUPT_PIN(const pin_t p);
286
+#define LPC1768_PIN_INTERRUPT_M(pin) (((pin >> 8) & 0b1) != 0)
286 287
 
287 288
 // Get the pin number at the given index
288 289
 pin_t GET_PIN_MAP_PIN(const int16_t ind);

Loading…
Cancel
Save