Browse Source

✨ M919 : Chopper Timing (#23400)

Scott Lahteine 2 years ago
parent
commit
6fbfeb6801

+ 3
- 0
Marlin/Configuration_adv.h View File

@@ -2979,6 +2979,9 @@
2979 2979
   //#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z
2980 2980
   //#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z
2981 2981
   //#define CHOPPER_TIMING_Z4 CHOPPER_TIMING_Z
2982
+  //#define CHOPPER_TIMING_I  CHOPPER_TIMING
2983
+  //#define CHOPPER_TIMING_J  CHOPPER_TIMING
2984
+  //#define CHOPPER_TIMING_K  CHOPPER_TIMING
2982 2985
   //#define CHOPPER_TIMING_E  CHOPPER_TIMING        // For Extruders (override below)
2983 2986
   //#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E
2984 2987
   //#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E

+ 69
- 45
Marlin/src/feature/tmc_util.h View File

@@ -64,13 +64,13 @@ class TMCStorage {
64 64
       uint8_t otpw_count = 0,
65 65
               error_count = 0;
66 66
       bool flag_otpw = false;
67
-      inline bool getOTPW() { return flag_otpw; }
68
-      inline void clear_otpw() { flag_otpw = 0; }
67
+      bool getOTPW() { return flag_otpw; }
68
+      void clear_otpw() { flag_otpw = 0; }
69 69
     #endif
70 70
 
71
-    inline uint16_t getMilliamps() { return val_mA; }
71
+    uint16_t getMilliamps() { return val_mA; }
72 72
 
73
-    inline void printLabel() {
73
+    void printLabel() {
74 74
       SERIAL_CHAR(AXIS_LETTER);
75 75
       if (DRIVER_ID > '0') SERIAL_CHAR(DRIVER_ID);
76 76
     }
@@ -97,25 +97,31 @@ class TMCMarlin : public TMC, public TMCStorage<AXIS_LETTER, DRIVER_ID> {
97 97
     TMCMarlin(const uint16_t CS, const float RS, const uint16_t pinMOSI, const uint16_t pinMISO, const uint16_t pinSCK, const uint8_t axis_chain_index) :
98 98
       TMC(CS, RS, pinMOSI, pinMISO, pinSCK,  axis_chain_index)
99 99
       {}
100
-    inline uint16_t rms_current() { return TMC::rms_current(); }
101
-    inline void rms_current(uint16_t mA) {
100
+    uint16_t rms_current() { return TMC::rms_current(); }
101
+    void rms_current(uint16_t mA) {
102 102
       this->val_mA = mA;
103 103
       TMC::rms_current(mA);
104 104
     }
105
-    inline void rms_current(const uint16_t mA, const float mult) {
105
+    void rms_current(const uint16_t mA, const float mult) {
106 106
       this->val_mA = mA;
107 107
       TMC::rms_current(mA, mult);
108 108
     }
109
-    inline uint16_t get_microstep_counter() { return TMC::MSCNT(); }
109
+    uint16_t get_microstep_counter() { return TMC::MSCNT(); }
110 110
 
111 111
     #if HAS_STEALTHCHOP
112
-      inline bool get_stealthChop()                { return this->en_pwm_mode(); }
113
-      inline bool get_stored_stealthChop()         { return this->stored.stealthChop_enabled; }
114
-      inline void refresh_stepping_mode()          { this->en_pwm_mode(this->stored.stealthChop_enabled); }
115
-      inline void set_stealthChop(const bool stch) { this->stored.stealthChop_enabled = stch; refresh_stepping_mode(); }
116
-      inline bool toggle_stepping_mode()           { set_stealthChop(!this->stored.stealthChop_enabled); return get_stealthChop(); }
112
+      bool get_stealthChop()                { return this->en_pwm_mode(); }
113
+      bool get_stored_stealthChop()         { return this->stored.stealthChop_enabled; }
114
+      void refresh_stepping_mode()          { this->en_pwm_mode(this->stored.stealthChop_enabled); }
115
+      void set_stealthChop(const bool stch) { this->stored.stealthChop_enabled = stch; refresh_stepping_mode(); }
116
+      bool toggle_stepping_mode()           { set_stealthChop(!this->stored.stealthChop_enabled); return get_stealthChop(); }
117 117
     #endif
118 118
 
119
+    void set_chopper_times(const chopper_timing_t &ct) {
120
+      TMC::toff(ct.toff);
121
+      TMC::hysteresis_end(ct.hend);
122
+      TMC::hysteresis_start(ct.hstrt);
123
+    }
124
+
119 125
     #if ENABLED(HYBRID_THRESHOLD)
120 126
       uint32_t get_pwm_thrs() {
121 127
         return _tmc_thrs(this->microsteps(), this->TPWMTHRS(), planner.settings.axis_steps_per_mm[AXIS_ID]);
@@ -127,7 +133,7 @@ class TMCMarlin : public TMC, public TMCStorage<AXIS_LETTER, DRIVER_ID> {
127 133
     #endif
128 134
 
129 135
     #if USE_SENSORLESS
130
-      inline int16_t homing_threshold() { return TMC::sgt(); }
136
+      int16_t homing_threshold() { return TMC::sgt(); }
131 137
       void homing_threshold(int16_t sgt_val) {
132 138
         sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max);
133 139
         TMC::sgt(sgt_val);
@@ -139,13 +145,13 @@ class TMCMarlin : public TMC, public TMCStorage<AXIS_LETTER, DRIVER_ID> {
139 145
     #endif
140 146
 
141 147
     #if HAS_LCD_MENU
142
-      inline void refresh_stepper_current() { rms_current(this->val_mA); }
148
+      void refresh_stepper_current() { rms_current(this->val_mA); }
143 149
 
144 150
       #if ENABLED(HYBRID_THRESHOLD)
145
-        inline void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); }
151
+        void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); }
146 152
       #endif
147 153
       #if USE_SENSORLESS
148
-        inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
154
+        void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
149 155
       #endif
150 156
     #endif
151 157
 
@@ -167,24 +173,30 @@ class TMCMarlin<TMC2208Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC220
167 173
       {}
168 174
 
169 175
     uint16_t rms_current() { return TMC2208Stepper::rms_current(); }
170
-    inline void rms_current(const uint16_t mA) {
176
+    void rms_current(const uint16_t mA) {
171 177
       this->val_mA = mA;
172 178
       TMC2208Stepper::rms_current(mA);
173 179
     }
174
-    inline void rms_current(const uint16_t mA, const float mult) {
180
+    void rms_current(const uint16_t mA, const float mult) {
175 181
       this->val_mA = mA;
176 182
       TMC2208Stepper::rms_current(mA, mult);
177 183
     }
178
-    inline uint16_t get_microstep_counter() { return TMC2208Stepper::MSCNT(); }
184
+    uint16_t get_microstep_counter() { return TMC2208Stepper::MSCNT(); }
179 185
 
180 186
     #if HAS_STEALTHCHOP
181
-      inline bool get_stealthChop()                { return !this->en_spreadCycle(); }
182
-      inline bool get_stored_stealthChop()         { return this->stored.stealthChop_enabled; }
183
-      inline void refresh_stepping_mode()          { this->en_spreadCycle(!this->stored.stealthChop_enabled); }
184
-      inline void set_stealthChop(const bool stch) { this->stored.stealthChop_enabled = stch; refresh_stepping_mode(); }
185
-      inline bool toggle_stepping_mode()           { set_stealthChop(!this->stored.stealthChop_enabled); return get_stealthChop(); }
187
+      bool get_stealthChop()                { return !this->en_spreadCycle(); }
188
+      bool get_stored_stealthChop()         { return this->stored.stealthChop_enabled; }
189
+      void refresh_stepping_mode()          { this->en_spreadCycle(!this->stored.stealthChop_enabled); }
190
+      void set_stealthChop(const bool stch) { this->stored.stealthChop_enabled = stch; refresh_stepping_mode(); }
191
+      bool toggle_stepping_mode()           { set_stealthChop(!this->stored.stealthChop_enabled); return get_stealthChop(); }
186 192
     #endif
187 193
 
194
+    void set_chopper_times(const chopper_timing_t &ct) {
195
+      TMC2208Stepper::toff(ct.toff);
196
+      TMC2208Stepper::hysteresis_end(ct.hend);
197
+      TMC2208Stepper::hysteresis_start(ct.hstrt);
198
+    }
199
+
188 200
     #if ENABLED(HYBRID_THRESHOLD)
189 201
       uint32_t get_pwm_thrs() {
190 202
         return _tmc_thrs(this->microsteps(), this->TPWMTHRS(), planner.settings.axis_steps_per_mm[AXIS_ID]);
@@ -196,10 +208,10 @@ class TMCMarlin<TMC2208Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC220
196 208
     #endif
197 209
 
198 210
     #if HAS_LCD_MENU
199
-      inline void refresh_stepper_current() { rms_current(this->val_mA); }
211
+      void refresh_stepper_current() { rms_current(this->val_mA); }
200 212
 
201 213
       #if ENABLED(HYBRID_THRESHOLD)
202
-        inline void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); }
214
+        void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); }
203 215
       #endif
204 216
     #endif
205 217
 };
@@ -215,24 +227,30 @@ class TMCMarlin<TMC2209Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC220
215 227
       {}
216 228
     uint8_t get_address() { return slave_address; }
217 229
     uint16_t rms_current() { return TMC2209Stepper::rms_current(); }
218
-    inline void rms_current(const uint16_t mA) {
230
+    void rms_current(const uint16_t mA) {
219 231
       this->val_mA = mA;
220 232
       TMC2209Stepper::rms_current(mA);
221 233
     }
222
-    inline void rms_current(const uint16_t mA, const float mult) {
234
+    void rms_current(const uint16_t mA, const float mult) {
223 235
       this->val_mA = mA;
224 236
       TMC2209Stepper::rms_current(mA, mult);
225 237
     }
226
-    inline uint16_t get_microstep_counter() { return TMC2209Stepper::MSCNT(); }
238
+    uint16_t get_microstep_counter() { return TMC2209Stepper::MSCNT(); }
227 239
 
228 240
     #if HAS_STEALTHCHOP
229
-      inline bool get_stealthChop()                { return !this->en_spreadCycle(); }
230
-      inline bool get_stored_stealthChop()         { return this->stored.stealthChop_enabled; }
231
-      inline void refresh_stepping_mode()          { this->en_spreadCycle(!this->stored.stealthChop_enabled); }
232
-      inline void set_stealthChop(const bool stch) { this->stored.stealthChop_enabled = stch; refresh_stepping_mode(); }
233
-      inline bool toggle_stepping_mode()           { set_stealthChop(!this->stored.stealthChop_enabled); return get_stealthChop(); }
241
+      bool get_stealthChop()                { return !this->en_spreadCycle(); }
242
+      bool get_stored_stealthChop()         { return this->stored.stealthChop_enabled; }
243
+      void refresh_stepping_mode()          { this->en_spreadCycle(!this->stored.stealthChop_enabled); }
244
+      void set_stealthChop(const bool stch) { this->stored.stealthChop_enabled = stch; refresh_stepping_mode(); }
245
+      bool toggle_stepping_mode()           { set_stealthChop(!this->stored.stealthChop_enabled); return get_stealthChop(); }
234 246
     #endif
235 247
 
248
+    void set_chopper_times(const chopper_timing_t &ct) {
249
+      TMC2209Stepper::toff(ct.toff);
250
+      TMC2209Stepper::hysteresis_end(ct.hend);
251
+      TMC2209Stepper::hysteresis_start(ct.hstrt);
252
+    }
253
+
236 254
     #if ENABLED(HYBRID_THRESHOLD)
237 255
       uint32_t get_pwm_thrs() {
238 256
         return _tmc_thrs(this->microsteps(), this->TPWMTHRS(), planner.settings.axis_steps_per_mm[AXIS_ID]);
@@ -243,7 +261,7 @@ class TMCMarlin<TMC2209Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC220
243 261
       }
244 262
     #endif
245 263
     #if USE_SENSORLESS
246
-      inline int16_t homing_threshold() { return TMC2209Stepper::SGTHRS(); }
264
+      int16_t homing_threshold() { return TMC2209Stepper::SGTHRS(); }
247 265
       void homing_threshold(int16_t sgt_val) {
248 266
         sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max);
249 267
         TMC2209Stepper::SGTHRS(sgt_val);
@@ -252,13 +270,13 @@ class TMCMarlin<TMC2209Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC220
252 270
     #endif
253 271
 
254 272
     #if HAS_LCD_MENU
255
-      inline void refresh_stepper_current() { rms_current(this->val_mA); }
273
+      void refresh_stepper_current() { rms_current(this->val_mA); }
256 274
 
257 275
       #if ENABLED(HYBRID_THRESHOLD)
258
-        inline void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); }
276
+        void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); }
259 277
       #endif
260 278
       #if USE_SENSORLESS
261
-        inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
279
+        void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
262 280
       #endif
263 281
     #endif
264 282
 
@@ -275,15 +293,21 @@ class TMCMarlin<TMC2660Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC266
275 293
     TMCMarlin(const uint16_t CS, const float RS, const uint16_t pinMOSI, const uint16_t pinMISO, const uint16_t pinSCK, const uint8_t) :
276 294
       TMC2660Stepper(CS, RS, pinMOSI, pinMISO, pinSCK)
277 295
       {}
278
-    inline uint16_t rms_current() { return TMC2660Stepper::rms_current(); }
279
-    inline void rms_current(const uint16_t mA) {
296
+    uint16_t rms_current() { return TMC2660Stepper::rms_current(); }
297
+    void rms_current(const uint16_t mA) {
280 298
       this->val_mA = mA;
281 299
       TMC2660Stepper::rms_current(mA);
282 300
     }
283
-    inline uint16_t get_microstep_counter() { return TMC2660Stepper::mstep(); }
301
+    uint16_t get_microstep_counter() { return TMC2660Stepper::mstep(); }
302
+
303
+    void set_chopper_times(const chopper_timing_t &ct) {
304
+      TMC2660Stepper::toff(ct.toff);
305
+      TMC2660Stepper::hysteresis_end(ct.hend);
306
+      TMC2660Stepper::hysteresis_start(ct.hstrt);
307
+    }
284 308
 
285 309
     #if USE_SENSORLESS
286
-      inline int16_t homing_threshold() { return TMC2660Stepper::sgt(); }
310
+      int16_t homing_threshold() { return TMC2660Stepper::sgt(); }
287 311
       void homing_threshold(int16_t sgt_val) {
288 312
         sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max);
289 313
         TMC2660Stepper::sgt(sgt_val);
@@ -292,10 +316,10 @@ class TMCMarlin<TMC2660Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC266
292 316
     #endif
293 317
 
294 318
     #if HAS_LCD_MENU
295
-      inline void refresh_stepper_current() { rms_current(this->val_mA); }
319
+      void refresh_stepper_current() { rms_current(this->val_mA); }
296 320
 
297 321
       #if USE_SENSORLESS
298
-        inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
322
+        void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
299 323
       #endif
300 324
     #endif
301 325
 

+ 13
- 11
Marlin/src/gcode/feature/trinamic/M906.cpp View File

@@ -63,16 +63,18 @@ void GcodeSuite::M906() {
63 63
   LOOP_LOGICAL_AXES(i) if (uint16_t value = parser.intval(axis_codes[i])) {
64 64
     report = false;
65 65
     switch (i) {
66
-      case X_AXIS:
67
-        #if AXIS_IS_TMC(X)
68
-          if (index < 0 || index == 0) TMC_SET_CURRENT(X);
69
-        #endif
70
-        #if AXIS_IS_TMC(X2)
71
-          if (index < 0 || index == 1) TMC_SET_CURRENT(X2);
72
-        #endif
73
-        break;
66
+      #if AXIS_IS_TMC(X) || AXIS_IS_TMC(X2)
67
+        case X_AXIS:
68
+          #if AXIS_IS_TMC(X)
69
+            if (index < 0 || index == 0) TMC_SET_CURRENT(X);
70
+          #endif
71
+          #if AXIS_IS_TMC(X2)
72
+            if (index < 0 || index == 1) TMC_SET_CURRENT(X2);
73
+          #endif
74
+          break;
75
+      #endif
74 76
 
75
-      #if HAS_Y_AXIS
77
+      #if AXIS_IS_TMC(Y) || AXIS_IS_TMC(Y2)
76 78
         case Y_AXIS:
77 79
           #if AXIS_IS_TMC(Y)
78 80
             if (index < 0 || index == 0) TMC_SET_CURRENT(Y);
@@ -83,7 +85,7 @@ void GcodeSuite::M906() {
83 85
           break;
84 86
       #endif
85 87
 
86
-      #if HAS_Z_AXIS
88
+      #if AXIS_IS_TMC(Z) || AXIS_IS_TMC(Z2) || AXIS_IS_TMC(Z3) || AXIS_IS_TMC(Z4)
87 89
         case Z_AXIS:
88 90
           #if AXIS_IS_TMC(Z)
89 91
             if (index < 0 || index == 0) TMC_SET_CURRENT(Z);
@@ -110,7 +112,7 @@ void GcodeSuite::M906() {
110 112
         case K_AXIS: TMC_SET_CURRENT(K); break;
111 113
       #endif
112 114
 
113
-      #if E_STEPPERS
115
+      #if AXIS_IS_TMC(E0) || AXIS_IS_TMC(E1) || AXIS_IS_TMC(E2) || AXIS_IS_TMC(E3) || AXIS_IS_TMC(E4) || AXIS_IS_TMC(E5) || AXIS_IS_TMC(E6) || AXIS_IS_TMC(E7)
114 116
         case E_AXIS: {
115 117
           const int8_t eindex = get_target_e_stepper_from_command(-2);
116 118
           #if AXIS_IS_TMC(E0)

+ 23
- 15
Marlin/src/gcode/feature/trinamic/M911-M914.cpp View File

@@ -264,14 +264,28 @@
264 264
     LOOP_LOGICAL_AXES(i) if (int32_t value = parser.longval(axis_codes[i])) {
265 265
       report = false;
266 266
       switch (i) {
267
-        case X_AXIS:
268
-          TERN_(X_HAS_STEALTHCHOP,  if (index < 0 || index == 0) TMC_SET_PWMTHRS(X,X));
269
-          TERN_(X2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_PWMTHRS(X,X2));
270
-          break;
271
-        case Y_AXIS:
272
-          TERN_(Y_HAS_STEALTHCHOP,  if (index < 0 || index == 0) TMC_SET_PWMTHRS(Y,Y));
273
-          TERN_(Y2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_PWMTHRS(Y,Y2));
274
-          break;
267
+        #if X_HAS_STEALTHCHOP || X2_HAS_STEALTHCHOP
268
+          case X_AXIS:
269
+            TERN_(X_HAS_STEALTHCHOP,  if (index < 0 || index == 0) TMC_SET_PWMTHRS(X,X));
270
+            TERN_(X2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_PWMTHRS(X,X2));
271
+            break;
272
+        #endif
273
+
274
+        #if Y_HAS_STEALTHCHOP || Y2_HAS_STEALTHCHOP
275
+          case Y_AXIS:
276
+            TERN_(Y_HAS_STEALTHCHOP,  if (index < 0 || index == 0) TMC_SET_PWMTHRS(Y,Y));
277
+            TERN_(Y2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_PWMTHRS(Y,Y2));
278
+            break;
279
+        #endif
280
+
281
+        #if Z_HAS_STEALTHCHOP || Z2_HAS_STEALTHCHOP || Z3_HAS_STEALTHCHOP || Z4_HAS_STEALTHCHOP
282
+          case Z_AXIS:
283
+            TERN_(Z_HAS_STEALTHCHOP,  if (index < 0 || index == 0) TMC_SET_PWMTHRS(Z,Z));
284
+            TERN_(Z2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_PWMTHRS(Z,Z2));
285
+            TERN_(Z3_HAS_STEALTHCHOP, if (index < 0 || index == 2) TMC_SET_PWMTHRS(Z,Z3));
286
+            TERN_(Z4_HAS_STEALTHCHOP, if (index < 0 || index == 3) TMC_SET_PWMTHRS(Z,Z4));
287
+            break;
288
+        #endif
275 289
 
276 290
         #if I_HAS_STEALTHCHOP
277 291
           case I_AXIS: TMC_SET_PWMTHRS(I,I); break;
@@ -283,13 +297,7 @@
283 297
           case K_AXIS: TMC_SET_PWMTHRS(K,K); break;
284 298
         #endif
285 299
 
286
-        case Z_AXIS:
287
-          TERN_(Z_HAS_STEALTHCHOP,  if (index < 0 || index == 0) TMC_SET_PWMTHRS(Z,Z));
288
-          TERN_(Z2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_PWMTHRS(Z,Z2));
289
-          TERN_(Z3_HAS_STEALTHCHOP, if (index < 0 || index == 2) TMC_SET_PWMTHRS(Z,Z3));
290
-          TERN_(Z4_HAS_STEALTHCHOP, if (index < 0 || index == 3) TMC_SET_PWMTHRS(Z,Z4));
291
-          break;
292
-        #if E_STEPPERS
300
+        #if E0_HAS_STEALTHCHOP || E1_HAS_STEALTHCHOP || E2_HAS_STEALTHCHOP || E3_HAS_STEALTHCHOP || E4_HAS_STEALTHCHOP || E5_HAS_STEALTHCHOP || E6_HAS_STEALTHCHOP || E7_HAS_STEALTHCHOP
293 301
           case E_AXIS: {
294 302
             const int8_t eindex = get_target_e_stepper_from_command(-2);
295 303
             TERN_(E0_HAS_STEALTHCHOP, if (eindex < 0 || eindex == 0) TMC_SET_PWMTHRS_E(0));

+ 266
- 0
Marlin/src/gcode/feature/trinamic/M919.cpp View File

@@ -0,0 +1,266 @@
1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../../../inc/MarlinConfig.h"
24
+
25
+#if HAS_TRINAMIC_CONFIG
26
+
27
+#if AXIS_COLLISION('I')
28
+  #error "M919 parameter collision with axis name."
29
+#endif
30
+
31
+#include "../../gcode.h"
32
+#include "../../../feature/tmc_util.h"
33
+#include "../../../module/stepper/indirection.h"
34
+
35
+#define DEBUG_OUT ENABLED(MARLIN_DEV_MODE)
36
+#include "../../../core/debug_out.h"
37
+
38
+template<typename TMC>
39
+static void tmc_print_chopper_time(TMC &st) {
40
+  st.printLabel();
41
+  SERIAL_ECHOLNPGM(" chopper .toff: ", st.toff(),
42
+                   " .hend: ", st.hysteresis_end(),
43
+                   " .hstrt: ", st.hysteresis_start());
44
+}
45
+
46
+/**
47
+ * M919: Set TMC stepper driver chopper times
48
+ *
49
+ * Parameters:
50
+ *   XYZ...E     - Selected axes
51
+ *   I[index]    - Axis sub-index (Omit for all XYZ steppers, 1 for X2, Y2, Z2; 2 for Z3; 3 for Z4)
52
+ *   T[index]    - Extruder index (Zero-based. Omit for all extruders.)
53
+ *   O           - time-off         [ 1..15]
54
+ *   P           - hysteresis_end   [-3..12]
55
+ *   S           - hysteresis_start [ 1...8]
56
+ *
57
+ * With no parameters report chopper times for all axes
58
+ */
59
+void GcodeSuite::M919() {
60
+  bool err = false;
61
+
62
+  int8_t toff = int8_t(parser.intval('O', -127));
63
+  if (toff != -127) {
64
+    if (WITHIN(toff, 1, 15))
65
+      DEBUG_ECHOLNPGM(".toff: ", toff);
66
+    else {
67
+      SERIAL_ECHOLNPGM("?O out of range (1..15)");
68
+      err = true;
69
+    }
70
+  }
71
+
72
+  int8_t hend = int8_t(parser.intval('P', -127));
73
+  if (hend != -127) {
74
+    if (WITHIN(hend, -3, 12))
75
+      DEBUG_ECHOLNPGM(".hend: ", hend);
76
+    else {
77
+      SERIAL_ECHOLNPGM("?P out of range (-3..12)");
78
+      err = true;
79
+    }
80
+  }
81
+
82
+  int8_t hstrt = int8_t(parser.intval('S', -127));
83
+  if (hstrt != -127) {
84
+    if (WITHIN(hstrt, 1, 8))
85
+      DEBUG_ECHOLNPGM(".hstrt: ", hstrt);
86
+    else {
87
+      SERIAL_ECHOLNPGM("?S out of range (1..8)");
88
+      err = true;
89
+    }
90
+  }
91
+
92
+  if (err) return;
93
+
94
+  #if AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z2) || AXIS_IS_TMC(Z3) || AXIS_IS_TMC(Z4)
95
+    const int8_t index = parser.byteval('I');
96
+  #else
97
+    constexpr int8_t index = -1;
98
+  #endif
99
+
100
+  auto make_chopper_timing = [](chopper_timing_t bct, const int8_t toff, const int8_t hend, const int8_t hstrt) {
101
+    chopper_timing_t uct = bct;
102
+    if (toff  != -127) uct.toff  = toff;
103
+    if (hend  != -127) uct.hend  = hend;
104
+    if (hstrt != -127) uct.hstrt = hstrt;
105
+    return uct;
106
+  };
107
+
108
+  #define TMC_SET_CHOPPER_TIME(Q) stepper##Q.set_chopper_times(make_chopper_timing(CHOPPER_TIMING_##Q, toff, hend, hstrt))
109
+
110
+  #if AXIS_IS_TMC(E0) || AXIS_IS_TMC(E1) || AXIS_IS_TMC(E2) || AXIS_IS_TMC(E3) || AXIS_IS_TMC(E4) || AXIS_IS_TMC(E5) || AXIS_IS_TMC(E6) || AXIS_IS_TMC(E7)
111
+    #define HAS_E_CHOPPER 1
112
+    int8_t eindex = -1;
113
+  #endif
114
+  bool report = true;
115
+  LOOP_LOGICAL_AXES(i) if (parser.seen_test(axis_codes[i])) {
116
+    report = false;
117
+
118
+    // Get the chopper timing for the specified axis and index
119
+    switch (i) {
120
+      default: // A specified axis isn't Trinamic
121
+        SERIAL_ECHOLNPGM("?Axis ", AS_CHAR(axis_codes[i]), " has no TMC drivers.");
122
+        break;
123
+
124
+      #if AXIS_IS_TMC(X) || AXIS_IS_TMC(X2)
125
+        case X_AXIS:
126
+          #if AXIS_IS_TMC(X)
127
+            if (index <= 0) TMC_SET_CHOPPER_TIME(X);
128
+          #endif
129
+          #if AXIS_IS_TMC(X2)
130
+            if (index < 0 || index == 1) TMC_SET_CHOPPER_TIME(X2);
131
+          #endif
132
+          break;
133
+      #endif
134
+
135
+      #if AXIS_IS_TMC(Y) || AXIS_IS_TMC(Y2)
136
+        case Y_AXIS:
137
+          #if AXIS_IS_TMC(Y)
138
+            if (index <= 0) TMC_SET_CHOPPER_TIME(Y);
139
+          #endif
140
+          #if AXIS_IS_TMC(Y2)
141
+            if (index < 0 || index == 1) TMC_SET_CHOPPER_TIME(Y2);
142
+          #endif
143
+          break;
144
+      #endif
145
+
146
+      #if AXIS_IS_TMC(Z) || AXIS_IS_TMC(Z2) || AXIS_IS_TMC(Z3) || AXIS_IS_TMC(Z4)
147
+        case Z_AXIS:
148
+          #if AXIS_IS_TMC(Z)
149
+            if (index <= 0) TMC_SET_CHOPPER_TIME(Z);
150
+          #endif
151
+          #if AXIS_IS_TMC(Z2)
152
+            if (index < 0 || index == 1) TMC_SET_CHOPPER_TIME(Z2);
153
+          #endif
154
+          #if AXIS_IS_TMC(Z3)
155
+            if (index < 0 || index == 2) TMC_SET_CHOPPER_TIME(Z3);
156
+          #endif
157
+          #if AXIS_IS_TMC(Z4)
158
+            if (index < 0 || index == 3) TMC_SET_CHOPPER_TIME(Z4);
159
+          #endif
160
+          break;
161
+      #endif
162
+
163
+      #if AXIS_IS_TMC(I)
164
+        case I_AXIS: TMC_SET_CHOPPER_TIME(I); break;
165
+      #endif
166
+      #if AXIS_IS_TMC(J)
167
+        case J_AXIS: TMC_SET_CHOPPER_TIME(J); break;
168
+      #endif
169
+      #if AXIS_IS_TMC(K)
170
+        case K_AXIS: TMC_SET_CHOPPER_TIME(K); break;
171
+      #endif
172
+
173
+      #if HAS_E_CHOPPER
174
+        case E_AXIS: {
175
+          #if AXIS_IS_TMC(E0)
176
+            if (eindex <= 0) TMC_SET_CHOPPER_TIME(E0);
177
+          #endif
178
+          #if AXIS_IS_TMC(E1)
179
+            if (eindex < 0 || eindex == 1) TMC_SET_CHOPPER_TIME(E1);
180
+          #endif
181
+          #if AXIS_IS_TMC(E2)
182
+            if (eindex < 0 || eindex == 2) TMC_SET_CHOPPER_TIME(E2);
183
+          #endif
184
+          #if AXIS_IS_TMC(E3)
185
+            if (eindex < 0 || eindex == 3) TMC_SET_CHOPPER_TIME(E3);
186
+          #endif
187
+          #if AXIS_IS_TMC(E4)
188
+            if (eindex < 0 || eindex == 4) TMC_SET_CHOPPER_TIME(E4);
189
+          #endif
190
+          #if AXIS_IS_TMC(E5)
191
+            if (eindex < 0 || eindex == 5) TMC_SET_CHOPPER_TIME(E5);
192
+          #endif
193
+          #if AXIS_IS_TMC(E6)
194
+            if (eindex < 0 || eindex == 6) TMC_SET_CHOPPER_TIME(E6);
195
+          #endif
196
+          #if AXIS_IS_TMC(E7)
197
+            if (eindex < 0 || eindex == 7) TMC_SET_CHOPPER_TIME(E7);
198
+          #endif
199
+        } break;
200
+      #endif
201
+    }
202
+  }
203
+
204
+  if (report) {
205
+    #define TMC_SAY_CHOPPER_TIME(Q) tmc_print_chopper_time(stepper##Q)
206
+    #if AXIS_IS_TMC(X)
207
+      TMC_SAY_CHOPPER_TIME(X);
208
+    #endif
209
+    #if AXIS_IS_TMC(X2)
210
+      TMC_SAY_CHOPPER_TIME(X2);
211
+    #endif
212
+    #if AXIS_IS_TMC(Y)
213
+      TMC_SAY_CHOPPER_TIME(Y);
214
+    #endif
215
+    #if AXIS_IS_TMC(Y2)
216
+      TMC_SAY_CHOPPER_TIME(Y2);
217
+    #endif
218
+    #if AXIS_IS_TMC(Z)
219
+      TMC_SAY_CHOPPER_TIME(Z);
220
+    #endif
221
+    #if AXIS_IS_TMC(Z2)
222
+      TMC_SAY_CHOPPER_TIME(Z2);
223
+    #endif
224
+    #if AXIS_IS_TMC(Z3)
225
+      TMC_SAY_CHOPPER_TIME(Z3);
226
+    #endif
227
+    #if AXIS_IS_TMC(Z4)
228
+      TMC_SAY_CHOPPER_TIME(Z4);
229
+    #endif
230
+    #if AXIS_IS_TMC(I)
231
+      TMC_SAY_CHOPPER_TIME(I);
232
+    #endif
233
+    #if AXIS_IS_TMC(J)
234
+      TMC_SAY_CHOPPER_TIME(J);
235
+    #endif
236
+    #if AXIS_IS_TMC(K)
237
+      TMC_SAY_CHOPPER_TIME(K);
238
+    #endif
239
+    #if AXIS_IS_TMC(E0)
240
+      TMC_SAY_CHOPPER_TIME(E0);
241
+    #endif
242
+    #if AXIS_IS_TMC(E1)
243
+      TMC_SAY_CHOPPER_TIME(E1);
244
+    #endif
245
+    #if AXIS_IS_TMC(E2)
246
+      TMC_SAY_CHOPPER_TIME(E2);
247
+    #endif
248
+    #if AXIS_IS_TMC(E3)
249
+      TMC_SAY_CHOPPER_TIME(E3);
250
+    #endif
251
+    #if AXIS_IS_TMC(E4)
252
+      TMC_SAY_CHOPPER_TIME(E4);
253
+    #endif
254
+    #if AXIS_IS_TMC(E5)
255
+      TMC_SAY_CHOPPER_TIME(E5);
256
+    #endif
257
+    #if AXIS_IS_TMC(E6)
258
+      TMC_SAY_CHOPPER_TIME(E6);
259
+    #endif
260
+    #if AXIS_IS_TMC(E7)
261
+      TMC_SAY_CHOPPER_TIME(E7);
262
+    #endif
263
+  }
264
+}
265
+
266
+#endif // HAS_TRINAMIC_CONFIG

+ 1
- 0
Marlin/src/gcode/gcode.cpp View File

@@ -971,6 +971,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
971 971
         #if USE_SENSORLESS
972 972
           case 914: M914(); break;                                // M914: Set StallGuard sensitivity.
973 973
         #endif
974
+        case 919: M919(); break;                                  // M919: Set stepper Chopper Times
974 975
       #endif
975 976
 
976 977
       #if HAS_L64XX

+ 2
- 0
Marlin/src/gcode/gcode.h View File

@@ -296,6 +296,7 @@
296 296
  * M916 - L6470 tuning: Increase KVAL_HOLD until thermal warning. (Requires at least one _DRIVER_TYPE L6470)
297 297
  * M917 - L6470 tuning: Find minimum current thresholds. (Requires at least one _DRIVER_TYPE L6470)
298 298
  * M918 - L6470 tuning: Increase speed until max or error. (Requires at least one _DRIVER_TYPE L6470)
299
+ * M919 - Get or Set motor Chopper Times (time_off, hysteresis_end, hysteresis_start) using axis codes XYZE, etc. If no parameters are given, report. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660)
299 300
  * M951 - Set Magnetic Parking Extruder parameters. (Requires MAGNETIC_PARKING_EXTRUDER)
300 301
  * M3426 - Read MCP3426 ADC over I2C. (Requires HAS_MCP3426_ADC)
301 302
  * M7219 - Control Max7219 Matrix LEDs. (Requires MAX7219_GCODE)
@@ -1140,6 +1141,7 @@ private:
1140 1141
       static void M914();
1141 1142
       static void M914_report(const bool forReplay=true);
1142 1143
     #endif
1144
+    static void M919();
1143 1145
   #endif
1144 1146
 
1145 1147
   #if HAS_L64XX

+ 8
- 8
Marlin/src/inc/Conditionals_post.h View File

@@ -2395,28 +2395,28 @@
2395 2395
 // ADC Temp Sensors (Thermistor or Thermocouple with amplifier ADC interface)
2396 2396
 //
2397 2397
 #define HAS_ADC_TEST(P) (PIN_EXISTS(TEMP_##P) && TEMP_SENSOR_##P != 0 && NONE(TEMP_SENSOR_##P##_IS_MAX_TC, TEMP_SENSOR_##P##_IS_DUMMY))
2398
-#if HAS_ADC_TEST(0)
2398
+#if HOTENDS > 0 && HAS_ADC_TEST(0)
2399 2399
   #define HAS_TEMP_ADC_0 1
2400 2400
 #endif
2401
-#if HAS_ADC_TEST(1)
2401
+#if HOTENDS > 1 && HAS_ADC_TEST(1)
2402 2402
   #define HAS_TEMP_ADC_1 1
2403 2403
 #endif
2404
-#if HAS_ADC_TEST(2)
2404
+#if HOTENDS > 2 && HAS_ADC_TEST(2)
2405 2405
   #define HAS_TEMP_ADC_2 1
2406 2406
 #endif
2407
-#if HAS_ADC_TEST(3)
2407
+#if HOTENDS > 3 && HAS_ADC_TEST(3)
2408 2408
   #define HAS_TEMP_ADC_3 1
2409 2409
 #endif
2410
-#if HAS_ADC_TEST(4)
2410
+#if HOTENDS > 4 && HAS_ADC_TEST(4)
2411 2411
   #define HAS_TEMP_ADC_4 1
2412 2412
 #endif
2413
-#if HAS_ADC_TEST(5)
2413
+#if HOTENDS > 5 && HAS_ADC_TEST(5)
2414 2414
   #define HAS_TEMP_ADC_5 1
2415 2415
 #endif
2416
-#if HAS_ADC_TEST(6)
2416
+#if HOTENDS > 6 && HAS_ADC_TEST(6)
2417 2417
   #define HAS_TEMP_ADC_6 1
2418 2418
 #endif
2419
-#if HAS_ADC_TEST(7)
2419
+#if HOTENDS > 7 && HAS_ADC_TEST(7)
2420 2420
   #define HAS_TEMP_ADC_7 1
2421 2421
 #endif
2422 2422
 #if HAS_ADC_TEST(BED)

+ 1
- 1
ini/features.ini View File

@@ -18,7 +18,7 @@ POSTMORTEM_DEBUGGING                   = src_filter=+<src/HAL/shared/cpu_excepti
18 18
                                          build_flags=-funwind-tables
19 19
 MKS_WIFI_MODULE                        = QRCode=https://github.com/makerbase-mks/QRCode/archive/master.zip
20 20
 HAS_TRINAMIC_CONFIG                    = TMCStepper@~0.7.3
21
-                                         src_filter=+<src/feature/tmc_util.cpp> +<src/module/stepper/trinamic.cpp> +<src/gcode/feature/trinamic/M122.cpp> +<src/gcode/feature/trinamic/M906.cpp> +<src/gcode/feature/trinamic/M911-M914.cpp>
21
+                                         src_filter=+<src/feature/tmc_util.cpp> +<src/module/stepper/trinamic.cpp> +<src/gcode/feature/trinamic/M122.cpp> +<src/gcode/feature/trinamic/M906.cpp> +<src/gcode/feature/trinamic/M911-M914.cpp> +<src/gcode/feature/trinamic/M919.cpp>
22 22
 HAS_STEALTHCHOP                        = src_filter=+<src/gcode/feature/trinamic/M569.cpp>
23 23
 SR_LCD_3W_NL                           = SailfishLCD=https://github.com/mikeshub/SailfishLCD/archive/master.zip
24 24
 HAS_MOTOR_CURRENT_I2C                  = SlowSoftI2CMaster

+ 1
- 0
platformio.ini View File

@@ -204,6 +204,7 @@ default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
204 204
   -<src/gcode/feature/trinamic/M569.cpp>
205 205
   -<src/gcode/feature/trinamic/M906.cpp>
206 206
   -<src/gcode/feature/trinamic/M911-M914.cpp>
207
+  -<src/gcode/feature/trinamic/M919.cpp>
207 208
   -<src/gcode/geometry/G17-G19.cpp>
208 209
   -<src/gcode/geometry/G53-G59.cpp>
209 210
   -<src/gcode/geometry/M206_M428.cpp>

Loading…
Cancel
Save