⚡️ Handle shared enable pins (#22824)
This commit is contained in:
committed by
Scott Lahteine
parent
25a131b942
commit
021ceeba0b
@@ -1375,13 +1375,13 @@ void Planner::check_axes_activity() {
|
||||
// Disable inactive axes
|
||||
//
|
||||
LOGICAL_AXIS_CODE(
|
||||
if (TERN0(DISABLE_E, !axis_active.e)) disable_e_steppers(),
|
||||
if (TERN0(DISABLE_X, !axis_active.x)) DISABLE_AXIS_X(),
|
||||
if (TERN0(DISABLE_Y, !axis_active.y)) DISABLE_AXIS_Y(),
|
||||
if (TERN0(DISABLE_Z, !axis_active.z)) DISABLE_AXIS_Z(),
|
||||
if (TERN0(DISABLE_I, !axis_active.i)) DISABLE_AXIS_I(),
|
||||
if (TERN0(DISABLE_J, !axis_active.j)) DISABLE_AXIS_J(),
|
||||
if (TERN0(DISABLE_K, !axis_active.k)) DISABLE_AXIS_K()
|
||||
if (TERN0(DISABLE_E, !axis_active.e)) stepper.disable_e_steppers(),
|
||||
if (TERN0(DISABLE_X, !axis_active.x)) stepper.disable_axis(X_AXIS),
|
||||
if (TERN0(DISABLE_Y, !axis_active.y)) stepper.disable_axis(Y_AXIS),
|
||||
if (TERN0(DISABLE_Z, !axis_active.z)) stepper.disable_axis(Z_AXIS),
|
||||
if (TERN0(DISABLE_I, !axis_active.i)) stepper.disable_axis(I_AXIS),
|
||||
if (TERN0(DISABLE_J, !axis_active.j)) stepper.disable_axis(J_AXIS),
|
||||
if (TERN0(DISABLE_K, !axis_active.k)) stepper.disable_axis(K_AXIS)
|
||||
);
|
||||
|
||||
//
|
||||
@@ -1707,7 +1707,7 @@ float Planner::triggered_position_mm(const AxisEnum axis) {
|
||||
|
||||
void Planner::finish_and_disable() {
|
||||
while (has_blocks_queued() || cleaning_buffer_counter) idle();
|
||||
disable_all_steppers();
|
||||
stepper.disable_all_steppers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2144,7 +2144,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
block->e_to_p_pressure = baricuda_e_to_p_pressure;
|
||||
#endif
|
||||
|
||||
TERN_(HAS_MULTI_EXTRUDER, block->extruder = extruder);
|
||||
E_TERN_(block->extruder = extruder);
|
||||
|
||||
#if ENABLED(AUTO_POWER_CONTROL)
|
||||
if (LINEAR_AXIS_GANG(
|
||||
@@ -2160,43 +2160,43 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
// Enable active axes
|
||||
#if EITHER(CORE_IS_XY, MARKFORGED_XY)
|
||||
if (block->steps.a || block->steps.b) {
|
||||
ENABLE_AXIS_X();
|
||||
ENABLE_AXIS_Y();
|
||||
stepper.enable_axis(X_AXIS);
|
||||
stepper.enable_axis(Y_AXIS);
|
||||
}
|
||||
#if DISABLED(Z_LATE_ENABLE)
|
||||
if (block->steps.z) ENABLE_AXIS_Z();
|
||||
if (block->steps.z) stepper.enable_axis(Z_AXIS);
|
||||
#endif
|
||||
#elif CORE_IS_XZ
|
||||
if (block->steps.a || block->steps.c) {
|
||||
ENABLE_AXIS_X();
|
||||
ENABLE_AXIS_Z();
|
||||
stepper.enable_axis(X_AXIS);
|
||||
stepper.enable_axis(Z_AXIS);
|
||||
}
|
||||
if (block->steps.y) ENABLE_AXIS_Y();
|
||||
if (block->steps.y) stepper.enable_axis(Y_AXIS);
|
||||
#elif CORE_IS_YZ
|
||||
if (block->steps.b || block->steps.c) {
|
||||
ENABLE_AXIS_Y();
|
||||
ENABLE_AXIS_Z();
|
||||
stepper.enable_axis(Y_AXIS);
|
||||
stepper.enable_axis(Z_AXIS);
|
||||
}
|
||||
if (block->steps.x) ENABLE_AXIS_X();
|
||||
if (block->steps.x) stepper.enable_axis(X_AXIS);
|
||||
#else
|
||||
LINEAR_AXIS_CODE(
|
||||
if (block->steps.x) ENABLE_AXIS_X(),
|
||||
if (block->steps.y) ENABLE_AXIS_Y(),
|
||||
if (TERN(Z_LATE_ENABLE, 0, block->steps.z)) ENABLE_AXIS_Z(),
|
||||
if (block->steps.i) ENABLE_AXIS_I(),
|
||||
if (block->steps.j) ENABLE_AXIS_J(),
|
||||
if (block->steps.k) ENABLE_AXIS_K()
|
||||
if (block->steps.x) stepper.enable_axis(X_AXIS),
|
||||
if (block->steps.y) stepper.enable_axis(Y_AXIS),
|
||||
if (TERN(Z_LATE_ENABLE, 0, block->steps.z)) stepper.enable_axis(Z_AXIS),
|
||||
if (block->steps.i) stepper.enable_axis(I_AXIS),
|
||||
if (block->steps.j) stepper.enable_axis(J_AXIS),
|
||||
if (block->steps.k) stepper.enable_axis(K_AXIS)
|
||||
);
|
||||
#endif
|
||||
#if EITHER(IS_CORE, MARKFORGED_XY)
|
||||
#if LINEAR_AXES >= 4
|
||||
if (block->steps.i) ENABLE_AXIS_I();
|
||||
if (block->steps.i) stepper.enable_axis(I_AXIS);
|
||||
#endif
|
||||
#if LINEAR_AXES >= 5
|
||||
if (block->steps.j) ENABLE_AXIS_J();
|
||||
if (block->steps.j) stepper.enable_axis(J_AXIS);
|
||||
#endif
|
||||
#if LINEAR_AXES >= 6
|
||||
if (block->steps.k) ENABLE_AXIS_K();
|
||||
if (block->steps.k) stepper.enable_axis(K_AXIS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -2214,27 +2214,27 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
|
||||
#define ENABLE_ONE_E(N) do{ \
|
||||
if (E_STEPPER_INDEX(extruder) == N) { \
|
||||
ENABLE_AXIS_E##N(); \
|
||||
stepper.ENABLE_EXTRUDER(N); \
|
||||
g_uc_extruder_last_move[N] = (BLOCK_BUFFER_SIZE) * 2; \
|
||||
if ((N) == 0 && TERN0(HAS_DUPLICATION_MODE, extruder_duplication_enabled)) \
|
||||
ENABLE_AXIS_E1(); \
|
||||
stepper.ENABLE_EXTRUDER(1); \
|
||||
} \
|
||||
else if (!g_uc_extruder_last_move[N]) { \
|
||||
DISABLE_AXIS_E##N(); \
|
||||
stepper.DISABLE_EXTRUDER(N); \
|
||||
if ((N) == 0 && TERN0(HAS_DUPLICATION_MODE, extruder_duplication_enabled)) \
|
||||
DISABLE_AXIS_E1(); \
|
||||
stepper.DISABLE_EXTRUDER(1); \
|
||||
} \
|
||||
}while(0);
|
||||
|
||||
#else
|
||||
|
||||
#define ENABLE_ONE_E(N) ENABLE_AXIS_E##N();
|
||||
#define ENABLE_ONE_E(N) stepper.ENABLE_EXTRUDER(N);
|
||||
|
||||
#endif
|
||||
|
||||
REPEAT(E_STEPPERS, ENABLE_ONE_E); // (ENABLE_ONE_E must end with semicolon)
|
||||
}
|
||||
#endif // EXTRUDERS
|
||||
#endif // HAS_EXTRUDERS
|
||||
|
||||
if (esteps)
|
||||
NOLESS(fr_mm_s, settings.min_feedrate_mm_s);
|
||||
@@ -3049,7 +3049,7 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s, cons
|
||||
FANS_LOOP(i) block->fan_speed[i] = thermalManager.fan_speed[i];
|
||||
#endif
|
||||
|
||||
TERN_(HAS_MULTI_EXTRUDER, block->extruder = extruder);
|
||||
E_TERN_(block->extruder = extruder);
|
||||
|
||||
block->page_idx = page_idx;
|
||||
|
||||
@@ -3085,7 +3085,7 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s, cons
|
||||
// Move buffer head
|
||||
block_buffer_head = next_buffer_head;
|
||||
|
||||
enable_all_steppers();
|
||||
stepper.enable_all_steppers();
|
||||
stepper.wake_up();
|
||||
}
|
||||
|
||||
|
@@ -251,17 +251,17 @@ xyz_pos_t Probe::offset; // Initialized by settings.load()
|
||||
void Probe::set_probing_paused(const bool dopause) {
|
||||
TERN_(PROBING_HEATERS_OFF, thermalManager.pause_heaters(dopause));
|
||||
TERN_(PROBING_FANS_OFF, thermalManager.set_fans_paused(dopause));
|
||||
TERN_(PROBING_ESTEPPERS_OFF, if (dopause) disable_e_steppers());
|
||||
TERN_(PROBING_ESTEPPERS_OFF, if (dopause) stepper.disable_e_steppers());
|
||||
#if ENABLED(PROBING_STEPPERS_OFF) && DISABLED(DELTA)
|
||||
static uint8_t old_trusted;
|
||||
if (dopause) {
|
||||
old_trusted = axis_trusted;
|
||||
DISABLE_AXIS_X();
|
||||
DISABLE_AXIS_Y();
|
||||
stepper.disable_axis(X_AXIS);
|
||||
stepper.disable_axis(Y_AXIS);
|
||||
}
|
||||
else {
|
||||
if (TEST(old_trusted, X_AXIS)) ENABLE_AXIS_X();
|
||||
if (TEST(old_trusted, Y_AXIS)) ENABLE_AXIS_Y();
|
||||
if (TEST(old_trusted, X_AXIS)) stepper.enable_axis(X_AXIS);
|
||||
if (TEST(old_trusted, Y_AXIS)) stepper.enable_axis(Y_AXIS);
|
||||
axis_trusted = old_trusted;
|
||||
}
|
||||
#endif
|
||||
|
@@ -3278,7 +3278,7 @@ void MarlinSettings::reset() {
|
||||
//
|
||||
// Tool-changing Parameters
|
||||
//
|
||||
TERN_(HAS_MULTI_EXTRUDER, gcode.M217_report(forReplay));
|
||||
E_TERN_(gcode.M217_report(forReplay));
|
||||
|
||||
//
|
||||
// Backlash Compensation
|
||||
|
@@ -123,6 +123,10 @@ Stepper stepper; // Singleton
|
||||
bool L64XX_OK_to_power_up = false; // flag to keep L64xx steppers powered down after a reset or power up
|
||||
#endif
|
||||
|
||||
#if ENABLED(AUTO_POWER_CONTROL)
|
||||
#include "../feature/power.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
#include "../feature/powerloss.h"
|
||||
#endif
|
||||
@@ -131,6 +135,10 @@ Stepper stepper; // Singleton
|
||||
#include "../feature/spindle_laser.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
#include "../lcd/extui/ui_api.h"
|
||||
#endif
|
||||
|
||||
// public:
|
||||
|
||||
#if EITHER(HAS_EXTRA_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
|
||||
@@ -145,6 +153,8 @@ Stepper stepper; // Singleton
|
||||
#endif
|
||||
#endif
|
||||
|
||||
axis_flags_t Stepper::axis_enabled; // {0}
|
||||
|
||||
// private:
|
||||
|
||||
block_t* Stepper::current_block; // (= nullptr) A pointer to the block currently being traced
|
||||
@@ -473,6 +483,89 @@ xyze_int8_t Stepper::count_direction{0};
|
||||
#define DIR_WAIT_AFTER()
|
||||
#endif
|
||||
|
||||
void Stepper::enable_axis(const AxisEnum axis) {
|
||||
#define _CASE_ENABLE(N) case N##_AXIS: ENABLE_AXIS_##N(); break;
|
||||
switch (axis) {
|
||||
LINEAR_AXIS_CODE(
|
||||
_CASE_ENABLE(X), _CASE_ENABLE(Y), _CASE_ENABLE(Z),
|
||||
_CASE_ENABLE(I), _CASE_ENABLE(J), _CASE_ENABLE(K)
|
||||
);
|
||||
default: break;
|
||||
}
|
||||
mark_axis_enabled(axis);
|
||||
}
|
||||
|
||||
bool Stepper::disable_axis(const AxisEnum axis) {
|
||||
mark_axis_disabled(axis);
|
||||
// If all the axes that share the enabled bit are disabled
|
||||
const bool can_disable = can_axis_disable(axis);
|
||||
if (can_disable) {
|
||||
#define _CASE_DISABLE(N) case N##_AXIS: DISABLE_AXIS_##N(); break;
|
||||
switch (axis) {
|
||||
LINEAR_AXIS_CODE(
|
||||
_CASE_DISABLE(X), _CASE_DISABLE(Y), _CASE_DISABLE(Z),
|
||||
_CASE_DISABLE(I), _CASE_DISABLE(J), _CASE_DISABLE(K)
|
||||
);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
return can_disable;
|
||||
}
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
|
||||
void Stepper::enable_extruder(E_TERN_(const uint8_t eindex)) {
|
||||
IF_DISABLED(HAS_MULTI_EXTRUDER, constexpr uint8_t eindex = 0);
|
||||
#define _CASE_ENA_E(N) case N: ENABLE_AXIS_E##N(); mark_axis_enabled(E_AXIS E_OPTARG(eindex)); break;
|
||||
switch (eindex) {
|
||||
REPEAT(E_STEPPERS, _CASE_ENA_E)
|
||||
}
|
||||
}
|
||||
|
||||
bool Stepper::disable_extruder(E_TERN_(const uint8_t eindex)) {
|
||||
IF_DISABLED(HAS_MULTI_EXTRUDER, constexpr uint8_t eindex = 0);
|
||||
mark_axis_disabled(E_AXIS E_OPTARG(eindex));
|
||||
const bool can_disable = can_axis_disable(E_AXIS E_OPTARG(eindex));
|
||||
if (can_disable) {
|
||||
#define _CASE_DIS_E(N) case N: DISABLE_AXIS_E##N(); break;
|
||||
switch (eindex) { REPEAT(E_STEPPERS, _CASE_DIS_E) }
|
||||
}
|
||||
return can_disable;
|
||||
}
|
||||
|
||||
void Stepper::enable_e_steppers() {
|
||||
#define _ENA_E(N) ENABLE_EXTRUDER(N);
|
||||
REPEAT(EXTRUDERS, _ENA_E)
|
||||
}
|
||||
|
||||
void Stepper::disable_e_steppers() {
|
||||
#define _DIS_E(N) DISABLE_EXTRUDER(N);
|
||||
REPEAT(EXTRUDERS, _DIS_E)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Stepper::enable_all_steppers() {
|
||||
TERN_(AUTO_POWER_CONTROL, powerManager.power_on());
|
||||
LINEAR_AXIS_CODE(
|
||||
enable_axis(X_AXIS), enable_axis(Y_AXIS), enable_axis(Z_AXIS),
|
||||
enable_axis(I_AXIS), enable_axis(J_AXIS), enable_axis(K_AXIS)
|
||||
);
|
||||
enable_e_steppers();
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onSteppersEnabled());
|
||||
}
|
||||
|
||||
void Stepper::disable_all_steppers() {
|
||||
LINEAR_AXIS_CODE(
|
||||
disable_axis(X_AXIS), disable_axis(Y_AXIS), disable_axis(Z_AXIS),
|
||||
disable_axis(I_AXIS), disable_axis(J_AXIS), disable_axis(K_AXIS)
|
||||
);
|
||||
disable_e_steppers();
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onSteppersDisabled());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the stepper direction of each axis
|
||||
*
|
||||
@@ -494,24 +587,12 @@ void Stepper::set_directions() {
|
||||
count_direction[_AXIS(A)] = 1; \
|
||||
}
|
||||
|
||||
#if HAS_X_DIR
|
||||
SET_STEP_DIR(X); // A
|
||||
#endif
|
||||
#if HAS_Y_DIR
|
||||
SET_STEP_DIR(Y); // B
|
||||
#endif
|
||||
#if HAS_Z_DIR
|
||||
SET_STEP_DIR(Z); // C
|
||||
#endif
|
||||
#if HAS_I_DIR
|
||||
SET_STEP_DIR(I);
|
||||
#endif
|
||||
#if HAS_J_DIR
|
||||
SET_STEP_DIR(J);
|
||||
#endif
|
||||
#if HAS_K_DIR
|
||||
SET_STEP_DIR(K);
|
||||
#endif
|
||||
TERN_(HAS_X_DIR, SET_STEP_DIR(X)); // A
|
||||
TERN_(HAS_Y_DIR, SET_STEP_DIR(Y)); // B
|
||||
TERN_(HAS_Z_DIR, SET_STEP_DIR(Z)); // C
|
||||
TERN_(HAS_I_DIR, SET_STEP_DIR(I));
|
||||
TERN_(HAS_J_DIR, SET_STEP_DIR(J));
|
||||
TERN_(HAS_K_DIR, SET_STEP_DIR(K));
|
||||
|
||||
#if DISABLED(LIN_ADVANCE)
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
@@ -2204,7 +2285,7 @@ uint32_t Stepper::block_phase_isr() {
|
||||
|
||||
TERN_(MIXING_EXTRUDER, mixer.stepper_setup(current_block->b_color));
|
||||
|
||||
TERN_(HAS_MULTI_EXTRUDER, stepper_extruder = current_block->extruder);
|
||||
E_TERN_(stepper_extruder = current_block->extruder);
|
||||
|
||||
// Initialize the trapezoid generator from the current block.
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
@@ -2227,7 +2308,7 @@ uint32_t Stepper::block_phase_isr() {
|
||||
|| current_block->direction_bits != last_direction_bits
|
||||
|| TERN(MIXING_EXTRUDER, false, stepper_extruder != last_moved_extruder)
|
||||
) {
|
||||
TERN_(HAS_MULTI_EXTRUDER, last_moved_extruder = stepper_extruder);
|
||||
E_TERN_(last_moved_extruder = stepper_extruder);
|
||||
TERN_(HAS_L64XX, L64XX_OK_to_power_up = true);
|
||||
set_directions(current_block->direction_bits);
|
||||
}
|
||||
@@ -2276,7 +2357,7 @@ uint32_t Stepper::block_phase_isr() {
|
||||
// If delayed Z enable, enable it now. This option will severely interfere with
|
||||
// timing between pulses when chaining motion between blocks, and it could lead
|
||||
// to lost steps in both X and Y axis, so avoid using it unless strictly necessary!!
|
||||
if (current_block->steps.z) ENABLE_AXIS_Z();
|
||||
if (current_block->steps.z) enable_axis(Z_AXIS);
|
||||
#endif
|
||||
|
||||
// Mark the time_nominal as not calculated yet
|
||||
@@ -2872,7 +2953,7 @@ void Stepper::report_positions() {
|
||||
|
||||
#if ENABLED(BABYSTEPPING)
|
||||
|
||||
#define _ENABLE_AXIS(AXIS) ENABLE_AXIS_## AXIS()
|
||||
#define _ENABLE_AXIS(A) enable_axis(_AXIS(A))
|
||||
#define _READ_DIR(AXIS) AXIS ##_DIR_READ()
|
||||
#define _INVERT_DIR(AXIS) INVERT_## AXIS ##_DIR
|
||||
#define _APPLY_DIR(AXIS, INVERT) AXIS ##_APPLY_DIR(INVERT, true)
|
||||
@@ -3000,8 +3081,10 @@ void Stepper::report_positions() {
|
||||
|
||||
const bool z_direction = direction ^ BABYSTEP_INVERT_Z;
|
||||
|
||||
ENABLE_AXIS_X(); ENABLE_AXIS_Y(); ENABLE_AXIS_Z();
|
||||
ENABLE_AXIS_I(); ENABLE_AXIS_J(); ENABLE_AXIS_K();
|
||||
LINEAR_AXIS_CODE(
|
||||
enable_axis(X_AXIS), enable_axis(Y_AXIS), enable_axis(Z_AXIS),
|
||||
enable_axis(I_AXIS), enable_axis(J_AXIS), enable_axis(K_AXIS)
|
||||
);
|
||||
|
||||
DIR_WAIT_BEFORE();
|
||||
|
||||
|
@@ -236,6 +236,71 @@
|
||||
// Perhaps DISABLE_MULTI_STEPPING should be required with ADAPTIVE_STEP_SMOOTHING.
|
||||
#define MIN_STEP_ISR_FREQUENCY (MAX_STEP_ISR_FREQUENCY_1X / 2)
|
||||
|
||||
#define ENABLE_COUNT (LINEAR_AXES + E_STEPPERS)
|
||||
typedef IF<(ENABLE_COUNT > 8), uint16_t, uint8_t>::type ena_mask_t;
|
||||
|
||||
// Axis flags type, for enabled state or other simple state
|
||||
typedef struct {
|
||||
union {
|
||||
ena_mask_t bits;
|
||||
struct {
|
||||
bool LINEAR_AXIS_LIST(X:1, Y:1, Z:1, I:1, J:1, K:1);
|
||||
#if HAS_EXTRUDERS
|
||||
bool LIST_N(EXTRUDERS, E0:1, E1:1, E2:1, E3:1, E4:1, E5:1, E6:1, E7:1);
|
||||
#endif
|
||||
};
|
||||
};
|
||||
constexpr ena_mask_t linear_bits() { return _BV(LINEAR_AXES) - 1; }
|
||||
constexpr ena_mask_t e_bits() { return (_BV(EXTRUDERS) - 1) << LINEAR_AXES; }
|
||||
} axis_flags_t;
|
||||
|
||||
// All the stepper enable pins
|
||||
constexpr pin_t ena_pins[] = {
|
||||
LINEAR_AXIS_LIST(X_ENABLE_PIN, Y_ENABLE_PIN, Z_ENABLE_PIN, I_ENABLE_PIN, J_ENABLE_PIN, K_ENABLE_PIN),
|
||||
LIST_N(E_STEPPERS, E0_ENABLE_PIN, E1_ENABLE_PIN, E2_ENABLE_PIN, E3_ENABLE_PIN, E4_ENABLE_PIN, E5_ENABLE_PIN, E6_ENABLE_PIN, E7_ENABLE_PIN)
|
||||
};
|
||||
|
||||
// Index of the axis or extruder element in a combined array
|
||||
constexpr uint8_t index_of_axis(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
|
||||
return uint8_t(axis) + (E_TERN0(axis < LINEAR_AXES ? 0 : eindex));
|
||||
}
|
||||
//#define __IAX_N(N,V...) _IAX_##N(V)
|
||||
//#define _IAX_N(N,V...) __IAX_N(N,V)
|
||||
//#define _IAX_1(A) index_of_axis(A)
|
||||
//#define _IAX_2(A,B) index_of_axis(A E_OPTARG(B))
|
||||
//#define INDEX_OF_AXIS(V...) _IAX_N(TWO_ARGS(V),V)
|
||||
|
||||
#define INDEX_OF_AXIS(A,V...) index_of_axis(A E_OPTARG(V+0))
|
||||
|
||||
// Bit mask for a matching enable pin, or 0
|
||||
constexpr ena_mask_t ena_same(const uint8_t a, const uint8_t b) {
|
||||
return ena_pins[a] == ena_pins[b] ? _BV(b) : 0;
|
||||
}
|
||||
|
||||
// Recursively get the enable overlaps mask for a given linear axis or extruder
|
||||
constexpr ena_mask_t ena_overlap(const uint8_t a=0, const uint8_t b=0) {
|
||||
return b >= ENABLE_COUNT ? 0 : (a == b ? 0 : ena_same(a, b)) | ena_overlap(a, b + 1);
|
||||
}
|
||||
|
||||
// Recursively get whether there's any overlap at all
|
||||
constexpr bool any_enable_overlap(const uint8_t a=0) {
|
||||
return a >= ENABLE_COUNT ? false : ena_overlap(a) || any_enable_overlap(a + 1);
|
||||
}
|
||||
|
||||
// Array of axes that overlap with each
|
||||
// TODO: Consider cases where >=2 steppers are used by a linear axis or extruder
|
||||
// (e.g., CoreXY, Dual XYZ, or E with multiple steppers, etc.).
|
||||
constexpr ena_mask_t enable_overlap[] = {
|
||||
#define _OVERLAP(N) ena_overlap(INDEX_OF_AXIS(AxisEnum(N))),
|
||||
REPEAT(LINEAR_AXES, _OVERLAP)
|
||||
#if HAS_EXTRUDERS
|
||||
#define _E_OVERLAP(N) ena_overlap(INDEX_OF_AXIS(E_AXIS, N)),
|
||||
REPEAT(E_STEPPERS, _E_OVERLAP)
|
||||
#endif
|
||||
};
|
||||
|
||||
//static_assert(!any_enable_overlap(), "There is some overlap.");
|
||||
|
||||
//
|
||||
// Stepper class definition
|
||||
//
|
||||
@@ -519,6 +584,43 @@ class Stepper {
|
||||
static void refresh_motor_power();
|
||||
#endif
|
||||
|
||||
static axis_flags_t axis_enabled; // Axis stepper(s) ENABLED states
|
||||
|
||||
static inline bool axis_is_enabled(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
|
||||
return TEST(axis_enabled.bits, INDEX_OF_AXIS(axis, eindex));
|
||||
}
|
||||
static inline void mark_axis_enabled(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
|
||||
SBI(axis_enabled.bits, INDEX_OF_AXIS(axis, eindex));
|
||||
}
|
||||
static inline void mark_axis_disabled(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
|
||||
CBI(axis_enabled.bits, INDEX_OF_AXIS(axis, eindex));
|
||||
}
|
||||
static inline bool can_axis_disable(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
|
||||
return !any_enable_overlap() || !(axis_enabled.bits & enable_overlap[INDEX_OF_AXIS(axis, eindex)]);
|
||||
}
|
||||
|
||||
static void enable_axis(const AxisEnum axis);
|
||||
static bool disable_axis(const AxisEnum axis);
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
static void enable_extruder(E_TERN_(const uint8_t eindex=0));
|
||||
static bool disable_extruder(E_TERN_(const uint8_t eindex=0));
|
||||
static void enable_e_steppers();
|
||||
static void disable_e_steppers();
|
||||
#else
|
||||
static inline void enable_extruder() {}
|
||||
static inline bool disable_extruder() {}
|
||||
static inline void enable_e_steppers() {}
|
||||
static inline void disable_e_steppers() {}
|
||||
#endif
|
||||
|
||||
#define ENABLE_EXTRUDER(N) enable_extruder(E_TERN_(N))
|
||||
#define DISABLE_EXTRUDER(N) disable_extruder(E_TERN_(N))
|
||||
#define AXIS_IS_ENABLED(N,V...) axis_is_enabled(N E_OPTARG(#V))
|
||||
|
||||
static void enable_all_steppers();
|
||||
static void disable_all_steppers();
|
||||
|
||||
// Update direction states for all steppers
|
||||
static void set_directions();
|
||||
|
||||
|
Reference in New Issue
Block a user