* M605: Set dual x-carriage movement mode * * M605 S0 : (FULL_CONTROL) The slicer has full control over both X-carriages and can achieve optimal travel * results as long as it supports dual X-carriages. * * M605 S1 : (AUTO_PARK) The firmware automatically parks and unparks the X-carriages on tool-change so that * additional slicer support is not requir
| 61 | * Note: the X axis should be homed after changing Dual X-carriage mode. |
| 62 | */ |
| 63 | void GcodeSuite::M605() { |
| 64 | planner.synchronize(); |
| 65 | |
| 66 | if (parser.seenval('S')) { |
| 67 | const DualXMode previous_mode = dual_x_carriage_mode; |
| 68 | |
| 69 | dual_x_carriage_mode = (DualXMode)parser.value_byte(); |
| 70 | idex_set_mirrored_mode(false); |
| 71 | |
| 72 | switch (dual_x_carriage_mode) { |
| 73 | |
| 74 | case DXC_FULL_CONTROL_MODE: |
| 75 | case DXC_AUTO_PARK_MODE: |
| 76 | break; |
| 77 | |
| 78 | case DXC_DUPLICATION_MODE: |
| 79 | // Set the X offset, but no less than the safety gap |
| 80 | if (parser.seenval('X')) duplicate_extruder_x_offset = _MAX(parser.value_linear_units(), (X2_MIN_POS) - (X1_MIN_POS)); |
| 81 | if (parser.seenval('R')) duplicate_extruder_temp_offset = parser.value_celsius_diff(); |
| 82 | // Always switch back to tool 0 |
| 83 | if (active_extruder != 0) tool_change(0); |
| 84 | break; |
| 85 | |
| 86 | case DXC_MIRRORED_MODE: { |
| 87 | if (previous_mode != DXC_DUPLICATION_MODE) { |
| 88 | SERIAL_ECHOLNPGM("Printer must be in DXC_DUPLICATION_MODE prior to "); |
| 89 | SERIAL_ECHOLNPGM("specifying DXC_MIRRORED_MODE."); |
| 90 | dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; |
| 91 | return; |
| 92 | } |
| 93 | idex_set_mirrored_mode(true); |
| 94 | |
| 95 | // Do a small 'jog' motion in the X axis |
| 96 | xyze_pos_t dest = current_position; dest.x -= 0.1f; |
| 97 | for (uint8_t i = 2; --i;) { |
| 98 | planner.buffer_line(dest, feedrate_mm_s, 0); |
| 99 | dest.x += 0.1f; |
| 100 | } |
| 101 | } return; |
| 102 | |
| 103 | default: |
| 104 | dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; |
| 105 | break; |
| 106 | } |
| 107 | |
| 108 | idex_set_parked(false); |
| 109 | set_duplication_enabled(false); |
| 110 | |
| 111 | #ifdef EVENT_GCODE_IDEX_AFTER_MODECHANGE |
| 112 | process_subcommands_now(F(EVENT_GCODE_IDEX_AFTER_MODECHANGE)); |
| 113 | #endif |
| 114 | } |
| 115 | else if (!parser.seen('W')) // if no S or W parameter, the DXC mode gets reset to the user's default |
| 116 | dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; |
| 117 | |
| 118 | #if ENABLED(DEBUG_DXC_MODE) |
| 119 | |
| 120 | if (parser.seen('W')) { |
nothing calls this directly
no test coverage detected