Browse Source

Unify step pulse timing of ISR / babystep (#16813)

Scott Lahteine 5 years ago
parent
commit
2836834d7e
No account linked to committer's email address
1 changed files with 73 additions and 87 deletions
  1. 73
    87
      Marlin/src/module/stepper.cpp

+ 73
- 87
Marlin/src/module/stepper.cpp View File

@@ -402,6 +402,7 @@ constexpr uint32_t NS_TO_PULSE_TIMER_TICKS(uint32_t NS) { return (NS + (NS_PER_P
402 402
 #define PULSE_HIGH_TICK_COUNT hal_timer_t(NS_TO_PULSE_TIMER_TICKS(_MIN_PULSE_HIGH_NS - _MIN(_MIN_PULSE_HIGH_NS, TIMER_SETUP_NS)))
403 403
 #define PULSE_LOW_TICK_COUNT hal_timer_t(NS_TO_PULSE_TIMER_TICKS(_MIN_PULSE_LOW_NS - _MIN(_MIN_PULSE_LOW_NS, TIMER_SETUP_NS)))
404 404
 
405
+#define USING_TIMED_PULSE() hal_timer_t end_tick_count = 0
405 406
 #define START_TIMED_PULSE(DIR) (end_tick_count = HAL_timer_get_count(PULSE_TIMER_NUM) + PULSE_##DIR##_TICK_COUNT)
406 407
 #define AWAIT_TIMED_PULSE() while (HAL_timer_get_count(PULSE_TIMER_NUM) < end_tick_count) { }
407 408
 #define START_HIGH_PULSE()  START_TIMED_PULSE(HIGH)
@@ -409,6 +410,18 @@ constexpr uint32_t NS_TO_PULSE_TIMER_TICKS(uint32_t NS) { return (NS + (NS_PER_P
409 410
 #define AWAIT_HIGH_PULSE()  AWAIT_TIMED_PULSE()
410 411
 #define AWAIT_LOW_PULSE()   AWAIT_TIMED_PULSE()
411 412
 
413
+#if MINIMUM_STEPPER_PRE_DIR_DELAY > 0
414
+  #define DIR_WAIT_BEFORE() DELAY_NS(MINIMUM_STEPPER_PRE_DIR_DELAY)
415
+#else
416
+  #define DIR_WAIT_BEFORE()
417
+#endif
418
+
419
+#if MINIMUM_STEPPER_POST_DIR_DELAY > 0
420
+  #define DIR_WAIT_AFTER() DELAY_NS(MINIMUM_STEPPER_POST_DIR_DELAY)
421
+#else
422
+  #define DIR_WAIT_AFTER()
423
+#endif
424
+
412 425
 void Stepper::wake_up() {
413 426
   // TCNT1 = 0;
414 427
   ENABLE_STEPPER_DRIVER_INTERRUPT();
@@ -423,9 +436,7 @@ void Stepper::wake_up() {
423 436
  */
424 437
 void Stepper::set_directions() {
425 438
 
426
-  #if MINIMUM_STEPPER_PRE_DIR_DELAY > 0
427
-    DELAY_NS(MINIMUM_STEPPER_PRE_DIR_DELAY);
428
-  #endif
439
+  DIR_WAIT_BEFORE();
429 440
 
430 441
   #define SET_STEP_DIR(A)                       \
431 442
     if (motor_direction(_AXIS(A))) {            \
@@ -494,10 +505,7 @@ void Stepper::set_directions() {
494 505
     }
495 506
   #endif
496 507
 
497
-  // A small delay may be needed after changing direction
498
-  #if MINIMUM_STEPPER_POST_DIR_DELAY > 0
499
-    DELAY_NS(MINIMUM_STEPPER_POST_DIR_DELAY);
500
-  #endif
508
+  DIR_WAIT_AFTER();
501 509
 }
502 510
 
503 511
 #if ENABLED(S_CURVE_ACCELERATION)
@@ -1488,12 +1496,12 @@ void Stepper::stepper_pulse_phase_isr() {
1488 1496
   // Take multiple steps per interrupt (For high speed moves)
1489 1497
   #if ISR_MULTI_STEPS
1490 1498
     bool firstStep = true;
1491
-    hal_timer_t end_tick_count = 0;
1499
+    USING_TIMED_PULSE();
1492 1500
   #endif
1493 1501
   xyze_bool_t step_needed{0};
1494 1502
 
1495 1503
   do {
1496
-    #define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP
1504
+    #define _APPLY_STEP(AXIS, INV, ALWAYS) AXIS ##_APPLY_STEP(INV, ALWAYS)
1497 1505
     #define _INVERT_STEP_PIN(AXIS) INVERT_## AXIS ##_STEP_PIN
1498 1506
 
1499 1507
     // Determine if a pulse is needed using Bresenham
@@ -1509,14 +1517,14 @@ void Stepper::stepper_pulse_phase_isr() {
1509 1517
     // Start an active pulse, if Bresenham says so, and update position
1510 1518
     #define PULSE_START(AXIS) do{ \
1511 1519
       if (step_needed[_AXIS(AXIS)]) { \
1512
-        _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), 0); \
1520
+        _APPLY_STEP(AXIS, !_INVERT_STEP_PIN(AXIS), 0); \
1513 1521
       } \
1514 1522
     }while(0)
1515 1523
 
1516 1524
     // Stop an active pulse, if any, and adjust error term
1517 1525
     #define PULSE_STOP(AXIS) do { \
1518 1526
       if (step_needed[_AXIS(AXIS)]) { \
1519
-        _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS), 0); \
1527
+        _APPLY_STEP(AXIS, _INVERT_STEP_PIN(AXIS), 0); \
1520 1528
       } \
1521 1529
     }while(0)
1522 1530
 
@@ -1978,9 +1986,7 @@ uint32_t Stepper::stepper_block_phase_isr() {
1978 1986
     else
1979 1987
       interval = LA_ADV_NEVER;
1980 1988
 
1981
-    #if MINIMUM_STEPPER_PRE_DIR_DELAY > 0
1982
-      DELAY_NS(MINIMUM_STEPPER_PRE_DIR_DELAY);
1983
-    #endif
1989
+    DIR_WAIT_BEFORE();
1984 1990
 
1985 1991
     #if ENABLED(MIXING_EXTRUDER)
1986 1992
       // We don't know which steppers will be stepped because LA loop follows,
@@ -1996,17 +2002,14 @@ uint32_t Stepper::stepper_block_phase_isr() {
1996 2002
         REV_E_DIR(stepper_extruder);
1997 2003
     #endif
1998 2004
 
1999
-    // A small delay may be needed after changing direction
2000
-    #if MINIMUM_STEPPER_POST_DIR_DELAY > 0
2001
-      DELAY_NS(MINIMUM_STEPPER_POST_DIR_DELAY);
2002
-    #endif
2005
+    DIR_WAIT_AFTER();
2003 2006
 
2004 2007
     //const hal_timer_t added_step_ticks = hal_timer_t(ADDED_STEP_TICKS);
2005 2008
 
2006 2009
     // Step E stepper if we have steps
2007 2010
     #if ISR_MULTI_STEPS
2008 2011
       bool firstStep = true;
2009
-      hal_timer_t end_tick_count = 0;
2012
+      USING_TIMED_PULSE();
2010 2013
     #endif
2011 2014
 
2012 2015
     while (LA_steps) {
@@ -2424,57 +2427,52 @@ void Stepper::report_positions() {
2424 2427
 
2425 2428
 #if ENABLED(BABYSTEPPING)
2426 2429
 
2427
-  #if MINIMUM_STEPPER_PULSE
2428
-    #define STEP_PULSE_CYCLES ((MINIMUM_STEPPER_PULSE) * CYCLES_PER_MICROSECOND)
2429
-  #else
2430
-    #define STEP_PULSE_CYCLES 0
2431
-  #endif
2432
-
2433
-  #if ENABLED(DELTA)
2434
-    #define CYCLES_EATEN_BABYSTEP (2 * 15)
2435
-  #else
2436
-    #define CYCLES_EATEN_BABYSTEP 0
2437
-  #endif
2438
-  #define EXTRA_CYCLES_BABYSTEP (STEP_PULSE_CYCLES - (CYCLES_EATEN_BABYSTEP))
2439
-
2440 2430
   #define _ENABLE_AXIS(AXIS) ENABLE_AXIS_## AXIS()
2441 2431
   #define _READ_DIR(AXIS) AXIS ##_DIR_READ()
2442 2432
   #define _INVERT_DIR(AXIS) INVERT_## AXIS ##_DIR
2443 2433
   #define _APPLY_DIR(AXIS, INVERT) AXIS ##_APPLY_DIR(INVERT, true)
2444 2434
 
2445
-  #if EXTRA_CYCLES_BABYSTEP > 20
2446
-    #define _SAVE_START const hal_timer_t pulse_start = HAL_timer_get_count(PULSE_TIMER_NUM)
2447
-    #define _PULSE_WAIT while (EXTRA_CYCLES_BABYSTEP > (uint32_t)(HAL_timer_get_count(PULSE_TIMER_NUM) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
2448
-  #else
2449
-    #define _SAVE_START NOOP
2450
-    #if EXTRA_CYCLES_BABYSTEP > 0
2451
-      #define _PULSE_WAIT DELAY_NS(EXTRA_CYCLES_BABYSTEP * NANOSECONDS_PER_CYCLE)
2452
-    #elif ENABLED(DELTA)
2453
-      #define _PULSE_WAIT DELAY_US(2);
2454
-    #elif STEP_PULSE_CYCLES > 0
2455
-      #define _PULSE_WAIT NOOP
2456
-    #else
2457
-      #define _PULSE_WAIT DELAY_US(4);
2458
-    #endif
2459
-  #endif
2460
-
2461
-  #define BABYSTEP_AXIS(AXIS, INVERT, DIR) {            \
2435
+  #if DISABLED(DELTA)
2436
+    #define BABYSTEP_AXIS(AXIS, INV, DIR) do{           \
2462 2437
       const uint8_t old_dir = _READ_DIR(AXIS);          \
2463 2438
       _ENABLE_AXIS(AXIS);                               \
2464
-      DELAY_NS(MINIMUM_STEPPER_PRE_DIR_DELAY);          \
2465
-      _APPLY_DIR(AXIS, _INVERT_DIR(AXIS)^DIR^INVERT);   \
2466
-      DELAY_NS(MINIMUM_STEPPER_POST_DIR_DELAY);         \
2467
-      _SAVE_START;                                      \
2468
-      _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), true); \
2469
-      _PULSE_WAIT;                                      \
2470
-      _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS), true);  \
2439
+      DIR_WAIT_BEFORE();                                \
2440
+      _APPLY_DIR(AXIS, _INVERT_DIR(AXIS)^DIR^INV);      \
2441
+      DIR_WAIT_AFTER();                                 \
2442
+      USING_TIMED_PULSE();                              \
2443
+      START_HIGH_PULSE();                               \
2444
+      _APPLY_STEP(AXIS, !_INVERT_STEP_PIN(AXIS), true); \
2445
+      AWAIT_HIGH_PULSE();                               \
2446
+      _APPLY_STEP(AXIS,  _INVERT_STEP_PIN(AXIS), true); \
2471 2447
       _APPLY_DIR(AXIS, old_dir);                        \
2472
-    }
2448
+    }while(0)
2449
+  #endif
2450
+
2451
+  #if IS_CORE
2452
+    #define BABYSTEP_CORE(A, B, INV, DIR) do{     \
2453
+      const xy_byte_t old_dir = { _READ_DIR(A), _READ_DIR(B) }; \
2454
+      _ENABLE_AXIS(A); _ENABLE_AXIS(B);           \
2455
+      DIR_WAIT_BEFORE();                          \
2456
+      _APPLY_DIR(A, _INVERT_DIR(A)^DIR^INV);      \
2457
+      _APPLY_DIR(B, _INVERT_DIR(B)^DIR^INV^(CORESIGN(1)<0)); \
2458
+      DIR_WAIT_AFTER();                           \
2459
+      USING_TIMED_PULSE();                        \
2460
+      START_HIGH_PULSE();                         \
2461
+      _APPLY_STEP(A, !_INVERT_STEP_PIN(A), true); \
2462
+      _APPLY_STEP(B, !_INVERT_STEP_PIN(B), true); \
2463
+      AWAIT_HIGH_PULSE();                         \
2464
+      _APPLY_STEP(A,  _INVERT_STEP_PIN(A), true); \
2465
+      _APPLY_STEP(B,  _INVERT_STEP_PIN(B), true); \
2466
+      _APPLY_DIR(A, old_dir.a); _APPLY_DIR(B, old_dir.b); \
2467
+    }while(0)
2468
+  #endif
2473 2469
 
2474 2470
   // MUST ONLY BE CALLED BY AN ISR,
2475 2471
   // No other ISR should ever interrupt this!
2476 2472
   void Stepper::babystep(const AxisEnum axis, const bool direction) {
2477
-    cli();
2473
+    DISABLE_ISRS();
2474
+
2475
+    USING_TIMED_PULSE();
2478 2476
 
2479 2477
     switch (axis) {
2480 2478
 
@@ -2482,11 +2480,9 @@ void Stepper::report_positions() {
2482 2480
 
2483 2481
         case X_AXIS:
2484 2482
           #if CORE_IS_XY
2485
-            BABYSTEP_AXIS(X, false, direction);
2486
-            BABYSTEP_AXIS(Y, false, direction);
2483
+            BABYSTEP_CORE(X, Y, false, direction);
2487 2484
           #elif CORE_IS_XZ
2488
-            BABYSTEP_AXIS(X, false, direction);
2489
-            BABYSTEP_AXIS(Z, false, direction);
2485
+            BABYSTEP_CORE(X, Z, false, direction);
2490 2486
           #else
2491 2487
             BABYSTEP_AXIS(X, false, direction);
2492 2488
           #endif
@@ -2494,11 +2490,9 @@ void Stepper::report_positions() {
2494 2490
 
2495 2491
         case Y_AXIS:
2496 2492
           #if CORE_IS_XY
2497
-            BABYSTEP_AXIS(X, false, direction);
2498
-            BABYSTEP_AXIS(Y, false, direction^(CORESIGN(1)<0));
2493
+            BABYSTEP_CORE(X, Y, false, direction);
2499 2494
           #elif CORE_IS_YZ
2500
-            BABYSTEP_AXIS(Y, false, direction);
2501
-            BABYSTEP_AXIS(Z, false, direction^(CORESIGN(1)<0));
2495
+            BABYSTEP_CORE(Y, Z, false, direction);
2502 2496
           #else
2503 2497
             BABYSTEP_AXIS(Y, false, direction);
2504 2498
           #endif
@@ -2509,13 +2503,9 @@ void Stepper::report_positions() {
2509 2503
       case Z_AXIS: {
2510 2504
 
2511 2505
         #if CORE_IS_XZ
2512
-          BABYSTEP_AXIS(X, BABYSTEP_INVERT_Z, direction);
2513
-          BABYSTEP_AXIS(Z, BABYSTEP_INVERT_Z, direction^(CORESIGN(1)<0));
2514
-
2506
+          BABYSTEP_CORE(X, Z, BABYSTEP_INVERT_Z, direction);
2515 2507
         #elif CORE_IS_YZ
2516
-          BABYSTEP_AXIS(Y, BABYSTEP_INVERT_Z, direction);
2517
-          BABYSTEP_AXIS(Z, BABYSTEP_INVERT_Z, direction^(CORESIGN(1)<0));
2518
-
2508
+          BABYSTEP_CORE(Y, Z, BABYSTEP_INVERT_Z, direction);
2519 2509
         #elif DISABLED(DELTA)
2520 2510
           BABYSTEP_AXIS(Z, BABYSTEP_INVERT_Z, direction);
2521 2511
 
@@ -2527,38 +2517,32 @@ void Stepper::report_positions() {
2527 2517
           ENABLE_AXIS_Y();
2528 2518
           ENABLE_AXIS_Z();
2529 2519
 
2530
-          #if MINIMUM_STEPPER_PRE_DIR_DELAY > 0
2531
-            DELAY_NS(MINIMUM_STEPPER_PRE_DIR_DELAY);
2532
-          #endif
2520
+          DIR_WAIT_BEFORE();
2533 2521
 
2534
-          const uint8_t old_x_dir_pin = X_DIR_READ(),
2535
-                        old_y_dir_pin = Y_DIR_READ(),
2536
-                        old_z_dir_pin = Z_DIR_READ();
2522
+          const xyz_byte_t old_dir = { X_DIR_READ(), Y_DIR_READ(), Z_DIR_READ() };
2537 2523
 
2538 2524
           X_DIR_WRITE(INVERT_X_DIR ^ z_direction);
2539 2525
           Y_DIR_WRITE(INVERT_Y_DIR ^ z_direction);
2540 2526
           Z_DIR_WRITE(INVERT_Z_DIR ^ z_direction);
2541 2527
 
2542
-          #if MINIMUM_STEPPER_POST_DIR_DELAY > 0
2543
-            DELAY_NS(MINIMUM_STEPPER_POST_DIR_DELAY);
2544
-          #endif
2528
+          DIR_WAIT_AFTER();
2545 2529
 
2546
-          _SAVE_START;
2530
+          START_HIGH_PULSE();
2547 2531
 
2548 2532
           X_STEP_WRITE(!INVERT_X_STEP_PIN);
2549 2533
           Y_STEP_WRITE(!INVERT_Y_STEP_PIN);
2550 2534
           Z_STEP_WRITE(!INVERT_Z_STEP_PIN);
2551 2535
 
2552
-          _PULSE_WAIT;
2536
+          AWAIT_HIGH_PULSE();
2553 2537
 
2554 2538
           X_STEP_WRITE(INVERT_X_STEP_PIN);
2555 2539
           Y_STEP_WRITE(INVERT_Y_STEP_PIN);
2556 2540
           Z_STEP_WRITE(INVERT_Z_STEP_PIN);
2557 2541
 
2558 2542
           // Restore direction bits
2559
-          X_DIR_WRITE(old_x_dir_pin);
2560
-          Y_DIR_WRITE(old_y_dir_pin);
2561
-          Z_DIR_WRITE(old_z_dir_pin);
2543
+          X_DIR_WRITE(old_dir.x);
2544
+          Y_DIR_WRITE(old_dir.y);
2545
+          Z_DIR_WRITE(old_dir.z);
2562 2546
 
2563 2547
         #endif
2564 2548
 
@@ -2566,7 +2550,9 @@ void Stepper::report_positions() {
2566 2550
 
2567 2551
       default: break;
2568 2552
     }
2569
-    sei();
2553
+
2554
+    START_LOW_PULSE(); AWAIT_LOW_PULSE();  // Prevent Stepper::ISR pulsing too soon
2555
+    ENABLE_ISRS();                         // Now it's ok for the ISR to run
2570 2556
   }
2571 2557
 
2572 2558
 #endif // BABYSTEPPING

Loading…
Cancel
Save