Add TMC2209 support (#14249)

This commit is contained in:
Scott Lahteine
2019-06-20 15:47:50 -05:00
committed by GitHub
parent ed0c70f0a0
commit 4df4c47994
208 changed files with 2732 additions and 644 deletions

View File

@ -69,7 +69,7 @@
#endif
;
#if ENABLED(TMC_DEBUG)
#if HAS_TMCX1X0 || HAS_DRIVER(TMC2208)
#if HAS_TMCX1X0 || HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)
uint8_t cs_actual;
#endif
#if HAS_STALLGUARD
@ -97,6 +97,7 @@
TMC_driver_data data;
const auto ds = data.drv_status = st.DRV_STATUS();
#ifdef __AVR__
// 8-bit optimization saves up to 70 bytes of PROGMEM per axis
uint8_t spart;
#if ENABLED(TMC_DEBUG)
@ -115,6 +116,7 @@
data.is_standstill = TEST(spart, STST_bp - 24);
data.sg_result_reasonable = !data.is_standstill; // sg_result has no reasonable meaning while standstill
#endif
#else // !__AVR__
data.is_ot = TEST(ds, OT_bp);
@ -137,7 +139,7 @@
#endif // HAS_TMCX1X0
#if HAS_DRIVER(TMC2208)
#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)
#if ENABLED(TMC_DEBUG)
static uint32_t get_pwm_scale(TMC2208Stepper &st) { return st.pwm_scale_sum(); }
@ -174,7 +176,7 @@
return data;
}
#endif // TMC2208
#endif // TMC2208 || TMC2209
#if HAS_DRIVER(TMC2660)
@ -228,9 +230,7 @@
SERIAL_ECHO(timestamp);
SERIAL_ECHOPGM(": ");
st.printLabel();
SERIAL_ECHOPGM(" driver overtemperature warning! (");
SERIAL_ECHO(st.getMilliamps());
SERIAL_ECHOLNPGM("mA)");
SERIAL_ECHOLNPAIR(" driver overtemperature warning! (", st.getMilliamps(), "mA)");
}
template<typename TMC>
@ -239,7 +239,7 @@
st.printLabel();
SERIAL_CHAR(':'); SERIAL_PRINT(pwm_scale, DEC);
#if ENABLED(TMC_DEBUG)
#if HAS_TMCX1X0 || HAS_DRIVER(TMC2208)
#if HAS_TMCX1X0 || HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)
SERIAL_CHAR('/'); SERIAL_PRINT(data.cs_actual, DEC);
#endif
#if HAS_STALLGUARD
@ -386,7 +386,7 @@
if ((report_tmc_status_interval = update_interval))
SERIAL_ECHOLNPGM("axis:pwm_scale"
#if HAS_STEALTHCHOP
"/current_scale"
"/curr_scale"
#endif
#if HAS_STALLGUARD
"/mech_load"
@ -398,6 +398,7 @@
enum TMC_debug_enum : char {
TMC_CODES,
TMC_UART_ADDR,
TMC_ENABLED,
TMC_CURRENT,
TMC_RMS_CURRENT,
@ -482,9 +483,9 @@
#if HAS_TMCX1X0
static void _tmc_parse_drv_status(TMC2130Stepper &st, const TMC_drv_status_enum i) {
switch (i) {
case TMC_STALLGUARD: if (st.stallguard()) SERIAL_CHAR('X'); break;
case TMC_SG_RESULT: SERIAL_PRINT(st.sg_result(), DEC); break;
case TMC_FSACTIVE: if (st.fsactive()) SERIAL_CHAR('X'); break;
case TMC_STALLGUARD: if (st.stallguard()) SERIAL_CHAR('*'); break;
case TMC_SG_RESULT: SERIAL_PRINT(st.sg_result(), DEC); break;
case TMC_FSACTIVE: if (st.fsactive()) SERIAL_CHAR('*'); break;
case TMC_DRV_CS_ACTUAL: SERIAL_PRINT(st.cs_actual(), DEC); break;
default: break;
}
@ -515,22 +516,37 @@
}
#endif
#if HAS_DRIVER(TMC2208)
#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)
static void _tmc_status(TMC2208Stepper &st, const TMC_debug_enum i) {
switch (i) {
case TMC_PWM_SCALE: SERIAL_PRINT(st.pwm_scale_sum(), DEC); break;
case TMC_STEALTHCHOP: serialprint_truefalse(st.stealth()); break;
case TMC_S2VSA: if (st.s2vsa()) SERIAL_CHAR('X'); break;
case TMC_S2VSB: if (st.s2vsb()) SERIAL_CHAR('X'); break;
case TMC_S2VSA: if (st.s2vsa()) SERIAL_CHAR('*'); break;
case TMC_S2VSB: if (st.s2vsb()) SERIAL_CHAR('*'); break;
default: break;
}
}
#if HAS_DRIVER(TMC2209)
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
static void _tmc_status(TMCMarlin<TMC2209Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> &st, const TMC_debug_enum i) {
switch (i) {
case TMC_SGT: SERIAL_PRINT(st.SGTHRS(), DEC); break;
case TMC_UART_ADDR: SERIAL_PRINT(st.get_address(), DEC); break;
default:
TMC2208Stepper *parent = &st;
_tmc_status(*parent, i);
break;
}
}
#endif
static void _tmc_parse_drv_status(TMC2208Stepper &st, const TMC_drv_status_enum i) {
switch (i) {
case TMC_T157: if (st.t157()) SERIAL_CHAR('X'); break;
case TMC_T150: if (st.t150()) SERIAL_CHAR('X'); break;
case TMC_T143: if (st.t143()) SERIAL_CHAR('X'); break;
case TMC_T120: if (st.t120()) SERIAL_CHAR('X'); break;
case TMC_T157: if (st.t157()) SERIAL_CHAR('*'); break;
case TMC_T150: if (st.t150()) SERIAL_CHAR('*'); break;
case TMC_T143: if (st.t143()) SERIAL_CHAR('*'); break;
case TMC_T120: if (st.t120()) SERIAL_CHAR('*'); break;
case TMC_DRV_CS_ACTUAL: SERIAL_PRINT(st.cs_actual(), DEC); break;
default: break;
}
@ -620,13 +636,13 @@
SERIAL_CHAR('\t');
switch (i) {
case TMC_DRV_CODES: st.printLabel(); break;
case TMC_STST: if (st.stst()) SERIAL_CHAR('X'); break;
case TMC_OLB: if (st.olb()) SERIAL_CHAR('X'); break;
case TMC_OLA: if (st.ola()) SERIAL_CHAR('X'); break;
case TMC_S2GB: if (st.s2gb()) SERIAL_CHAR('X'); break;
case TMC_S2GA: if (st.s2ga()) SERIAL_CHAR('X'); break;
case TMC_DRV_OTPW: if (st.otpw()) SERIAL_CHAR('X'); break;
case TMC_OT: if (st.ot()) SERIAL_CHAR('X'); break;
case TMC_STST: if (st.stst()) SERIAL_CHAR('*'); break;
case TMC_OLB: if (st.olb()) SERIAL_CHAR('*'); break;
case TMC_OLA: if (st.ola()) SERIAL_CHAR('*'); break;
case TMC_S2GB: if (st.s2gb()) SERIAL_CHAR('*'); break;
case TMC_S2GA: if (st.s2ga()) SERIAL_CHAR('*'); break;
case TMC_DRV_OTPW: if (st.otpw()) SERIAL_CHAR('*'); break;
case TMC_OT: if (st.ot()) SERIAL_CHAR('*'); break;
case TMC_DRV_STATUS_HEX: {
const uint32_t drv_status = st.DRV_STATUS();
SERIAL_CHAR('\t');
@ -759,6 +775,9 @@
#define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM, print_x, print_y, print_z, print_e); }while(0)
#define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM, print_x, print_y, print_z, print_e); }while(0)
TMC_REPORT("\t", TMC_CODES);
#if HAS_DRIVER(TMC2209)
TMC_REPORT("Address\t", TMC_UART_ADDR);
#endif
TMC_REPORT("Enabled\t", TMC_ENABLED);
TMC_REPORT("Set current", TMC_CURRENT);
TMC_REPORT("RMS current", TMC_RMS_CURRENT);
@ -770,7 +789,7 @@
#endif
TMC_REPORT("CS actual\t", TMC_CS_ACTUAL);
TMC_REPORT("PWM scale", TMC_PWM_SCALE);
#if HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2224) || HAS_DRIVER(TMC2660) || HAS_DRIVER(TMC2208)
#if HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2224) || HAS_DRIVER(TMC2660) || HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)
TMC_REPORT("vsense\t", TMC_VSENSE);
#endif
TMC_REPORT("stealthChop", TMC_STEALTHCHOP);
@ -802,7 +821,7 @@
DRV_REPORT("s2ga\t", TMC_S2GA);
DRV_REPORT("otpw\t", TMC_DRV_OTPW);
DRV_REPORT("ot\t", TMC_OT);
#if HAS_DRIVER(TMC2208)
#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)
DRV_REPORT("157C\t", TMC_T157);
DRV_REPORT("150C\t", TMC_T150);
DRV_REPORT("143C\t", TMC_T143);
@ -826,7 +845,7 @@
}
}
#endif
#if HAS_DRIVER(TMC2208)
#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209)
static void tmc_get_ic_registers(TMC2208Stepper, const TMC_get_registers_enum) { SERIAL_CHAR('\t'); }
#endif
@ -961,6 +980,15 @@
st.en_pwm_mode(restore_stealth);
st.diag1_stall(false);
}
bool tmc_enable_stallguard(TMC2209Stepper &st) {
st.TCOOLTHRS(0xFFFFF);
return true;
}
void tmc_disable_stallguard(TMC2209Stepper &st, const bool restore_stealth) {
st.TCOOLTHRS(0);
}
bool tmc_enable_stallguard(TMC2660Stepper) {
// TODO
return false;

View File

@ -92,7 +92,7 @@ class TMCStorage {
uint8_t hybrid_thrs = 0;
#endif
#if USE_SENSORLESS
int8_t homing_thrs = 0;
int16_t homing_thrs = 0;
#endif
} stored;
};
@ -100,10 +100,10 @@ class TMCStorage {
template<class TMC, char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
class TMCMarlin : public TMC, public TMCStorage<AXIS_LETTER, DRIVER_ID> {
public:
TMCMarlin(uint16_t cs_pin, float RS) :
TMCMarlin(const uint16_t cs_pin, const float RS) :
TMC(cs_pin, RS)
{}
TMCMarlin(uint16_t CS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK) :
TMCMarlin(const uint16_t CS, const float RS, const uint16_t pinMOSI, const uint16_t pinMISO, const uint16_t pinSCK) :
TMC(CS, RS, pinMOSI, pinMISO, pinSCK)
{}
inline uint16_t rms_current() { return TMC::rms_current(); }
@ -111,7 +111,7 @@ class TMCMarlin : public TMC, public TMCStorage<AXIS_LETTER, DRIVER_ID> {
this->val_mA = mA;
TMC::rms_current(mA);
}
inline void rms_current(uint16_t mA, float mult) {
inline void rms_current(const uint16_t mA, const float mult) {
this->val_mA = mA;
TMC::rms_current(mA, mult);
}
@ -132,8 +132,9 @@ class TMCMarlin : public TMC, public TMCStorage<AXIS_LETTER, DRIVER_ID> {
}
#endif
#if USE_SENSORLESS
inline int8_t sgt() { return TMC::sgt(); }
void sgt(const int8_t sgt_val) {
inline int16_t homing_threshold() { return TMC::sgt(); }
void homing_threshold(int16_t sgt_val) {
sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max);
TMC::sgt(sgt_val);
#if HAS_LCD_MENU
this->stored.homing_thrs = sgt_val;
@ -148,25 +149,28 @@ class TMCMarlin : public TMC, public TMCStorage<AXIS_LETTER, DRIVER_ID> {
inline void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); }
#endif
#if USE_SENSORLESS
inline void refresh_homing_thrs() { sgt(this->stored.homing_thrs); }
inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
#endif
#endif
static constexpr int8_t sgt_min = -64,
sgt_max = 63;
};
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
class TMCMarlin<TMC2208Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC2208Stepper, public TMCStorage<AXIS_LETTER, DRIVER_ID> {
public:
TMCMarlin(Stream * SerialPort, float RS, bool has_rx=true) :
TMC2208Stepper(SerialPort, RS, has_rx=true)
TMCMarlin(Stream * SerialPort, const float RS, const uint8_t) :
TMC2208Stepper(SerialPort, RS, /*has_rx=*/true)
{}
TMCMarlin(uint16_t RX, uint16_t TX, float RS, bool has_rx=true) :
TMC2208Stepper(RX, TX, RS, has_rx=true)
TMCMarlin(const uint16_t RX, const uint16_t TX, const float RS, const uint8_t, const bool has_rx=true) :
TMC2208Stepper(RX, TX, RS, has_rx)
{}
uint16_t rms_current() { return TMC2208Stepper::rms_current(); }
inline void rms_current(uint16_t mA) {
inline void rms_current(const uint16_t mA) {
this->val_mA = mA;
TMC2208Stepper::rms_current(mA);
}
inline void rms_current(uint16_t mA, float mult) {
inline void rms_current(const uint16_t mA, const float mult) {
this->val_mA = mA;
TMC2208Stepper::rms_current(mA, mult);
}
@ -195,24 +199,87 @@ class TMCMarlin<TMC2208Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC220
#endif
#endif
};
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
class TMCMarlin<TMC2209Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC2209Stepper, public TMCStorage<AXIS_LETTER, DRIVER_ID> {
public:
TMCMarlin(Stream * SerialPort, const float RS, const uint8_t addr) :
TMC2209Stepper(SerialPort, RS, addr)
{}
TMCMarlin(const uint16_t RX, const uint16_t TX, const float RS, const uint8_t addr, const bool) :
TMC2209Stepper(RX, TX, RS, addr)
{}
uint8_t get_address() { return slave_address; }
uint16_t rms_current() { return TMC2209Stepper::rms_current(); }
inline void rms_current(const uint16_t mA) {
this->val_mA = mA;
TMC2209Stepper::rms_current(mA);
}
inline void rms_current(const uint16_t mA, const float mult) {
this->val_mA = mA;
TMC2209Stepper::rms_current(mA, mult);
}
#if HAS_STEALTHCHOP
inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); }
inline bool get_stealthChop_status() { return !this->en_spreadCycle(); }
#endif
#if ENABLED(HYBRID_THRESHOLD)
uint32_t get_pwm_thrs() {
return _tmc_thrs(this->microsteps(), this->TPWMTHRS(), planner.settings.axis_steps_per_mm[AXIS_ID]);
}
void set_pwm_thrs(const uint32_t thrs) {
TMC2209Stepper::TPWMTHRS(_tmc_thrs(this->microsteps(), thrs, planner.settings.axis_steps_per_mm[AXIS_ID]));
#if HAS_LCD_MENU
this->stored.hybrid_thrs = thrs;
#endif
}
#endif
#if USE_SENSORLESS
inline int16_t homing_threshold() { return TMC2209Stepper::SGTHRS(); }
void homing_threshold(int16_t sgt_val) {
sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max);
TMC2209Stepper::SGTHRS(sgt_val);
#if HAS_LCD_MENU
this->stored.homing_thrs = sgt_val;
#endif
}
#endif
#if HAS_LCD_MENU
inline void refresh_stepper_current() { rms_current(this->val_mA); }
#if ENABLED(HYBRID_THRESHOLD)
inline void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); }
#endif
#if USE_SENSORLESS
inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
#endif
#endif
static constexpr uint8_t sgt_min = 0,
sgt_max = 255;
};
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
class TMCMarlin<TMC2660Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC2660Stepper, public TMCStorage<AXIS_LETTER, DRIVER_ID> {
public:
TMCMarlin(uint16_t cs_pin, float RS) :
TMCMarlin(const uint16_t cs_pin, const float RS) :
TMC2660Stepper(cs_pin, RS)
{}
TMCMarlin(uint16_t CS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK) :
TMCMarlin(const uint16_t CS, const float RS, const uint16_t pinMOSI, const uint16_t pinMISO, const uint16_t pinSCK) :
TMC2660Stepper(CS, RS, pinMOSI, pinMISO, pinSCK)
{}
inline uint16_t rms_current() { return TMC2660Stepper::rms_current(); }
inline void rms_current(uint16_t mA) {
inline void rms_current(const uint16_t mA) {
this->val_mA = mA;
TMC2660Stepper::rms_current(mA);
}
#if USE_SENSORLESS
inline int8_t sgt() { return TMC2660Stepper::sgt(); }
void sgt(const int8_t sgt_val) {
inline int16_t homing_threshold() { return TMC2660Stepper::sgt(); }
void homing_threshold(int16_t sgt_val) {
sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max);
TMC2660Stepper::sgt(sgt_val);
#if HAS_LCD_MENU
this->stored.homing_thrs = sgt_val;
@ -224,9 +291,12 @@ class TMCMarlin<TMC2660Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC266
inline void refresh_stepper_current() { rms_current(this->val_mA); }
#if USE_SENSORLESS
inline void refresh_homing_thrs() { sgt(this->stored.homing_thrs); }
inline void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); }
#endif
#endif
static constexpr int8_t sgt_min = -64,
sgt_max = 63;
};
template<typename TMC>
@ -262,7 +332,7 @@ void tmc_print_current(TMC &st) {
void tmc_print_sgt(TMC &st) {
st.printLabel();
SERIAL_ECHOPGM(" homing sensitivity: ");
SERIAL_PRINTLN(st.sgt(), DEC);
SERIAL_PRINTLN(st.homing_threshold(), DEC);
}
#endif
@ -293,6 +363,9 @@ void test_tmc_connection(const bool test_x, const bool test_y, const bool test_z
bool tmc_enable_stallguard(TMC2130Stepper &st);
void tmc_disable_stallguard(TMC2130Stepper &st, const bool restore_stealth);
bool tmc_enable_stallguard(TMC2209Stepper &st);
void tmc_disable_stallguard(TMC2209Stepper &st, const bool restore_stealth);
bool tmc_enable_stallguard(TMC2660Stepper);
void tmc_disable_stallguard(TMC2660Stepper, const bool);
#endif