✨ Support for up to 9 axes (linear, rotary) (#23112)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
@@ -179,10 +179,10 @@
|
||||
|
||||
#define _EN_ITEM(N) , E##N
|
||||
|
||||
typedef struct { uint16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_stepper_current_t;
|
||||
typedef struct { uint32_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_hybrid_threshold_t;
|
||||
typedef struct { int16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4; } tmc_sgt_t;
|
||||
typedef struct { bool LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_stealth_enabled_t;
|
||||
typedef struct { uint16_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_stepper_current_t;
|
||||
typedef struct { uint32_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_hybrid_threshold_t;
|
||||
typedef struct { int16_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4; } tmc_sgt_t;
|
||||
typedef struct { bool NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_stealth_enabled_t;
|
||||
|
||||
#undef _EN_ITEM
|
||||
|
||||
@@ -210,7 +210,7 @@ typedef struct SettingsDataStruct {
|
||||
//
|
||||
// DISTINCT_E_FACTORS
|
||||
//
|
||||
uint8_t e_factors; // DISTINCT_AXES - LINEAR_AXES
|
||||
uint8_t e_factors; // DISTINCT_AXES - NUM_AXES
|
||||
|
||||
//
|
||||
// Planner settings
|
||||
@@ -444,7 +444,7 @@ typedef struct SettingsDataStruct {
|
||||
// HAS_MOTOR_CURRENT_PWM
|
||||
//
|
||||
#ifndef MOTOR_CURRENT_COUNT
|
||||
#define MOTOR_CURRENT_COUNT LINEAR_AXES
|
||||
#define MOTOR_CURRENT_COUNT NUM_AXES
|
||||
#endif
|
||||
uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]; // M907 X Z E ...
|
||||
|
||||
@@ -590,7 +590,7 @@ void MarlinSettings::postprocess() {
|
||||
#endif
|
||||
|
||||
// Software endstops depend on home_offset
|
||||
LOOP_LINEAR_AXES(i) {
|
||||
LOOP_NUM_AXES(i) {
|
||||
update_workspace_offset((AxisEnum)i);
|
||||
update_software_endstops((AxisEnum)i);
|
||||
}
|
||||
@@ -738,7 +738,7 @@ void MarlinSettings::postprocess() {
|
||||
|
||||
working_crc = 0; // clear before first "real data"
|
||||
|
||||
const uint8_t e_factors = DISTINCT_AXES - (LINEAR_AXES);
|
||||
const uint8_t e_factors = DISTINCT_AXES - (NUM_AXES);
|
||||
_FIELD_TEST(e_factors);
|
||||
EEPROM_WRITE(e_factors);
|
||||
|
||||
@@ -755,7 +755,7 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_WRITE(dummyf);
|
||||
#endif
|
||||
#else
|
||||
const xyze_pos_t planner_max_jerk = LOGICAL_AXIS_ARRAY(float(DEFAULT_EJERK), 10, 10, 0.4, 0.4, 0.4, 0.4);
|
||||
const xyze_pos_t planner_max_jerk = LOGICAL_AXIS_ARRAY(float(DEFAULT_EJERK), 10, 10, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4);
|
||||
EEPROM_WRITE(planner_max_jerk);
|
||||
#endif
|
||||
|
||||
@@ -1234,6 +1234,15 @@ void MarlinSettings::postprocess() {
|
||||
#if AXIS_IS_TMC(K)
|
||||
tmc_stepper_current.K = stepperK.getMilliamps();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(U)
|
||||
tmc_stepper_current.U = stepperU.getMilliamps();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(V)
|
||||
tmc_stepper_current.V = stepperV.getMilliamps();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(W)
|
||||
tmc_stepper_current.W = stepperW.getMilliamps();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(X2)
|
||||
tmc_stepper_current.X2 = stepperX2.getMilliamps();
|
||||
#endif
|
||||
@@ -1291,6 +1300,9 @@ void MarlinSettings::postprocess() {
|
||||
TERN_(I_HAS_STEALTHCHOP, tmc_hybrid_threshold.I = stepperI.get_pwm_thrs());
|
||||
TERN_(J_HAS_STEALTHCHOP, tmc_hybrid_threshold.J = stepperJ.get_pwm_thrs());
|
||||
TERN_(K_HAS_STEALTHCHOP, tmc_hybrid_threshold.K = stepperK.get_pwm_thrs());
|
||||
TERN_(U_HAS_STEALTHCHOP, tmc_hybrid_threshold.U = stepperU.get_pwm_thrs());
|
||||
TERN_(V_HAS_STEALTHCHOP, tmc_hybrid_threshold.V = stepperV.get_pwm_thrs());
|
||||
TERN_(W_HAS_STEALTHCHOP, tmc_hybrid_threshold.W = stepperW.get_pwm_thrs());
|
||||
TERN_(X2_HAS_STEALTHCHOP, tmc_hybrid_threshold.X2 = stepperX2.get_pwm_thrs());
|
||||
TERN_(Y2_HAS_STEALTHCHOP, tmc_hybrid_threshold.Y2 = stepperY2.get_pwm_thrs());
|
||||
TERN_(Z2_HAS_STEALTHCHOP, tmc_hybrid_threshold.Z2 = stepperZ2.get_pwm_thrs());
|
||||
@@ -1307,7 +1319,7 @@ void MarlinSettings::postprocess() {
|
||||
#else
|
||||
#define _EN_ITEM(N) , .E##N = 30
|
||||
const tmc_hybrid_threshold_t tmc_hybrid_threshold = {
|
||||
LINEAR_AXIS_LIST(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3),
|
||||
NUM_AXIS_LIST(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3, .U = 3, .V = 3, .W = 3),
|
||||
.X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3, .Z4 = 3
|
||||
REPEAT(E_STEPPERS, _EN_ITEM)
|
||||
};
|
||||
@@ -1322,13 +1334,16 @@ void MarlinSettings::postprocess() {
|
||||
{
|
||||
tmc_sgt_t tmc_sgt{0};
|
||||
#if USE_SENSORLESS
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
TERN_(X_SENSORLESS, tmc_sgt.X = stepperX.homing_threshold()),
|
||||
TERN_(Y_SENSORLESS, tmc_sgt.Y = stepperY.homing_threshold()),
|
||||
TERN_(Z_SENSORLESS, tmc_sgt.Z = stepperZ.homing_threshold()),
|
||||
TERN_(I_SENSORLESS, tmc_sgt.I = stepperI.homing_threshold()),
|
||||
TERN_(J_SENSORLESS, tmc_sgt.J = stepperJ.homing_threshold()),
|
||||
TERN_(K_SENSORLESS, tmc_sgt.K = stepperK.homing_threshold())
|
||||
TERN_(K_SENSORLESS, tmc_sgt.K = stepperK.homing_threshold()),
|
||||
TERN_(U_SENSORLESS, tmc_sgt.U = stepperU.homing_threshold()),
|
||||
TERN_(V_SENSORLESS, tmc_sgt.V = stepperV.homing_threshold()),
|
||||
TERN_(W_SENSORLESS, tmc_sgt.W = stepperW.homing_threshold())
|
||||
);
|
||||
TERN_(X2_SENSORLESS, tmc_sgt.X2 = stepperX2.homing_threshold());
|
||||
TERN_(Y2_SENSORLESS, tmc_sgt.Y2 = stepperY2.homing_threshold());
|
||||
@@ -1352,6 +1367,9 @@ void MarlinSettings::postprocess() {
|
||||
TERN_(I_HAS_STEALTHCHOP, tmc_stealth_enabled.I = stepperI.get_stored_stealthChop());
|
||||
TERN_(J_HAS_STEALTHCHOP, tmc_stealth_enabled.J = stepperJ.get_stored_stealthChop());
|
||||
TERN_(K_HAS_STEALTHCHOP, tmc_stealth_enabled.K = stepperK.get_stored_stealthChop());
|
||||
TERN_(U_HAS_STEALTHCHOP, tmc_stealth_enabled.U = stepperU.get_stored_stealthChop());
|
||||
TERN_(V_HAS_STEALTHCHOP, tmc_stealth_enabled.V = stepperV.get_stored_stealthChop());
|
||||
TERN_(W_HAS_STEALTHCHOP, tmc_stealth_enabled.W = stepperW.get_stored_stealthChop());
|
||||
TERN_(X2_HAS_STEALTHCHOP, tmc_stealth_enabled.X2 = stepperX2.get_stored_stealthChop());
|
||||
TERN_(Y2_HAS_STEALTHCHOP, tmc_stealth_enabled.Y2 = stepperY2.get_stored_stealthChop());
|
||||
TERN_(Z2_HAS_STEALTHCHOP, tmc_stealth_enabled.Z2 = stepperZ2.get_stored_stealthChop());
|
||||
@@ -1441,7 +1459,7 @@ void MarlinSettings::postprocess() {
|
||||
{
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
xyz_float_t backlash_distance_mm;
|
||||
LOOP_LINEAR_AXES(axis) backlash_distance_mm[axis] = backlash.get_distance_mm((AxisEnum)axis);
|
||||
LOOP_NUM_AXES(axis) backlash_distance_mm[axis] = backlash.get_distance_mm((AxisEnum)axis);
|
||||
const uint8_t backlash_correction = backlash.get_correction_uint8();
|
||||
#else
|
||||
const xyz_float_t backlash_distance_mm{0};
|
||||
@@ -1653,16 +1671,16 @@ void MarlinSettings::postprocess() {
|
||||
{
|
||||
// Get only the number of E stepper parameters previously stored
|
||||
// Any steppers added later are set to their defaults
|
||||
uint32_t tmp1[LINEAR_AXES + e_factors];
|
||||
float tmp2[LINEAR_AXES + e_factors];
|
||||
feedRate_t tmp3[LINEAR_AXES + e_factors];
|
||||
uint32_t tmp1[NUM_AXES + e_factors];
|
||||
float tmp2[NUM_AXES + e_factors];
|
||||
feedRate_t tmp3[NUM_AXES + e_factors];
|
||||
EEPROM_READ((uint8_t *)tmp1, sizeof(tmp1)); // max_acceleration_mm_per_s2
|
||||
EEPROM_READ(planner.settings.min_segment_time_us);
|
||||
EEPROM_READ((uint8_t *)tmp2, sizeof(tmp2)); // axis_steps_per_mm
|
||||
EEPROM_READ((uint8_t *)tmp3, sizeof(tmp3)); // max_feedrate_mm_s
|
||||
|
||||
if (!validating) LOOP_DISTINCT_AXES(i) {
|
||||
const bool in = (i < e_factors + LINEAR_AXES);
|
||||
const bool in = (i < e_factors + NUM_AXES);
|
||||
planner.settings.max_acceleration_mm_per_s2[i] = in ? tmp1[i] : pgm_read_dword(&_DMA[ALIM(i, _DMA)]);
|
||||
planner.settings.axis_steps_per_mm[i] = in ? tmp2[i] : pgm_read_float(&_DASU[ALIM(i, _DASU)]);
|
||||
planner.settings.max_feedrate_mm_s[i] = in ? tmp3[i] : pgm_read_float(&_DMF[ALIM(i, _DMF)]);
|
||||
@@ -2175,6 +2193,15 @@ void MarlinSettings::postprocess() {
|
||||
#if AXIS_IS_TMC(K)
|
||||
SET_CURR(K);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(U)
|
||||
SET_CURR(U);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(V)
|
||||
SET_CURR(V);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(W)
|
||||
SET_CURR(W);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E0)
|
||||
SET_CURR(E0);
|
||||
#endif
|
||||
@@ -2222,6 +2249,9 @@ void MarlinSettings::postprocess() {
|
||||
TERN_(I_HAS_STEALTHCHOP, stepperI.set_pwm_thrs(tmc_hybrid_threshold.I));
|
||||
TERN_(J_HAS_STEALTHCHOP, stepperJ.set_pwm_thrs(tmc_hybrid_threshold.J));
|
||||
TERN_(K_HAS_STEALTHCHOP, stepperK.set_pwm_thrs(tmc_hybrid_threshold.K));
|
||||
TERN_(U_HAS_STEALTHCHOP, stepperU.set_pwm_thrs(tmc_hybrid_threshold.U));
|
||||
TERN_(V_HAS_STEALTHCHOP, stepperV.set_pwm_thrs(tmc_hybrid_threshold.V));
|
||||
TERN_(W_HAS_STEALTHCHOP, stepperW.set_pwm_thrs(tmc_hybrid_threshold.W));
|
||||
TERN_(E0_HAS_STEALTHCHOP, stepperE0.set_pwm_thrs(tmc_hybrid_threshold.E0));
|
||||
TERN_(E1_HAS_STEALTHCHOP, stepperE1.set_pwm_thrs(tmc_hybrid_threshold.E1));
|
||||
TERN_(E2_HAS_STEALTHCHOP, stepperE2.set_pwm_thrs(tmc_hybrid_threshold.E2));
|
||||
@@ -2243,13 +2273,16 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_READ(tmc_sgt);
|
||||
#if USE_SENSORLESS
|
||||
if (!validating) {
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
TERN_(X_SENSORLESS, stepperX.homing_threshold(tmc_sgt.X)),
|
||||
TERN_(Y_SENSORLESS, stepperY.homing_threshold(tmc_sgt.Y)),
|
||||
TERN_(Z_SENSORLESS, stepperZ.homing_threshold(tmc_sgt.Z)),
|
||||
TERN_(I_SENSORLESS, stepperI.homing_threshold(tmc_sgt.I)),
|
||||
TERN_(J_SENSORLESS, stepperJ.homing_threshold(tmc_sgt.J)),
|
||||
TERN_(K_SENSORLESS, stepperK.homing_threshold(tmc_sgt.K))
|
||||
TERN_(K_SENSORLESS, stepperK.homing_threshold(tmc_sgt.K)),
|
||||
TERN_(U_SENSORLESS, stepperU.homing_threshold(tmc_sgt.U)),
|
||||
TERN_(V_SENSORLESS, stepperV.homing_threshold(tmc_sgt.V)),
|
||||
TERN_(W_SENSORLESS, stepperW.homing_threshold(tmc_sgt.W))
|
||||
);
|
||||
TERN_(X2_SENSORLESS, stepperX2.homing_threshold(tmc_sgt.X2));
|
||||
TERN_(Y2_SENSORLESS, stepperY2.homing_threshold(tmc_sgt.Y2));
|
||||
@@ -2277,6 +2310,9 @@ void MarlinSettings::postprocess() {
|
||||
TERN_(I_HAS_STEALTHCHOP, SET_STEPPING_MODE(I));
|
||||
TERN_(J_HAS_STEALTHCHOP, SET_STEPPING_MODE(J));
|
||||
TERN_(K_HAS_STEALTHCHOP, SET_STEPPING_MODE(K));
|
||||
TERN_(U_HAS_STEALTHCHOP, SET_STEPPING_MODE(U));
|
||||
TERN_(V_HAS_STEALTHCHOP, SET_STEPPING_MODE(V));
|
||||
TERN_(W_HAS_STEALTHCHOP, SET_STEPPING_MODE(W));
|
||||
TERN_(X2_HAS_STEALTHCHOP, SET_STEPPING_MODE(X2));
|
||||
TERN_(Y2_HAS_STEALTHCHOP, SET_STEPPING_MODE(Y2));
|
||||
TERN_(Z2_HAS_STEALTHCHOP, SET_STEPPING_MODE(Z2));
|
||||
@@ -2397,7 +2433,7 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_READ(backlash_smoothing_mm);
|
||||
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
LOOP_LINEAR_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, backlash_distance_mm[axis]);
|
||||
LOOP_NUM_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, backlash_distance_mm[axis]);
|
||||
backlash.set_correction_uint8(backlash_correction);
|
||||
#ifdef BACKLASH_SMOOTHING_MM
|
||||
backlash.set_smoothing_mm(backlash_smoothing_mm);
|
||||
@@ -2773,8 +2809,17 @@ void MarlinSettings::reset() {
|
||||
#if HAS_K_AXIS && !defined(DEFAULT_KJERK)
|
||||
#define DEFAULT_KJERK 0
|
||||
#endif
|
||||
#if HAS_U_AXIS && !defined(DEFAULT_UJERK)
|
||||
#define DEFAULT_UJERK 0
|
||||
#endif
|
||||
#if HAS_V_AXIS && !defined(DEFAULT_VJERK)
|
||||
#define DEFAULT_VJERK 0
|
||||
#endif
|
||||
#if HAS_W_AXIS && !defined(DEFAULT_WJERK)
|
||||
#define DEFAULT_WJERK 0
|
||||
#endif
|
||||
planner.max_jerk.set(
|
||||
LINEAR_AXIS_LIST(DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK, DEFAULT_IJERK, DEFAULT_JJERK, DEFAULT_KJERK)
|
||||
NUM_AXIS_LIST(DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK, DEFAULT_IJERK, DEFAULT_JJERK, DEFAULT_KJERK, DEFAULT_UJERK, DEFAULT_VJERK, DEFAULT_WJERK)
|
||||
);
|
||||
TERN_(HAS_CLASSIC_E_JERK, planner.max_jerk.e = DEFAULT_EJERK);
|
||||
#endif
|
||||
@@ -2836,7 +2881,7 @@ void MarlinSettings::reset() {
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
backlash.set_correction(BACKLASH_CORRECTION);
|
||||
constexpr xyz_float_t tmp = BACKLASH_DISTANCE_MM;
|
||||
LOOP_LINEAR_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, tmp[axis]);
|
||||
LOOP_NUM_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, tmp[axis]);
|
||||
#ifdef BACKLASH_SMOOTHING_MM
|
||||
backlash.set_smoothing_mm(BACKLASH_SMOOTHING_MM);
|
||||
#endif
|
||||
@@ -2881,11 +2926,11 @@ void MarlinSettings::reset() {
|
||||
//
|
||||
#if HAS_BED_PROBE
|
||||
constexpr float dpo[] = NOZZLE_TO_PROBE_OFFSET;
|
||||
static_assert(COUNT(dpo) == LINEAR_AXES, "NOZZLE_TO_PROBE_OFFSET must contain offsets for each linear axis X, Y, Z....");
|
||||
static_assert(COUNT(dpo) == NUM_AXES, "NOZZLE_TO_PROBE_OFFSET must contain offsets for each linear axis X, Y, Z....");
|
||||
#if HAS_PROBE_XY_OFFSET
|
||||
LOOP_LINEAR_AXES(a) probe.offset[a] = dpo[a];
|
||||
LOOP_NUM_AXES(a) probe.offset[a] = dpo[a];
|
||||
#else
|
||||
probe.offset.set(LINEAR_AXIS_LIST(0, 0, dpo[Z_AXIS], 0, 0, 0));
|
||||
probe.offset.set(NUM_AXIS_LIST(0, 0, dpo[Z_AXIS], 0, 0, 0, 0, 0, 0));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user