From 4067d15c92b6acbe0da3f87fce1b33ccf2d56ce8 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 14 Apr 2017 22:44:08 -0500 Subject: [PATCH] Cleanup, extend TMC2130 implementation --- .travis.yml | 2 +- Marlin/Marlin_main.cpp | 277 +++++++++++++++++++++++++++------ Marlin/configuration_store.cpp | 20 +-- Marlin/stepper_indirection.cpp | 62 +++++--- 4 files changed, 275 insertions(+), 86 deletions(-) diff --git a/.travis.yml b/.travis.yml index e877b2b34..f4e0f8d08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -409,7 +409,7 @@ script: - restore_configs - opt_enable_adv HAVE_TMC2130 X_IS_TMC2130 Y_IS_TMC2130 Z_IS_TMC2130 - build_marlin - - opt_enable_adv AUTOMATIC_CURRENT_CONTROL STEALTHCHOP + - opt_enable_adv AUTOMATIC_CURRENT_CONTROL STEALTHCHOP HYBRID_THRESHOLD SENSORLESS_HOMING - build_marlin # # tvrrug Config need to check board type for sanguino atmega644p diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 5626a2226..cf64cdc96 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -198,6 +198,8 @@ * M910 - Commit digipot/DAC value to external EEPROM via I2C. (Requires DAC_STEPPER_CURRENT) * M911 - Report stepper driver overtemperature pre-warn condition. (Requires HAVE_TMC2130) * M912 - Clear stepper driver overtemperature pre-warn condition flag. (Requires HAVE_TMC2130) + * M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD) + * M914 - Set SENSORLESS_HOMING sensitivity. (Requires SENSORLESS_HOMING) * M350 - Set microstepping mode. (Requires digital microstepping pins.) * M351 - Toggle MS1 MS2 pins directly. (Requires digital microstepping pins.) * @@ -647,6 +649,10 @@ static bool send_ok[BUFSIZE]; bool chdkActive = false; #endif +#ifdef AUTOMATIC_CURRENT_CONTROL + bool auto_current_control = 0; +#endif + #if ENABLED(PID_EXTRUSION_SCALING) int lpq_len = 20; #endif @@ -2756,6 +2762,28 @@ static void do_homing_move(const AxisEnum axis, float distance, float fr_mm_s=0. #endif } +/** + * TMC2130 specific sensorless homing using stallGuard2. + * stallGuard2 only works when in spreadCycle mode. + * spreadCycle and stealthChop are mutually exclusive. + */ +#if ENABLED(SENSORLESS_HOMING) + void tmc2130_sensorless_homing(TMC2130Stepper &st, bool enable=true) { + #if ENABLED(STEALTHCHOP) + if (enable) { + st.coolstep_min_speed(1024UL * 1024UL - 1UL); + st.stealthChop(0); + } + else { + st.coolstep_min_speed(0); + st.stealthChop(1); + } + #endif + + st.diag1_stall(enable ? 1 : 0); + } +#endif + /** * Home an individual "raw axis" to its endstop. * This applies to XYZ on Cartesian and Core robots, and @@ -2804,6 +2832,16 @@ static void homeaxis(const AxisEnum axis) { if (axis == Z_AXIS) stepper.set_homing_flag(true); #endif + // Disable stealthChop if used. Enable diag1 pin on driver. + #if ENABLED(SENSORLESS_HOMING) + #if ENABLED(X_IS_TMC2130) + if (axis == X_AXIS) tmc2130_sensorless_homing(stepperX); + #endif + #if ENABLED(Y_IS_TMC2130) + if (axis == Y_AXIS) tmc2130_sensorless_homing(stepperY); + #endif + #endif + // Fast move towards endstop until triggered #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Home 1 Fast:"); @@ -2888,6 +2926,16 @@ static void homeaxis(const AxisEnum axis) { #endif + // Re-enable stealthChop if used. Disable diag1 pin on driver. + #if ENABLED(SENSORLESS_HOMING) + #if ENABLED(X_IS_TMC2130) + if (axis == X_AXIS) tmc2130_sensorless_homing(stepperX, false); + #endif + #if ENABLED(Y_IS_TMC2130) + if (axis == Y_AXIS) tmc2130_sensorless_homing(stepperY, false); + #endif + #endif + // Put away the Z probe #if HOMING_Z_WITH_PROBE if (axis == Z_AXIS && STOW_PROBE()) return; @@ -6902,6 +6950,11 @@ inline void gcode_M140() { OUT_WRITE(SUICIDE_PIN, HIGH); #endif + #if ENABLED(HAVE_TMC2130) + delay(100); + tmc2130_init(); // Settings only stick when the driver has power + #endif + #if ENABLED(ULTIPANEL) powersupply = true; LCD_MESSAGEPGM(WELCOME_MSG); @@ -8770,22 +8823,21 @@ inline void gcode_M503() { #if ENABLED(HAVE_TMC2130) - static void tmc2130_print_current(const int mA, const char name) { + static void tmc2130_get_current(TMC2130Stepper &st, const char name) { SERIAL_CHAR(name); SERIAL_ECHOPGM(" axis driver current: "); - SERIAL_ECHOLN(mA); + SERIAL_ECHOLN(st.getCurrent()); } - static void tmc2130_set_current(const int mA, TMC2130Stepper &st, const char name) { - tmc2130_print_current(mA, name); - st.setCurrent(mA, 0.11, 0.5); - } - static void tmc2130_get_current(TMC2130Stepper &st, const char name) { - tmc2130_print_current(st.getCurrent(), name); + static void tmc2130_set_current(TMC2130Stepper &st, const char name, const int mA) { + st.setCurrent(mA, R_SENSE, HOLD_MULTIPLIER); + tmc2130_get_current(st, name); } + static void tmc2130_report_otpw(TMC2130Stepper &st, const char name) { SERIAL_CHAR(name); SERIAL_ECHOPGM(" axis temperature prewarn triggered: "); serialprintPGM(st.getOTPW() ? PSTR("true") : PSTR("false")); + SERIAL_EOL; } static void tmc2130_clear_otpw(TMC2130Stepper &st, const char name) { st.clear_otpw(); @@ -8793,10 +8845,32 @@ inline void gcode_M503() { SERIAL_ECHOLNPGM(" prewarn flag cleared"); } + static void tmc2130_get_pwmthrs(TMC2130Stepper &st, const char name, const uint16_t spmm) { + SERIAL_CHAR(name); + SERIAL_ECHOPGM(" stealthChop max speed set to "); + SERIAL_ECHOLN(12650000UL * st.microsteps() / (256 * st.stealth_max_speed() * spmm)); + } + static void tmc2130_set_pwmthrs(TMC2130Stepper &st, const char name, const int32_t thrs, const uint32_t spmm) { + st.stealth_max_speed(12650000UL * st.microsteps() / (256 * thrs * spmm)); + tmc2130_get_pwmthrs(st, name, spmm); + } + + static void tmc2130_get_sgt(TMC2130Stepper &st, const char name) { + SERIAL_CHAR(name); + SERIAL_ECHOPGM(" driver homing sensitivity set to "); + SERIAL_ECHOLN(st.sgt()); + } + static void tmc2130_set_sgt(TMC2130Stepper &st, const char name, const int8_t sgt_val) { + st.sgt(sgt_val); + tmc2130_get_sgt(st, name); + } + /** * M906: Set motor current in milliamps using axis codes X, Y, Z, E - * * Report driver currents when no axis specified + * + * S1: Enable automatic current control + * S0: Disable */ inline void gcode_M906() { uint16_t values[XYZE]; @@ -8804,21 +8878,25 @@ inline void gcode_M503() { values[i] = code_seen(axis_codes[i]) ? code_value_int() : 0; #if ENABLED(X_IS_TMC2130) - if (values[X_AXIS]) tmc2130_set_current(values[X_AXIS], stepperX, 'X'); + if (values[X_AXIS]) tmc2130_set_current(stepperX, 'X', values[X_AXIS]); else tmc2130_get_current(stepperX, 'X'); #endif #if ENABLED(Y_IS_TMC2130) - if (values[Y_AXIS]) tmc2130_set_current(values[Y_AXIS], stepperY, 'Y'); + if (values[Y_AXIS]) tmc2130_set_current(stepperY, 'Y', values[Y_AXIS]); else tmc2130_get_current(stepperY, 'Y'); #endif #if ENABLED(Z_IS_TMC2130) - if (values[Z_AXIS]) tmc2130_set_current(values[Z_AXIS], stepperZ, 'Z'); + if (values[Z_AXIS]) tmc2130_set_current(stepperZ, 'Z', values[Z_AXIS]); else tmc2130_get_current(stepperZ, 'Z'); #endif #if ENABLED(E0_IS_TMC2130) - if (values[E_AXIS]) tmc2130_set_current(values[E_AXIS], stepperE0, 'E'); + if (values[E_AXIS]) tmc2130_set_current(stepperE0, 'E', values[E_AXIS]); else tmc2130_get_current(stepperE0, 'E'); #endif + + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + if (code_seen('S')) auto_current_control = code_value_bool(); + #endif } /** @@ -8826,17 +8904,19 @@ inline void gcode_M503() { * The flag is held by the library and persist until manually cleared by M912 */ inline void gcode_M911() { + const bool reportX = code_seen('X'), reportY = code_seen('Y'), reportZ = code_seen('Z'), reportE = code_seen('E'), + reportAll = (!reportX && !reportY && !reportZ && !reportE) || (reportX && reportY && reportZ && reportE); #if ENABLED(X_IS_TMC2130) - tmc2130_report_otpw(stepperX, 'X'); + if (reportX || reportAll) tmc2130_report_otpw(stepperX, 'X'); #endif #if ENABLED(Y_IS_TMC2130) - tmc2130_report_otpw(stepperY, 'Y'); + if (reportY || reportAll) tmc2130_report_otpw(stepperY, 'Y'); #endif #if ENABLED(Z_IS_TMC2130) - tmc2130_report_otpw(stepperZ, 'Z'); + if (reportZ || reportAll) tmc2130_report_otpw(stepperZ, 'Z'); #endif #if ENABLED(E0_IS_TMC2130) - tmc2130_report_otpw(stepperE0, 'E'); + if (reportE || reportAll) tmc2130_report_otpw(stepperE0, 'E'); #endif } @@ -8844,20 +8924,66 @@ inline void gcode_M503() { * M912: Clear TMC2130 stepper driver overtemperature pre-warn flag held by the library */ inline void gcode_M912() { + const bool clearX = code_seen('X'), clearY = code_seen('Y'), clearZ = code_seen('Z'), clearE = code_seen('E'), + clearAll = (!clearX && !clearY && !clearZ && !clearE) || (clearX && clearY && clearZ && clearE); #if ENABLED(X_IS_TMC2130) - if (code_seen('X')) tmc2130_clear_otpw(stepperX, 'X'); + if (clearX || clearAll) tmc2130_clear_otpw(stepperX, 'X'); #endif #if ENABLED(Y_IS_TMC2130) - if (code_seen('Y')) tmc2130_clear_otpw(stepperY, 'Y'); + if (clearY || clearAll) tmc2130_clear_otpw(stepperY, 'Y'); #endif #if ENABLED(Z_IS_TMC2130) - if (code_seen('Z')) tmc2130_clear_otpw(stepperZ, 'Z'); + if (clearZ || clearAll) tmc2130_clear_otpw(stepperZ, 'Z'); #endif #if ENABLED(E0_IS_TMC2130) - if (code_seen('E')) tmc2130_clear_otpw(stepperE0, 'E'); + if (clearE || clearAll) tmc2130_clear_otpw(stepperE0, 'E'); #endif } + /** + * M913: Set HYBRID_THRESHOLD speed. + */ + #if ENABLED(HYBRID_THRESHOLD) + inline void gcode_M913() { + uint16_t values[XYZE]; + LOOP_XYZE(i) + values[i] = code_seen(axis_codes[i]) ? code_value_int() : 0; + + #if ENABLED(X_IS_TMC2130) + if (values[X_AXIS]) tmc2130_set_pwmthrs(stepperX, 'X', values[X_AXIS], planner.axis_steps_per_mm[X_AXIS]); + else tmc2130_get_pwmthrs(stepperX, 'X', planner.axis_steps_per_mm[X_AXIS]); + #endif + #if ENABLED(Y_IS_TMC2130) + if (values[Y_AXIS]) tmc2130_set_pwmthrs(stepperY, 'Y', values[Y_AXIS], planner.axis_steps_per_mm[Y_AXIS]); + else tmc2130_get_pwmthrs(stepperY, 'Y', planner.axis_steps_per_mm[Y_AXIS]); + #endif + #if ENABLED(Z_IS_TMC2130) + if (values[Z_AXIS]) tmc2130_set_pwmthrs(stepperZ, 'Z', values[Z_AXIS], planner.axis_steps_per_mm[Z_AXIS]); + else tmc2130_get_pwmthrs(stepperZ, 'Z', planner.axis_steps_per_mm[Z_AXIS]); + #endif + #if ENABLED(E0_IS_TMC2130) + if (values[E_AXIS]) tmc2130_set_pwmthrs(stepperE0, 'E', values[E_AXIS], planner.axis_steps_per_mm[E_AXIS]); + else tmc2130_get_pwmthrs(stepperE0, 'E', planner.axis_steps_per_mm[E_AXIS]); + #endif + } + #endif // HYBRID_THRESHOLD + + /** + * M914: Set SENSORLESS_HOMING sensitivity. + */ + #if ENABLED(SENSORLESS_HOMING) + inline void gcode_M914() { + #if ENABLED(X_IS_TMC2130) + if (code_seen(axis_codes[X_AXIS])) tmc2130_set_sgt(stepperX, 'X', code_value_int()); + else tmc2130_get_sgt(stepperX, 'X'); + #endif + #if ENABLED(Y_IS_TMC2130) + if (code_seen(axis_codes[Y_AXIS])) tmc2130_set_sgt(stepperY, 'Y', code_value_int()); + else tmc2130_get_sgt(stepperY, 'Y'); + #endif + } + #endif // SENSORLESS_HOMING + #endif // HAVE_TMC2130 /** @@ -8865,10 +8991,9 @@ inline void gcode_M503() { */ inline void gcode_M907() { #if HAS_DIGIPOTSS - LOOP_XYZE(i) - if (code_seen(axis_codes[i])) stepper.digipot_current(i, code_value_int()); + LOOP_XYZE(i) if (code_seen(axis_codes[i])) stepper.digipot_current(i, code_value_int()); if (code_seen('B')) stepper.digipot_current(4, code_value_int()); - if (code_seen('S')) for (int i = 0; i <= 4; i++) stepper.digipot_current(i, code_value_int()); + if (code_seen('S')) for (uint8_t i = 0; i <= 4; i++) stepper.digipot_current(i, code_value_int()); #elif HAS_MOTOR_CURRENT_PWM #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) if (code_seen('X')) stepper.digipot_current(0, code_value_int()); @@ -8884,11 +9009,11 @@ inline void gcode_M907() { // this one uses actual amps in floating point LOOP_XYZE(i) if (code_seen(axis_codes[i])) digipot_i2c_set_current(i, code_value_float()); // for each additional extruder (named B,C,D,E..., channels 4,5,6,7...) - for (int i = NUM_AXIS; i < DIGIPOT_I2C_NUM_CHANNELS; i++) if (code_seen('B' + i - (NUM_AXIS))) digipot_i2c_set_current(i, code_value_float()); + for (uint8_t i = NUM_AXIS; i < DIGIPOT_I2C_NUM_CHANNELS; i++) if (code_seen('B' + i - (NUM_AXIS))) digipot_i2c_set_current(i, code_value_float()); #endif #if ENABLED(DAC_STEPPER_CURRENT) if (code_seen('S')) { - float dac_percent = code_value_float(); + const float dac_percent = code_value_float(); for (uint8_t i = 0; i <= 4; i++) dac_current_percent(i, dac_percent); } LOOP_XYZE(i) if (code_seen(axis_codes[i])) dac_current_percent(i, code_value_float()); @@ -10165,6 +10290,18 @@ void process_next_command() { case 912: // M911: Clear TMC2130 prewarn triggered flags gcode_M912(); break; + + #if ENABLED(HYBRID_THRESHOLD) + case 913: // M913: Set HYBRID_THRESHOLD speed. + gcode_M913(); + break; + #endif + + #if ENABLED(SENSORLESS_HOMING) + case 914: // M914: Set SENSORLESS_HOMING sensitivity. + gcode_M914(); + break; + #endif #endif #if HAS_MICROSTEPS @@ -11390,23 +11527,58 @@ void disable_all_steppers() { disable_e_steppers(); } -#if ENABLED(AUTOMATIC_CURRENT_CONTROL) +#if ENABLED(HAVE_TMC2130) - void automatic_current_control(const TMC2130Stepper &st) { - #if CURRENT_STEP > 0 - const bool is_otpw = st.checkOT(), // Check otpw even if we don't adjust. Allows for flag inspection. - is_otpw_triggered = st.getOTPW(); + void automatic_current_control(TMC2130Stepper &st, String axisID) { + // Check otpw even if we don't use automatic control. Allows for flag inspection. + const bool is_otpw = st.checkOT(); - if (!is_otpw && !is_otpw_triggered) { - // OTPW bit not triggered yet -> Increase current - const uint16_t current = st.getCurrent() + CURRENT_STEP; - if (current <= AUTO_ADJUST_MAX) st.SilentStepStick2130(current); + // Report if a warning was triggered + static bool previous_otpw = false; + if (is_otpw && !previous_otpw) { + char timestamp[10]; + duration_t elapsed = print_job_timer.duration(); + const bool has_days = (elapsed.value > 60*60*24L); + (void)elapsed.toDigital(timestamp, has_days); + SERIAL_ECHO(timestamp); + SERIAL_ECHO(": "); + SERIAL_ECHO(axisID); + SERIAL_ECHOLNPGM(" driver overtemperature warning!"); + } + previous_otpw = is_otpw; + + #if CURRENT_STEP > 0 && ENABLED(AUTOMATIC_CURRENT_CONTROL) + // Return if user has not enabled current control start with M906 S1. + if (!auto_current_control) return; + + /** + * Decrease current if is_otpw is true. + * Bail out if driver is disabled. + * Increase current if OTPW has not been triggered yet. + */ + uint16_t current = st.getCurrent(); + if (is_otpw) { + st.setCurrent(current - CURRENT_STEP, R_SENSE, HOLD_MULTIPLIER); + #if ENABLED(REPORT_CURRENT_CHANGE) + SERIAL_ECHO(axisID); + SERIAL_ECHOPAIR(" current decreased to ", st.getCurrent()); + #endif } - else if (is_otpw && is_otpw_triggered) { - // OTPW bit triggered, triggered flag raised -> Decrease current - st.SilentStepStick2130((float)st.getCurrent() - CURRENT_STEP); + + else if (!st.isEnabled()) + return; + + else if (!is_otpw && !st.getOTPW()) { + current += CURRENT_STEP; + if (current <= AUTO_ADJUST_MAX) { + st.setCurrent(current, R_SENSE, HOLD_MULTIPLIER); + #if ENABLED(REPORT_CURRENT_CHANGE) + SERIAL_ECHO(axisID); + SERIAL_ECHOPAIR(" current increased to ", st.getCurrent()); + #endif + } } - // OTPW bit cleared (we've cooled down), triggered flag still raised until manually cleared -> Do nothing, we're good + SERIAL_EOL; #endif } @@ -11415,34 +11587,37 @@ void disable_all_steppers() { if (ELAPSED(millis(), next_cOT)) { next_cOT = millis() + 5000; #if ENABLED(X_IS_TMC2130) - automatic_current_control(stepperX); + automatic_current_control(stepperX, "X"); #endif #if ENABLED(Y_IS_TMC2130) - automatic_current_control(stepperY); + automatic_current_control(stepperY, "Y"); #endif #if ENABLED(Z_IS_TMC2130) - automatic_current_control(stepperZ); + automatic_current_control(stepperZ, "Z"); #endif #if ENABLED(X2_IS_TMC2130) - automatic_current_control(stepperX2); + automatic_current_control(stepperX2, "X2"); #endif #if ENABLED(Y2_IS_TMC2130) - automatic_current_control(stepperY2); + automatic_current_control(stepperY2, "Y2"); #endif #if ENABLED(Z2_IS_TMC2130) - automatic_current_control(stepperZ2); + automatic_current_control(stepperZ2, "Z2"); #endif #if ENABLED(E0_IS_TMC2130) - automatic_current_control(stepperE0); + automatic_current_control(stepperE0, "E0"); #endif #if ENABLED(E1_IS_TMC2130) - automatic_current_control(stepperE1); + automatic_current_control(stepperE1, "E1"); #endif #if ENABLED(E2_IS_TMC2130) - automatic_current_control(stepperE2); + automatic_current_control(stepperE2, "E2"); #endif #if ENABLED(E3_IS_TMC2130) - automatic_current_control(stepperE3); + automatic_current_control(stepperE3, "E3"); + #endif + #if ENABLED(E4_IS_TMC2130) + automatic_current_control(stepperE4, "E4"); #endif #if ENABLED(E4_IS_TMC2130) automatic_current_control(stepperE4); @@ -11450,7 +11625,7 @@ void disable_all_steppers() { } } -#endif // AUTOMATIC_CURRENT_CONTROL +#endif // HAVE_TMC2130 /** * Manage several activities: @@ -11648,7 +11823,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) { handle_status_leds(); #endif - #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + #if ENABLED(HAVE_TMC2130) checkOverTemp(); #endif diff --git a/Marlin/configuration_store.cpp b/Marlin/configuration_store.cpp index 16775bbd1..d19296d2b 100644 --- a/Marlin/configuration_store.cpp +++ b/Marlin/configuration_store.cpp @@ -1124,34 +1124,34 @@ void MarlinSettings::reset() { #if ENABLED(HAVE_TMC2130) #if ENABLED(X_IS_TMC2130) - stepperX.setCurrent(X_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperX.setCurrent(X_CURRENT, R_SENSE, HOLD_MULTIPLIER); #endif #if ENABLED(Y_IS_TMC2130) - stepperY.setCurrent(Y_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperY.setCurrent(Y_CURRENT, R_SENSE, HOLD_MULTIPLIER); #endif #if ENABLED(Z_IS_TMC2130) - stepperZ.setCurrent(Z_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperZ.setCurrent(Z_CURRENT, R_SENSE, HOLD_MULTIPLIER); #endif #if ENABLED(X2_IS_TMC2130) - stepperX2.setCurrent(X2_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperX2.setCurrent(X2_CURRENT, R_SENSE, HOLD_MULTIPLIER); #endif #if ENABLED(Y2_IS_TMC2130) - stepperY2.setCurrent(Y2_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperY2.setCurrent(Y2_CURRENT, R_SENSE, HOLD_MULTIPLIER); #endif #if ENABLED(Z2_IS_TMC2130) - stepperZ2.setCurrent(Z2_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperZ2.setCurrent(Z2_CURRENT, R_SENSE, HOLD_MULTIPLIER); #endif #if ENABLED(E0_IS_TMC2130) - stepperE0.setCurrent(E0_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperE0.setCurrent(E0_CURRENT, R_SENSE, HOLD_MULTIPLIER); #endif #if ENABLED(E1_IS_TMC2130) - stepperE1.setCurrent(E1_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperE1.setCurrent(E1_CURRENT, R_SENSE, HOLD_MULTIPLIER); #endif #if ENABLED(E2_IS_TMC2130) - stepperE2.setCurrent(E2_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperE2.setCurrent(E2_CURRENT, R_SENSE, HOLD_MULTIPLIER); #endif #if ENABLED(E3_IS_TMC2130) - stepperE3.setCurrent(E3_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + stepperE3.setCurrent(E3_CURRENT, R_SENSE, HOLD_MULTIPLIER); #endif #endif diff --git a/Marlin/stepper_indirection.cpp b/Marlin/stepper_indirection.cpp index 4e072dff2..0fe3a801c 100644 --- a/Marlin/stepper_indirection.cpp +++ b/Marlin/stepper_indirection.cpp @@ -129,8 +129,9 @@ #include #include + #include "enum.h" - #define _TMC2130_DEFINE(ST) TMC2130Stepper stepper##ST(ST##_ENABLE_PIN, ST##_DIR_PIN, ST##_STEP_PIN, ST##_CHIP_SELECT) + #define _TMC2130_DEFINE(ST) TMC2130Stepper stepper##ST(ST##_ENABLE_PIN, ST##_DIR_PIN, ST##_STEP_PIN, ST##_CS_PIN) // Stepper objects of TMC2130 steppers used #if ENABLED(X_IS_TMC2130) @@ -169,61 +170,74 @@ // Use internal reference voltage for current calculations. This is the default. // Following values from Trinamic's spreadsheet with values for a NEMA17 (42BYGHW609) - void tmc2130_init(TMC2130Stepper &st, const uint16_t max_current, const uint16_t microsteps) { + // https://www.trinamic.com/products/integrated-circuits/details/tmc2130/ + void tmc2130_init(TMC2130Stepper &st, const uint16_t microsteps, const uint32_t thrs, const uint32_t spmm) { st.begin(); st.setCurrent(st.getCurrent(), R_SENSE, HOLD_MULTIPLIER); st.microsteps(microsteps); - st.blank_time(24); - st.off_time(8); + st.blank_time(36); + st.off_time(5); // Only enables the driver if used with stealthChop st.interpolate(INTERPOLATE); + st.power_down_delay(128); // ~2s until driver lowers to hold current + st.hysterisis_start(0); // HSTRT = 1 + st.hysterisis_low(1); // HEND = -2 + st.diag1_active_high(1); // For sensorless homing #if ENABLED(STEALTHCHOP) + st.stealth_freq(1); // f_pwm = 2/683 f_clk + st.stealth_autoscale(1); + st.stealth_gradient(5); + st.stealth_amplitude(255); st.stealthChop(1); - #endif - #if ENABLED(SENSORLESS_HOMING) - st.coolstep_min_speed(1048575); - st.sg_stall_value(STALL_THRESHOLD); - st.sg_filter(1); - st.diag1_stall(1); - st.diag1_active_high(1); + #if ENABLED(HYBRID_THRESHOLD) + st.stealth_max_speed(12650000UL*st.microsteps()/(256*thrs*spmm)); + #endif + #elif ENABLED(SENSORLESS_HOMING) + st.coolstep_min_speed(1024UL * 1024UL - 1UL); #endif } - #define _TMC2130_INIT(ST) tmc2130_init(stepper##ST, ST##_MAX_CURRENT, ST##_MICROSTEPS) + #define _TMC2130_INIT(ST, SPMM) tmc2130_init(stepper##ST, ST##_MICROSTEPS, ST##_HYBRID_THRESHOLD, SPMM) void tmc2130_init() { - delay(500); // Let power stabilize before configuring the steppers + constexpr uint16_t steps_per_mm[] = DEFAULT_AXIS_STEPS_PER_UNIT; #if ENABLED(X_IS_TMC2130) - _TMC2130_INIT(X); + _TMC2130_INIT( X, steps_per_mm[X_AXIS]); + #if ENABLED(SENSORLESS_HOMING) + stepperX.sg_stall_value(X_HOMING_SENSITIVITY); + #endif #endif #if ENABLED(X2_IS_TMC2130) - _TMC2130_INIT(X2); + _TMC2130_INIT(X2, steps_per_mm[X_AXIS]); #endif #if ENABLED(Y_IS_TMC2130) - _TMC2130_INIT(Y); + _TMC2130_INIT( Y, steps_per_mm[Y_AXIS]); + #if ENABLED(SENSORLESS_HOMING) + stepperY.sg_stall_value(Y_HOMING_SENSITIVITY); + #endif #endif #if ENABLED(Y2_IS_TMC2130) - _TMC2130_INIT(Y2); + _TMC2130_INIT(Y2, steps_per_mm[Y_AXIS]); #endif #if ENABLED(Z_IS_TMC2130) - _TMC2130_INIT(Z); + _TMC2130_INIT( Z, steps_per_mm[Z_AXIS]); #endif #if ENABLED(Z2_IS_TMC2130) - _TMC2130_INIT(Z2); + _TMC2130_INIT(Z2, steps_per_mm[Z_AXIS]); #endif #if ENABLED(E0_IS_TMC2130) - _TMC2130_INIT(E0); + _TMC2130_INIT(E0, steps_per_mm[E_AXIS]); #endif #if ENABLED(E1_IS_TMC2130) - _TMC2130_INIT(E1); + { constexpr int extruder = 1; _TMC2130_INIT(E1, steps_per_mm[E_AXIS_N]); } #endif #if ENABLED(E2_IS_TMC2130) - _TMC2130_INIT(E2); + { constexpr int extruder = 2; _TMC2130_INIT(E2, steps_per_mm[E_AXIS_N]); } #endif #if ENABLED(E3_IS_TMC2130) - _TMC2130_INIT(E3); + { constexpr int extruder = 3; _TMC2130_INIT(E3, steps_per_mm[E_AXIS_N]); } #endif #if ENABLED(E4_IS_TMC2130) - _TMC2130_INIT(E4); + { constexpr int extruder = 4; _TMC2130_INIT(E4, steps_per_mm[E_AXIS_N]); } #endif TMC2130_ADV()