24 #include "../inc/MarlinConfig.h"
25 #include "../lcd/ultralcd.h"
29 #include <TMCStepper.h>
30 #include "../module/planner.h"
32 #define TMC_X_LABEL 'X', '0'
33 #define TMC_Y_LABEL 'Y', '0'
34 #define TMC_Z_LABEL 'Z', '0'
36 #define TMC_X2_LABEL 'X', '2'
37 #define TMC_Y2_LABEL 'Y', '2'
38 #define TMC_Z2_LABEL 'Z', '2'
39 #define TMC_Z3_LABEL 'Z', '3'
41 #define TMC_E0_LABEL 'E', '0'
42 #define TMC_E1_LABEL 'E', '1'
43 #define TMC_E2_LABEL 'E', '2'
44 #define TMC_E3_LABEL 'E', '3'
45 #define TMC_E4_LABEL 'E', '4'
46 #define TMC_E5_LABEL 'E', '5'
48 #define CHOPPER_DEFAULT_12V { 3, -1, 1 }
49 #define CHOPPER_DEFAULT_19V { 4, 1, 1 }
50 #define CHOPPER_DEFAULT_24V { 4, 2, 1 }
51 #define CHOPPER_DEFAULT_36V { 5, 2, 4 }
52 #define CHOPPER_PRUSAMK3_24V { 3, -2, 6 }
53 #define CHOPPER_MARLIN_119 { 5, 2, 3 }
55 #if ENABLED(MONITOR_DRIVER_STATUS) && !defined(MONITOR_DRIVER_STATUS_INTERVAL_MS)
56 #define MONITOR_DRIVER_STATUS_INTERVAL_MS 500u
59 constexpr uint16_t _tmc_thrs(
const uint16_t msteps,
const uint32_t thrs,
const uint32_t spmm) {
60 return 12650000UL * msteps / (256 * thrs * spmm);
63 template<
char AXIS_LETTER,
char DRIVER_ID>
72 #if ENABLED(MONITOR_DRIVER_STATUS)
75 bool flag_otpw =
false;
76 inline bool getOTPW() {
return flag_otpw; }
77 inline void clear_otpw() { flag_otpw = 0; }
80 inline uint16_t getMilliamps() {
return val_mA; }
82 inline void printLabel() {
89 bool stealthChop_enabled =
false;
91 #if ENABLED(HYBRID_THRESHOLD)
95 int16_t homing_thrs = 0;
100 template<
class TMC,
char AXIS_LETTER,
char DRIVER_ID, AxisEnum AXIS_ID>
101 class TMCMarlin :
public TMC,
public TMCStorage<AXIS_LETTER, DRIVER_ID> {
103 TMCMarlin(
const uint16_t cs_pin,
const float RS) :
106 TMCMarlin(
const uint16_t cs_pin,
const float RS,
const uint8_t axis_chain_index) :
107 TMC(cs_pin, RS, axis_chain_index)
109 TMCMarlin(
const uint16_t CS,
const float RS,
const uint16_t pinMOSI,
const uint16_t pinMISO,
const uint16_t pinSCK) :
110 TMC(CS, RS, pinMOSI, pinMISO, pinSCK)
112 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) :
113 TMC(CS, RS, pinMOSI, pinMISO, pinSCK, axis_chain_index)
115 inline uint16_t rms_current() {
return TMC::rms_current(); }
116 inline void rms_current(uint16_t mA) {
118 TMC::rms_current(mA);
120 inline void rms_current(
const uint16_t mA,
const float mult) {
122 TMC::rms_current(mA, mult);
126 inline void refresh_stepping_mode() { this->en_pwm_mode(this->stored.stealthChop_enabled); }
127 inline bool get_stealthChop_status() {
return this->en_pwm_mode(); }
129 #if ENABLED(HYBRID_THRESHOLD)
130 uint32_t get_pwm_thrs() {
133 void set_pwm_thrs(
const uint32_t thrs) {
136 this->stored.hybrid_thrs = thrs;
141 inline int16_t homing_threshold() {
return TMC::sgt(); }
142 void homing_threshold(int16_t sgt_val) {
143 sgt_val = (int16_t)
constrain(sgt_val, sgt_min, sgt_max);
146 this->stored.homing_thrs = sgt_val;
149 #if ENABLED(SPI_ENDSTOPS)
150 bool test_stall_status();
155 inline void refresh_stepper_current() { rms_current(this->val_mA); }
157 #if ENABLED(HYBRID_THRESHOLD)
158 inline void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); }
161 inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
165 static constexpr int8_t sgt_min = -64,
168 template<
char AXIS_LETTER,
char DRIVER_ID, AxisEnum AXIS_ID>
169 class TMCMarlin<TMC2208Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> :
public TMC2208Stepper,
public TMCStorage<AXIS_LETTER, DRIVER_ID> {
171 TMCMarlin(
Stream * SerialPort,
const float RS,
const uint8_t) :
172 TMC2208Stepper(SerialPort, RS, true)
174 TMCMarlin(
const uint16_t RX,
const uint16_t TX,
const float RS,
const uint8_t,
const bool has_rx=
true) :
175 TMC2208Stepper(RX, TX, RS, has_rx)
177 uint16_t rms_current() {
return TMC2208Stepper::rms_current(); }
178 inline void rms_current(
const uint16_t mA) {
180 TMC2208Stepper::rms_current(mA);
182 inline void rms_current(
const uint16_t mA,
const float mult) {
184 TMC2208Stepper::rms_current(mA, mult);
188 inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); }
189 inline bool get_stealthChop_status() {
return !this->en_spreadCycle(); }
191 #if ENABLED(HYBRID_THRESHOLD)
192 uint32_t get_pwm_thrs() {
195 void set_pwm_thrs(
const uint32_t thrs) {
198 this->stored.hybrid_thrs = thrs;
204 inline void refresh_stepper_current() { rms_current(this->val_mA); }
206 #if ENABLED(HYBRID_THRESHOLD)
207 inline void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); }
212 template<
char AXIS_LETTER,
char DRIVER_ID, AxisEnum AXIS_ID>
213 class TMCMarlin<TMC2209Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> :
public TMC2209Stepper,
public TMCStorage<AXIS_LETTER, DRIVER_ID> {
215 TMCMarlin(
Stream * SerialPort,
const float RS,
const uint8_t addr) :
216 TMC2209Stepper(SerialPort, RS, addr)
218 TMCMarlin(
const uint16_t RX,
const uint16_t TX,
const float RS,
const uint8_t addr,
const bool) :
219 TMC2209Stepper(RX, TX, RS, addr)
221 uint8_t get_address() {
return slave_address; }
222 uint16_t rms_current() {
return TMC2209Stepper::rms_current(); }
223 inline void rms_current(
const uint16_t mA) {
225 TMC2209Stepper::rms_current(mA);
227 inline void rms_current(
const uint16_t mA,
const float mult) {
229 TMC2209Stepper::rms_current(mA, mult);
233 inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); }
234 inline bool get_stealthChop_status() {
return !this->en_spreadCycle(); }
236 #if ENABLED(HYBRID_THRESHOLD)
237 uint32_t get_pwm_thrs() {
240 void set_pwm_thrs(
const uint32_t thrs) {
243 this->stored.hybrid_thrs = thrs;
248 inline int16_t homing_threshold() {
return TMC2209Stepper::SGTHRS(); }
249 void homing_threshold(int16_t sgt_val) {
250 sgt_val = (int16_t)
constrain(sgt_val, sgt_min, sgt_max);
251 TMC2209Stepper::SGTHRS(sgt_val);
253 this->stored.homing_thrs = sgt_val;
259 inline void refresh_stepper_current() { rms_current(this->val_mA); }
261 #if ENABLED(HYBRID_THRESHOLD)
262 inline void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); }
265 inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
269 static constexpr
uint8_t sgt_min = 0,
273 template<
char AXIS_LETTER,
char DRIVER_ID, AxisEnum AXIS_ID>
274 class TMCMarlin<TMC2660Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> :
public TMC2660Stepper,
public TMCStorage<AXIS_LETTER, DRIVER_ID> {
276 TMCMarlin(
const uint16_t cs_pin,
const float RS,
const uint8_t) :
277 TMC2660Stepper(cs_pin, RS)
279 TMCMarlin(
const uint16_t CS,
const float RS,
const uint16_t pinMOSI,
const uint16_t pinMISO,
const uint16_t pinSCK,
const uint8_t) :
280 TMC2660Stepper(CS, RS, pinMOSI, pinMISO, pinSCK)
282 inline uint16_t rms_current() {
return TMC2660Stepper::rms_current(); }
283 inline void rms_current(
const uint16_t mA) {
285 TMC2660Stepper::rms_current(mA);
289 inline int16_t homing_threshold() {
return TMC2660Stepper::sgt(); }
290 void homing_threshold(int16_t sgt_val) {
291 sgt_val = (int16_t)
constrain(sgt_val, sgt_min, sgt_max);
292 TMC2660Stepper::sgt(sgt_val);
294 this->stored.homing_thrs = sgt_val;
300 inline void refresh_stepper_current() { rms_current(this->val_mA); }
303 inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
307 static constexpr int8_t sgt_min = -64,
311 template<
typename TMC>
312 void tmc_print_current(TMC &st) {
317 #if ENABLED(MONITOR_DRIVER_STATUS)
318 template<
typename TMC>
319 void tmc_report_otpw(TMC &st) {
325 template<
typename TMC>
326 void tmc_clear_otpw(TMC &st) {
332 #if ENABLED(HYBRID_THRESHOLD)
333 template<
typename TMC>
334 void tmc_print_pwmthrs(TMC &st) {
340 template<
typename TMC>
341 void tmc_print_sgt(TMC &st) {
348 void monitor_tmc_driver();
349 void test_tmc_connection(
const bool test_x,
const bool test_y,
const bool test_z,
const bool test_e);
351 #if ENABLED(TMC_DEBUG)
352 #if ENABLED(MONITOR_DRIVER_STATUS)
353 void tmc_set_report_interval(
const uint16_t update_interval);
355 void tmc_report_all(
const bool print_x,
const bool print_y,
const bool print_z,
const bool print_e);
356 void tmc_get_registers(
const bool print_x,
const bool print_y,
const bool print_z,
const bool print_e);
369 struct sensorless_t {
bool x, y, z, x2, y2, z2, z3; };
371 #if ENABLED(IMPROVE_HOMING_RELIABILITY)
373 constexpr uint16_t default_sg_guard_duration = 400;
375 struct slow_homing_t {
383 bool tmc_enable_stallguard(TMC2130Stepper &st);
384 void tmc_disable_stallguard(TMC2130Stepper &st,
const bool restore_stealth);
386 bool tmc_enable_stallguard(TMC2209Stepper &st);
387 void tmc_disable_stallguard(TMC2209Stepper &st,
const bool restore_stealth);
389 bool tmc_enable_stallguard(TMC2660Stepper);
390 void tmc_disable_stallguard(TMC2660Stepper,
const bool);
392 #if ENABLED(SPI_ENDSTOPS)
394 template<
class TMC,
char AXIS_LETTER,
char DRIVER_ID, AxisEnum AXIS_ID>
395 bool TMCMarlin<TMC, AXIS_LETTER, DRIVER_ID, AXIS_ID>::test_stall_status() {
396 this->switchCSpin(
LOW);
399 TMC2130_n::DRV_STATUS_t drv_status{0};
400 drv_status.sr = this->DRV_STATUS();
402 this->switchCSpin(
HIGH);
404 return drv_status.stallGuard;
406 #endif // SPI_ENDSTOPS
408 #endif // USE_SENSORLESS
411 void tmc_init_cs_pins();
414 #endif // HAS_TRINAMIC