From 45f949d83351b077d4d39d0936336439896bbcc3 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 6 Mar 2017 23:00:43 -0600 Subject: [PATCH] TMC2130 Library: @teemuatlut replaces @makertum --- .travis.yml | 8 +- Marlin/Configuration_adv.h | 247 +++++------------ Marlin/Marlin.ino | 4 +- Marlin/Marlin_main.cpp | 236 +++++++++++----- Marlin/configuration_store.cpp | 226 +++++++++++++++- Marlin/stepper.cpp | 2 +- Marlin/stepper_indirection.cpp | 480 ++++++--------------------------- Marlin/stepper_indirection.h | 46 ++-- 8 files changed, 570 insertions(+), 679 deletions(-) diff --git a/.travis.yml b/.travis.yml index cad55428a6..86d4f67983 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,8 +47,8 @@ install: # - sudo mv TMC26XStepper /usr/local/share/arduino/libraries/TMC26XStepper # # Install: TMC2130 Stepper Motor Controller library - - git clone https://github.com/MarlinFirmware/Trinamic_TMC2130.git - - sudo mv Trinamic_TMC2130/Trinamic_TMC2130 /usr/local/share/arduino/libraries/Trinamic_TMC2130 + - git clone https://github.com/teemuatlut/TMC2130Stepper.git + - sudo mv TMC2130Stepper /usr/local/share/arduino/libraries/TMC2130Stepper # before_script: # @@ -396,7 +396,9 @@ script: # TMC2130 Config # - restore_configs - - opt_enable_adv HAVE_TMC2130DRIVER X_IS_TMC2130 Y_IS_TMC2130 Z_IS_TMC2130 E0_IS_TMC2130 + - opt_enable_adv HAVE_TMC2130 X_IS_TMC2130 Y_IS_TMC2130 Z_IS_TMC2130 + - build_marlin + - opt_enable_adv AUTOMATIC_CURRENT_CONTROL STEALTHCHOP - build_marlin # # tvrrug Config need to check board type for sanguino atmega644p diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 8e1c520989..475a081383 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -761,14 +761,15 @@ // even if it takes longer than DEFAULT_STEPPER_DEACTIVE_TIME. #endif -/******************************************************************************\ - * enable this section if you have TMC26X motor drivers. - * you need to import the TMC26XStepper library into the Arduino IDE for this - ******************************************************************************/ - // @section tmc +/** + * Enable this section if you have TMC26X motor drivers. + * You will need to import the TMC26XStepper library into the Arduino IDE for this + * (https://github.com/trinamic/TMC26XStepper.git) + */ //#define HAVE_TMCDRIVER + #if ENABLED(HAVE_TMCDRIVER) //#define X_IS_TMC @@ -826,23 +827,31 @@ // @section TMC2130 - /** * Enable this for SilentStepStick Trinamic TMC2130 SPI-configurable stepper drivers. * - * To use TMC2130 drivers in SPI mode, you'll also need the TMC2130 Arduino library - * (https://github.com/makertum/Trinamic_TMC2130). + * You'll also need the TMC2130Stepper Arduino library + * (https://github.com/teemuatlut/TMC2130Stepper). * * To use TMC2130 stepper drivers in SPI mode connect your SPI2130 pins to * the hardware SPI interface on your board and define the required CS pins * in your `pins_MYBOARD.h` file. (e.g., RAMPS 1.4 uses AUX3 pins `X_CS_PIN 53`, `Y_CS_PIN 49`, etc.). */ +//#define HAVE_TMC2130 -//#define HAVE_TMC2130DRIVER +#if ENABLED(HAVE_TMC2130) + #define STEALTHCHOP -#if ENABLED(HAVE_TMC2130DRIVER) - - //#define TMC2130_ADVANCED_CONFIGURATION + /** + * Let Marlin automatically control stepper current. + * This is still an experimental feature. + * Increase current every 5s by CURRENT_STEP until stepper temperature prewarn gets triggered, + * then decrease current by CURRENT_STEP until temperature prewarn is cleared. + * Adjusting starts from X/Y/Z/E_MAX_CURRENT but will not increase over AUTO_ADJUST_MAX + */ + //#define AUTOMATIC_CURRENT_CONTROL + #define CURRENT_STEP 50 // [mA] + #define AUTO_ADJUST_MAX 1300 // [mA], 1300mA_rms = 1840mA_peak // CHOOSE YOUR MOTORS HERE, THIS IS MANDATORY //#define X_IS_TMC2130 @@ -856,182 +865,68 @@ //#define E2_IS_TMC2130 //#define E3_IS_TMC2130 - #if ENABLED(TMC2130_ADVANCED_CONFIGURATION) + /** + * Stepper driver settings + */ - // If you've enabled TMC2130_ADVANCED_CONFIGURATION, define global settings below. - // Enabled settings will be automatically applied to all axes specified above. - // - // Please read the TMC2130 datasheet: - // http://www.trinamic.com/_articles/products/integrated-circuits/tmc2130/_datasheet/TMC2130_datasheet.pdf - // All settings here have the same (sometimes cryptic) names as in the datasheet. - // - // The following, uncommented settings are only suggestion. + #define R_SENSE 0.11 // R_sense resistor for SilentStepStick2130 + #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current + #define INTERPOLATE 1 // Interpolate X/Y/Z_MICROSTEPS to 256 - /* GENERAL CONFIGURATION */ + #define X_MAX_CURRENT 1000 // rms current in mA + #define X_MICROSTEPS 16 // FULLSTEP..256 + #define X_CHIP_SELECT 40 // Pin - //#define GLOBAL_EN_PWM_MODE 0 - #define GLOBAL_I_SCALE_ANALOG 1 // [0,1] 0: Normal, 1: AIN - //#define GLOBAL_INTERNAL_RSENSE 0 // [0,1] 0: Normal, 1: Internal - #define GLOBAL_EN_PWM_MODE 0 // [0,1] 0: Normal, 1: stealthChop with velocity threshold - //#define GLOBAL_ENC_COMMUTATION 0 // [0,1] - #define GLOBAL_SHAFT 0 // [0,1] 0: normal, 1: invert - //#define GLOBAL_DIAG0_ERROR 0 // [0,1] - //#define GLOBAL_DIAG0_OTPW 0 // [0,1] - //#define GLOBAL_DIAG0_STALL 0 // [0,1] - //#define GLOBAL_DIAG1_STALL 0 // [0,1] - //#define GLOBAL_DIAG1_INDEX 0 // [0,1] - //#define GLOBAL_DIAG1_ONSTATE 0 // [0,1] - //#define GLOBAL_DIAG1_ONSTATE 0 // [0,1] - //#define GLOBAL_DIAG0_INT_PUSHPULL 0 // [0,1] - //#define GLOBAL_DIAG1_INT_PUSHPULL 0 // [0,1] - //#define GLOBAL_SMALL_HYSTERESIS 0 // [0,1] - //#define GLOBAL_STOP_ENABLE 0 // [0,1] - //#define GLOBAL_DIRECT_MODE 0 // [0,1] + #define Y_MAX_CURRENT 1000 + #define Y_MICROSTEPS 16 + #define Y_CHIP_SELECT 42 - /* VELOCITY-DEPENDENT DRIVE FEATURES */ + #define Z_MAX_CURRENT 1000 + #define Z_MICROSTEPS 16 + #define Z_CHIP_SELECT 65 - #define GLOBAL_IHOLD 22 // [0-31] 0: min, 31: max - #define GLOBAL_IRUN 31 // [0-31] 0: min, 31: max - #define GLOBAL_IHOLDDELAY 15 // [0-15] 0: min, 15: about 4 seconds - //#define GLOBAL_TPOWERDOWN 0 // [0-255] 0: min, 255: about 4 seconds - //#define GLOBAL_TPWMTHRS 0 // [0-1048576] e.g. 20 corresponds with 2000 steps/s - //#define GLOBAL_TCOOLTHRS 0 // [0-1048576] e.g. 20 corresponds with 2000 steps/s - #define GLOBAL_THIGH 10 // [0-1048576] e.g. 20 corresponds with 2000 steps/s + //#define X2_MAX_CURRENT 1000 + //#define X2_MICROSTEPS 16 + //#define X2_CHIP_SELECT -1 - /* SPI MODE CONFIGURATION */ + //#define Y2_MAX_CURRENT 1000 + //#define Y2_MICROSTEPS 16 + //#define Y2_CHIP_SELECT -1 - //#define GLOBAL_XDIRECT 0 + //#define Z2_MAX_CURRENT 1000 + //#define Z2_MICROSTEPS 16 + //#define Z2_CHIP_SELECT -1 - /* DCSTEP MINIMUM VELOCITY */ + //#define E0_MAX_CURRENT 1000 + //#define E0_MICROSTEPS 16 + //#define E0_CHIP_SELECT -1 - //#define GLOBAL_VDCMIN 0 + //#define E1_MAX_CURRENT 1000 + //#define E1_MICROSTEPS 16 + //#define E1_CHIP_SELECT -1 - /* MOTOR DRIVER CONFIGURATION*/ + //#define E2_MAX_CURRENT 1000 + //#define E2_MICROSTEPS 16 + //#define E2_CHIP_SELECT -1 - //#define GLOBAL_DEDGE 0 - //#define GLOBAL_DISS2G 0 - #define GLOBAL_INTPOL 1 // 0: off 1: 256 microstep interpolation - #define GLOBAL_MRES 16 // number of microsteps - #define GLOBAL_SYNC 1 // [0-15] - #define GLOBAL_VHIGHCHM 1 // [0,1] 0: normal, 1: high velocity stepper mode - #define GLOBAL_VHIGHFS 0 // [0,1] 0: normal, 1: switch to full steps for high velocities - // #define GLOBAL_VSENSE 0 // [0,1] 0: normal, 1: high sensitivity (not recommended) - #define GLOBAL_TBL 1 // 0-3: set comparator blank time to 16, 24, 36 or 54 clocks, 1 or 2 is recommended - #define GLOBAL_CHM 0 // [0,1] 0: spreadCycle, 1: Constant off time with fast decay time. - //#define GLOBAL_RNDTF 0 - //#define GLOBAL_DISFDCC 0 - //#define GLOBAL_FD 0 - //#define GLOBAL_HEND 0 - //#define GLOBAL_HSTRT 0 - #define GLOBAL_TOFF 10 // 0: driver disable, 1: use only with TBL>2, 2-15: off time setting during slow decay phase + //#define E3_MAX_CURRENT 1000 + //#define E3_MICROSTEPS 16 + //#define E3_CHIP_SELECT -1 - //#define GLOBAL_SFILT 0 - //#define GLOBAL_SGT 0 - //#define GLOBAL_SEIMIN 0 - //#define GLOBAL_SEDN 0 - //#define GLOBAL_SEMAX 0 - //#define GLOBAL_SEUP 0 - //#define GLOBAL_SEMIN 0 + /** + * You can set your own advanced settings by filling in predefined functions. + * A list of available functions can be found on the library github page + * https://github.com/teemuatlut/TMC2130Stepper + * + * Example: + * #define TMC2130_ADV() { \ + * stepperX.diag0_temp_prewarn(1); \ + * stepperX.interpolate(0); \ + * } + */ + #define TMC2130_ADV() { } - //#define GLOBAL_DC_TIME 0 - //#define GLOBAL_DC_SG 0 - - //#define GLOBAL_FREEWHEEL 0 - //#define GLOBAL_PWM_SYMMETRIC 0 - //#define GLOBAL_PWM_AUTOSCALE 0 - //#define GLOBAL_PWM_FREQ 0 - //#define GLOBAL_PWM_GRAD 0 - //#define GLOBAL_PWM_AMPL 0 - - //#define GLOBAL_ENCM_CTRL 0 - - #else - - #define X_IHOLD 31 // [0-31] 0: min, 31: max - #define X_IRUN 31 // [0-31] 0: min, 31: max - #define X_IHOLDDELAY 15 // [0-15] 0: min, 15: about 4 seconds - #define X_I_SCALE_ANALOG 1 // 0: Normal, 1: AIN - #define X_MRES 16 // number of microsteps - #define X_TBL 1 // 0-3: set comparator blank time to 16, 24, 36 or 54 clocks, 1 or 2 is recommended - #define X_TOFF 8 // 0: driver disable, 1: use only with TBL>2, 2-15: off time setting during slow decay phase - - #define X2_IHOLD 31 - #define X2_IRUN 31 - #define X2_IHOLDDELAY 15 - #define X2_I_SCALE_ANALOG 1 - #define X2_MRES 16 - #define X2_TBL 1 - #define X2_TOFF 8 - - #define Y_IHOLD 31 - #define Y_IRUN 31 - #define Y_IHOLDDELAY 15 - #define Y_I_SCALE_ANALOG 1 - #define Y_MRES 16 - #define Y_TBL 1 - #define Y_TOFF 8 - - #define Y2_IHOLD 31 - #define Y2_IRUN 31 - #define Y2_IHOLDDELAY 15 - #define Y2_I_SCALE_ANALOG 1 - #define Y2_MRES 16 - #define Y2_TBL 1 - #define Y2_TOFF 8 - - #define Z_IHOLD 31 - #define Z_IRUN 31 - #define Z_IHOLDDELAY 15 - #define Z_I_SCALE_ANALOG 1 - #define Z_MRES 16 - #define Z_TBL 1 - #define Z_TOFF 8 - - #define Z2_IHOLD 31 - #define Z2_IRUN 31 - #define Z2_IHOLDDELAY 15 - #define Z2_I_SCALE_ANALOG 1 - #define Z2_MRES 16 - #define Z2_TBL 1 - #define Z2_TOFF 8 - - #define E0_IHOLD 31 - #define E0_IRUN 31 - #define E0_IHOLDDELAY 15 - #define E0_I_SCALE_ANALOG 1 - #define E0_MRES 16 - #define E0_TBL 1 - #define E0_TOFF 8 - - #define E1_IHOLD 31 - #define E1_IRUN 31 - #define E1_IHOLDDELAY 15 - #define E1_I_SCALE_ANALOG 1 - #define E1_MRES 16 - #define E1_TBL 1 - #define E1_TOFF 8 - - #define E2_IHOLD 31 - #define E2_IRUN 31 - #define E2_IHOLDDELAY 15 - #define E2_I_SCALE_ANALOG 1 - #define E2_MRES 16 - #define E2_TBL 1 - #define E2_TOFF 8 - - #define E3_IHOLD 31 - #define E3_IRUN 31 - #define E3_IHOLDDELAY 15 - #define E3_I_SCALE_ANALOG 1 - #define E3_MRES 16 - #define E3_TBL 1 - #define E3_TOFF 8 - - #endif // TMC2130_ADVANCED_CONFIGURATION - -#endif // HAVE_TMC2130DRIVER - -// @section L6470 +#endif // ENABLED(HAVE_TMC2130) /** * Enable this section if you have L6470 motor drivers. @@ -1039,6 +934,8 @@ * (https://github.com/ameyer/Arduino-L6470) */ +// @section l6470 + //#define HAVE_L6470DRIVER #if ENABLED(HAVE_L6470DRIVER) diff --git a/Marlin/Marlin.ino b/Marlin/Marlin.ino index 7c6279ed33..49b6fd14ba 100644 --- a/Marlin/Marlin.ino +++ b/Marlin/Marlin.ino @@ -61,9 +61,9 @@ #include #endif -#if ENABLED(HAVE_TMC2130DRIVER) +#if ENABLED(HAVE_TMC2130) #include - #include + #include #endif #if ENABLED(HAVE_L6470DRIVER) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 05baf4c056..bf11c6313f 100755 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -189,10 +189,13 @@ * M666 - Set delta endstop adjustment. (Requires DELTA) * M605 - Set dual x-carriage movement mode: "M605 S [X] [R]". (Requires DUAL_X_CARRIAGE) * M851 - Set Z probe's Z offset in current units. (Negative = below the nozzle.) + * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. (Requires HAVE_TMC2130) * M907 - Set digital trimpot motor current using axis codes. (Requires a board with digital trimpots) * M908 - Control digital trimpot directly. (Requires DAC_STEPPER_CURRENT or DIGIPOTSS_PIN) * M909 - Print digipot/DAC current value. (Requires DAC_STEPPER_CURRENT) * 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) * M350 - Set microstepping mode. (Requires digital microstepping pins.) * M351 - Toggle MS1 MS2 pins directly. (Requires digital microstepping pins.) * @@ -6127,58 +6130,6 @@ inline void gcode_M120() { endstops.enable_globally(true); } */ inline void gcode_M121() { endstops.enable_globally(false); } -#if ENABLED(HAVE_TMC2130DRIVER) - - /** - * M122: Output Trinamic TMC2130 status to serial output. Very bad formatting. - */ - - static void tmc2130_report(Trinamic_TMC2130 &stepr, const char *name) { - stepr.read_STAT(); - SERIAL_PROTOCOL(name); - SERIAL_PROTOCOL(": "); - stepr.isReset() ? SERIAL_PROTOCOLPGM("RESET ") : SERIAL_PROTOCOLPGM("----- "); - stepr.isError() ? SERIAL_PROTOCOLPGM("ERROR ") : SERIAL_PROTOCOLPGM("----- "); - stepr.isStallguard() ? SERIAL_PROTOCOLPGM("SLGRD ") : SERIAL_PROTOCOLPGM("----- "); - stepr.isStandstill() ? SERIAL_PROTOCOLPGM("STILL ") : SERIAL_PROTOCOLPGM("----- "); - SERIAL_PROTOCOLLN(stepr.debug()); - } - - inline void gcode_M122() { - SERIAL_PROTOCOLLNPGM("Reporting TMC2130 status"); - #if ENABLED(X_IS_TMC2130) - tmc2130_report(stepperX, "X"); - #endif - #if ENABLED(X2_IS_TMC2130) - tmc2130_report(stepperX2, "X2"); - #endif - #if ENABLED(Y_IS_TMC2130) - tmc2130_report(stepperY, "Y"); - #endif - #if ENABLED(Y2_IS_TMC2130) - tmc2130_report(stepperY2, "Y2"); - #endif - #if ENABLED(Z_IS_TMC2130) - tmc2130_report(stepperZ, "Z"); - #endif - #if ENABLED(Z2_IS_TMC2130) - tmc2130_report(stepperZ2, "Z2"); - #endif - #if ENABLED(E0_IS_TMC2130) - tmc2130_report(stepperE0, "E0"); - #endif - #if ENABLED(E1_IS_TMC2130) - tmc2130_report(stepperE1, "E1"); - #endif - #if ENABLED(E2_IS_TMC2130) - tmc2130_report(stepperE2, "E2"); - #endif - #if ENABLED(E3_IS_TMC2130) - tmc2130_report(stepperE3, "E3"); - #endif - } -#endif // HAVE_TMC2130DRIVER - #if ENABLED(BLINKM) || ENABLED(RGB_LED) void set_led_color(const uint8_t r, const uint8_t g, const uint8_t b) { @@ -7610,7 +7561,7 @@ inline void gcode_M503() { SERIAL_ECHOLNPAIR(MSG_DUPLICATION_MODE, extruder_duplication_enabled ? MSG_ON : MSG_OFF); } -#endif // M605 +#endif // DUAL_NOZZLE_DUPLICATION_MODE #if ENABLED(LIN_ADVANCE) /** @@ -7637,7 +7588,99 @@ inline void gcode_M503() { if (ratio) SERIAL_ECHOLN(ratio); else SERIAL_ECHOLNPGM("Automatic"); } } -#endif +#endif // LIN_ADVANCE + +#if ENABLED(HAVE_TMC2130) + + static void tmc2130_print_current(const int mA, const char name) { + SERIAL_CHAR(name); + SERIAL_ECHOPGM(" axis driver current: "); + SERIAL_ECHOLN(mA); + } + 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_report_otpw(TMC2130Stepper &st, const char name) { + SERIAL_CHAR(name); + SERIAL_ECHOPGM(" axis temperature prewarn triggered: "); + serialprintPGM(st.getOTPW() ? PSTR("true") : PSTR("false")); + } + static void tmc2130_clear_otpw(TMC2130Stepper &st, const char name) { + st.clear_otpw(); + SERIAL_CHAR(name); + SERIAL_ECHOLNPGM(" prewarn flag cleared"); + } + + /** + * M906: Set motor current in milliamps using axis codes X, Y, Z, E + * + * Report driver currents when no axis specified + */ + inline void gcode_M906() { + uint16_t values[NUM_AXIS]; + 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_current(values[X_AXIS], stepperX, 'X'); + else tmc2130_get_current(stepperX, 'X'); + #endif + #if ENABLED(Y_IS_TMC2130) + if (values[Y_AXIS]) tmc2130_set_current(values[Y_AXIS], stepperY, 'Y'); + else tmc2130_get_current(stepperY, 'Y'); + #endif + #if ENABLED(Z_IS_TMC2130) + if (values[Z_AXIS]) tmc2130_set_current(values[Z_AXIS], stepperZ, 'Z'); + else tmc2130_get_current(stepperZ, 'Z'); + #endif + #if ENABLED(E0_IS_TMC2130) + if (values[E_AXIS]) tmc2130_set_current(values[E_AXIS], stepperE0, 'E'); + else tmc2130_get_current(stepperE0, 'E'); + #endif + } + + /** + * M911: Report TMC2130 stepper driver overtemperature pre-warn flag + * The flag is held by the library and persist until manually cleared by M912 + */ + inline void gcode_M911() { + #if ENABLED(X_IS_TMC2130) + tmc2130_report_otpw(stepperX, 'X'); + #endif + #if ENABLED(Y_IS_TMC2130) + tmc2130_report_otpw(stepperY, 'Y'); + #endif + #if ENABLED(Z_IS_TMC2130) + tmc2130_report_otpw(stepperZ, 'Z'); + #endif + #if ENABLED(E0_IS_TMC2130) + tmc2130_report_otpw(stepperE0, 'E'); + #endif + } + + /** + * M912: Clear TMC2130 stepper driver overtemperature pre-warn flag held by the library + */ + inline void gcode_M912() { + #if ENABLED(X_IS_TMC2130) + if (code_seen('X')) tmc2130_clear_otpw(stepperX, 'X'); + #endif + #if ENABLED(Y_IS_TMC2130) + if (code_seen('Y')) tmc2130_clear_otpw(stepperY, 'Y'); + #endif + #if ENABLED(Z_IS_TMC2130) + if (code_seen('Z')) tmc2130_clear_otpw(stepperZ, 'Z'); + #endif + #if ENABLED(E0_IS_TMC2130) + if (code_seen('E')) tmc2130_clear_otpw(stepperE0, 'E'); + #endif + } + +#endif // HAVE_TMC2130 /** * M907: Set digital trimpot motor current using axis codes X, Y, Z, E, B, S @@ -8600,12 +8643,6 @@ void process_next_command() { gcode_M121(); break; - #if ENABLED(HAVE_TMC2130DRIVER) - case 122: // M122: Diagnose, used to debug TMC2130 - gcode_M122(); - break; - #endif - #if ENABLED(ULTIPANEL) case 145: // M145: Set material heatup parameters @@ -8882,6 +8919,12 @@ void process_next_command() { break; #endif + #if ENABLED(HAVE_TMC2130) + case 906: // M906: Set motor current in milliamps using axis codes X, Y, Z, E + gcode_M906(); + break; + #endif + case 907: // M907: Set digital trimpot motor current using axis codes. gcode_M907(); break; @@ -8906,6 +8949,16 @@ void process_next_command() { #endif // HAS_DIGIPOTSS || DAC_STEPPER_CURRENT + #if ENABLED(HAVE_TMC2130) + case 911: // M911: Report TMC2130 prewarn triggered flags + gcode_M911(); + break; + + case 912: // M911: Clear TMC2130 prewarn triggered flags + gcode_M912(); + break; + #endif + #if HAS_MICROSTEPS case 350: // M350: Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers. @@ -10169,6 +10222,65 @@ void disable_all_steppers() { disable_e3(); } +#if ENABLED(AUTOMATIC_CURRENT_CONTROL) + + 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(); + + 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); + } + else if (is_otpw && is_otpw_triggered) { + // OTPW bit triggered, triggered flag raised -> Decrease current + st.SilentStepStick2130((float)st.getCurrent() - CURRENT_STEP); + } + // OTPW bit cleared (we've cooled down), triggered flag still raised until manually cleared -> Do nothing, we're good + #endif + } + + void checkOverTemp() { + static millis_t next_cOT = 0; + if (ELAPSED(millis(), next_cOT)) { + next_cOT = millis() + 5000; + #if ENABLED(X_IS_TMC2130) + automatic_current_control(stepperX); + #endif + #if ENABLED(Y_IS_TMC2130) + automatic_current_control(stepperY); + #endif + #if ENABLED(Z_IS_TMC2130) + automatic_current_control(stepperZ); + #endif + #if ENABLED(X2_IS_TMC2130) + automatic_current_control(stepperX2); + #endif + #if ENABLED(Y2_IS_TMC2130) + automatic_current_control(stepperY2); + #endif + #if ENABLED(Z2_IS_TMC2130) + automatic_current_control(stepperZ2); + #endif + #if ENABLED(E0_IS_TMC2130) + automatic_current_control(stepperE0); + #endif + #if ENABLED(E1_IS_TMC2130) + automatic_current_control(stepperE1); + #endif + #if ENABLED(E2_IS_TMC2130) + automatic_current_control(stepperE2); + #endif + #if ENABLED(E3_IS_TMC2130) + automatic_current_control(stepperE3); + #endif + } + } + +#endif // AUTOMATIC_CURRENT_CONTROL + /** * Manage several activities: * - Check for Filament Runout @@ -10360,6 +10472,10 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) { handle_status_leds(); #endif + #if ENABLED(AUTOMATIC_CURRENT_CONTROL) + checkOverTemp(); + #endif + planner.check_axes_activity(); } diff --git a/Marlin/configuration_store.cpp b/Marlin/configuration_store.cpp index b43de1fc9d..7af06aaad5 100644 --- a/Marlin/configuration_store.cpp +++ b/Marlin/configuration_store.cpp @@ -36,13 +36,13 @@ * */ -#define EEPROM_VERSION "V29" +#define EEPROM_VERSION "V30" // Change EEPROM version if these are changed: #define EEPROM_OFFSET 100 /** - * V29 EEPROM Layout: + * V30 EEPROM Layout: * * 100 Version (char x4) * 104 EEPROM Checksum (uint16_t) @@ -128,8 +128,20 @@ * 509 M200 D volumetric_enabled (bool) * 510 M200 T D filament_size (float x4) (T0..3) * - * 526 Minimum end-point - * 1847 (526 + 36 + 9 + 288 + 988) Maximum end-point + * TMC2130: 20 bytes + * 526 M906 X TMC2130 X-stepper current (uint16_t) + * 528 M906 Y TMC2130 Y-stepper current (uint16_t) + * 530 M906 Z TMC2130 Z-stepper current (uint16_t) + * 532 M906 X2 TMC2130 X2-stepper current (uint16_t) + * 534 M906 Y2 TMC2130 Y2-stepper current (uint16_t) + * 536 M906 Z2 TMC2130 Z2-stepper current (uint16_t) + * 538 M906 E0 TMC2130 E0-stepper current (uint16_t) + * 540 M906 E1 TMC2130 E1-stepper current (uint16_t) + * 542 M906 E2 TMC2130 E2-stepper current (uint16_t) + * 544 M906 E3 TMC2130 E3-stepper current (uint16_t) + * + * 546 Minimum end-point + * 1867 (546 + 36 + 9 + 288 + 988) Maximum end-point * */ #include "Marlin.h" @@ -144,6 +156,10 @@ #include "mesh_bed_leveling.h" #endif +#if ENABLED(HAVE_TMC2130) + #include "stepper_indirection.h" +#endif + #if ENABLED(ABL_BILINEAR_SUBDIVISION) extern void bed_level_virt_interpolate(); #endif @@ -432,10 +448,78 @@ void Config_Postprocess() { EEPROM_WRITE(dummy); } + // Save TCM2130 Configuration, and placeholder values + uint16_t val; + #if ENABLED(HAVE_TMC2130) + #if ENABLED(X_IS_TMC2130) + val = stepperX.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(Y_IS_TMC2130) + val = stepperY.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(Z_IS_TMC2130) + val = stepperZ.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(X2_IS_TMC2130) + val = stepperX2.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(Y2_IS_TMC2130) + val = stepperY2.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(Z2_IS_TMC2130) + val = stepperZ2.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(E0_IS_TMC2130) + val = stepperE0.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(E1_IS_TMC2130) + val = stepperE1.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(E2_IS_TMC2130) + val = stepperE2.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #if ENABLED(E3_IS_TMC2130) + val = stepperE3.getCurrent(); + #else + val = 0; + #endif + EEPROM_WRITE(val); + #else + val = 0; + for (uint8_t q = 0; q < 10; ++q) EEPROM_WRITE(val); + #endif + if (!eeprom_write_error) { - uint16_t final_checksum = eeprom_checksum, - eeprom_size = eeprom_index; + const uint16_t final_checksum = eeprom_checksum, + eeprom_size = eeprom_index; // Write the EEPROM header eeprom_index = EEPROM_OFFSET; @@ -684,6 +768,52 @@ void Config_Postprocess() { if (q < COUNT(filament_size)) filament_size[q] = dummy; } + uint16_t val; + #if ENABLED(HAVE_TMC2130) + EEPROM_READ(val); + #if ENABLED(X_IS_TMC2130) + stepperX.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(Y_IS_TMC2130) + stepperY.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(Z_IS_TMC2130) + stepperZ.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(X2_IS_TMC2130) + stepperX2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(Y2_IS_TMC2130) + stepperY2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(Z2_IS_TMC2130) + stepperZ2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(E0_IS_TMC2130) + stepperE0.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(E1_IS_TMC2130) + stepperE1.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(E2_IS_TMC2130) + stepperE2.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + EEPROM_READ(val); + #if ENABLED(E3_IS_TMC2130) + stepperE3.setCurrent(val, R_SENSE, HOLD_MULTIPLIER); + #endif + #else + for (uint8_t q = 0; q < 10; q++) EEPROM_READ(val); + #endif + if (eeprom_checksum == stored_checksum) { if (eeprom_read_error) Config_ResetDefault(); @@ -852,6 +982,39 @@ void Config_ResetDefault() { #endif ); + #if ENABLED(HAVE_TMC2130) + #if ENABLED(X_IS_TMC2130) + stepperX.setCurrent(X_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(Y_IS_TMC2130) + stepperY.setCurrent(Y_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(Z_IS_TMC2130) + stepperZ.setCurrent(Z_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(X2_IS_TMC2130) + stepperX2.setCurrent(X2_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(Y2_IS_TMC2130) + stepperY2.setCurrent(Y2_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(Z2_IS_TMC2130) + stepperZ2.setCurrent(Z2_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(E0_IS_TMC2130) + stepperE0.setCurrent(E0_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(E1_IS_TMC2130) + stepperE1.setCurrent(E1_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(E2_IS_TMC2130) + stepperE2.setCurrent(E2_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #if ENABLED(E3_IS_TMC2130) + stepperE3.setCurrent(E3_MAX_CURRENT, R_SENSE, HOLD_MULTIPLIER); + #endif + #endif + Config_Postprocess(); SERIAL_ECHO_START; @@ -1184,14 +1347,57 @@ void Config_ResetDefault() { * Auto Bed Leveling */ #if HAS_BED_PROBE - if (!forReplay) { - CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Z-Probe Offset (mm):"); - } CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Z-Probe Offset (mm):"); + CONFIG_ECHO_START; + } SERIAL_ECHOPAIR(" M851 Z", zprobe_zoffset); SERIAL_EOL; #endif + + /** + * TMC2130 stepper driver current + */ + #if ENABLED(HAVE_TMC2130) + CONFIG_ECHO_START; + if (!forReplay) { + SERIAL_ECHOLNPGM("Stepper driver current:"); + CONFIG_ECHO_START; + } + SERIAL_ECHO(" M906"); + #if ENABLED(X_IS_TMC2130) + SERIAL_ECHOPAIR(" X", stepperX.getCurrent()); + #endif + #if ENABLED(Y_IS_TMC2130) + SERIAL_ECHOPAIR(" Y", stepperY.getCurrent()); + #endif + #if ENABLED(Z_IS_TMC2130) + SERIAL_ECHOPAIR(" Z", stepperZ.getCurrent()); + #endif + #if ENABLED(X2_IS_TMC2130) + SERIAL_ECHOPAIR(" X2", stepperX2.getCurrent()); + #endif + #if ENABLED(Y2_IS_TMC2130) + SERIAL_ECHOPAIR(" Y2", stepperY2.getCurrent()); + #endif + #if ENABLED(Z2_IS_TMC2130) + SERIAL_ECHOPAIR(" Z2", stepperZ2.getCurrent()); + #endif + #if ENABLED(E0_IS_TMC2130) + SERIAL_ECHOPAIR(" E0", stepperE0.getCurrent()); + #endif + #if ENABLED(E1_IS_TMC2130) + SERIAL_ECHOPAIR(" E1", stepperE1.getCurrent()); + #endif + #if ENABLED(E2_IS_TMC2130) + SERIAL_ECHOPAIR(" E2", stepperE2.getCurrent()); + #endif + #if ENABLED(E3_IS_TMC2130) + SERIAL_ECHOPAIR(" E3", stepperE3.getCurrent()); + #endif + SERIAL_EOL; + #endif } #endif // !DISABLE_M503 diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp index da48097dd2..3874c79340 100644 --- a/Marlin/stepper.cpp +++ b/Marlin/stepper.cpp @@ -894,7 +894,7 @@ void Stepper::init() { #endif // Init TMC2130 Steppers - #if ENABLED(HAVE_TMC2130DRIVER) + #if ENABLED(HAVE_TMC2130) tmc2130_init(); #endif diff --git a/Marlin/stepper_indirection.cpp b/Marlin/stepper_indirection.cpp index 8f9f6adf21..930b2752d4 100644 --- a/Marlin/stepper_indirection.cpp +++ b/Marlin/stepper_indirection.cpp @@ -21,25 +21,15 @@ */ /** - stepper_indirection.c - stepper motor driver indirection - to allow some stepper functions to be done via SPI/I2c instead of direct pin manipulation - Part of Marlin - - Copyright (c) 2015 Dominik Wenger - - Marlin 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. - - Marlin 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 Marlin. If not, see . -*/ + * stepper_indirection.cpp + * + * Stepper motor driver indirection to allow some stepper functions to + * be done via SPI/I2c instead of direct pin manipulation. + * + * Part of Marlin + * + * Copyright (c) 2015 Dominik Wenger + */ #include "stepper_indirection.h" @@ -53,41 +43,43 @@ #include #include + #define _TMC_DEFINE(ST) TMC26XStepper stepper##ST(200, ST##_ENABLE_PIN, ST##_STEP_PIN, ST##_DIR_PIN, ST##_MAX_CURRENT, ST##_SENSE_RESISTOR) + #if ENABLED(X_IS_TMC) - TMC26XStepper stepperX(200, X_ENABLE_PIN, X_STEP_PIN, X_DIR_PIN, X_MAX_CURRENT, X_SENSE_RESISTOR); + _TMC_DEFINE(X); #endif #if ENABLED(X2_IS_TMC) - TMC26XStepper stepperX2(200, X2_ENABLE_PIN, X2_STEP_PIN, X2_DIR_PIN, X2_MAX_CURRENT, X2_SENSE_RESISTOR); + _TMC_DEFINE(X2); #endif #if ENABLED(Y_IS_TMC) - TMC26XStepper stepperY(200, Y_ENABLE_PIN, Y_STEP_PIN, Y_DIR_PIN, Y_MAX_CURRENT, Y_SENSE_RESISTOR); + _TMC_DEFINE(Y); #endif #if ENABLED(Y2_IS_TMC) - TMC26XStepper stepperY2(200, Y2_ENABLE_PIN, Y2_STEP_PIN, Y2_DIR_PIN, Y2_MAX_CURRENT, Y2_SENSE_RESISTOR); + _TMC_DEFINE(Y2); #endif #if ENABLED(Z_IS_TMC) - TMC26XStepper stepperZ(200, Z_ENABLE_PIN, Z_STEP_PIN, Z_DIR_PIN, Z_MAX_CURRENT, Z_SENSE_RESISTOR); + _TMC_DEFINE(Z); #endif #if ENABLED(Z2_IS_TMC) - TMC26XStepper stepperZ2(200, Z2_ENABLE_PIN, Z2_STEP_PIN, Z2_DIR_PIN, Z2_MAX_CURRENT, Z2_SENSE_RESISTOR); + _TMC_DEFINE(Z2); #endif #if ENABLED(E0_IS_TMC) - TMC26XStepper stepperE0(200, E0_ENABLE_PIN, E0_STEP_PIN, E0_DIR_PIN, E0_MAX_CURRENT, E0_SENSE_RESISTOR); + _TMC_DEFINE(E0); #endif #if ENABLED(E1_IS_TMC) - TMC26XStepper stepperE1(200, E1_ENABLE_PIN, E1_STEP_PIN, E1_DIR_PIN, E1_MAX_CURRENT, E1_SENSE_RESISTOR); + _TMC_DEFINE(E1); #endif #if ENABLED(E2_IS_TMC) - TMC26XStepper stepperE2(200, E2_ENABLE_PIN, E2_STEP_PIN, E2_DIR_PIN, E2_MAX_CURRENT, E2_SENSE_RESISTOR); + _TMC_DEFINE(E2); #endif #if ENABLED(E3_IS_TMC) - TMC26XStepper stepperE3(200, E3_ENABLE_PIN, E3_STEP_PIN, E3_DIR_PIN, E3_MAX_CURRENT, E3_SENSE_RESISTOR); + _TMC_DEFINE(E3); #endif #define _TMC_INIT(A) do{ \ stepper##A.setMicrosteps(A##_MICROSTEPS); \ stepper##A.start(); \ - } while(0) + }while(0) void tmc_init() { #if ENABLED(X_IS_TMC) @@ -127,394 +119,70 @@ // // TMC2130 Driver objects and inits // -#if ENABLED(HAVE_TMC2130DRIVER) +#if ENABLED(HAVE_TMC2130) #include - #include + #include - #if ENABLED(TMC2130_ADVANCED_CONFIGURATION) + #define _TMC2130_DEFINE(ST) TMC2130Stepper stepper##ST(ST##_ENABLE_PIN, ST##_DIR_PIN, ST##_STEP_PIN, ST##_CHIP_SELECT) - #ifdef GLOBAL_I_SCALE_ANALOG - #define _2130_set_I_scale_analog(A) stepper##A.set_I_scale_analog(GLOBAL_I_SCALE_ANALOG) - #else - #define _2130_set_I_scale_analog(A) NOOP - #endif - #ifdef GLOBAL_INTERNAL_RSENSE - #define _2130_set_internal_Rsense(A) stepper##A.set_internal_Rsense(GLOBAL_INTERNAL_RSENSE) - #else - #define _2130_set_internal_Rsense(A) NOOP - #endif - #ifdef GLOBAL_EN_PWM_MODE - #define _2130_set_en_pwm_mode(A) stepper##A.set_en_pwm_mode(GLOBAL_EN_PWM_MODE) - #else - #define _2130_set_en_pwm_mode(A) NOOP - #endif - #ifdef GLOBAL_ENC_COMMUTATION - #define _2130_set_enc_commutation(A) stepper##A.set_enc_commutation(GLOBAL_ENC_COMMUTATION) - #else - #define _2130_set_enc_commutation(A) NOOP - #endif - #ifdef GLOBAL_SHAFT - #define _2130_set_shaft(A) stepper##A.set_shaft(GLOBAL_SHAFT) - #else - #define _2130_set_shaft(A) NOOP - #endif - #ifdef GLOBAL_DIAG0_ERROR - #define _2130_set_diag0_error(A) stepper##A.set_diag0_error(GLOBAL_DIAG0_ERROR) - #else - #define _2130_set_diag0_error(A) NOOP - #endif - #ifdef GLOBAL_DIAG0_OTPW - #define _2130_set_diag0_otpw(A) stepper##A.set_diag0_otpw(GLOBAL_DIAG0_OTPW) - #else - #define _2130_set_diag0_otpw(A) NOOP - #endif - #ifdef GLOBAL_DIAG0_STALL - #define _2130_set_diag0_stall(A) stepper##A.set_diag0_stall(GLOBAL_DIAG0_STALL) - #else - #define _2130_set_diag0_stall(A) NOOP - #endif - #ifdef GLOBAL_DIAG1_STALL - #define _2130_set_diag1_stall(A) stepper##A.set_diag1_stall(GLOBAL_DIAG1_STALL) - #else - #define _2130_set_diag1_stall(A) NOOP - #endif - #ifdef GLOBAL_DIAG1_INDEX - #define _2130_set_diag1_index(A) stepper##A.set_diag1_index(GLOBAL_DIAG1_INDEX) - #else - #define _2130_set_diag1_index(A) NOOP - #endif - #ifdef GLOBAL_DIAG1_ONSTATE - #define _2130_set_diag1_onstate(A) stepper##A.set_diag1_onstate(GLOBAL_DIAG1_ONSTATE) - #else - #define _2130_set_diag1_onstate(A) NOOP - #endif - #ifdef GLOBAL_DIAG1_ONSTATE - #define _2130_set_diag1_steps_skipped(A) stepper##A.set_diag1_steps_skipped(GLOBAL_DIAG1_ONSTATE) - #else - #define _2130_set_diag1_steps_skipped(A) NOOP - #endif - #ifdef GLOBAL_DIAG0_INT_PUSHPULL - #define _2130_set_diag0_int_pushpull(A) stepper##A.set_diag0_int_pushpull(GLOBAL_DIAG0_INT_PUSHPULL) - #else - #define _2130_set_diag0_int_pushpull(A) NOOP - #endif - #ifdef GLOBAL_DIAG1_INT_PUSHPULL - #define _2130_set_diag1_int_pushpull(A) stepper##A.set_diag1_int_pushpull(GLOBAL_DIAG1_INT_PUSHPULL) - #else - #define _2130_set_diag1_int_pushpull(A) NOOP - #endif - #ifdef GLOBAL_SMALL_HYSTERESIS - #define _2130_set_small_hysteresis(A) stepper##A.set_small_hysteresis(GLOBAL_SMALL_HYSTERESIS) - #else - #define _2130_set_small_hysteresis(A) NOOP - #endif - #ifdef GLOBAL_STOP_ENABLE - #define _2130_set_stop_enable(A) stepper##A.set_stop_enable(GLOBAL_STOP_ENABLE) - #else - #define _2130_set_stop_enable(A) NOOP - #endif - #ifdef GLOBAL_DIRECT_MODE - #define _2130_set_direct_mode(A) stepper##A.set_direct_mode(GLOBAL_DIRECT_MODE) - #else - #define _2130_set_direct_mode(A) NOOP - #endif - #if defined(GLOBAL_IHOLD) && defined(GLOBAL_IRUN) && defined(GLOBAL_IHOLDDELAY) - #define _2130_set_IHOLD_IRUN(A) stepper##A.set_IHOLD_IRUN(GLOBAL_IHOLD, GLOBAL_IRUN, GLOBAL_IHOLDDELAY) - #else - #define _2130_set_IHOLD_IRUN(A) NOOP - #endif - #ifdef GLOBAL_TPOWERDOWN - #define _2130_set_TPOWERDOWN(A) stepper##A.set_TPOWERDOWN(GLOBAL_TPOWERDOWN) - #else - #define _2130_set_TPOWERDOWN(A) NOOP - #endif - #ifdef GLOBAL_TPWMTHRS - #define _2130_set_TPWMTHRS(A) stepper##A.set_TPWMTHRS(GLOBAL_TPWMTHRS) - #else - #define _2130_set_TPWMTHRS(A) NOOP - #endif - #ifdef GLOBAL_TCOOLTHRS - #define _2130_set_TCOOLTHRS(A) stepper##A.set_TCOOLTHRS(GLOBAL_TCOOLTHRS) - #else - #define _2130_set_TCOOLTHRS(A) NOOP - #endif - #ifdef GLOBAL_THIGH - #define _2130_set_THIGH(A) stepper##A.set_THIGH(GLOBAL_THIGH) - #else - #define _2130_set_THIGH(A) NOOP - #endif - #ifdef GLOBAL_XDIRECT - #define _2130_set_XDIRECT(A) stepper##A.set_XDIRECT(GLOBAL_XDIRECT) - #else - #define _2130_set_XDIRECT(A) NOOP - #endif - #ifdef GLOBAL_VDCMIN - #define _2130_set_VDCMIN(A) stepper##A.set_VDCMIN(GLOBAL_VDCMIN) - #else - #define _2130_set_VDCMIN(A) NOOP - #endif - #ifdef GLOBAL_DEDGE - #define _2130_set_dedge(A) stepper##A.set_dedge(GLOBAL_DEDGE) - #else - #define _2130_set_dedge(A) NOOP - #endif - #ifdef GLOBAL_DISS2G - #define _2130_set_diss2g(A) stepper##A.set_diss2g(GLOBAL_DISS2G) - #else - #define _2130_set_diss2g(A) NOOP - #endif - #ifdef GLOBAL_INTPOL - #define _2130_set_intpol(A) stepper##A.set_intpol(GLOBAL_INTPOL) - #else - #define _2130_set_intpol(A) NOOP - #endif - #ifdef GLOBAL_MRES - #define _2130_set_mres(A) stepper##A.set_mres(GLOBAL_MRES) - #else - #define _2130_set_mres(A) NOOP - #endif - #ifdef GLOBAL_SYNC - #define _2130_set_sync(A) stepper##A.set_sync(GLOBAL_SYNC) - #else - #define _2130_set_sync(A) NOOP - #endif - #ifdef GLOBAL_VHIGHCHM - #define _2130_set_vhighchm(A) stepper##A.set_vhighchm(GLOBAL_VHIGHCHM) - #else - #define _2130_set_vhighchm(A) NOOP - #endif - #ifdef GLOBAL_VHIGHFS - #define _2130_set_vhighfs(A) stepper##A.set_vhighfs(GLOBAL_VHIGHFS) - #else - #define _2130_set_vhighfs(A) NOOP - #endif - #ifdef GLOBAL_VSENSE - #define _2130_set_vsense(A) stepper##A.set_vsense(GLOBAL_VSENSE) - #else - #define _2130_set_vsense(A) NOOP - #endif - #ifdef GLOBAL_TBL - #define _2130_set_tbl(A) stepper##A.set_tbl(GLOBAL_TBL) - #else - #define _2130_set_tbl(A) NOOP - #endif - #ifdef GLOBAL_CHM - #define _2130_set_chm(A) stepper##A.set_chm(GLOBAL_CHM) - #else - #define _2130_set_chm(A) NOOP - #endif - #ifdef GLOBAL_RNDTF - #define _2130_set_rndtf(A) stepper##A.set_rndtf(GLOBAL_RNDTF) - #else - #define _2130_set_rndtf(A) NOOP - #endif - #ifdef GLOBAL_DISFDCC - #define _2130_set_disfdcc(A) stepper##A.set_disfdcc(GLOBAL_DISFDCC) - #else - #define _2130_set_disfdcc(A) NOOP - #endif - #ifdef GLOBAL_FD - #define _2130_set_fd(A) stepper##A.set_fd(GLOBAL_FD) - #else - #define _2130_set_fd(A) NOOP - #endif - #ifdef GLOBAL_HEND - #define _2130_set_hend(A) stepper##A.set_hend(GLOBAL_HEND) - #else - #define _2130_set_hend(A) NOOP - #endif - #ifdef GLOBAL_HSTRT - #define _2130_set_hstrt(A) stepper##A.set_hstrt(GLOBAL_HSTRT) - #else - #define _2130_set_hstrt(A) NOOP - #endif - #ifdef GLOBAL_TOFF - #define _2130_set_toff(A) stepper##A.set_toff(GLOBAL_TOFF) - #else - #define _2130_set_toff(A) NOOP - #endif - #ifdef GLOBAL_SFILT - #define _2130_set_sfilt(A) stepper##A.set_sfilt(GLOBAL_SFILT) - #else - #define _2130_set_sfilt(A) NOOP - #endif - #ifdef GLOBAL_SGT - #define _2130_set_sgt(A) stepper##A.set_sgt(GLOBAL_SGT) - #else - #define _2130_set_sgt(A) NOOP - #endif - #ifdef GLOBAL_SEIMIN - #define _2130_set_seimin(A) stepper##A.set_seimin(GLOBAL_SEIMIN) - #else - #define _2130_set_seimin(A) NOOP - #endif - #ifdef GLOBAL_SEDN - #define _2130_set_sedn(A) stepper##A.set_sedn(GLOBAL_SEDN) - #else - #define _2130_set_sedn(A) NOOP - #endif - #ifdef GLOBAL_SEMAX - #define _2130_set_semax(A) stepper##A.set_semax(GLOBAL_SEMAX) - #else - #define _2130_set_semax(A) NOOP - #endif - #ifdef GLOBAL_SEUP - #define _2130_set_seup(A) stepper##A.set_seup(GLOBAL_SEUP) - #else - #define _2130_set_seup(A) NOOP - #endif - #ifdef GLOBAL_SEMIN - #define _2130_set_semin(A) stepper##A.set_semin(GLOBAL_SEMIN) - #else - #define _2130_set_semin(A) NOOP - #endif - #if defined(GLOBAL_DC_TIME) && defined(GLOBAL_DC_SG) - #define _2130_set_DCCTRL(A) stepper##A.set_DCCTRL(GLOBAL_DC_TIME, GLOBAL_DC_SG) - #else - #define _2130_set_DCCTRL(A) NOOP - #endif - #ifdef GLOBAL_FREEWHEEL - #define _2130_set_freewheel(A) stepper##A.set_freewheel(GLOBAL_FREEWHEEL) - #else - #define _2130_set_freewheel(A) NOOP - #endif - #ifdef GLOBAL_PWM_SYMMETRIC - #define _2130_set_pwm_symmetric(A) stepper##A.set_pwm_symmetric(GLOBAL_PWM_SYMMETRIC) - #else - #define _2130_set_pwm_symmetric(A) NOOP - #endif - #ifdef GLOBAL_PWM_AUTOSCALE - #define _2130_set_pwm_autoscale(A) stepper##A.set_pwm_autoscale(GLOBAL_PWM_AUTOSCALE) - #else - #define _2130_set_pwm_autoscale(A) NOOP - #endif - #ifdef GLOBAL_PWM_FREQ - #define _2130_set_pwm_freq(A) stepper##A.set_pwm_freq(GLOBAL_PWM_FREQ) - #else - #define _2130_set_pwm_freq(A) NOOP - #endif - #ifdef GLOBAL_PWM_GRAD - #define _2130_set_PWM_GRAD(A) stepper##A.set_PWM_GRAD(GLOBAL_PWM_GRAD) - #else - #define _2130_set_PWM_GRAD(A) NOOP - #endif - #ifdef GLOBAL_PWM_AMPL - #define _2130_set_PWM_AMPL(A) stepper##A.set_PWM_AMPL(GLOBAL_PWM_AMPL) - #else - #define _2130_set_PWM_AMPL(A) NOOP - #endif - #ifdef GLOBAL_ENCM_CTRL - #define _2130_set_ENCM_CTRL(A) stepper##A.set_ENCM_CTRL(GLOBAL_ENCM_CTRL) - #else - #define _2130_set_ENCM_CTRL(A) NOOP - #endif - - #define _TMC2130_INIT(A) do{ \ - stepper##A.init(); \ - _2130_set_I_scale_analog(A); \ - _2130_set_internal_Rsense(A); \ - _2130_set_en_pwm_mode(A); \ - _2130_set_enc_commutation(A); \ - _2130_set_shaft(A); \ - _2130_set_diag0_error(A); \ - _2130_set_diag0_otpw(A); \ - _2130_set_diag0_stall(A); \ - _2130_set_diag1_stall(A); \ - _2130_set_diag1_index(A); \ - _2130_set_diag1_onstate(A); \ - _2130_set_diag1_steps_skipped(A); \ - _2130_set_diag0_int_pushpull(A); \ - _2130_set_diag1_int_pushpull(A); \ - _2130_set_small_hysteresis(A); \ - _2130_set_stop_enable(A); \ - _2130_set_direct_mode(A); \ - _2130_set_IHOLD_IRUN(A); \ - _2130_set_TPOWERDOWN(A); \ - _2130_set_TPWMTHRS(A); \ - _2130_set_TCOOLTHRS(A); \ - _2130_set_THIGH(A); \ - _2130_set_XDIRECT(A); \ - _2130_set_VDCMIN(A); \ - _2130_set_dedge(A); \ - _2130_set_diss2g(A); \ - _2130_set_intpol(A); \ - _2130_set_mres(A); \ - _2130_set_sync(A); \ - _2130_set_vhighchm(A); \ - _2130_set_vhighfs(A); \ - _2130_set_vsense(A); \ - _2130_set_tbl(A); \ - _2130_set_chm(A); \ - _2130_set_rndtf(A); \ - _2130_set_disfdcc(A); \ - _2130_set_fd(A); \ - _2130_set_hend(A); \ - _2130_set_hstrt(A); \ - _2130_set_toff(A); \ - _2130_set_sfilt(A); \ - _2130_set_sgt(A); \ - _2130_set_seimin(A); \ - _2130_set_sedn(A); \ - _2130_set_semax(A); \ - _2130_set_seup(A); \ - _2130_set_semin(A); \ - _2130_set_DCCTRL(A); \ - _2130_set_freewheel(A); \ - _2130_set_pwm_symmetric(A); \ - _2130_set_pwm_autoscale(A); \ - _2130_set_pwm_freq(A); \ - _2130_set_PWM_GRAD(A); \ - _2130_set_PWM_AMPL(A); \ - _2130_set_ENCM_CTRL(A); \ - } while(0) - - #else // !TMC2130_ADVANCED_CONFIGURATION - - #define _TMC2130_INIT(A) do{ \ - stepper##A.init(); \ - stepper##A.set_mres(A##_MRES); \ - stepper##A.set_IHOLD_IRUN(A##_IHOLD, A##_IRUN, A##_IHOLDDELAY); \ - stepper##A.set_I_scale_analog(A##_I_SCALE_ANALOG); \ - stepper##A.set_tbl(A##_TBL); \ - stepper##A.set_toff(A##_TOFF); \ - } while(0) - - #endif // TMC2130_ADVANCED_CONFIGURATION - - // Stepper objects of TMC2310 steppers used + // Stepper objects of TMC2130 steppers used #if ENABLED(X_IS_TMC2130) - Trinamic_TMC2130 stepperX(X_CS_PIN); + _TMC2130_DEFINE(X); #endif #if ENABLED(X2_IS_TMC2130) - Trinamic_TMC2130 stepperX2(X2_CS_PIN); + _TMC2130_DEFINE(X2); #endif #if ENABLED(Y_IS_TMC2130) - Trinamic_TMC2130 stepperY(Y_CS_PIN); + _TMC2130_DEFINE(Y); #endif #if ENABLED(Y2_IS_TMC2130) - Trinamic_TMC2130 stepperY2(Y2_CS_PINR); + _TMC2130_DEFINE(Y2); #endif #if ENABLED(Z_IS_TMC2130) - Trinamic_TMC2130 stepperZ(Z_CS_PIN); + _TMC2130_DEFINE(Z); #endif #if ENABLED(Z2_IS_TMC2130) - Trinamic_TMC2130 stepperZ2(Z2_CS_PIN); + _TMC2130_DEFINE(Z2); #endif #if ENABLED(E0_IS_TMC2130) - Trinamic_TMC2130 stepperE0(E0_CS_PIN); + _TMC2130_DEFINE(E0); #endif #if ENABLED(E1_IS_TMC2130) - Trinamic_TMC2130 stepperE1(E1_CS_PIN); + _TMC2130_DEFINE(E1); #endif #if ENABLED(E2_IS_TMC2130) - Trinamic_TMC2130 stepperE2(E2_CS_PIN); + _TMC2130_DEFINE(E2); #endif #if ENABLED(E3_IS_TMC2130) - Trinamic_TMC2130 stepperE3(E3_CS_PIN); + _TMC2130_DEFINE(E3); #endif + // 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) { + st.begin(); + st.setCurrent(st.getCurrent(), R_SENSE, HOLD_MULTIPLIER); + st.microsteps(microsteps); + st.blank_time(24); + st.off_time(8); + st.interpolate(INTERPOLATE); + #if ENABLED(STEALTHCHOP) + 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); + #endif + } + + #define _TMC2130_INIT(ST) tmc2130_init(stepper##ST, ST##_MAX_CURRENT, ST##_MICROSTEPS) + void tmc2130_init() { + delay(500); // Let power stabilize before configuring the steppers #if ENABLED(X_IS_TMC2130) _TMC2130_INIT(X); #endif @@ -545,9 +213,11 @@ #if ENABLED(E3_IS_TMC2130) _TMC2130_INIT(E3); #endif - } -#endif // HAVE_TMC2130DRIVER + TMC2130_ADV() + } +#endif // HAVE_TMC2130 + // // L6470 Driver objects and inits @@ -557,36 +227,38 @@ #include #include + #define _L6470_DEFINE(ST) L6470 stepper##ST(ST##_ENABLE_PIN) + // L6470 Stepper objects #if ENABLED(X_IS_L6470) - L6470 stepperX(X_ENABLE_PIN); + _L6470_DEFINE(X); #endif #if ENABLED(X2_IS_L6470) - L6470 stepperX2(X2_ENABLE_PIN); + _L6470_DEFINE(X2); #endif #if ENABLED(Y_IS_L6470) - L6470 stepperY(Y_ENABLE_PIN); + _L6470_DEFINE(Y); #endif #if ENABLED(Y2_IS_L6470) - L6470 stepperY2(Y2_ENABLE_PIN); + _L6470_DEFINE(Y2); #endif #if ENABLED(Z_IS_L6470) - L6470 stepperZ(Z_ENABLE_PIN); + _L6470_DEFINE(Z); #endif #if ENABLED(Z2_IS_L6470) - L6470 stepperZ2(Z2_ENABLE_PIN); + _L6470_DEFINE(Z2); #endif #if ENABLED(E0_IS_L6470) - L6470 stepperE0(E0_ENABLE_PIN); + _L6470_DEFINE(E0); #endif #if ENABLED(E1_IS_L6470) - L6470 stepperE1(E1_ENABLE_PIN); + _L6470_DEFINE(E1); #endif #if ENABLED(E2_IS_L6470) - L6470 stepperE2(E2_ENABLE_PIN); + _L6470_DEFINE(E2); #endif #if ENABLED(E3_IS_L6470) - L6470 stepperE3(E3_ENABLE_PIN); + _L6470_DEFINE(E3); #endif #define _L6470_INIT(A) do{ \ diff --git a/Marlin/stepper_indirection.h b/Marlin/stepper_indirection.h index 0dc941bd14..5b9a1715fc 100644 --- a/Marlin/stepper_indirection.h +++ b/Marlin/stepper_indirection.h @@ -53,10 +53,8 @@ void tmc_init(); #endif -// TMC130 drivers have STEP/DIR/ENABLE on normal pins -#if ENABLED(HAVE_TMC2130DRIVER) - #include - #include +#if ENABLED(HAVE_TMC2130) + #include void tmc2130_init(); #endif @@ -83,8 +81,8 @@ #define X_ENABLE_WRITE(STATE) stepperX.setEnabled(STATE) #define X_ENABLE_READ stepperX.isEnabled() #else - #if ENABLED(HAVE_TMC2130DRIVER) && ENABLED(X_IS_TMC2130) - extern Trinamic_TMC2130 stepperX; + #if ENABLED(HAVE_TMC2130) && ENABLED(X_IS_TMC2130) + extern TMC2130Stepper stepperX; #endif #define X_ENABLE_INIT SET_OUTPUT(X_ENABLE_PIN) #define X_ENABLE_WRITE(STATE) WRITE(X_ENABLE_PIN,STATE) @@ -114,8 +112,8 @@ #define Y_ENABLE_WRITE(STATE) stepperY.setEnabled(STATE) #define Y_ENABLE_READ stepperY.isEnabled() #else - #if ENABLED(HAVE_TMC2130DRIVER) && ENABLED(Y_IS_TMC2130) - extern Trinamic_TMC2130 stepperY; + #if ENABLED(HAVE_TMC2130) && ENABLED(Y_IS_TMC2130) + extern TMC2130Stepper stepperY; #endif #define Y_ENABLE_INIT SET_OUTPUT(Y_ENABLE_PIN) #define Y_ENABLE_WRITE(STATE) WRITE(Y_ENABLE_PIN,STATE) @@ -145,8 +143,8 @@ #define Z_ENABLE_WRITE(STATE) stepperZ.setEnabled(STATE) #define Z_ENABLE_READ stepperZ.isEnabled() #else - #if ENABLED(HAVE_TMC2130DRIVER) && ENABLED(Z_IS_TMC2130) - extern Trinamic_TMC2130 stepperZ; + #if ENABLED(HAVE_TMC2130) && ENABLED(Z_IS_TMC2130) + extern TMC2130Stepper stepperZ; #endif #define Z_ENABLE_INIT SET_OUTPUT(Z_ENABLE_PIN) #define Z_ENABLE_WRITE(STATE) WRITE(Z_ENABLE_PIN,STATE) @@ -177,8 +175,8 @@ #define X2_ENABLE_WRITE(STATE) stepperX2.setEnabled(STATE) #define X2_ENABLE_READ stepperX2.isEnabled() #else - #if ENABLED(HAVE_TMC2130DRIVER) && ENABLED(X2_IS_TMC2130) - extern Trinamic_TMC2130 stepperX2; + #if ENABLED(HAVE_TMC2130) && ENABLED(X2_IS_TMC2130) + extern TMC2130Stepper stepperX2; #endif #define X2_ENABLE_INIT SET_OUTPUT(X2_ENABLE_PIN) #define X2_ENABLE_WRITE(STATE) WRITE(X2_ENABLE_PIN,STATE) @@ -210,8 +208,8 @@ #define Y2_ENABLE_WRITE(STATE) stepperY2.setEnabled(STATE) #define Y2_ENABLE_READ stepperY2.isEnabled() #else - #if ENABLED(HAVE_TMC2130DRIVER) && ENABLED(Y2_IS_TMC2130) - extern Trinamic_TMC2130 stepperY2; + #if ENABLED(HAVE_TMC2130) && ENABLED(Y2_IS_TMC2130) + extern TMC2130Stepper stepperY2; #endif #define Y2_ENABLE_INIT SET_OUTPUT(Y2_ENABLE_PIN) #define Y2_ENABLE_WRITE(STATE) WRITE(Y2_ENABLE_PIN,STATE) @@ -243,8 +241,8 @@ #define Z2_ENABLE_WRITE(STATE) stepperZ2.setEnabled(STATE) #define Z2_ENABLE_READ stepperZ2.isEnabled() #else - #if ENABLED(HAVE_TMC2130DRIVER) && ENABLED(Z2_IS_TMC2130) - extern Trinamic_TMC2130 stepperZ2; + #if ENABLED(HAVE_TMC2130) && ENABLED(Z2_IS_TMC2130) + extern TMC2130Stepper stepperZ2; #endif #define Z2_ENABLE_INIT SET_OUTPUT(Z2_ENABLE_PIN) #define Z2_ENABLE_WRITE(STATE) WRITE(Z2_ENABLE_PIN,STATE) @@ -275,8 +273,8 @@ #define E0_ENABLE_WRITE(STATE) stepperE0.setEnabled(STATE) #define E0_ENABLE_READ stepperE0.isEnabled() #else - #if ENABLED(HAVE_TMC2130DRIVER) && ENABLED(E0_IS_TMC2130) - extern Trinamic_TMC2130 stepperE0; + #if ENABLED(HAVE_TMC2130) && ENABLED(E0_IS_TMC2130) + extern TMC2130Stepper stepperE0; #endif #define E0_ENABLE_INIT SET_OUTPUT(E0_ENABLE_PIN) #define E0_ENABLE_WRITE(STATE) WRITE(E0_ENABLE_PIN,STATE) @@ -306,8 +304,8 @@ #define E1_ENABLE_WRITE(STATE) stepperE1.setEnabled(STATE) #define E1_ENABLE_READ stepperE1.isEnabled() #else - #if ENABLED(HAVE_TMC2130DRIVER) && ENABLED(E1_IS_TMC2130) - extern Trinamic_TMC2130 stepperE1; + #if ENABLED(HAVE_TMC2130) && ENABLED(E1_IS_TMC2130) + extern TMC2130Stepper stepperE1; #endif #define E1_ENABLE_INIT SET_OUTPUT(E1_ENABLE_PIN) #define E1_ENABLE_WRITE(STATE) WRITE(E1_ENABLE_PIN,STATE) @@ -337,8 +335,8 @@ #define E2_ENABLE_WRITE(STATE) stepperE2.setEnabled(STATE) #define E2_ENABLE_READ stepperE2.isEnabled() #else - #if ENABLED(HAVE_TMC2130DRIVER) && ENABLED(E2_IS_TMC2130) - extern Trinamic_TMC2130 stepperE2; + #if ENABLED(HAVE_TMC2130) && ENABLED(E2_IS_TMC2130) + extern TMC2130Stepper stepperE2; #endif #define E2_ENABLE_INIT SET_OUTPUT(E2_ENABLE_PIN) #define E2_ENABLE_WRITE(STATE) WRITE(E2_ENABLE_PIN,STATE) @@ -368,8 +366,8 @@ #define E3_ENABLE_WRITE(STATE) stepperE3.setEnabled(STATE) #define E3_ENABLE_READ stepperE3.isEnabled() #else - #if ENABLED(HAVE_TMC2130DRIVER) && ENABLED(E3_IS_TMC2130) - extern Trinamic_TMC2130 stepperE3; + #if ENABLED(HAVE_TMC2130) && ENABLED(E3_IS_TMC2130) + extern TMC2130Stepper stepperE3; #endif #define E3_ENABLE_INIT SET_OUTPUT(E3_ENABLE_PIN) #define E3_ENABLE_WRITE(STATE) WRITE(E3_ENABLE_PIN,STATE)