️ Handle shared enable pins (#22824)

This commit is contained in:
Scott Lahteine
2021-09-28 01:07:51 -05:00
committed by Scott Lahteine
parent 25a131b942
commit 021ceeba0b
26 changed files with 523 additions and 252 deletions

View File

@ -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();