Bladeren bron

Merge pull request #5829 from thinkyhead/rc_fix_isr_reentry

Combine fixes for LIN_ADVANCE and temperature ISR
Scott Lahteine 8 jaren geleden
bovenliggende
commit
c04d6b5aa6
4 gewijzigde bestanden met toevoegingen van 62 en 18 verwijderingen
  1. 37
    6
      Marlin/planner.cpp
  2. 13
    11
      Marlin/stepper.cpp
  3. 10
    1
      Marlin/temperature.cpp
  4. 2
    0
      Marlin/temperature.h

+ 37
- 6
Marlin/planner.cpp Bestand weergeven

@@ -672,11 +672,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const
672 672
   #endif
673 673
 
674 674
   #if ENABLED(LIN_ADVANCE)
675
-    const float target_float[XYZE] = { a, b, c, e },
676
-                de_float = target_float[E_AXIS] - position_float[E_AXIS],
677
-                mm_D_float = sqrt(sq(target_float[X_AXIS] - position_float[X_AXIS]) + sq(target_float[Y_AXIS] - position_float[Y_AXIS]));
678
-
679
-    memcpy(position_float, target_float, sizeof(position_float));
675
+    const float mm_D_float = sqrt(sq(a - position_float[X_AXIS]) + sq(b - position_float[Y_AXIS]));
680 676
   #endif
681 677
 
682 678
   const long da = target[X_AXIS] - position[X_AXIS],
@@ -707,15 +703,28 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const
707 703
   //*/
708 704
 
709 705
   // DRYRUN ignores all temperature constraints and assures that the extruder is instantly satisfied
710
-  if (DEBUGGING(DRYRUN)) position[E_AXIS] = target[E_AXIS];
706
+  if (DEBUGGING(DRYRUN)) {
707
+    position[E_AXIS] = target[E_AXIS];
708
+    #if ENABLED(LIN_ADVANCE)
709
+      position_float[E_AXIS] = e;
710
+    #endif
711
+  }
711 712
 
712 713
   long de = target[E_AXIS] - position[E_AXIS];
713 714
 
715
+  #if ENABLED(LIN_ADVANCE)
716
+    float de_float = e - position_float[E_AXIS];
717
+  #endif
718
+
714 719
   #if ENABLED(PREVENT_COLD_EXTRUSION)
715 720
     if (de) {
716 721
       if (thermalManager.tooColdToExtrude(extruder)) {
717 722
         position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
718 723
         de = 0; // no difference
724
+        #if ENABLED(LIN_ADVANCE)
725
+          position_float[E_AXIS] = e;
726
+          de_float = 0;
727
+        #endif
719 728
         SERIAL_ECHO_START;
720 729
         SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP);
721 730
       }
@@ -723,6 +732,10 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const
723 732
         if (labs(de) > (int32_t)axis_steps_per_mm[E_AXIS_N] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int
724 733
           position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
725 734
           de = 0; // no difference
735
+          #if ENABLED(LIN_ADVANCE)
736
+            position_float[E_AXIS] = e;
737
+            de_float = 0;
738
+          #endif
726 739
           SERIAL_ECHO_START;
727 740
           SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP);
728 741
         }
@@ -1342,6 +1355,12 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const
1342 1355
 
1343 1356
   // Update the position (only when a move was queued)
1344 1357
   memcpy(position, target, sizeof(position));
1358
+  #if ENABLED(LIN_ADVANCE)
1359
+    position_float[X_AXIS] = a;
1360
+    position_float[Y_AXIS] = b;
1361
+    position_float[Z_AXIS] = c;
1362
+    position_float[E_AXIS] = e;
1363
+  #endif
1345 1364
 
1346 1365
   recalculate();
1347 1366
 
@@ -1367,6 +1386,12 @@ void Planner::_set_position_mm(const float &a, const float &b, const float &c, c
1367 1386
        nb = position[Y_AXIS] = lround(b * axis_steps_per_mm[Y_AXIS]),
1368 1387
        nc = position[Z_AXIS] = lround(c * axis_steps_per_mm[Z_AXIS]),
1369 1388
        ne = position[E_AXIS] = lround(e * axis_steps_per_mm[_EINDEX]);
1389
+  #if ENABLED(LIN_ADVANCE)
1390
+    position_float[X_AXIS] = a;
1391
+    position_float[Y_AXIS] = b;
1392
+    position_float[Z_AXIS] = c;
1393
+    position_float[E_AXIS] = e;
1394
+  #endif
1370 1395
   stepper.set_position(na, nb, nc, ne);
1371 1396
   previous_nominal_speed = 0.0; // Resets planner junction speeds. Assumes start from rest.
1372 1397
   ZERO(previous_speed);
@@ -1392,6 +1417,9 @@ void Planner::set_position_mm_kinematic(const float position[NUM_AXIS]) {
1392 1417
  */
1393 1418
 void Planner::sync_from_steppers() {
1394 1419
   LOOP_XYZE(i) position[i] = stepper.position((AxisEnum)i);
1420
+  #if ENABLED(LIN_ADVANCE)
1421
+    LOOP_XYZE(i) position_float[i] = stepper.position((AxisEnum)i) * steps_to_mm[i];
1422
+  #endif
1395 1423
 }
1396 1424
 
1397 1425
 /**
@@ -1405,6 +1433,9 @@ void Planner::set_position_mm(const AxisEnum axis, const float& v) {
1405 1433
     const uint8_t axis_index = axis;
1406 1434
   #endif
1407 1435
   position[axis] = lround(v * axis_steps_per_mm[axis_index]);
1436
+  #if ENABLED(LIN_ADVANCE)
1437
+    position_float[axis] = v;
1438
+  #endif
1408 1439
   stepper.set_position(axis, v);
1409 1440
   previous_speed[axis] = 0.0;
1410 1441
 }

+ 13
- 11
Marlin/stepper.cpp Bestand weergeven

@@ -342,13 +342,14 @@ ISR(TIMER1_COMPA_vect) {
342 342
   #endif
343 343
 }
344 344
 
345
-void Stepper::isr() {
346
-  #define _ENABLE_ISRs() cli(); SBI(TIMSK0, OCIE0B); ENABLE_STEPPER_DRIVER_INTERRUPT()
345
+#define _ENABLE_ISRs() do { cli(); if (thermalManager.in_temp_isr) CBI(TIMSK0, OCIE0B); else SBI(TIMSK0, OCIE0B); ENABLE_STEPPER_DRIVER_INTERRUPT(); } while(0)
347 346
 
348
-  uint16_t timer, remainder, ocr_val;
347
+void Stepper::isr() {
349 348
 
350 349
   static uint32_t step_remaining = 0;
351 350
 
351
+  uint16_t ocr_val;
352
+
352 353
   #define ENDSTOP_NOMINAL_OCR_VAL 3000    // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
353 354
   #define OCR_VAL_TOLERANCE 1000          // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
354 355
 
@@ -366,7 +367,7 @@ void Stepper::isr() {
366 367
     #define SPLIT(L) do { \
367 368
       _SPLIT(L); \
368 369
       if (ENDSTOPS_ENABLED && L > ENDSTOP_NOMINAL_OCR_VAL) { \
369
-        remainder = (uint16_t)L % (ENDSTOP_NOMINAL_OCR_VAL); \
370
+        uint16_t remainder = (uint16_t)L % (ENDSTOP_NOMINAL_OCR_VAL); \
370 371
         ocr_val = (remainder < OCR_VAL_TOLERANCE) ? ENDSTOP_NOMINAL_OCR_VAL + remainder : ENDSTOP_NOMINAL_OCR_VAL; \
371 372
         step_remaining = (uint16_t)L - ocr_val; \
372 373
       } \
@@ -374,13 +375,16 @@ void Stepper::isr() {
374 375
 
375 376
     if (step_remaining && ENDSTOPS_ENABLED) {   // Just check endstops - not yet time for a step
376 377
       endstops.update();
377
-      ocr_val = step_remaining;
378 378
       if (step_remaining > ENDSTOP_NOMINAL_OCR_VAL) {
379
-        step_remaining = step_remaining - ENDSTOP_NOMINAL_OCR_VAL;
379
+        step_remaining -= ENDSTOP_NOMINAL_OCR_VAL;
380 380
         ocr_val = ENDSTOP_NOMINAL_OCR_VAL;
381 381
       }
382
-      else step_remaining = 0;  //  last one before the ISR that does the step
383
-      _NEXT_ISR(ocr_val);  //
382
+      else {
383
+        ocr_val = step_remaining;
384
+        step_remaining = 0;  //  last one before the ISR that does the step
385
+      }
386
+
387
+      _NEXT_ISR(ocr_val);
384 388
 
385 389
       NOLESS(OCR1A, TCNT1 + 16);
386 390
 
@@ -867,9 +871,7 @@ void Stepper::isr() {
867 871
     NOLESS(OCR1A, TCNT1 + 16);
868 872
 
869 873
     // Restore original ISR settings
870
-    cli();
871
-    SBI(TIMSK0, OCIE0B);
872
-    ENABLE_STEPPER_DRIVER_INTERRUPT();
874
+    _ENABLE_ISRs();
873 875
   }
874 876
 
875 877
 #endif // ADVANCE or LIN_ADVANCE

+ 10
- 1
Marlin/temperature.cpp Bestand weergeven

@@ -1483,8 +1483,15 @@ void Temperature::set_current_temp_raw() {
1483 1483
  */
1484 1484
 ISR(TIMER0_COMPB_vect) { Temperature::isr(); }
1485 1485
 
1486
+volatile bool Temperature::in_temp_isr = false;
1487
+
1486 1488
 void Temperature::isr() {
1487
-  //Allow UART and stepper ISRs
1489
+  // The stepper ISR can interrupt this ISR. When it does it re-enables this ISR
1490
+  // at the end of its run, potentially causing re-entry. This flag prevents it.
1491
+  if (in_temp_isr) return;
1492
+  in_temp_isr = true;
1493
+  
1494
+  // Allow UART and stepper ISRs
1488 1495
   CBI(TIMSK0, OCIE0B); //Disable Temperature ISR
1489 1496
   sei();
1490 1497
 
@@ -1949,5 +1956,7 @@ void Temperature::isr() {
1949 1956
     }
1950 1957
   #endif
1951 1958
 
1959
+  cli();
1960
+  in_temp_isr = false;
1952 1961
   SBI(TIMSK0, OCIE0B); //re-enable Temperature ISR
1953 1962
 }

+ 2
- 0
Marlin/temperature.h Bestand weergeven

@@ -61,6 +61,8 @@ class Temperature {
61 61
                  current_temperature_bed_raw,
62 62
                  target_temperature_bed;
63 63
 
64
+    static volatile bool in_temp_isr;
65
+
64 66
     #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
65 67
       static float redundant_temperature;
66 68
     #endif

Laden…
Annuleren
Opslaan