Skip to content

Commit

Permalink
Allow both, SPINDLE_FEATURE and LASER_FEATURE. Stop and restore cutte…
Browse files Browse the repository at this point in the history
…r status during tool change
  • Loading branch information
DerAndere1 committed Jan 4, 2025
1 parent d719c91 commit 171d441
Show file tree
Hide file tree
Showing 16 changed files with 400 additions and 80 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
83 changes: 72 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(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,25 @@ 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 ENABLED(LASER_FEATURE)
if (active_tool_type == TYPE_LASER)
WRITE(LASER_ENA_PIN, enabled() ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE);
#endif
#if ENABLED(SPINDLE_FEATURE)
if (active_tool_type == TYPE_SPINDLE)
WRITE(SPINDLE_LASER_ENA_PIN, enabled() ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE);
#endif
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 +222,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
3 changes: 3 additions & 0 deletions Marlin/src/inc/Conditionals-4-adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,9 @@
//
#if ANY(SPINDLE_FEATURE, LASER_FEATURE)
#define HAS_CUTTER 1
#if ENABLED(LASER_FEATURE)
#define LASER_TOOL EXTRUDERS
#endif
#define _CUTTER_POWER_PWM255 1
#define _CUTTER_POWER_PERCENT 2
#define _CUTTER_POWER_RPM 3
Expand Down
Loading

0 comments on commit 171d441

Please sign in to comment.