@@ -1483,6 +1483,80 @@ void set_axis_not_trusted(const AxisEnum axis) {
1483
1483
#endif
1484
1484
}
1485
1485
1486
+ /* *
1487
+ * Move the axis back to its home_phase if set and driver is capable (TMC)
1488
+ *
1489
+ * Improves homing repeatability by homing to stepper coil's nearest absolute
1490
+ * phase position. Trinamic drivers use a stepper phase table with 1024 values
1491
+ * spanning 4 full steps with 256 positions each (ergo, 1024 positions).
1492
+ */
1493
+ void backout_to_tmc_homing_phase (const AxisEnum axis) {
1494
+ #ifdef TMC_HOME_PHASE
1495
+ const abc_long_t home_phase = TMC_HOME_PHASE;
1496
+
1497
+ // check if home phase is disabled for this axis.
1498
+ if (home_phase[axis] < 0 ) return ;
1499
+
1500
+ int16_t axisMicrostepSize;
1501
+ int16_t phaseCurrent;
1502
+ bool invertDir;
1503
+
1504
+ switch (axis) {
1505
+ #ifdef X_MICROSTEPS
1506
+ case X_AXIS:
1507
+ axisMicrostepSize = 256 / (X_MICROSTEPS);
1508
+ phaseCurrent = stepperX.get_microstep_counter ();
1509
+ invertDir = INVERT_X_DIR;
1510
+ break ;
1511
+ #endif
1512
+ #ifdef Y_MICROSTEPS
1513
+ case Y_AXIS:
1514
+ axisMicrostepSize = 256 / (Y_MICROSTEPS);
1515
+ phaseCurrent = stepperY.get_microstep_counter ();
1516
+ invertDir = INVERT_Y_DIR;
1517
+ break ;
1518
+ #endif
1519
+ #ifdef Z_MICROSTEPS
1520
+ case Z_AXIS:
1521
+ axisMicrostepSize = 256 / (Z_MICROSTEPS);
1522
+ phaseCurrent = stepperZ.get_microstep_counter ();
1523
+ invertDir = INVERT_Z_DIR;
1524
+ break ;
1525
+ #endif
1526
+ default : return ;
1527
+ }
1528
+
1529
+ // Depending on invert dir measure the distance to nearest home phase.
1530
+ int16_t phaseDelta = (invertDir ? -1 : 1 ) * (home_phase[axis] - phaseCurrent);
1531
+
1532
+ // Check if home distance within endstop assumed repeatability noise of .05mm and warn.
1533
+ if (ABS (phaseDelta) * planner.steps_to_mm [axis] / axisMicrostepSize < 0 .05f )
1534
+ DEBUG_ECHOLNPAIR (" Selected home phase " , home_phase[axis],
1535
+ " too close to endstop trigger phase " , phaseCurrent,
1536
+ " . Pick a different phase for " , axis_codes[axis]);
1537
+
1538
+ // Skip to next if target position is behind current. So it only moves away from endstop.
1539
+ if (phaseDelta < 0 ) phaseDelta += 1024 ;
1540
+
1541
+ // Get the integer µsteps to target. Unreachable phase? Consistently stop at the µstep before / after based on invertDir.
1542
+ const float mmDelta = -(int16_t (phaseDelta / axisMicrostepSize) * planner.steps_to_mm [axis] * (Z_HOME_DIR));
1543
+
1544
+ // optional debug messages.
1545
+ if (DEBUGGING (LEVELING)) {
1546
+ DEBUG_ECHOLNPAIR (
1547
+ " Endstop " , axis_codes[axis], " hit at Phase:" , phaseCurrent,
1548
+ " Delta:" , phaseDelta, " Distance:" , mmDelta
1549
+ );
1550
+ }
1551
+
1552
+ if (mmDelta != 0 ) {
1553
+ // retrace by the amount computed in mmDelta.
1554
+ do_homing_move (axis, mmDelta, get_homing_bump_feedrate (axis));
1555
+ }
1556
+ #endif
1557
+ }
1558
+
1559
+
1486
1560
/* *
1487
1561
* Home an individual "raw axis" to its endstop.
1488
1562
* This applies to XYZ on Cartesian and Core robots, and
@@ -1742,6 +1816,9 @@ void homeaxis(const AxisEnum axis) {
1742
1816
}
1743
1817
#endif
1744
1818
1819
+ // move back to homing phase if configured and capable
1820
+ backout_to_tmc_homing_phase (axis);
1821
+
1745
1822
#if IS_SCARA
1746
1823
1747
1824
set_axis_is_at_home (axis);
@@ -1753,10 +1830,13 @@ void homeaxis(const AxisEnum axis) {
1753
1830
// so here it re-homes each tower in turn.
1754
1831
// Delta homing treats the axes as normal linear axes.
1755
1832
1756
- // retrace by the amount specified in delta_endstop_adj + additional dist in order to have minimum steps
1757
- if (delta_endstop_adj[axis] * Z_HOME_DIR <= 0 ) {
1758
- if (DEBUGGING (LEVELING)) DEBUG_ECHOLNPGM (" delta_endstop_adj:" );
1759
- do_homing_move (axis, delta_endstop_adj[axis] - (MIN_STEPS_PER_SEGMENT + 1 ) * planner.steps_to_mm [axis] * Z_HOME_DIR);
1833
+ const float adjDistance = delta_endstop_adj[axis],
1834
+ minDistance = (MIN_STEPS_PER_SEGMENT) * planner.steps_to_mm [axis];
1835
+
1836
+ // Retrace by the amount specified in delta_endstop_adj if more than min steps.
1837
+ if (adjDistance * (Z_HOME_DIR) < 0 && ABS (adjDistance) > minDistance) { // away from endstop, more than min distance
1838
+ if (DEBUGGING (LEVELING)) DEBUG_ECHOLNPAIR (" adjDistance:" , adjDistance);
1839
+ do_homing_move (axis, adjDistance, get_homing_bump_feedrate (axis));
1760
1840
}
1761
1841
1762
1842
#else // CARTESIAN / CORE
0 commit comments