✨ MarkForged YX kinematics (#23163)
This commit is contained in:
		
				
					committed by
					
						 Scott Lahteine
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							018c7b1cf4
						
					
				
				
					commit
					0e60c8b7e0
				
			| @@ -756,6 +756,7 @@ | |||||||
| //#define COREZX | //#define COREZX | ||||||
| //#define COREZY | //#define COREZY | ||||||
| //#define MARKFORGED_XY  // MarkForged. See https://reprap.org/forum/read.php?152,504042 | //#define MARKFORGED_XY  // MarkForged. See https://reprap.org/forum/read.php?152,504042 | ||||||
|  | //#define MARKFORGED_YX | ||||||
|  |  | ||||||
| // Enable for a belt style printer with endless "Z" motion | // Enable for a belt style printer with endless "Z" motion | ||||||
| //#define BELTPRINTER | //#define BELTPRINTER | ||||||
|   | |||||||
| @@ -82,7 +82,7 @@ enum AxisEnum : uint8_t { | |||||||
|   #undef _EN_ITEM |   #undef _EN_ITEM | ||||||
|  |  | ||||||
|   // Core also keeps toolhead directions |   // Core also keeps toolhead directions | ||||||
|   #if EITHER(IS_CORE, MARKFORGED_XY) |   #if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     , X_HEAD, Y_HEAD, Z_HEAD |     , X_HEAD, Y_HEAD, Z_HEAD | ||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|   | |||||||
| @@ -60,7 +60,8 @@ void safe_delay(millis_t ms) { | |||||||
|       TERN_(DELTA,         "Delta") |       TERN_(DELTA,         "Delta") | ||||||
|       TERN_(IS_SCARA,      "SCARA") |       TERN_(IS_SCARA,      "SCARA") | ||||||
|       TERN_(IS_CORE,       "Core") |       TERN_(IS_CORE,       "Core") | ||||||
|       TERN_(MARKFORGED_XY, "MarkForged") |       TERN_(MARKFORGED_XY, "MarkForgedXY") | ||||||
|  |       TERN_(MARKFORGED_YX, "MarkForgedYX") | ||||||
|       TERN_(IS_CARTESIAN,  "Cartesian") |       TERN_(IS_CARTESIAN,  "Cartesian") | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -64,7 +64,7 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const | |||||||
|   static axis_bits_t last_direction_bits; |   static axis_bits_t last_direction_bits; | ||||||
|   axis_bits_t changed_dir = last_direction_bits ^ dm; |   axis_bits_t changed_dir = last_direction_bits ^ dm; | ||||||
|   // Ignore direction change unless steps are taken in that direction |   // Ignore direction change unless steps are taken in that direction | ||||||
|   #if DISABLED(CORE_BACKLASH) || ENABLED(MARKFORGED_XY) |   #if DISABLED(CORE_BACKLASH) || EITHER(MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     if (!da) CBI(changed_dir, X_AXIS); |     if (!da) CBI(changed_dir, X_AXIS); | ||||||
|     if (!db) CBI(changed_dir, Y_AXIS); |     if (!db) CBI(changed_dir, Y_AXIS); | ||||||
|     if (!dc) CBI(changed_dir, Z_AXIS); |     if (!dc) CBI(changed_dir, Z_AXIS); | ||||||
|   | |||||||
| @@ -162,7 +162,8 @@ void GcodeSuite::M360() { | |||||||
|     TERN_(DELTA,         "Delta") |     TERN_(DELTA,         "Delta") | ||||||
|     TERN_(IS_SCARA,      "SCARA") |     TERN_(IS_SCARA,      "SCARA") | ||||||
|     TERN_(IS_CORE,       "Core") |     TERN_(IS_CORE,       "Core") | ||||||
|     TERN_(MARKFORGED_XY, "MarkForged") |     TERN_(MARKFORGED_XY, "MarkForgedXY") | ||||||
|  |     TERN_(MARKFORGED_YX, "MarkForgedYX") | ||||||
|     TERN_(IS_CARTESIAN,  "Cartesian") |     TERN_(IS_CARTESIAN,  "Cartesian") | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1079,7 +1079,7 @@ | |||||||
|     #define CORE_AXIS_2 C_AXIS |     #define CORE_AXIS_2 C_AXIS | ||||||
|   #endif |   #endif | ||||||
|   #define CORESIGN(n) (ANY(COREYX, COREZX, COREZY) ? (-(n)) : (n)) |   #define CORESIGN(n) (ANY(COREYX, COREZX, COREZY) ? (-(n)) : (n)) | ||||||
| #elif ENABLED(MARKFORGED_XY) | #elif EITHER(MARKFORGED_XY, MARKFORGED_YX) | ||||||
|   // Markforged kinematics |   // Markforged kinematics | ||||||
|   #define CORE_AXIS_1 A_AXIS |   #define CORE_AXIS_1 A_AXIS | ||||||
|   #define CORE_AXIS_2 B_AXIS |   #define CORE_AXIS_2 B_AXIS | ||||||
|   | |||||||
| @@ -193,7 +193,7 @@ | |||||||
|  |  | ||||||
| // Calibration codes only for non-core axes | // Calibration codes only for non-core axes | ||||||
| #if EITHER(BACKLASH_GCODE, CALIBRATION_GCODE) | #if EITHER(BACKLASH_GCODE, CALIBRATION_GCODE) | ||||||
|   #if EITHER(IS_CORE, MARKFORGED_XY) |   #if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     #define CAN_CALIBRATE(A,B) (_AXIS(A) == B) |     #define CAN_CALIBRATE(A,B) (_AXIS(A) == B) | ||||||
|   #else |   #else | ||||||
|     #define CAN_CALIBRATE(A,B) true |     #define CAN_CALIBRATE(A,B) true | ||||||
|   | |||||||
| @@ -914,7 +914,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | |||||||
| #if ENABLED(BABYSTEPPING) | #if ENABLED(BABYSTEPPING) | ||||||
|   #if ENABLED(SCARA) |   #if ENABLED(SCARA) | ||||||
|     #error "BABYSTEPPING is not implemented for SCARA yet." |     #error "BABYSTEPPING is not implemented for SCARA yet." | ||||||
|   #elif BOTH(MARKFORGED_XY, BABYSTEP_XY) |   #elif ENABLED(BABYSTEP_XY) && EITHER(MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     #error "BABYSTEPPING only implemented for Z axis on MarkForged." |     #error "BABYSTEPPING only implemented for Z axis on MarkForged." | ||||||
|   #elif BOTH(DELTA, BABYSTEP_XY) |   #elif BOTH(DELTA, BABYSTEP_XY) | ||||||
|     #error "BABYSTEPPING only implemented for Z axis on deltabots." |     #error "BABYSTEPPING only implemented for Z axis on deltabots." | ||||||
| @@ -1461,8 +1461,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | |||||||
| /** | /** | ||||||
|  * Allow only one kinematic type to be defined |  * Allow only one kinematic type to be defined | ||||||
|  */ |  */ | ||||||
| #if MANY(DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY, FOAMCUTTER_XYUV) | #if MANY(DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY, MARKFORGED_YX, FOAMCUTTER_XYUV) | ||||||
|   #error "Please enable only one of DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY, or FOAMCUTTER_XYUV." |   #error "Please enable only one of DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY, MARKFORGED_YX, or FOAMCUTTER_XYUV." | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -1960,8 +1960,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | |||||||
| #if ENABLED(DUAL_X_CARRIAGE) | #if ENABLED(DUAL_X_CARRIAGE) | ||||||
|   #if EXTRUDERS < 2 |   #if EXTRUDERS < 2 | ||||||
|     #error "DUAL_X_CARRIAGE requires 2 (or more) extruders." |     #error "DUAL_X_CARRIAGE requires 2 (or more) extruders." | ||||||
|   #elif ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY) |   #elif ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     #error "DUAL_X_CARRIAGE cannot be used with COREXY, COREYX, COREXZ, COREZX, or MARKFORGED_XY." |     #error "DUAL_X_CARRIAGE cannot be used with COREXY, COREYX, COREXZ, COREZX, MARKFORGED_YX, or MARKFORGED_XY." | ||||||
|   #elif !GOOD_AXIS_PINS(X2) |   #elif !GOOD_AXIS_PINS(X2) | ||||||
|     #error "DUAL_X_CARRIAGE requires X2 stepper pins to be defined." |     #error "DUAL_X_CARRIAGE requires X2 stepper pins to be defined." | ||||||
|   #elif !HAS_X_MAX |   #elif !HAS_X_MAX | ||||||
| @@ -3203,8 +3203,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | |||||||
|   #error "CoreXZ requires both X and Z to use sensorless homing if either one does." |   #error "CoreXZ requires both X and Z to use sensorless homing if either one does." | ||||||
| #elif CORE_IS_YZ && Y_SENSORLESS != Z_SENSORLESS && !HOMING_Z_WITH_PROBE | #elif CORE_IS_YZ && Y_SENSORLESS != Z_SENSORLESS && !HOMING_Z_WITH_PROBE | ||||||
|   #error "CoreYZ requires both Y and Z to use sensorless homing if either one does." |   #error "CoreYZ requires both Y and Z to use sensorless homing if either one does." | ||||||
| #elif ENABLED(MARKFORGED_XY) && X_SENSORLESS != Y_SENSORLESS | #elif EITHER(MARKFORGED_XY, MARKFORGED_YX) && X_SENSORLESS != Y_SENSORLESS | ||||||
|   #error "MARKFORGED_XY requires both X and Y to use sensorless homing if either one does." |   #error "MARKFORGED requires both X and Y to use sensorless homing if either one does." | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // Other TMC feature requirements | // Other TMC feature requirements | ||||||
| @@ -3464,7 +3464,7 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive."); | |||||||
|     #error "BACKLASH_COMPENSATION requires BACKLASH_DISTANCE_MM." |     #error "BACKLASH_COMPENSATION requires BACKLASH_DISTANCE_MM." | ||||||
|   #elif !defined(BACKLASH_CORRECTION) |   #elif !defined(BACKLASH_CORRECTION) | ||||||
|     #error "BACKLASH_COMPENSATION requires BACKLASH_CORRECTION." |     #error "BACKLASH_COMPENSATION requires BACKLASH_CORRECTION." | ||||||
|   #elif ENABLED(MARKFORGED_XY) |   #elif EITHER(MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     constexpr float backlash_arr[] = BACKLASH_DISTANCE_MM; |     constexpr float backlash_arr[] = BACKLASH_DISTANCE_MM; | ||||||
|     static_assert(!backlash_arr[CORE_AXIS_1] && !backlash_arr[CORE_AXIS_2], |     static_assert(!backlash_arr[CORE_AXIS_1] && !backlash_arr[CORE_AXIS_2], | ||||||
|                   "BACKLASH_COMPENSATION can only apply to " STRINGIFY(NORMAL_AXIS) " on a MarkForged system."); |                   "BACKLASH_COMPENSATION can only apply to " STRINGIFY(NORMAL_AXIS) " on a MarkForged system."); | ||||||
|   | |||||||
| @@ -38,7 +38,7 @@ void menu_backlash() { | |||||||
|  |  | ||||||
|   EDIT_ITEM_FAST(percent, MSG_BACKLASH_CORRECTION, &backlash.correction, all_off, all_on); |   EDIT_ITEM_FAST(percent, MSG_BACKLASH_CORRECTION, &backlash.correction, all_off, all_on); | ||||||
|  |  | ||||||
|   #if DISABLED(CORE_BACKLASH) || ENABLED(MARKFORGED_XY) |   #if DISABLED(CORE_BACKLASH) || EITHER(MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     #define _CAN_CALI AXIS_CAN_CALIBRATE |     #define _CAN_CALI AXIS_CAN_CALIBRATE | ||||||
|   #else |   #else | ||||||
|     #define _CAN_CALI(A) true |     #define _CAN_CALI(A) true | ||||||
|   | |||||||
| @@ -617,7 +617,7 @@ void Endstops::update() { | |||||||
|   #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX))) |   #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX))) | ||||||
|   #define COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT)) |   #define COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT)) | ||||||
|  |  | ||||||
|   #if ENABLED(G38_PROBE_TARGET) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY) |   #if ENABLED(G38_PROBE_TARGET) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_XY) | ||||||
|     #define HAS_G38_PROBE 1 |     #define HAS_G38_PROBE 1 | ||||||
|     // For G38 moves check the probe's pin for ALL movement |     // For G38 moves check the probe's pin for ALL movement | ||||||
|     if (G38_move) UPDATE_ENDSTOP_BIT(Z, TERN(USES_Z_MIN_PROBE_PIN, MIN_PROBE, MIN)); |     if (G38_move) UPDATE_ENDSTOP_BIT(Z, TERN(USES_Z_MIN_PROBE_PIN, MIN_PROBE, MIN)); | ||||||
| @@ -628,12 +628,12 @@ void Endstops::update() { | |||||||
|   #define X_MAX_TEST() TERN1(DUAL_X_CARRIAGE, TERN0(X_HOME_TO_MAX, stepper.last_moved_extruder == 0) || TERN0(X2_HOME_TO_MAX, stepper.last_moved_extruder != 0)) |   #define X_MAX_TEST() TERN1(DUAL_X_CARRIAGE, TERN0(X_HOME_TO_MAX, stepper.last_moved_extruder == 0) || TERN0(X2_HOME_TO_MAX, stepper.last_moved_extruder != 0)) | ||||||
|  |  | ||||||
|   // Use HEAD for core axes, AXIS for others |   // Use HEAD for core axes, AXIS for others | ||||||
|   #if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY) |   #if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_XY) | ||||||
|     #define X_AXIS_HEAD X_HEAD |     #define X_AXIS_HEAD X_HEAD | ||||||
|   #else |   #else | ||||||
|     #define X_AXIS_HEAD X_AXIS |     #define X_AXIS_HEAD X_AXIS | ||||||
|   #endif |   #endif | ||||||
|   #if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY) |   #if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     #define Y_AXIS_HEAD Y_HEAD |     #define Y_AXIS_HEAD Y_HEAD | ||||||
|   #else |   #else | ||||||
|     #define Y_AXIS_HEAD Y_AXIS |     #define Y_AXIS_HEAD Y_AXIS | ||||||
| @@ -1111,7 +1111,7 @@ void Endstops::update() { | |||||||
|     bool hit = false; |     bool hit = false; | ||||||
|     #if X_SPI_SENSORLESS |     #if X_SPI_SENSORLESS | ||||||
|       if (tmc_spi_homing.x && (stepperX.test_stall_status() |       if (tmc_spi_homing.x && (stepperX.test_stall_status() | ||||||
|         #if ANY(CORE_IS_XY, MARKFORGED_XY) && Y_SPI_SENSORLESS |         #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && Y_SPI_SENSORLESS | ||||||
|           || stepperY.test_stall_status() |           || stepperY.test_stall_status() | ||||||
|         #elif CORE_IS_XZ && Z_SPI_SENSORLESS |         #elif CORE_IS_XZ && Z_SPI_SENSORLESS | ||||||
|           || stepperZ.test_stall_status() |           || stepperZ.test_stall_status() | ||||||
| @@ -1123,7 +1123,7 @@ void Endstops::update() { | |||||||
|     #endif |     #endif | ||||||
|     #if Y_SPI_SENSORLESS |     #if Y_SPI_SENSORLESS | ||||||
|       if (tmc_spi_homing.y && (stepperY.test_stall_status() |       if (tmc_spi_homing.y && (stepperY.test_stall_status() | ||||||
|         #if ANY(CORE_IS_XY, MARKFORGED_XY) && X_SPI_SENSORLESS |         #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && X_SPI_SENSORLESS | ||||||
|           || stepperX.test_stall_status() |           || stepperX.test_stall_status() | ||||||
|         #elif CORE_IS_YZ && Z_SPI_SENSORLESS |         #elif CORE_IS_YZ && Z_SPI_SENSORLESS | ||||||
|           || stepperZ.test_stall_status() |           || stepperZ.test_stall_status() | ||||||
|   | |||||||
| @@ -1367,7 +1367,7 @@ void prepare_line_to_destination() { | |||||||
|             #if AXIS_HAS_STALLGUARD(X2) |             #if AXIS_HAS_STALLGUARD(X2) | ||||||
|               stealth_states.x2 = tmc_enable_stallguard(stepperX2); |               stealth_states.x2 = tmc_enable_stallguard(stepperX2); | ||||||
|             #endif |             #endif | ||||||
|             #if EITHER(CORE_IS_XY, MARKFORGED_XY) && Y_SENSORLESS |             #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && Y_SENSORLESS | ||||||
|               stealth_states.y = tmc_enable_stallguard(stepperY); |               stealth_states.y = tmc_enable_stallguard(stepperY); | ||||||
|             #elif CORE_IS_XZ && Z_SENSORLESS |             #elif CORE_IS_XZ && Z_SENSORLESS | ||||||
|               stealth_states.z = tmc_enable_stallguard(stepperZ); |               stealth_states.z = tmc_enable_stallguard(stepperZ); | ||||||
| @@ -1380,7 +1380,7 @@ void prepare_line_to_destination() { | |||||||
|             #if AXIS_HAS_STALLGUARD(Y2) |             #if AXIS_HAS_STALLGUARD(Y2) | ||||||
|               stealth_states.y2 = tmc_enable_stallguard(stepperY2); |               stealth_states.y2 = tmc_enable_stallguard(stepperY2); | ||||||
|             #endif |             #endif | ||||||
|             #if EITHER(CORE_IS_XY, MARKFORGED_XY) && X_SENSORLESS |             #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && X_SENSORLESS | ||||||
|               stealth_states.x = tmc_enable_stallguard(stepperX); |               stealth_states.x = tmc_enable_stallguard(stepperX); | ||||||
|             #elif CORE_IS_YZ && Z_SENSORLESS |             #elif CORE_IS_YZ && Z_SENSORLESS | ||||||
|               stealth_states.z = tmc_enable_stallguard(stepperZ); |               stealth_states.z = tmc_enable_stallguard(stepperZ); | ||||||
| @@ -1444,7 +1444,7 @@ void prepare_line_to_destination() { | |||||||
|             #if AXIS_HAS_STALLGUARD(X2) |             #if AXIS_HAS_STALLGUARD(X2) | ||||||
|               tmc_disable_stallguard(stepperX2, enable_stealth.x2); |               tmc_disable_stallguard(stepperX2, enable_stealth.x2); | ||||||
|             #endif |             #endif | ||||||
|             #if EITHER(CORE_IS_XY, MARKFORGED_XY) && Y_SENSORLESS |             #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && Y_SENSORLESS | ||||||
|               tmc_disable_stallguard(stepperY, enable_stealth.y); |               tmc_disable_stallguard(stepperY, enable_stealth.y); | ||||||
|             #elif CORE_IS_XZ && Z_SENSORLESS |             #elif CORE_IS_XZ && Z_SENSORLESS | ||||||
|               tmc_disable_stallguard(stepperZ, enable_stealth.z); |               tmc_disable_stallguard(stepperZ, enable_stealth.z); | ||||||
| @@ -1457,7 +1457,7 @@ void prepare_line_to_destination() { | |||||||
|             #if AXIS_HAS_STALLGUARD(Y2) |             #if AXIS_HAS_STALLGUARD(Y2) | ||||||
|               tmc_disable_stallguard(stepperY2, enable_stealth.y2); |               tmc_disable_stallguard(stepperY2, enable_stealth.y2); | ||||||
|             #endif |             #endif | ||||||
|             #if EITHER(CORE_IS_XY, MARKFORGED_XY) && X_SENSORLESS |             #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) && X_SENSORLESS | ||||||
|               tmc_disable_stallguard(stepperX, enable_stealth.x); |               tmc_disable_stallguard(stepperX, enable_stealth.x); | ||||||
|             #elif CORE_IS_YZ && Z_SENSORLESS |             #elif CORE_IS_YZ && Z_SENSORLESS | ||||||
|               tmc_disable_stallguard(stepperZ, enable_stealth.z); |               tmc_disable_stallguard(stepperZ, enable_stealth.z); | ||||||
| @@ -2011,7 +2011,7 @@ void prepare_line_to_destination() { | |||||||
|         do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis)); |         do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis)); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     #else // CARTESIAN / CORE / MARKFORGED_XY |     #else // CARTESIAN / CORE / MARKFORGED_XY / MARKFORGED_YX | ||||||
|  |  | ||||||
|       set_axis_is_at_home(axis); |       set_axis_is_at_home(axis); | ||||||
|       sync_plan_position(); |       sync_plan_position(); | ||||||
| @@ -2041,7 +2041,7 @@ void prepare_line_to_destination() { | |||||||
|         #if ENABLED(SENSORLESS_HOMING) |         #if ENABLED(SENSORLESS_HOMING) | ||||||
|           planner.synchronize(); |           planner.synchronize(); | ||||||
|           if (false |           if (false | ||||||
|             #if EITHER(IS_CORE, MARKFORGED_XY) |             #if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|               || axis != NORMAL_AXIS |               || axis != NORMAL_AXIS | ||||||
|             #endif |             #endif | ||||||
|           ) safe_delay(200);  // Short delay to allow belts to spring back |           ) safe_delay(200);  // Short delay to allow belts to spring back | ||||||
|   | |||||||
| @@ -1743,7 +1743,7 @@ float Planner::get_axis_position_mm(const AxisEnum axis) { | |||||||
|     else |     else | ||||||
|       axis_steps = stepper.position(axis); |       axis_steps = stepper.position(axis); | ||||||
|  |  | ||||||
|   #elif ENABLED(MARKFORGED_XY) |   #elif EITHER(MARKFORGED_XY, MARKFORGED_YX) | ||||||
|  |  | ||||||
|     // Requesting one of the joined axes? |     // Requesting one of the joined axes? | ||||||
|     if (axis == CORE_AXIS_1 || axis == CORE_AXIS_2) { |     if (axis == CORE_AXIS_1 || axis == CORE_AXIS_2) { | ||||||
| @@ -1917,10 +1917,13 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|  |  | ||||||
|   // Compute direction bit-mask for this block |   // Compute direction bit-mask for this block | ||||||
|   axis_bits_t dm = 0; |   axis_bits_t dm = 0; | ||||||
|   #if CORE_IS_XY |   #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     if (da < 0) SBI(dm, X_HEAD);                  // Save the toolhead's true direction in X |     if (da < 0) SBI(dm, X_HEAD);                  // Save the toolhead's true direction in X | ||||||
|     if (db < 0) SBI(dm, Y_HEAD);                  // ...and Y |     if (db < 0) SBI(dm, Y_HEAD);                  // ...and Y | ||||||
|     if (dc < 0) SBI(dm, Z_AXIS); |     if (dc < 0) SBI(dm, Z_AXIS); | ||||||
|  |   #endif | ||||||
|  |   #if IS_CORE | ||||||
|  |     #if CORE_IS_XY | ||||||
|       if (da + db < 0) SBI(dm, A_AXIS);           // Motor A direction |       if (da + db < 0) SBI(dm, A_AXIS);           // Motor A direction | ||||||
|       if (CORESIGN(da - db) < 0) SBI(dm, B_AXIS); // Motor B direction |       if (CORESIGN(da - db) < 0) SBI(dm, B_AXIS); // Motor B direction | ||||||
|     #elif CORE_IS_XZ |     #elif CORE_IS_XZ | ||||||
| @@ -1935,12 +1938,22 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|       if (dc < 0) SBI(dm, Z_HEAD);                // ...and Z |       if (dc < 0) SBI(dm, Z_HEAD);                // ...and Z | ||||||
|       if (db + dc < 0) SBI(dm, B_AXIS);           // Motor B direction |       if (db + dc < 0) SBI(dm, B_AXIS);           // Motor B direction | ||||||
|       if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction |       if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction | ||||||
|  |     #endif | ||||||
|  |     #if LINEAR_AXES >= 4 | ||||||
|  |       if (di < 0) SBI(dm, I_AXIS); | ||||||
|  |     #endif | ||||||
|  |     #if LINEAR_AXES >= 5 | ||||||
|  |       if (dj < 0) SBI(dm, J_AXIS); | ||||||
|  |     #endif | ||||||
|  |     #if LINEAR_AXES >= 6 | ||||||
|  |       if (dk < 0) SBI(dm, K_AXIS); | ||||||
|  |     #endif | ||||||
|   #elif ENABLED(MARKFORGED_XY) |   #elif ENABLED(MARKFORGED_XY) | ||||||
|     if (da < 0) SBI(dm, X_HEAD);                // Save the toolhead's true direction in X |  | ||||||
|     if (db < 0) SBI(dm, Y_HEAD);                // ...and Y |  | ||||||
|     if (dc < 0) SBI(dm, Z_AXIS); |  | ||||||
|     if (da + db < 0) SBI(dm, A_AXIS);              // Motor A direction |     if (da + db < 0) SBI(dm, A_AXIS);              // Motor A direction | ||||||
|     if (db < 0) SBI(dm, B_AXIS);                   // Motor B direction |     if (db < 0) SBI(dm, B_AXIS);                   // Motor B direction | ||||||
|  |   #elif ENABLED(MARKFORGED_YX) | ||||||
|  |     if (da < 0) SBI(dm, A_AXIS);                   // Motor A direction | ||||||
|  |     if (db + da < 0) SBI(dm, B_AXIS);              // Motor B direction | ||||||
|   #else |   #else | ||||||
|     LINEAR_AXIS_CODE( |     LINEAR_AXIS_CODE( | ||||||
|       if (da < 0) SBI(dm, X_AXIS), |       if (da < 0) SBI(dm, X_AXIS), | ||||||
| @@ -1952,21 +1965,8 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|     ); |     ); | ||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|   #if IS_CORE |  | ||||||
|     #if LINEAR_AXES >= 4 |  | ||||||
|       if (di < 0) SBI(dm, I_AXIS); |  | ||||||
|     #endif |  | ||||||
|     #if LINEAR_AXES >= 5 |  | ||||||
|       if (dj < 0) SBI(dm, J_AXIS); |  | ||||||
|     #endif |  | ||||||
|     #if LINEAR_AXES >= 6 |  | ||||||
|       if (dk < 0) SBI(dm, K_AXIS); |  | ||||||
|     #endif |  | ||||||
|   #endif |  | ||||||
|  |  | ||||||
|   TERN_(HAS_EXTRUDERS, if (de < 0) SBI(dm, E_AXIS)); |  | ||||||
|  |  | ||||||
|   #if HAS_EXTRUDERS |   #if HAS_EXTRUDERS | ||||||
|  |     if (de < 0) SBI(dm, E_AXIS); | ||||||
|     const float esteps_float = de * e_factor[extruder]; |     const float esteps_float = de * e_factor[extruder]; | ||||||
|     const uint32_t esteps = ABS(esteps_float) + 0.5f; |     const uint32_t esteps = ABS(esteps_float) + 0.5f; | ||||||
|   #else |   #else | ||||||
| @@ -1996,6 +1996,8 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|     block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db + dc), ABS(db - dc), ABS(di), ABS(dj), ABS(dk))); |     block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db + dc), ABS(db - dc), ABS(di), ABS(dj), ABS(dk))); | ||||||
|   #elif ENABLED(MARKFORGED_XY) |   #elif ENABLED(MARKFORGED_XY) | ||||||
|     block->steps.set(LINEAR_AXIS_LIST(ABS(da + db), ABS(db), ABS(dc), ABS(di), ABS(dj), ABS(dk))); |     block->steps.set(LINEAR_AXIS_LIST(ABS(da + db), ABS(db), ABS(dc), ABS(di), ABS(dj), ABS(dk))); | ||||||
|  |   #elif ENABLED(MARKFORGED_YX) | ||||||
|  |     block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db + da), ABS(dc), ABS(di), ABS(dj), ABS(dk))); | ||||||
|   #elif IS_SCARA |   #elif IS_SCARA | ||||||
|     block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db), ABS(dc), ABS(di), ABS(dj), ABS(dk))); |     block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db), ABS(dc), ABS(di), ABS(dj), ABS(dk))); | ||||||
|   #else |   #else | ||||||
| @@ -2012,15 +2014,18 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|    * Having the real displacement of the head, we can calculate the total movement length and apply the desired speed. |    * Having the real displacement of the head, we can calculate the total movement length and apply the desired speed. | ||||||
|    */ |    */ | ||||||
|   struct DistanceMM : abce_float_t { |   struct DistanceMM : abce_float_t { | ||||||
|     #if EITHER(IS_CORE, MARKFORGED_XY) |     #if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|       struct { float x, y, z; } head; |       struct { float x, y, z; } head; | ||||||
|     #endif |     #endif | ||||||
|   } steps_dist_mm; |   } steps_dist_mm; | ||||||
|   #if IS_CORE |  | ||||||
|     #if CORE_IS_XY |   #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     steps_dist_mm.head.x = da * mm_per_step[A_AXIS]; |     steps_dist_mm.head.x = da * mm_per_step[A_AXIS]; | ||||||
|     steps_dist_mm.head.y = db * mm_per_step[B_AXIS]; |     steps_dist_mm.head.y = db * mm_per_step[B_AXIS]; | ||||||
|     steps_dist_mm.z      = dc * mm_per_step[Z_AXIS]; |     steps_dist_mm.z      = dc * mm_per_step[Z_AXIS]; | ||||||
|  |   #endif | ||||||
|  |   #if IS_CORE | ||||||
|  |     #if CORE_IS_XY | ||||||
|       steps_dist_mm.a      = (da + db) * mm_per_step[A_AXIS]; |       steps_dist_mm.a      = (da + db) * mm_per_step[A_AXIS]; | ||||||
|       steps_dist_mm.b      = CORESIGN(da - db) * mm_per_step[B_AXIS]; |       steps_dist_mm.b      = CORESIGN(da - db) * mm_per_step[B_AXIS]; | ||||||
|     #elif CORE_IS_XZ |     #elif CORE_IS_XZ | ||||||
| @@ -2046,11 +2051,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|       steps_dist_mm.k = dk * mm_per_step[K_AXIS]; |       steps_dist_mm.k = dk * mm_per_step[K_AXIS]; | ||||||
|     #endif |     #endif | ||||||
|   #elif ENABLED(MARKFORGED_XY) |   #elif ENABLED(MARKFORGED_XY) | ||||||
|     steps_dist_mm.head.x = da * mm_per_step[A_AXIS]; |  | ||||||
|     steps_dist_mm.head.y = db * mm_per_step[B_AXIS]; |  | ||||||
|     steps_dist_mm.z      = dc * mm_per_step[Z_AXIS]; |  | ||||||
|     steps_dist_mm.a      = (da - db) * mm_per_step[A_AXIS]; |     steps_dist_mm.a      = (da - db) * mm_per_step[A_AXIS]; | ||||||
|     steps_dist_mm.b      = db * mm_per_step[B_AXIS]; |     steps_dist_mm.b      = db * mm_per_step[B_AXIS]; | ||||||
|  |   #elif ENABLED(MARKFORGED_YX) | ||||||
|  |     steps_dist_mm.a      = da * mm_per_step[A_AXIS]; | ||||||
|  |     steps_dist_mm.b      = (db - da) * mm_per_step[B_AXIS]; | ||||||
|   #else |   #else | ||||||
|     LINEAR_AXIS_CODE( |     LINEAR_AXIS_CODE( | ||||||
|       steps_dist_mm.a = da * mm_per_step[A_AXIS], |       steps_dist_mm.a = da * mm_per_step[A_AXIS], | ||||||
| @@ -2082,7 +2087,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|       block->millimeters = millimeters; |       block->millimeters = millimeters; | ||||||
|     else { |     else { | ||||||
|       block->millimeters = SQRT( |       block->millimeters = SQRT( | ||||||
|         #if EITHER(CORE_IS_XY, MARKFORGED_XY) |         #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|           LINEAR_AXIS_GANG( |           LINEAR_AXIS_GANG( | ||||||
|               sq(steps_dist_mm.head.x), + sq(steps_dist_mm.head.y), + sq(steps_dist_mm.z), |               sq(steps_dist_mm.head.x), + sq(steps_dist_mm.head.y), + sq(steps_dist_mm.z), | ||||||
|             + sq(steps_dist_mm.i),      + sq(steps_dist_mm.j),      + sq(steps_dist_mm.k) |             + sq(steps_dist_mm.i),      + sq(steps_dist_mm.j),      + sq(steps_dist_mm.k) | ||||||
| @@ -2161,7 +2166,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|   // Enable active axes |   // Enable active axes | ||||||
|   #if EITHER(CORE_IS_XY, MARKFORGED_XY) |   #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     if (block->steps.a || block->steps.b) { |     if (block->steps.a || block->steps.b) { | ||||||
|       stepper.enable_axis(X_AXIS); |       stepper.enable_axis(X_AXIS); | ||||||
|       stepper.enable_axis(Y_AXIS); |       stepper.enable_axis(Y_AXIS); | ||||||
| @@ -2191,7 +2196,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|       if (block->steps.k) stepper.enable_axis(K_AXIS) |       if (block->steps.k) stepper.enable_axis(K_AXIS) | ||||||
|     ); |     ); | ||||||
|   #endif |   #endif | ||||||
|   #if EITHER(IS_CORE, MARKFORGED_XY) |   #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     #if LINEAR_AXES >= 4 |     #if LINEAR_AXES >= 4 | ||||||
|       if (block->steps.i) stepper.enable_axis(I_AXIS); |       if (block->steps.i) stepper.enable_axis(I_AXIS); | ||||||
|     #endif |     #endif | ||||||
| @@ -2549,7 +2554,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move, | |||||||
|      * => normalize the complete junction vector. |      * => normalize the complete junction vector. | ||||||
|      * Elsewise, when needed JD will factor-in the E component |      * Elsewise, when needed JD will factor-in the E component | ||||||
|      */ |      */ | ||||||
|     if (EITHER(IS_CORE, MARKFORGED_XY) || esteps > 0) |     if (ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) || esteps > 0) | ||||||
|       normalize_junction_vector(unit_vec);  // Normalize with XYZE components |       normalize_junction_vector(unit_vec);  // Normalize with XYZE components | ||||||
|     else |     else | ||||||
|       unit_vec *= inverse_millimeters;      // Use pre-calculated (1 / SQRT(x^2 + y^2 + z^2)) |       unit_vec *= inverse_millimeters;      // Use pre-calculated (1 / SQRT(x^2 + y^2 + z^2)) | ||||||
|   | |||||||
| @@ -2212,6 +2212,8 @@ uint32_t Stepper::block_phase_isr() { | |||||||
|           #define Y_CMP(A,B) ((A)!=(B)) |           #define Y_CMP(A,B) ((A)!=(B)) | ||||||
|         #endif |         #endif | ||||||
|         #define Y_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Y_CMP(D_(1),D_(2))) ) |         #define Y_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Y_CMP(D_(1),D_(2))) ) | ||||||
|  |       #elif ENABLED(MARKFORGED_YX) | ||||||
|  |         #define Y_MOVE_TEST (current_block->steps.a != current_block->steps.b) | ||||||
|       #else |       #else | ||||||
|         #define Y_MOVE_TEST !!current_block->steps.b |         #define Y_MOVE_TEST !!current_block->steps.b | ||||||
|       #endif |       #endif | ||||||
| @@ -2800,7 +2802,7 @@ void Stepper::init() { | |||||||
|  * derive the current XYZE position later on. |  * derive the current XYZE position later on. | ||||||
|  */ |  */ | ||||||
| void Stepper::_set_position(const abce_long_t &spos) { | void Stepper::_set_position(const abce_long_t &spos) { | ||||||
|   #if EITHER(IS_CORE, MARKFORGED_XY) |   #if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) | ||||||
|     #if CORE_IS_XY |     #if CORE_IS_XY | ||||||
|       // corexy positioning |       // corexy positioning | ||||||
|       // these equations follow the form of the dA and dB equations on https://www.corexy.com/theory.html |       // these equations follow the form of the dA and dB equations on https://www.corexy.com/theory.html | ||||||
| @@ -2813,6 +2815,8 @@ void Stepper::_set_position(const abce_long_t &spos) { | |||||||
|       count_position.set(spos.a, spos.b + spos.c, CORESIGN(spos.b - spos.c)); |       count_position.set(spos.a, spos.b + spos.c, CORESIGN(spos.b - spos.c)); | ||||||
|     #elif ENABLED(MARKFORGED_XY) |     #elif ENABLED(MARKFORGED_XY) | ||||||
|       count_position.set(spos.a - spos.b, spos.b, spos.c); |       count_position.set(spos.a - spos.b, spos.b, spos.c); | ||||||
|  |     #elif ENABLED(MARKFORGED_YX) | ||||||
|  |       count_position.set(spos.a, spos.b - spos.a, spos.c); | ||||||
|     #endif |     #endif | ||||||
|     TERN_(HAS_EXTRUDERS, count_position.e = spos.e); |     TERN_(HAS_EXTRUDERS, count_position.e = spos.e); | ||||||
|   #else |   #else | ||||||
| @@ -2884,6 +2888,10 @@ void Stepper::endstop_triggered(const AxisEnum axis) { | |||||||
|       axis == CORE_AXIS_1 |       axis == CORE_AXIS_1 | ||||||
|         ? count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2] |         ? count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2] | ||||||
|         : count_position[CORE_AXIS_2] |         : count_position[CORE_AXIS_2] | ||||||
|  |     #elif ENABLED(MARKFORGED_YX) | ||||||
|  |       axis == CORE_AXIS_1 | ||||||
|  |         ? count_position[CORE_AXIS_1] | ||||||
|  |         : count_position[CORE_AXIS_2] - count_position[CORE_AXIS_1] | ||||||
|     #else // !IS_CORE |     #else // !IS_CORE | ||||||
|       count_position[axis] |       count_position[axis] | ||||||
|     #endif |     #endif | ||||||
| @@ -2912,10 +2920,10 @@ int32_t Stepper::triggered_position(const AxisEnum axis) { | |||||||
|   return v; |   return v; | ||||||
| } | } | ||||||
|  |  | ||||||
| #if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, IS_SCARA, DELTA) | #if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_YX, IS_SCARA, DELTA) | ||||||
|   #define SAYS_A 1 |   #define SAYS_A 1 | ||||||
| #endif | #endif | ||||||
| #if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY, IS_SCARA, DELTA) | #if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY, MARKFORGED_YX, IS_SCARA, DELTA) | ||||||
|   #define SAYS_B 1 |   #define SAYS_B 1 | ||||||
| #endif | #endif | ||||||
| #if ANY(CORE_IS_XZ, CORE_IS_YZ, DELTA) | #if ANY(CORE_IS_XZ, CORE_IS_YZ, DELTA) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user