Skip to content

Editable TMC Homing Current #27760

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2995,6 +2995,8 @@

#define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current

//#define EDITABLE_HOMING_CURRENT // Add a G-code and menu to modify the Homing Current

/**
* Interpolate microsteps to 256
* Override for each driver with <driver>_INTERPOLATE settings below
Expand Down
3 changes: 2 additions & 1 deletion Marlin/src/core/language.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,9 @@
#define STR_FILAMENT_RUNOUT_SENSOR "Filament runout sensor"
#define STR_DRIVER_STEPPING_MODE "Driver stepping mode"
#define STR_STEPPER_DRIVER_CURRENT "Stepper driver current"
#define STR_HOMING_CURRENT "Homing Current (mA)"
#define STR_HYBRID_THRESHOLD "Hybrid Threshold"
#define STR_STALLGUARD_THRESHOLD "StallGuard threshold"
#define STR_STALLGUARD_THRESHOLD "StallGuard Threshold"
#define STR_HOME_OFFSET "Home offset"
#define STR_SOFT_ENDSTOPS "Soft endstops"
#define STR_MATERIAL_HEATUP "Material heatup parameters"
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/feature/tmc_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
#endif
#endif

#if ENABLED(EDITABLE_HOMING_CURRENT)
homing_current_t homing_current_mA;
#endif

/**
* Check for over temperature or short to ground error flags.
* Report and log warning of overtemperature condition.
Expand Down
26 changes: 26 additions & 0 deletions Marlin/src/feature/tmc_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,32 @@ void test_tmc_connection(LOGICAL_AXIS_DECL_LC(const bool, true));

#endif // USE_SENSORLESS

#if HAS_HOMING_CURRENT

// Axes that have a distinct homing current
struct homing_current_t {
OPTCODE(X_HAS_HOME_CURRENT, uint16_t X)
OPTCODE(Y_HAS_HOME_CURRENT, uint16_t Y)
OPTCODE(Z_HAS_HOME_CURRENT, uint16_t Z)
OPTCODE(X2_HAS_HOME_CURRENT, uint16_t X2)
OPTCODE(Y2_HAS_HOME_CURRENT, uint16_t Y2)
OPTCODE(Z2_HAS_HOME_CURRENT, uint16_t Z2)
OPTCODE(Z3_HAS_HOME_CURRENT, uint16_t Z3)
OPTCODE(Z4_HAS_HOME_CURRENT, uint16_t Z4)
OPTCODE(I_HAS_HOME_CURRENT, uint16_t I)
OPTCODE(J_HAS_HOME_CURRENT, uint16_t J)
OPTCODE(K_HAS_HOME_CURRENT, uint16_t K)
OPTCODE(U_HAS_HOME_CURRENT, uint16_t U)
OPTCODE(V_HAS_HOME_CURRENT, uint16_t V)
OPTCODE(W_HAS_HOME_CURRENT, uint16_t W)
};

#if ENABLED(EDITABLE_HOMING_CURRENT)
extern homing_current_t homing_current_mA;
#endif

#endif // HAS_HOMING_CURRENT

#endif // HAS_TRINAMIC_CONFIG

#if HAS_TMC_SPI
Expand Down
9 changes: 8 additions & 1 deletion Marlin/src/gcode/feature/trinamic/M906.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ static void tmc_print_current(TMC &st) {
/**
* M906: Set motor current in milliamps.
*
* With no parameters report driver currents.
*
* Parameters:
* X[current] - Set mA current for X driver(s)
* Y[current] - Set mA current for Y driver(s)
Expand All @@ -52,9 +54,14 @@ static void tmc_print_current(TMC &st) {
* I[index] - Axis sub-index (Omit or 0 for X, Y, Z; 1 for X2, Y2, Z2; 2 for Z3; 3 for Z4.)
* T[index] - Extruder index (Zero-based. Omit for E0 only.)
*
* With no parameters report driver currents.
* With EDITABLE_HOMING_CURRENT:
* H - Set / Report Homing Current. Alias for M920.
*/
void GcodeSuite::M906() {
#if ENABLED(EDITABLE_HOMING_CURRENT)
if (parser.seen_test('H')) return M920();
#endif

#define TMC_SAY_CURRENT(Q) tmc_print_current(stepper##Q)
#define TMC_SET_CURRENT(Q) stepper##Q.rms_current(value)

Expand Down
144 changes: 144 additions & 0 deletions Marlin/src/gcode/feature/trinamic/M920.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

#include "../../../inc/MarlinConfigPre.h"

#if ENABLED(EDITABLE_HOMING_CURRENT)

#include "../../gcode.h"
#include "../../../feature/tmc_util.h"

#if AXIS_COLLISION('I')
#define I_PARAM 'S'
#define I_PARAM_STR "S"
#warning "Use 'M920 S' instead of 'M920 I' for the stepper number."
#else
#define I_PARAM 'I'
#define I_PARAM_STR "I"
#endif

/**
* M920: Set Homing Current for one or more axes
*
* Parameters:
* X[current] - Homing Current to use for X axis stepper(s)
* Y[current] - Homing Current to use for Y axis stepper(s)
* Z[current] - Homing Current to use for Z axis stepper(s)
* A[current] - Homing Current to use for A axis stepper(s)
* B[current] - Homing Current to use for B axis stepper(s)
* C[current] - Homing Current to use for C axis stepper(s)
* U[current] - Homing Current to use for U axis stepper(s)
* V[current] - Homing Current to use for V axis stepper(s)
* W[current] - Homing Current to use for W axis stepper(s)
*
* I<index> - For multi-stepper axes, the zero-based index of the stepper to modify in each axis.
* If omitted all steppers of each axis will be set to the given axis current.
*/
void GcodeSuite::M920() {
bool report = true;
const uint8_t index = parser.byteval(I_PARAM);
LOOP_NUM_AXES(i) if (parser.seen(AXIS_CHAR(i))) {
const int16_t value = parser.value_int();
report = false;
switch (i) {
#if X_HAS_HOME_CURRENT
case X_AXIS:
if (index < 1) homing_current_mA.X = value;
TERN_(X2_HAS_HOME_CURRENT, if (!index || index == 1) homing_current_mA.X2 = value);
break;
#endif
#if Y_HAS_HOME_CURRENT
case Y_AXIS:
if (index < 1) homing_current_mA.Y = value;
TERN_(Y2_HAS_HOME_CURRENT, if (!index || index == 1) homing_current_mA.Y2 = value);
break;
#endif
#if Z_HAS_HOME_CURRENT
case Z_AXIS:
if (index < 1) homing_current_mA.Z = value;
TERN_(Z2_HAS_HOME_CURRENT, if (!index || index == 1) homing_current_mA.Z2 = value);
TERN_(Z3_HAS_HOME_CURRENT, if (!index || index == 2) homing_current_mA.Z3 = value);
TERN_(Z4_HAS_HOME_CURRENT, if (!index || index == 3) homing_current_mA.Z4 = value);
break;
#endif
OPTCODE(I_HAS_HOME_CURRENT, case I_AXIS: homing_current_mA.I = value; break)
OPTCODE(J_HAS_HOME_CURRENT, case J_AXIS: homing_current_mA.J = value; break)
OPTCODE(K_HAS_HOME_CURRENT, case K_AXIS: homing_current_mA.K = value; break)
OPTCODE(U_HAS_HOME_CURRENT, case U_AXIS: homing_current_mA.U = value; break)
OPTCODE(V_HAS_HOME_CURRENT, case V_AXIS: homing_current_mA.V = value; break)
OPTCODE(W_HAS_HOME_CURRENT, case W_AXIS: homing_current_mA.W = value; break)
}
}

if (report) M920_report();
}

void GcodeSuite::M920_report(const bool forReplay/*=true*/) {
TERN_(MARLIN_SMALL_BUILD, return);

report_heading(forReplay, F(STR_HOMING_CURRENT));

auto say_M920 = [](const bool forReplay, int16_t index=-1) {
report_echo_start(forReplay);
SERIAL_ECHOPGM(" M920");
if (index >= 0) SERIAL_ECHOPGM(" " I_PARAM_STR, index);
};

#if X_SENSORLESS || Y_SENSORLESS || Z_SENSORLESS
#if X2_SENSORLESS || Y2_SENSORLESS || Z2_SENSORLESS || Z3_SENSORLESS || Z4_SENSORLESS
say_M920(forReplay, 0);
#else
say_M920(forReplay);
#endif
TERN_(X_SENSORLESS, SERIAL_ECHOPGM_P(SP_X_STR, homing_current_mA.X));
TERN_(Y_SENSORLESS, SERIAL_ECHOPGM_P(SP_Y_STR, homing_current_mA.Y));
TERN_(Z_SENSORLESS, SERIAL_ECHOPGM_P(SP_Z_STR, homing_current_mA.Z));
#if X2_SENSORLESS || Y2_SENSORLESS || Z2_SENSORLESS || Z3_SENSORLESS || Z4_SENSORLESS
say_M920(forReplay);
#endif
TERN_(I_SENSORLESS, SERIAL_ECHOPGM_P(SP_I_STR, homing_current_mA.I));
TERN_(J_SENSORLESS, SERIAL_ECHOPGM_P(SP_J_STR, homing_current_mA.J));
TERN_(K_SENSORLESS, SERIAL_ECHOPGM_P(SP_K_STR, homing_current_mA.K));
TERN_(U_SENSORLESS, SERIAL_ECHOPGM_P(SP_U_STR, homing_current_mA.U));
TERN_(V_SENSORLESS, SERIAL_ECHOPGM_P(SP_V_STR, homing_current_mA.V));
TERN_(W_SENSORLESS, SERIAL_ECHOPGM_P(SP_W_STR, homing_current_mA.W));
SERIAL_EOL();
#endif

#if X2_SENSORLESS || Y2_SENSORLESS || Z2_SENSORLESS
say_M920(forReplay, 1);
TERN_(X2_SENSORLESS, SERIAL_ECHOPGM_P(SP_X_STR, homing_current_mA.X2));
TERN_(Y2_SENSORLESS, SERIAL_ECHOPGM_P(SP_Y_STR, homing_current_mA.Y2));
TERN_(Z2_SENSORLESS, SERIAL_ECHOPGM_P(SP_Z_STR, homing_current_mA.Z2));
SERIAL_EOL();
#endif
#if Z3_SENSORLESS
say_M920(forReplay, 2);
SERIAL_ECHOLNPGM(" Z", homing_current_mA.Z3);
#endif
#if Z4_SENSORLESS
say_M920(forReplay, 3);
SERIAL_ECHOLNPGM(" Z", homing_current_mA.Z4);
#endif
}

#endif // EDITABLE_HOMING_CURRENT
7 changes: 5 additions & 2 deletions Marlin/src/gcode/gcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1056,12 +1056,15 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 912: M912(); break; // M912: Clear TMC2130 prewarn triggered flags
#endif
#if ENABLED(HYBRID_THRESHOLD)
case 913: M913(); break; // M913: Set HYBRID_THRESHOLD speed.
case 913: M913(); break; // M913: Set HYBRID_THRESHOLD speed
#endif
#if USE_SENSORLESS
case 914: M914(); break; // M914: Set StallGuard sensitivity.
case 914: M914(); break; // M914: Set StallGuard sensitivity
#endif
case 919: M919(); break; // M919: Set stepper Chopper Times
#if ENABLED(EDITABLE_HOMING_CURRENT)
case 920: M920(); break; // M920: Set Homing Current
#endif
#endif

#if HAS_MICROSTEPS
Expand Down
5 changes: 5 additions & 0 deletions Marlin/src/gcode/gcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@
* M914 - Set StallGuard sensitivity. (Requires SENSORLESS_HOMING or SENSORLESS_PROBING)
* M919 - Set or Report motor Chopper Times (time_off, hysteresis_end, hysteresis_start) using axis codes XYZE, etc.
* If no parameters are given, report. (Requires *_DRIVER_TYPE TMC(2130|2160|5130|5160|2208|2209|2660))
* M920 - Set Homing Current. (Requires distinct *_CURRENT_HOME settings)
* M936 - OTA update firmware. (Requires OTA_FIRMWARE_UPDATE)
* M951 - Set Magnetic Parking Extruder parameters. (Requires MAGNETIC_PARKING_EXTRUDER)
* M3426 - Read MCP3426 ADC over I2C. (Requires HAS_MCP3426_ADC)
Expand Down Expand Up @@ -1259,6 +1260,10 @@ class GcodeSuite {
static void M914_report(const bool forReplay=true);
#endif
static void M919();
#if ENABLED(EDITABLE_HOMING_CURRENT)
static void M920();
static void M920_report(const bool forReplay=true);
#endif
#endif

#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM || HAS_MOTOR_CURRENT_I2C || HAS_MOTOR_CURRENT_DAC
Expand Down
1 change: 1 addition & 0 deletions Marlin/src/lcd/language/language_en.h
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,7 @@ namespace LanguageNarrow_en {
LSTR MSG_TMC_HOMING_THRS = _UxGT("Sensorless Homing");
LSTR MSG_TMC_STEPPING_MODE = _UxGT("Stepping Mode");
LSTR MSG_TMC_STEALTHCHOP = _UxGT("StealthChop");
LSTR MSG_TMC_HOMING_CURRENT = _UxGT("Homing Current");

LSTR MSG_SERVICE_RESET = _UxGT("Reset");
LSTR MSG_SERVICE_IN = _UxGT(" in:");
Expand Down
34 changes: 31 additions & 3 deletions Marlin/src/lcd/menu/menu_tmc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,33 @@ void menu_tmc_current() {

#endif // SENSORLESS_HOMING

#if ENABLED(EDITABLE_HOMING_CURRENT)

#define TMC_EDIT_HOMING_CURRENT(ST, STR) EDIT_ITEM_FAST_F(uint16_4, F(STR), &homing_current_mA.ST, ST##_CURRENT / 3, ST##_CURRENT)

void menu_tmc_homing_current() {
START_MENU();
STATIC_ITEM(MSG_TMC_HOMING_CURRENT);
BACK_ITEM(MSG_TMC_DRIVERS);
TERN_( X_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(X, STR_X));
TERN_(X2_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(X2, STR_X2));
TERN_( Y_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(Y, STR_Y));
TERN_(Y2_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(Y2, STR_Y2));
TERN_( Z_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(Z, STR_Z));
TERN_(Z2_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(Z2, STR_Z2));
TERN_(Z3_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(Z3, STR_Z3));
TERN_(Z4_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(Z4, STR_Z4));
TERN_( I_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(I, STR_I));
TERN_( J_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(J, STR_J));
TERN_( K_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(K, STR_K));
TERN_( U_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(U, STR_U));
TERN_( V_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(V, STR_V));
TERN_( W_HAS_HOME_CURRENT, TMC_EDIT_HOMING_CURRENT(W, STR_W));
END_MENU();
}

#endif // EDITABLE_HOMING_CURRENT

#if HAS_STEALTHCHOP

#define TMC_EDIT_STEP_MODE(ST, STR) EDIT_ITEM_F(bool, F(STR), &stepper##ST.stored.stealthChop_enabled, []{ stepper##ST.refresh_stepping_mode(); })
Expand Down Expand Up @@ -143,9 +170,10 @@ void menu_tmc() {
START_MENU();
BACK_ITEM(MSG_ADVANCED_SETTINGS);
SUBMENU(MSG_TMC_CURRENT, menu_tmc_current);
TERN_(HYBRID_THRESHOLD, SUBMENU(MSG_TMC_HYBRID_THRS, menu_tmc_hybrid_thrs));
TERN_(SENSORLESS_HOMING, SUBMENU(MSG_TMC_HOMING_THRS, menu_tmc_homing_thrs));
TERN_(HAS_STEALTHCHOP, SUBMENU(MSG_TMC_STEPPING_MODE, menu_tmc_step_mode));
TERN_(HYBRID_THRESHOLD, SUBMENU(MSG_TMC_HYBRID_THRS, menu_tmc_hybrid_thrs));
TERN_(SENSORLESS_HOMING, SUBMENU(MSG_TMC_HOMING_THRS, menu_tmc_homing_thrs));
TERN_(EDITABLE_HOMING_CURRENT, SUBMENU(MSG_TMC_HOMING_CURRENT, menu_tmc_homing_current));
TERN_(HAS_STEALTHCHOP, SUBMENU(MSG_TMC_STEALTHCHOP, menu_tmc_step_mode));
END_MENU();
}

Expand Down
Loading
Loading