Skip to content

Commit

Permalink
TOOLS, G10, TOOL_LENGTH_COMPENSATION (G43, G49), allow all combos of …
Browse files Browse the repository at this point in the history
…HOTENDS, EXTRUDERS, TOOLS, LASER_FEATURE, SPINDLE_FEATURE
  • Loading branch information
DerAndere1 committed Dec 29, 2024
1 parent 4eb8a87 commit 4c0bc3b
Show file tree
Hide file tree
Showing 41 changed files with 859 additions and 168 deletions.
2 changes: 2 additions & 0 deletions Marlin/src/HAL/AVR/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
#include "../ServoTimers.h" // Needed to check timer availability (_useTimer3)
#if SPINDLE_LASER_PWM_PIN == 4 || WITHIN(SPINDLE_LASER_PWM_PIN, 11, 13)
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by a system interrupt."
#elif LASER_PWM_PIN == 4 || WITHIN(LASER_PWM_PIN, 11, 13)
#error "Counter/Timer for LASER_PWM_PIN is used by a system interrupt."
#elif NUM_SERVOS > 0 && defined(_useTimer3) && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5)
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
#endif
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/HAL/LINUX/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
#endif

#if ENABLED(LASER_USE_PWM) && !(LASER_PWM_PIN == 4 || LASER_PWM_PIN == 6 || LASER_PWM_PIN == 11)
#error "LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
#endif

#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
#error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported for HAL/LINUX."
#endif
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/HAL/NATIVE_SIM/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
#endif

#if ENABLED(LASER_USE_PWM) && !(LASER_PWM_PIN == 4 || LASER_PWM_PIN == 6 || LASER_PWM_PIN == 11)
#error "LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
#endif

#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
#error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported for HAL/LINUX."
#endif
Expand Down
10 changes: 10 additions & 0 deletions Marlin/src/core/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,16 @@ enum AxisEnum : uint8_t {
#define LOOP_DISTINCT_AXES(VAR) for (uint8_t VAR = 0; VAR < DISTINCT_AXES; ++VAR)
#define LOOP_DISTINCT_E(VAR) for (uint8_t VAR = 0; VAR < DISTINCT_E; ++VAR)


//
// Enumerates tool types
//
enum ToolTypeEnum : uint8_t {
TYPE_EXTRUDER,
TYPE_LASER,
TYPE_SPINDLE
};

//
// feedRate_t is just a humble float that can represent mm/s or mm/min
//
Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/feature/powerloss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ void PrintJobRecovery::resume() {
#endif

// Restore the previously active tool (with no_move)
#if HAS_MULTI_EXTRUDER || HAS_MULTI_HOTEND
#if HAS_TOOLCHANGE
PROCESS_SUBCOMMANDS_NOW(TS('T', info.active_extruder, 'S'));
#endif

Expand Down Expand Up @@ -652,7 +652,7 @@ void PrintJobRecovery::resume() {
DEBUG_EOL();
#endif

#if HAS_MULTI_EXTRUDER
#if HAS_MULTI_TOOLS
DEBUG_ECHOLNPGM("active_extruder: ", info.active_extruder);
#endif

Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/feature/powerloss.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ typedef struct {
#if HAS_WORKSPACE_OFFSET
xyz_pos_t workspace_offset;
#endif
#if HAS_MULTI_EXTRUDER
#if HAS_MULTI_TOOLS
uint8_t active_extruder;
#endif

Expand Down
79 changes: 68 additions & 11 deletions Marlin/src/feature/spindle_laser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#endif

SpindleLaser cutter;
ToolTypeEnum SpindleLaser::active_tool_type; // Tool type: 0 for extruder, 1 for spindle, 2 for laser
bool SpindleLaser::enable_state; // Virtual enable state, controls enable pin if present and or apply power if > 0
uint8_t SpindleLaser::power, // Actual power output 0-255 ocr or "0 = off" > 0 = "on"
SpindleLaser::last_power_applied; // = 0 // Basic power state tracking
Expand All @@ -65,21 +66,42 @@ cutter_frequency_t SpindleLaser::frequency; // PWM fre
* Init the cutter to a safe OFF state
*/
void SpindleLaser::init() {
#if ENABLED(LASER_FEATURE) && LASER_TOOL == 0
active_tool_type = TYPE_LASER;
#elif ENABLED(SPINDLE_FEATURE) && DISABLED(LASER_FEATURE) && !EXTRUDERS
active_tool_type = TYPE_SPINDLE;
#else
active_tool_type = TYPE_EXTRUDER;
#endif
#if ENABLED(SPINDLE_SERVO)
servo[SPINDLE_SERVO_NR].move(SPINDLE_SERVO_MIN);
#elif PIN_EXISTS(SPINDLE_LASER_ENA)
OUT_WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Init spindle to off
#endif
#if PIN_EXISTS(LASER_ENA)
OUT_WRITE(LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Init laser to off
#endif
#if ENABLED(SPINDLE_CHANGE_DIR)
OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR); // Init rotation to clockwise (M3)
#endif
#if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY
frequency = SPINDLE_LASER_FREQUENCY;
hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY);
#if ENABLED(SPINDLE_FEATURE)
hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY);
#endif
#if ENABLED(LASER_FEATURE)
hal.set_pwm_frequency(pin_t(LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY);
#endif
#endif
#if ENABLED(SPINDLE_LASER_USE_PWM)
SET_PWM(SPINDLE_LASER_PWM_PIN);
hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed
#if ENABLED(SPINDLE_FEATURE)
SET_PWM(SPINDLE_LASER_PWM_PIN);
hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed
#endif
#if ENABLED(LASER_FEATURE)
SET_PWM(SPINDLE_LASER_PWM_PIN);
hal.set_pwm_duty(pin_t(LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed
#endif
#endif
#if ENABLED(AIR_EVACUATION)
OUT_WRITE(AIR_EVACUATION_PIN, !AIR_EVACUATION_ACTIVE); // Init Vacuum/Blower OFF
Expand All @@ -98,21 +120,46 @@ void SpindleLaser::init() {
*/
void SpindleLaser::_set_ocr(const uint8_t ocr) {
#if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY
hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency);
#if ENABLED(LASER_FEATURE)
if (active_tool_type == TYPE_LASER)
hal.set_pwm_frequency(pin_t(LASER_PWM_PIN), frequency);
#endif
#if ENABLED(SPINDLE_FEATURE)
if (active_tool_type != TYPE_LASER)
hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency);
#endif
#endif

#if ENABLED(LASER_FEATURE)
if (active_tool_type == TYPE_LASER)
hal.set_pwm_duty(pin_t(LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
#endif
#if ENABLED(SPINDLE_FEATURE)
if (active_tool_type != TYPE_LASER)
hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
#endif
hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
}

void SpindleLaser::set_ocr(const uint8_t ocr) {
#if PIN_EXISTS(LASER_ENA)
if (active_tool_type == TYPE_LASER)
WRITE(LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_STATE); // Cutter ON
#endif
#if PIN_EXISTS(SPINDLE_LASER_ENA)
WRITE(SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_STATE); // Cutter ON
if (active_tool_type != TYPE_LASER)
WRITE(SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_STATE); // Cutter ON
#endif
_set_ocr(ocr);
}

void SpindleLaser::ocr_off() {
#if PIN_EXISTS(LASER_ENA)
if (active_tool_type == TYPE_LASER)
WRITE(LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Cutter OFF
#endif
#if PIN_EXISTS(SPINDLE_LASER_ENA)
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Cutter OFF
if (active_tool_type == TYPE_SPINDLE)
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Cutter OFF
#endif
_set_ocr(0);
}
Expand Down Expand Up @@ -143,13 +190,21 @@ void SpindleLaser::apply_power(const uint8_t opwr) {
#elif ENABLED(SPINDLE_SERVO)
servo[SPINDLE_SERVO_NR].move(opwr);
#else
WRITE(SPINDLE_LASER_ENA_PIN, enabled() ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE);
if (active_tool_type == TYPE_LASER)
WRITE(LASER_ENA_PIN, enabled() ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE);
else if (active_tool_type == TYPE_SPINDLE)
WRITE(SPINDLE_LASER_ENA_PIN, enabled() ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE);
isReadyForUI = true;
#endif
}
else {
#if PIN_EXISTS(LASER_ENA)
if (active_tool_type == TYPE_LASER)
WRITE(LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE);
#endif
#if PIN_EXISTS(SPINDLE_LASER_ENA)
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE);
if (active_tool_type == TYPE_SPINDLE)
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE);
#endif
isReadyForUI = false; // Only used for UI display updates.
TERN_(SPINDLE_LASER_USE_PWM, ocr_off());
Expand All @@ -163,8 +218,10 @@ void SpindleLaser::apply_power(const uint8_t opwr) {
*/
void SpindleLaser::set_reverse(const bool reverse) {
const bool dir_state = (reverse == SPINDLE_INVERT_DIR); // Forward (M3) HIGH when not inverted
if (TERN0(SPINDLE_STOP_ON_DIR_CHANGE, enabled()) && READ(SPINDLE_DIR_PIN) != dir_state) disable();
WRITE(SPINDLE_DIR_PIN, dir_state);
if (active_tool_type == TYPE_SPINDLE) {
if (TERN0(SPINDLE_STOP_ON_DIR_CHANGE, enabled()) && READ(SPINDLE_DIR_PIN) != dir_state) disable();
WRITE(SPINDLE_DIR_PIN, dir_state);
}
}
#endif

Expand Down
19 changes: 18 additions & 1 deletion Marlin/src/feature/spindle_laser.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

#include "../libs/buzzer.h"

#include "../core/types.h"

// Inline laser power
#include "../module/planner.h"

Expand Down Expand Up @@ -105,6 +107,7 @@ class SpindleLaser {
#endif

static bool isReadyForUI; // Ready to apply power setting from the UI to OCR
static ToolTypeEnum active_tool_type; // Tool type: 0 for extruder, 1 for spindle, 2 for laser
static bool enable_state;
static uint8_t power,
last_power_applied; // Basic power state tracking
Expand All @@ -117,7 +120,18 @@ class SpindleLaser {
static void init();

#if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY
static void refresh_frequency() { hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency); }
static void refresh_frequency() {
#if ENABLED(LASER_FEATURE)
if (active_tool_type == TYPE_LASER) {
hal.set_pwm_frequency(pin_t(LASER_PWM_PIN), frequency);
}
#endif
#if ENABLED(SPINDLE_FEATURE)
if (active_tool_type != TYPE_LASER) {
hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency);
}
#endif
}
#endif

// Modifying this function should update everywhere
Expand Down Expand Up @@ -211,6 +225,9 @@ class SpindleLaser {
enable = false;
apply_power(0);
}
#if PIN_EXISTS(LASER_ENA)
WRITE(LASER_ENA_PIN, enable ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE);
#endif
#if PIN_EXISTS(SPINDLE_LASER_ENA)
WRITE(SPINDLE_LASER_ENA_PIN, enable ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE);
#endif
Expand Down
6 changes: 3 additions & 3 deletions Marlin/src/gcode/calibrate/G28.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#include "../../module/motion.h" // for set/restore_homing_current
#endif

#if HAS_MULTI_HOTEND
#if HAS_TOOLCHANGE
#include "../../module/tool_change.h"
#endif

Expand Down Expand Up @@ -285,7 +285,7 @@ void GcodeSuite::G28() {
#endif

// Always home with tool 0 active
#if HAS_MULTI_HOTEND
#if HAS_TOOLCHANGE
#if DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE)
const uint8_t old_tool_index = active_extruder;
#endif
Expand Down Expand Up @@ -548,7 +548,7 @@ void GcodeSuite::G28() {
TERN_(CAN_SET_LEVELING_AFTER_G28, if (leveling_restore_state) set_bed_leveling_enabled());

// Restore the active tool after homing
#if HAS_MULTI_HOTEND && (DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE))
#if HAS_TOOLCHANGE && (DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE))
tool_change(old_tool_index, TERN(PARKING_EXTRUDER, !pe_final_change_must_unpark, DISABLED(DUAL_X_CARRIAGE))); // Do move if one of these
#endif

Expand Down
15 changes: 8 additions & 7 deletions Marlin/src/gcode/calibrate/G425.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#include "../../module/endstops.h"
#include "../../feature/bedlevel/bedlevel.h"

#if HAS_MULTI_HOTEND
#if HAS_TOOLCHANGE
#include "../../module/tool_change.h"
#endif

Expand Down Expand Up @@ -174,7 +174,7 @@ inline void park_above_object(measurements_t &m, const float uncertainty) {
#if HAS_HOTEND_OFFSET

inline void normalize_hotend_offsets() {
for (uint8_t e = 1; e < HOTENDS; ++e)
for (uint8_t e = 1; e < TOOLS; ++e)
hotend_offset[e] -= hotend_offset[0];
hotend_offset[0].reset();
}
Expand Down Expand Up @@ -617,7 +617,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
// This function requires normalize_hotend_offsets() to be called
//
inline void report_hotend_offsets() {
for (uint8_t e = 1; e < HOTENDS; ++e)
for (uint8_t e = 1; e < TOOLS; ++e)
SERIAL_ECHOLNPGM_P(PSTR("T"), e, PSTR(" Hotend Offset X"), hotend_offset[e].x, SP_Y_STR, hotend_offset[e].y, SP_Z_STR, hotend_offset[e].z);
}
#endif
Expand Down Expand Up @@ -750,7 +750,7 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const
TEMPORARY_BACKLASH_CORRECTION(backlash.all_on);
TEMPORARY_BACKLASH_SMOOTHING(0.0f);

TERN(HAS_MULTI_HOTEND, set_nozzle(m, extruder), UNUSED(extruder));
TERN(HAS_TOOLCHANGE, set_nozzle(m, extruder), UNUSED(extruder));

probe_sides(m, uncertainty);

Expand Down Expand Up @@ -794,7 +794,7 @@ inline void calibrate_all_toolheads(measurements_t &m, const float uncertainty)

TERN_(HAS_HOTEND_OFFSET, normalize_hotend_offsets());

TERN_(HAS_MULTI_HOTEND, set_nozzle(m, 0));
TERN_(HAS_TOOLCHANGE, set_nozzle(m, 0));
}

/**
Expand Down Expand Up @@ -822,8 +822,9 @@ inline void calibrate_all() {
TERN_(BACKLASH_GCODE, calibrate_backlash(m, CALIBRATION_MEASUREMENT_UNCERTAIN));

// Cycle the toolheads so the servos settle into their "natural" positions
#if HAS_MULTI_HOTEND
HOTEND_LOOP() set_nozzle(m, e);
#if HAS_TOOLCHANGE
for (int8_t t = 0; t < TOOLS; t++)
set_nozzle(m, e);
#endif

// Do a slow and precise calibration of the toolheads
Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/gcode/config/M217.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#include "../../inc/MarlinConfigPre.h"

#if HAS_MULTI_EXTRUDER
#if HAS_MULTI_TOOLS

#include "../gcode.h"

Expand Down Expand Up @@ -220,4 +220,4 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
SERIAL_ECHOLNPGM_P(SP_Z_STR, LINEAR_UNIT(toolchange_settings.z_raise));
}

#endif // HAS_MULTI_EXTRUDER
#endif // HAS_MULTI_TOOLS
14 changes: 7 additions & 7 deletions Marlin/src/gcode/config/M218.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,21 @@ void GcodeSuite::M218() {

if (!parser.seen_any()) return M218_report();

const int8_t target_extruder = get_target_extruder_from_command();
if (target_extruder < 0) return;
const int8_t target_tool = get_target_tool_from_command();
if (target_tool < 0) return;

#if HAS_X_AXIS
if (parser.seenval('X')) hotend_offset[target_extruder].x = parser.value_linear_units();
if (parser.seenval('X')) hotend_offset[target_tool].x = parser.value_linear_units();
#endif
#if HAS_Y_AXIS
if (parser.seenval('Y')) hotend_offset[target_extruder].y = parser.value_linear_units();
if (parser.seenval('Y')) hotend_offset[target_tool].y = parser.value_linear_units();
#endif
#if HAS_Z_AXIS
if (parser.seenval('Z')) hotend_offset[target_extruder].z = parser.value_linear_units();
if (parser.seenval('Z')) hotend_offset[target_tool].z = parser.value_linear_units();
#endif

#if ENABLED(DELTA)
if (target_extruder == active_extruder)
if (target_tool == active_extruder)
do_blocking_move_to_xy(current_position, planner.settings.max_feedrate_mm_s[X_AXIS]);
#endif
}
Expand All @@ -66,7 +66,7 @@ void GcodeSuite::M218_report(const bool forReplay/*=true*/) {
TERN_(MARLIN_SMALL_BUILD, return);

report_heading_etc(forReplay, F(STR_HOTEND_OFFSETS));
for (uint8_t e = 1; e < HOTENDS; ++e) {
for (uint8_t e = 1; e < TOOLS; ++e) {
report_echo_start(forReplay);
SERIAL_ECHOLNPGM_P(
PSTR(" M218 T"), e,
Expand Down
Loading

0 comments on commit 4c0bc3b

Please sign in to comment.