Improvements for Laser / Spindle (#17661)
This commit is contained in:
@ -129,7 +129,7 @@ uint8_t Planner::delay_before_delivering; // This counter delays delivery
|
||||
planner_settings_t Planner::settings; // Initialized by settings.load()
|
||||
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
laser_state_t Planner::laser; // Current state for blocks
|
||||
laser_state_t Planner::laser_inline; // Current state for blocks
|
||||
#endif
|
||||
|
||||
uint32_t Planner::max_acceleration_steps_per_s2[XYZE_N]; // (steps/s^2) Derived from mm_per_s2
|
||||
@ -1693,7 +1693,7 @@ bool Planner::_buffer_steps(const xyze_long_t &target
|
||||
* fr_mm_s - (target) speed of the move
|
||||
* extruder - target extruder
|
||||
*
|
||||
* Returns true is movement is acceptable, false otherwise
|
||||
* Returns true if movement is acceptable, false otherwise
|
||||
*/
|
||||
bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
const abce_long_t &target
|
||||
@ -1803,8 +1803,8 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
|
||||
// Update block laser power
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
block->laser.status = laser.status;
|
||||
block->laser.power = laser.power;
|
||||
block->laser.status = laser_inline.status;
|
||||
block->laser.power = laser_inline.power;
|
||||
#endif
|
||||
|
||||
// Number of steps for each axis
|
||||
|
@ -117,8 +117,15 @@ enum BlockFlag : char {
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
|
||||
typedef struct {
|
||||
uint8_t status, // See planner settings for meaning
|
||||
power; // Ditto; When in trapezoid mode this is nominal power
|
||||
bool isPlanned:1;
|
||||
bool isEnabled:1;
|
||||
bool dir:1;
|
||||
bool Reserved:6;
|
||||
} power_status_t;
|
||||
|
||||
typedef struct {
|
||||
power_status_t status; // See planner settings for meaning
|
||||
uint8_t power; // Ditto; When in trapezoid mode this is nominal power
|
||||
#if ENABLED(LASER_POWER_INLINE_TRAPEZOID)
|
||||
uint8_t power_entry; // Entry power for the laser
|
||||
#if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT)
|
||||
@ -234,18 +241,15 @@ typedef struct block_t {
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
typedef struct {
|
||||
/**
|
||||
* Laser status bitmask; most bits are unused;
|
||||
* 0: Planner buffer enable
|
||||
* 1: Laser enable
|
||||
* 2: Reserved for direction
|
||||
* Laser status flags
|
||||
*/
|
||||
uint8_t status;
|
||||
power_status_t status;
|
||||
/**
|
||||
* Laser power: 0 or 255 in case of PWM-less laser,
|
||||
* or the OCR value;
|
||||
* or the OCR (oscillator count register) value;
|
||||
*
|
||||
* Using OCR instead of raw power,
|
||||
* as it avoids floating points during move loop
|
||||
* Using OCR instead of raw power, because it avoids
|
||||
* floating point operations during the move loop.
|
||||
*/
|
||||
uint8_t power;
|
||||
} laser_state_t;
|
||||
@ -332,7 +336,7 @@ class Planner {
|
||||
static planner_settings_t settings;
|
||||
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
static laser_state_t laser;
|
||||
static laser_state_t laser_inline;
|
||||
#endif
|
||||
|
||||
static uint32_t max_acceleration_steps_per_s2[XYZE_N]; // (steps/s^2) Derived from mm_per_s2
|
||||
|
@ -244,8 +244,8 @@ xyze_long_t Stepper::count_position{0};
|
||||
xyze_int8_t Stepper::count_direction{0};
|
||||
|
||||
#if ENABLED(LASER_POWER_INLINE_TRAPEZOID)
|
||||
Stepper::stepper_laser_t Stepper::laser = {
|
||||
.trap_en = false,
|
||||
Stepper::stepper_laser_t Stepper::laser_trap = {
|
||||
.enabled = false,
|
||||
.cur_power = 0,
|
||||
.cruise_set = false,
|
||||
#if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT)
|
||||
@ -1843,28 +1843,28 @@ uint32_t Stepper::block_phase_isr() {
|
||||
|
||||
// Update laser - Accelerating
|
||||
#if ENABLED(LASER_POWER_INLINE_TRAPEZOID)
|
||||
if (laser.trap_en) {
|
||||
if (laser_trap.enabled) {
|
||||
#if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT)
|
||||
if (current_block->laser.entry_per) {
|
||||
laser.acc_step_count -= step_events_completed - laser.last_step_count;
|
||||
laser.last_step_count = step_events_completed;
|
||||
laser_trap.acc_step_count -= step_events_completed - laser_trap.last_step_count;
|
||||
laser_trap.last_step_count = step_events_completed;
|
||||
|
||||
// Should be faster than a divide, since this should trip just once
|
||||
if (laser.acc_step_count < 0) {
|
||||
while (laser.acc_step_count < 0) {
|
||||
laser.acc_step_count += current_block->laser.entry_per;
|
||||
if (laser.cur_power < current_block->laser.power) laser.cur_power++;
|
||||
if (laser_trap.acc_step_count < 0) {
|
||||
while (laser_trap.acc_step_count < 0) {
|
||||
laser_trap.acc_step_count += current_block->laser.entry_per;
|
||||
if (laser_trap.cur_power < current_block->laser.power) laser_trap.cur_power++;
|
||||
}
|
||||
cutter.set_ocr_power(laser.cur_power);
|
||||
cutter.set_ocr_power(laser_trap.cur_power);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (laser.till_update)
|
||||
laser.till_update--;
|
||||
if (laser_trap.till_update)
|
||||
laser_trap.till_update--;
|
||||
else {
|
||||
laser.till_update = LASER_POWER_INLINE_TRAPEZOID_CONT_PER;
|
||||
laser.cur_power = (current_block->laser.power * acc_step_rate) / current_block->nominal_rate;
|
||||
cutter.set_ocr_power(laser.cur_power); // Cycle efficiency is irrelevant it the last line was many cycles
|
||||
laser_trap.till_update = LASER_POWER_INLINE_TRAPEZOID_CONT_PER;
|
||||
laser_trap.cur_power = (current_block->laser.power * acc_step_rate) / current_block->nominal_rate;
|
||||
cutter.set_ocr_power(laser_trap.cur_power); // Cycle efficiency is irrelevant it the last line was many cycles
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1920,28 +1920,28 @@ uint32_t Stepper::block_phase_isr() {
|
||||
|
||||
// Update laser - Decelerating
|
||||
#if ENABLED(LASER_POWER_INLINE_TRAPEZOID)
|
||||
if (laser.trap_en) {
|
||||
if (laser_trap.enabled) {
|
||||
#if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT)
|
||||
if (current_block->laser.exit_per) {
|
||||
laser.acc_step_count -= step_events_completed - laser.last_step_count;
|
||||
laser.last_step_count = step_events_completed;
|
||||
laser_trap.acc_step_count -= step_events_completed - laser_trap.last_step_count;
|
||||
laser_trap.last_step_count = step_events_completed;
|
||||
|
||||
// Should be faster than a divide, since this should trip just once
|
||||
if (laser.acc_step_count < 0) {
|
||||
while (laser.acc_step_count < 0) {
|
||||
laser.acc_step_count += current_block->laser.exit_per;
|
||||
if (laser.cur_power > current_block->laser.power_exit) laser.cur_power--;
|
||||
if (laser_trap.acc_step_count < 0) {
|
||||
while (laser_trap.acc_step_count < 0) {
|
||||
laser_trap.acc_step_count += current_block->laser.exit_per;
|
||||
if (laser_trap.cur_power > current_block->laser.power_exit) laser_trap.cur_power--;
|
||||
}
|
||||
cutter.set_ocr_power(laser.cur_power);
|
||||
cutter.set_ocr_power(laser_trap.cur_power);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (laser.till_update)
|
||||
laser.till_update--;
|
||||
if (laser_trap.till_update)
|
||||
laser_trap.till_update--;
|
||||
else {
|
||||
laser.till_update = LASER_POWER_INLINE_TRAPEZOID_CONT_PER;
|
||||
laser.cur_power = (current_block->laser.power * step_rate) / current_block->nominal_rate;
|
||||
cutter.set_ocr_power(laser.cur_power); // Cycle efficiency isn't relevant when the last line was many cycles
|
||||
laser_trap.till_update = LASER_POWER_INLINE_TRAPEZOID_CONT_PER;
|
||||
laser_trap.cur_power = (current_block->laser.power * step_rate) / current_block->nominal_rate;
|
||||
cutter.set_ocr_power(laser_trap.cur_power); // Cycle efficiency isn't relevant when the last line was many cycles
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1966,16 +1966,16 @@ uint32_t Stepper::block_phase_isr() {
|
||||
|
||||
// Update laser - Cruising
|
||||
#if ENABLED(LASER_POWER_INLINE_TRAPEZOID)
|
||||
if (laser.trap_en) {
|
||||
if (!laser.cruise_set) {
|
||||
laser.cur_power = current_block->laser.power;
|
||||
cutter.set_ocr_power(laser.cur_power);
|
||||
laser.cruise_set = true;
|
||||
if (laser_trap.enabled) {
|
||||
if (!laser_trap.cruise_set) {
|
||||
laser_trap.cur_power = current_block->laser.power;
|
||||
cutter.set_ocr_power(laser_trap.cur_power);
|
||||
laser_trap.cruise_set = true;
|
||||
}
|
||||
#if ENABLED(LASER_POWER_INLINE_TRAPEZOID_CONT)
|
||||
laser.till_update = LASER_POWER_INLINE_TRAPEZOID_CONT_PER;
|
||||
laser_trap.till_update = LASER_POWER_INLINE_TRAPEZOID_CONT_PER;
|
||||
#else
|
||||
laser.last_step_count = step_events_completed;
|
||||
laser_trap.last_step_count = step_events_completed;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@ -2000,7 +2000,10 @@ uint32_t Stepper::block_phase_isr() {
|
||||
return interval; // No more queued movements!
|
||||
}
|
||||
|
||||
TERN_(HAS_CUTTER, cutter.apply_power(current_block->cutter_power));
|
||||
// For non-inline cutter, grossly apply power
|
||||
#if ENABLED(LASER_FEATURE) && DISABLED(LASER_POWER_INLINE)
|
||||
cutter.apply_power(current_block->cutter_power);
|
||||
#endif
|
||||
|
||||
TERN_(POWER_LOSS_RECOVERY, recovery.info.sdpos = current_block->sdpos);
|
||||
|
||||
@ -2150,15 +2153,9 @@ uint32_t Stepper::block_phase_isr() {
|
||||
else LA_isr_rate = LA_ADV_NEVER;
|
||||
#endif
|
||||
|
||||
if (
|
||||
#if HAS_L64XX
|
||||
true // Always set direction for L64xx (This also enables the chips)
|
||||
#else
|
||||
current_block->direction_bits != last_direction_bits
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
|| stepper_extruder != last_moved_extruder
|
||||
#endif
|
||||
#endif
|
||||
if ( ENABLED(HAS_L64XX) // Always set direction for L64xx (Also enables the chips)
|
||||
|| current_block->direction_bits != last_direction_bits
|
||||
|| TERN(MIXING_EXTRUDER, false, stepper_extruder != last_moved_extruder)
|
||||
) {
|
||||
last_direction_bits = current_block->direction_bits;
|
||||
#if EXTRUDERS > 1
|
||||
@ -2170,33 +2167,31 @@ uint32_t Stepper::block_phase_isr() {
|
||||
}
|
||||
|
||||
#if ENABLED(LASER_POWER_INLINE)
|
||||
const uint8_t stat = current_block->laser.status;
|
||||
const power_status_t stat = current_block->laser.status;
|
||||
#if ENABLED(LASER_POWER_INLINE_TRAPEZOID)
|
||||
laser.trap_en = (stat & 0x03) == 0x03;
|
||||
laser.cur_power = current_block->laser.power_entry; // RESET STATE
|
||||
laser.cruise_set = false;
|
||||
laser_trap.enabled = stat.isPlanned && stat.isEnabled;
|
||||
laser_trap.cur_power = current_block->laser.power_entry; // RESET STATE
|
||||
laser_trap.cruise_set = false;
|
||||
#if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT)
|
||||
laser.last_step_count = 0;
|
||||
laser.acc_step_count = current_block->laser.entry_per / 2;
|
||||
laser_trap.last_step_count = 0;
|
||||
laser_trap.acc_step_count = current_block->laser.entry_per / 2;
|
||||
#else
|
||||
laser.till_update = 0;
|
||||
laser_trap.till_update = 0;
|
||||
#endif
|
||||
// Always have PWM in this case
|
||||
if (TEST(stat, 0)) { // Planner controls the laser
|
||||
if (TEST(stat, 1)) // Laser is on
|
||||
cutter.set_ocr_power(laser.cur_power);
|
||||
else
|
||||
cutter.set_power(0);
|
||||
if (stat.isPlanned) { // Planner controls the laser
|
||||
cutter.set_ocr_power(
|
||||
stat.isEnabled ? laser_trap.cur_power : 0 // ON with power or OFF
|
||||
);
|
||||
}
|
||||
#else
|
||||
if (TEST(stat, 0)) { // Planner controls the laser
|
||||
if (stat.isPlanned) { // Planner controls the laser
|
||||
#if ENABLED(SPINDLE_LASER_PWM)
|
||||
if (TEST(stat, 1)) // Laser is on
|
||||
cutter.set_ocr_power(current_block->laser.power);
|
||||
else
|
||||
cutter.set_power(0);
|
||||
cutter.set_ocr_power(
|
||||
stat.isEnabled ? current_block->laser.power : 0 // ON with power or OFF
|
||||
);
|
||||
#else
|
||||
cutter.set_enabled(TEST(stat, 1));
|
||||
cutter.set_enabled(stat.isEnabled);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@ -2237,15 +2232,14 @@ uint32_t Stepper::block_phase_isr() {
|
||||
#if ENABLED(LASER_POWER_INLINE_CONTINUOUS)
|
||||
else { // No new block found; so apply inline laser parameters
|
||||
// This should mean ending file with 'M5 I' will stop the laser; thus the inline flag isn't needed
|
||||
const uint8_t stat = planner.laser.status;
|
||||
if (TEST(stat, 0)) { // Planner controls the laser
|
||||
const power_status_t stat = planner.laser_inline.status;
|
||||
if (stat.isPlanned) { // Planner controls the laser
|
||||
#if ENABLED(SPINDLE_LASER_PWM)
|
||||
if (TEST(stat, 1)) // Laser is on
|
||||
cutter.set_ocr_power(planner.laser.power);
|
||||
else
|
||||
cutter.set_power(0);
|
||||
cutter.set_ocr_power(
|
||||
stat.isEnabled ? planner.laser_inline.power : 0 // ON with power or OFF
|
||||
);
|
||||
#else
|
||||
cutter.set_enabled(TEST(stat, 1));
|
||||
cutter.set_enabled(stat.isEnabled);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user