⚡️ Handle shared enable pins (#22824)
This commit is contained in:
parent
25a131b942
commit
021ceeba0b
|
@ -81,10 +81,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
#include "lcd/extui/ui_api.h"
|
||||
#endif
|
||||
|
||||
#if HAS_ETHERNET
|
||||
#include "feature/ethernet.h"
|
||||
#endif
|
||||
|
@ -312,48 +308,6 @@ bool pin_is_protected(const pin_t pin) {
|
|||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
void enable_e_steppers() {
|
||||
#define _ENA_E(N) ENABLE_AXIS_E##N();
|
||||
REPEAT(E_STEPPERS, _ENA_E)
|
||||
}
|
||||
|
||||
void enable_all_steppers() {
|
||||
TERN_(AUTO_POWER_CONTROL, powerManager.power_on());
|
||||
ENABLE_AXIS_X();
|
||||
ENABLE_AXIS_Y();
|
||||
ENABLE_AXIS_Z();
|
||||
ENABLE_AXIS_I(); // Marlin 6-axis support by DerAndere (https://github.com/DerAndere1/Marlin/wiki)
|
||||
ENABLE_AXIS_J();
|
||||
ENABLE_AXIS_K();
|
||||
enable_e_steppers();
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onSteppersEnabled());
|
||||
}
|
||||
|
||||
void disable_e_steppers() {
|
||||
#define _DIS_E(N) DISABLE_AXIS_E##N();
|
||||
REPEAT(E_STEPPERS, _DIS_E)
|
||||
}
|
||||
|
||||
void disable_e_stepper(const uint8_t e) {
|
||||
#define _CASE_DIS_E(N) case N: DISABLE_AXIS_E##N(); break;
|
||||
switch (e) {
|
||||
REPEAT(E_STEPPERS, _CASE_DIS_E)
|
||||
}
|
||||
}
|
||||
|
||||
void disable_all_steppers() {
|
||||
DISABLE_AXIS_X();
|
||||
DISABLE_AXIS_Y();
|
||||
DISABLE_AXIS_Z();
|
||||
DISABLE_AXIS_I();
|
||||
DISABLE_AXIS_J();
|
||||
DISABLE_AXIS_K();
|
||||
disable_e_steppers();
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onSteppersDisabled());
|
||||
}
|
||||
|
||||
/**
|
||||
* A Print Job exists when the timer is running or SD is printing
|
||||
*/
|
||||
|
@ -464,13 +418,13 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
|
|||
already_shutdown_steppers = true; // L6470 SPI will consume 99% of free time without this
|
||||
|
||||
// Individual axes will be disabled if configured
|
||||
if (ENABLED(DISABLE_INACTIVE_X)) DISABLE_AXIS_X();
|
||||
if (ENABLED(DISABLE_INACTIVE_Y)) DISABLE_AXIS_Y();
|
||||
if (ENABLED(DISABLE_INACTIVE_Z)) DISABLE_AXIS_Z();
|
||||
if (ENABLED(DISABLE_INACTIVE_I)) DISABLE_AXIS_I();
|
||||
if (ENABLED(DISABLE_INACTIVE_J)) DISABLE_AXIS_J();
|
||||
if (ENABLED(DISABLE_INACTIVE_K)) DISABLE_AXIS_K();
|
||||
if (ENABLED(DISABLE_INACTIVE_E)) disable_e_steppers();
|
||||
TERN_(DISABLE_INACTIVE_X, stepper.disable_axis(X_AXIS));
|
||||
TERN_(DISABLE_INACTIVE_Y, stepper.disable_axis(Y_AXIS));
|
||||
TERN_(DISABLE_INACTIVE_Z, stepper.disable_axis(Z_AXIS));
|
||||
TERN_(DISABLE_INACTIVE_I, stepper.disable_axis(I_AXIS));
|
||||
TERN_(DISABLE_INACTIVE_J, stepper.disable_axis(J_AXIS));
|
||||
TERN_(DISABLE_INACTIVE_K, stepper.disable_axis(K_AXIS));
|
||||
TERN_(DISABLE_INACTIVE_E, stepper.disable_e_steppers());
|
||||
|
||||
TERN_(AUTO_BED_LEVELING_UBL, ubl.steppers_were_disabled());
|
||||
}
|
||||
|
@ -689,13 +643,13 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
|
|||
#if ENABLED(SWITCHING_EXTRUDER)
|
||||
bool oldstatus;
|
||||
switch (active_extruder) {
|
||||
default: oldstatus = E0_ENABLE_READ(); ENABLE_AXIS_E0(); break;
|
||||
default: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 0); stepper.ENABLE_EXTRUDER(0); break;
|
||||
#if E_STEPPERS > 1
|
||||
case 2: case 3: oldstatus = E1_ENABLE_READ(); ENABLE_AXIS_E1(); break;
|
||||
case 2: case 3: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 1); stepper.ENABLE_EXTRUDER(1); break;
|
||||
#if E_STEPPERS > 2
|
||||
case 4: case 5: oldstatus = E2_ENABLE_READ(); ENABLE_AXIS_E2(); break;
|
||||
case 4: case 5: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 2); stepper.ENABLE_EXTRUDER(2); break;
|
||||
#if E_STEPPERS > 3
|
||||
case 6: case 7: oldstatus = E3_ENABLE_READ(); ENABLE_AXIS_E3(); break;
|
||||
case 6: case 7: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 3); stepper.ENABLE_EXTRUDER(3); break;
|
||||
#endif // E_STEPPERS > 3
|
||||
#endif // E_STEPPERS > 2
|
||||
#endif // E_STEPPERS > 1
|
||||
|
@ -704,7 +658,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
|
|||
bool oldstatus;
|
||||
switch (active_extruder) {
|
||||
default:
|
||||
#define _CASE_EN(N) case N: oldstatus = E##N##_ENABLE_READ(); ENABLE_AXIS_E##N(); break;
|
||||
#define _CASE_EN(N) case N: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, N); stepper.ENABLE_EXTRUDER(N); break;
|
||||
REPEAT(E_STEPPERS, _CASE_EN);
|
||||
}
|
||||
#endif
|
||||
|
@ -718,17 +672,17 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
|
|||
|
||||
#if ENABLED(SWITCHING_EXTRUDER)
|
||||
switch (active_extruder) {
|
||||
default: oldstatus = E0_ENABLE_WRITE(oldstatus); break;
|
||||
default: if (oldstatus) stepper.ENABLE_EXTRUDER(0); else stepper.DISABLE_EXTRUDER(0); break;
|
||||
#if E_STEPPERS > 1
|
||||
case 2: case 3: oldstatus = E1_ENABLE_WRITE(oldstatus); break;
|
||||
case 2: case 3: if (oldstatus) stepper.ENABLE_EXTRUDER(1); else stepper.DISABLE_EXTRUDER(1); break;
|
||||
#if E_STEPPERS > 2
|
||||
case 4: case 5: oldstatus = E2_ENABLE_WRITE(oldstatus); break;
|
||||
case 4: case 5: if (oldstatus) stepper.ENABLE_EXTRUDER(2); else stepper.DISABLE_EXTRUDER(2); break;
|
||||
#endif // E_STEPPERS > 2
|
||||
#endif // E_STEPPERS > 1
|
||||
}
|
||||
#else // !SWITCHING_EXTRUDER
|
||||
switch (active_extruder) {
|
||||
#define _CASE_RESTORE(N) case N: E##N##_ENABLE_WRITE(oldstatus); break;
|
||||
#define _CASE_RESTORE(N) case N: if (oldstatus) stepper.ENABLE_EXTRUDER(N); else stepper.DISABLE_EXTRUDER(N); break;
|
||||
REPEAT(E_STEPPERS, _CASE_RESTORE);
|
||||
}
|
||||
#endif // !SWITCHING_EXTRUDER
|
||||
|
@ -940,7 +894,7 @@ void minkill(const bool steppers_off/*=false*/) {
|
|||
TERN_(HAS_CUTTER, cutter.kill()); // Reiterate cutter shutdown
|
||||
|
||||
// Power off all steppers (for M112) or just the E steppers
|
||||
steppers_off ? disable_all_steppers() : disable_e_steppers();
|
||||
steppers_off ? stepper.disable_all_steppers() : stepper.disable_e_steppers();
|
||||
|
||||
TERN_(PSU_CONTROL, powerManager.power_off());
|
||||
|
||||
|
|
|
@ -38,15 +38,6 @@ inline void idle_no_sleep() { idle(true); }
|
|||
extern bool G38_did_trigger; // Flag from the ISR to indicate the endstop changed
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The axis order in all axis related arrays is X, Y, Z, E
|
||||
*/
|
||||
void enable_e_steppers();
|
||||
void enable_all_steppers();
|
||||
void disable_e_stepper(const uint8_t e);
|
||||
void disable_e_steppers();
|
||||
void disable_all_steppers();
|
||||
|
||||
void kill(PGM_P const lcd_error=nullptr, PGM_P const lcd_component=nullptr, const bool steppers_off=false);
|
||||
void minkill(const bool steppers_off=false);
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#if ENABLED(USE_CONTROLLER_FAN)
|
||||
|
||||
#include "controllerfan.h"
|
||||
#include "../module/stepper/indirection.h"
|
||||
#include "../module/stepper.h"
|
||||
#include "../module/temperature.h"
|
||||
|
||||
ControllerFan controllerFan;
|
||||
|
@ -54,33 +54,12 @@ void ControllerFan::update() {
|
|||
if (ELAPSED(ms, nextMotorCheck)) {
|
||||
nextMotorCheck = ms + 2500UL; // Not a time critical function, so only check every 2.5s
|
||||
|
||||
#define MOTOR_IS_ON(A,B) (A##_ENABLE_READ() == bool(B##_ENABLE_ON))
|
||||
#define _OR_ENABLED_E(N) || MOTOR_IS_ON(E##N,E)
|
||||
|
||||
const bool motor_on = (
|
||||
( DISABLED(CONTROLLER_FAN_IGNORE_Z) &&
|
||||
( MOTOR_IS_ON(Z,Z)
|
||||
|| TERN0(HAS_Z2_ENABLE, MOTOR_IS_ON(Z2,Z))
|
||||
|| TERN0(HAS_Z3_ENABLE, MOTOR_IS_ON(Z3,Z))
|
||||
|| TERN0(HAS_Z4_ENABLE, MOTOR_IS_ON(Z4,Z))
|
||||
)
|
||||
) || (
|
||||
DISABLED(CONTROLLER_FAN_USE_Z_ONLY) &&
|
||||
( MOTOR_IS_ON(X,X) || MOTOR_IS_ON(Y,Y)
|
||||
|| TERN0(HAS_X2_ENABLE, MOTOR_IS_ON(X2,X))
|
||||
|| TERN0(HAS_Y2_ENABLE, MOTOR_IS_ON(Y2,Y))
|
||||
#if E_STEPPERS
|
||||
REPEAT(E_STEPPERS, _OR_ENABLED_E)
|
||||
#endif
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// If any triggers for the controller fan are true...
|
||||
// - At least one stepper driver is enabled
|
||||
// - The heated bed is enabled
|
||||
// - TEMP_SENSOR_BOARD is reporting >= CONTROLLER_FAN_MIN_BOARD_TEMP
|
||||
if ( motor_on
|
||||
const ena_mask_t axis_mask = TERN(CONTROLLER_FAN_USE_Z_ONLY, _BV(Z_AXIS), ~TERN0(CONTROLLER_FAN_IGNORE_Z, _BV(Z_AXIS)));
|
||||
if ( (stepper.axis_enabled.bits & axis_mask)
|
||||
|| TERN0(HAS_HEATED_BED, thermalManager.temp_bed.soft_pwm_amount > 0)
|
||||
|| TERN0(HAS_CONTROLLER_FAN_MIN_BOARD_TEMP, thermalManager.wholeDegBoard() >= CONTROLLER_FAN_MIN_BOARD_TEMP)
|
||||
) lastMotorOn = ms; //... set time to NOW so the fan will turn on
|
||||
|
|
|
@ -75,7 +75,7 @@ void FWRetract::reset() {
|
|||
|
||||
LOOP_L_N(i, EXTRUDERS) {
|
||||
retracted[i] = false;
|
||||
TERN_(HAS_MULTI_EXTRUDER, retracted_swap[i] = false);
|
||||
E_TERN_(retracted_swap[i] = false);
|
||||
current_retract[i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ void FWRetract::reset() {
|
|||
* Note: Auto-retract will apply the set Z hop in addition to any Z hop
|
||||
* included in the G-code. Use M207 Z0 to to prevent double hop.
|
||||
*/
|
||||
void FWRetract::retract(const bool retracting OPTARG(HAS_MULTI_EXTRUDER, bool swapping/*=false*/)) {
|
||||
void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/)) {
|
||||
// Prevent two retracts or recovers in a row
|
||||
if (retracted[active_extruder] == retracting) return;
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
static void retract(const bool retracting OPTARG(HAS_MULTI_EXTRUDER, bool swapping = false));
|
||||
static void retract(const bool retracting E_OPTARG(bool swapping=false));
|
||||
|
||||
static void M207_report();
|
||||
static void M207();
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "../MarlinCore.h"
|
||||
#include "../module/planner.h"
|
||||
#include "../module/stepper.h"
|
||||
|
||||
void mmu_init() {
|
||||
SET_OUTPUT(E_MUX0_PIN);
|
||||
|
@ -35,7 +36,7 @@ void mmu_init() {
|
|||
|
||||
void select_multiplexed_stepper(const uint8_t e) {
|
||||
planner.synchronize();
|
||||
disable_e_steppers();
|
||||
stepper.disable_e_steppers();
|
||||
WRITE(E_MUX0_PIN, TEST(e, 0) ? HIGH : LOW);
|
||||
WRITE(E_MUX1_PIN, TEST(e, 1) ? HIGH : LOW);
|
||||
WRITE(E_MUX2_PIN, TEST(e, 2) ? HIGH : LOW);
|
||||
|
|
|
@ -35,7 +35,7 @@ MMU2 mmu2;
|
|||
#include "../../libs/nozzle.h"
|
||||
#include "../../module/temperature.h"
|
||||
#include "../../module/planner.h"
|
||||
#include "../../module/stepper/indirection.h"
|
||||
#include "../../module/stepper.h"
|
||||
#include "../../MarlinCore.h"
|
||||
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
|
@ -486,7 +486,7 @@ static void mmu2_not_responding() {
|
|||
|
||||
if (index != extruder) {
|
||||
|
||||
DISABLE_AXIS_E0();
|
||||
stepper.disable_extruder();
|
||||
ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
|
||||
|
||||
command(MMU_CMD_T0 + index);
|
||||
|
@ -495,7 +495,7 @@ static void mmu2_not_responding() {
|
|||
if (load_to_gears()) {
|
||||
extruder = index; // filament change is finished
|
||||
active_extruder = 0;
|
||||
ENABLE_AXIS_E0();
|
||||
stepper.enable_extruder();
|
||||
SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder);
|
||||
}
|
||||
ui.reset_status();
|
||||
|
@ -531,13 +531,13 @@ static void mmu2_not_responding() {
|
|||
#if ENABLED(MMU2_MENUS)
|
||||
planner.synchronize();
|
||||
const uint8_t index = mmu2_choose_filament();
|
||||
DISABLE_AXIS_E0();
|
||||
stepper.disable_extruder();
|
||||
command(MMU_CMD_T0 + index);
|
||||
manage_response(true, true);
|
||||
|
||||
if (load_to_gears()) {
|
||||
mmu_loop();
|
||||
ENABLE_AXIS_E0();
|
||||
stepper.enable_extruder();
|
||||
extruder = index;
|
||||
active_extruder = 0;
|
||||
}
|
||||
|
@ -566,7 +566,7 @@ static void mmu2_not_responding() {
|
|||
set_runout_valid(false);
|
||||
|
||||
if (index != extruder) {
|
||||
DISABLE_AXIS_E0();
|
||||
stepper.disable_extruder();
|
||||
if (FILAMENT_PRESENT()) {
|
||||
DEBUG_ECHOLNPGM("Unloading\n");
|
||||
mmu_loading_flag = false;
|
||||
|
@ -582,7 +582,7 @@ static void mmu2_not_responding() {
|
|||
extruder = index;
|
||||
active_extruder = 0;
|
||||
|
||||
ENABLE_AXIS_E0();
|
||||
stepper.enable_extruder();
|
||||
SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder);
|
||||
|
||||
ui.reset_status();
|
||||
|
@ -620,14 +620,14 @@ static void mmu2_not_responding() {
|
|||
#if ENABLED(MMU2_MENUS)
|
||||
planner.synchronize();
|
||||
uint8_t index = mmu2_choose_filament();
|
||||
DISABLE_AXIS_E0();
|
||||
stepper.disable_extruder();
|
||||
command(MMU_CMD_T0 + index);
|
||||
manage_response(true, true);
|
||||
mmu_continue_loading();
|
||||
command(MMU_CMD_C0);
|
||||
mmu_loop();
|
||||
|
||||
ENABLE_AXIS_E0();
|
||||
stepper.enable_extruder();
|
||||
extruder = index;
|
||||
active_extruder = 0;
|
||||
#else
|
||||
|
@ -670,14 +670,14 @@ static void mmu2_not_responding() {
|
|||
set_runout_valid(false);
|
||||
|
||||
if (index != extruder) {
|
||||
DISABLE_AXIS_E0();
|
||||
stepper.disable_extruder();
|
||||
ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
|
||||
command(MMU_CMD_T0 + index);
|
||||
manage_response(true, true);
|
||||
command(MMU_CMD_C0);
|
||||
extruder = index; //filament change is finished
|
||||
active_extruder = 0;
|
||||
ENABLE_AXIS_E0();
|
||||
stepper.enable_extruder();
|
||||
SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder);
|
||||
ui.reset_status();
|
||||
}
|
||||
|
@ -714,13 +714,13 @@ static void mmu2_not_responding() {
|
|||
#if ENABLED(MMU2_MENUS)
|
||||
planner.synchronize();
|
||||
uint8_t index = mmu2_choose_filament();
|
||||
DISABLE_AXIS_E0();
|
||||
stepper.disable_extruder();
|
||||
command(MMU_CMD_T0 + index);
|
||||
manage_response(true, true);
|
||||
command(MMU_CMD_C0);
|
||||
mmu_loop();
|
||||
|
||||
ENABLE_AXIS_E0();
|
||||
stepper.enable_extruder();
|
||||
extruder = index;
|
||||
active_extruder = 0;
|
||||
#else
|
||||
|
@ -912,7 +912,7 @@ bool MMU2::load_filament_to_nozzle(const uint8_t index) {
|
|||
return false;
|
||||
}
|
||||
|
||||
DISABLE_AXIS_E0();
|
||||
stepper.disable_extruder();
|
||||
command(MMU_CMD_T0 + index);
|
||||
manage_response(true, true);
|
||||
|
||||
|
@ -950,7 +950,7 @@ bool MMU2::eject_filament(const uint8_t index, const bool recover) {
|
|||
|
||||
LCD_MESSAGEPGM(MSG_MMU2_EJECTING_FILAMENT);
|
||||
|
||||
ENABLE_AXIS_E0();
|
||||
stepper.enable_extruder();
|
||||
current_position.e -= MMU2_FILAMENTCHANGE_EJECT_FEED;
|
||||
line_to_current_position(MMM_TO_MMS(2500));
|
||||
planner.synchronize();
|
||||
|
@ -979,7 +979,7 @@ bool MMU2::eject_filament(const uint8_t index, const bool recover) {
|
|||
|
||||
BUZZ(200, 404);
|
||||
|
||||
DISABLE_AXIS_E0();
|
||||
stepper.disable_extruder();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1016,7 +1016,7 @@ bool MMU2::unload() {
|
|||
void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) {
|
||||
|
||||
planner.synchronize();
|
||||
ENABLE_AXIS_E0();
|
||||
stepper.enable_extruder();
|
||||
|
||||
const E_Step* step = sequence;
|
||||
|
||||
|
@ -1034,7 +1034,7 @@ void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) {
|
|||
step++;
|
||||
}
|
||||
|
||||
DISABLE_AXIS_E0();
|
||||
stepper.disable_extruder();
|
||||
}
|
||||
|
||||
#endif // HAS_PRUSA_MMU2
|
||||
|
|
|
@ -302,8 +302,8 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
|
|||
* send current back to their board, potentially frying it.
|
||||
*/
|
||||
inline void disable_active_extruder() {
|
||||
#if HAS_E_STEPPER_ENABLE
|
||||
disable_e_stepper(active_extruder);
|
||||
#if HAS_EXTRUDERS
|
||||
stepper.DISABLE_EXTRUDER(active_extruder);
|
||||
safe_delay(100);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "../inc/MarlinConfig.h"
|
||||
|
||||
#include "power.h"
|
||||
#include "../module/stepper/indirection.h"
|
||||
#include "../module/stepper.h"
|
||||
#include "../MarlinCore.h"
|
||||
|
||||
#if ENABLED(PS_OFF_SOUND)
|
||||
|
@ -120,6 +120,9 @@ void Power::power_off() {
|
|||
*/
|
||||
bool Power::is_power_needed() {
|
||||
|
||||
// If any of the stepper drivers are enabled...
|
||||
if (stepper.axis_enabled.bits) return true;
|
||||
|
||||
if (printJobOngoing() || printingIsPaused()) return true;
|
||||
|
||||
#if ENABLED(AUTO_POWER_FANS)
|
||||
|
@ -140,23 +143,6 @@ void Power::power_off() {
|
|||
if (TERN0(AUTO_POWER_COOLER_FAN, thermalManager.coolerfan_speed))
|
||||
return true;
|
||||
|
||||
// If any of the drivers or the bed are enabled...
|
||||
if (X_ENABLE_READ() == X_ENABLE_ON || Y_ENABLE_READ() == Y_ENABLE_ON || Z_ENABLE_READ() == Z_ENABLE_ON
|
||||
#if HAS_X2_ENABLE
|
||||
|| X2_ENABLE_READ() == X_ENABLE_ON
|
||||
#endif
|
||||
#if HAS_Y2_ENABLE
|
||||
|| Y2_ENABLE_READ() == Y_ENABLE_ON
|
||||
#endif
|
||||
#if HAS_Z2_ENABLE
|
||||
|| Z2_ENABLE_READ() == Z_ENABLE_ON
|
||||
#endif
|
||||
#if E_STEPPERS
|
||||
#define _OR_ENABLED_E(N) || E##N##_ENABLE_READ() == E_ENABLE_ON
|
||||
REPEAT(E_STEPPERS, _OR_ENABLED_E)
|
||||
#endif
|
||||
) return true;
|
||||
|
||||
#if HAS_HOTEND
|
||||
HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0 || thermalManager.temp_hotend[e].soft_pwm_amount > 0) return true;
|
||||
#endif
|
||||
|
|
|
@ -186,7 +186,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW
|
|||
TERN_(GCODE_REPEAT_MARKERS, info.stored_repeat = repeat);
|
||||
TERN_(HAS_HOME_OFFSET, info.home_offset = home_offset);
|
||||
TERN_(HAS_POSITION_SHIFT, info.position_shift = position_shift);
|
||||
TERN_(HAS_MULTI_EXTRUDER, info.active_extruder = active_extruder);
|
||||
E_TERN_(info.active_extruder = active_extruder);
|
||||
|
||||
#if DISABLED(NO_VOLUMETRICS)
|
||||
info.flag.volumetric_enabled = parser.volumetric_enabled;
|
||||
|
|
|
@ -48,10 +48,10 @@
|
|||
void GcodeSuite::M301() {
|
||||
// multi-extruder PID patch: M301 updates or prints a single extruder's PID values
|
||||
// default behavior (omitting E parameter) is to update for extruder 0 only
|
||||
int8_t e = parser.byteval('E', -1); // extruder being updated
|
||||
int8_t e = E_TERN0(parser.byteval('E', -1)); // extruder being updated
|
||||
|
||||
if (!parser.seen("PID" TERN_(PID_EXTRUSION_SCALING, "CL") TERN_(PID_FAN_SCALING, "F")))
|
||||
return M301_report(true, e);
|
||||
return M301_report(true E_OPTARG(e));
|
||||
|
||||
if (e == -1) e = 0;
|
||||
|
||||
|
@ -78,8 +78,9 @@ void GcodeSuite::M301() {
|
|||
SERIAL_ERROR_MSG(STR_INVALID_EXTRUDER);
|
||||
}
|
||||
|
||||
void GcodeSuite::M301_report(const bool forReplay/*=true*/, const int8_t eindex/*=-1*/) {
|
||||
void GcodeSuite::M301_report(const bool forReplay/*=true*/ E_OPTARG(const int8_t eindex/*=-1*/)) {
|
||||
report_heading(forReplay, PSTR(STR_HOTEND_PID));
|
||||
IF_DISABLED(HAS_MULTI_EXTRUDER, constexpr int8_t eindex = -1);
|
||||
HOTEND_LOOP() {
|
||||
if (e == eindex || eindex == -1) {
|
||||
report_echo_start(forReplay);
|
||||
|
|
|
@ -29,29 +29,186 @@
|
|||
#include "../../feature/bedlevel/bedlevel.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* M17: Enable stepper motors
|
||||
*/
|
||||
void GcodeSuite::M17() {
|
||||
if (parser.seen_axis()) {
|
||||
LOGICAL_AXIS_CODE(
|
||||
if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) enable_e_steppers(),
|
||||
if (parser.seen_test('X')) ENABLE_AXIS_X(),
|
||||
if (parser.seen_test('Y')) ENABLE_AXIS_Y(),
|
||||
if (parser.seen_test('Z')) ENABLE_AXIS_Z(),
|
||||
if (parser.seen_test(AXIS4_NAME)) ENABLE_AXIS_I(),
|
||||
if (parser.seen_test(AXIS5_NAME)) ENABLE_AXIS_J(),
|
||||
if (parser.seen_test(AXIS6_NAME)) ENABLE_AXIS_K()
|
||||
#define DEBUG_OUT ENABLED(MARLIN_DEV_MODE)
|
||||
#include "../../core/debug_out.h"
|
||||
#include "../../libs/hex_print.h"
|
||||
|
||||
inline axis_flags_t selected_axis_bits() {
|
||||
axis_flags_t selected{0};
|
||||
#if HAS_EXTRUDERS
|
||||
if (parser.seen('E')) {
|
||||
if (E_TERN0(parser.has_value())) {
|
||||
const uint8_t e = parser.value_int();
|
||||
if (e < EXTRUDERS)
|
||||
selected.bits = _BV(INDEX_OF_AXIS(E_AXIS, e));
|
||||
}
|
||||
else
|
||||
selected.bits = selected.e_bits();
|
||||
}
|
||||
#endif
|
||||
selected.bits |= LINEAR_AXIS_GANG(
|
||||
(parser.seen_test('X') << X_AXIS),
|
||||
| (parser.seen_test('Y') << Y_AXIS),
|
||||
| (parser.seen_test('Z') << Z_AXIS),
|
||||
| (parser.seen_test(AXIS4_NAME) << I_AXIS),
|
||||
| (parser.seen_test(AXIS5_NAME) << J_AXIS),
|
||||
| (parser.seen_test(AXIS6_NAME) << K_AXIS)
|
||||
);
|
||||
return selected;
|
||||
}
|
||||
else {
|
||||
LCD_MESSAGEPGM(MSG_NO_MOVE);
|
||||
enable_all_steppers();
|
||||
|
||||
// Enable specified axes and warn about other affected axes
|
||||
void do_enable(const axis_flags_t to_enable) {
|
||||
const ena_mask_t was_enabled = stepper.axis_enabled.bits,
|
||||
shall_enable = to_enable.bits & ~was_enabled;
|
||||
|
||||
DEBUG_ECHOLNPGM("Now Enabled: ", hex_word(stepper.axis_enabled.bits), " Enabling: ", hex_word(to_enable.bits), " | ", shall_enable);
|
||||
|
||||
if (!shall_enable) return; // All specified axes already enabled?
|
||||
|
||||
ena_mask_t also_enabled = 0; // Track steppers enabled due to overlap
|
||||
|
||||
// Enable all flagged axes
|
||||
LOOP_LINEAR_AXES(a) {
|
||||
if (TEST(shall_enable, a)) {
|
||||
stepper.enable_axis(AxisEnum(a)); // Mark and enable the requested axis
|
||||
DEBUG_ECHOLNPGM("Enabled ", axis_codes[a], " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... Enabled: ", hex_word(stepper.axis_enabled.bits));
|
||||
also_enabled |= enable_overlap[a];
|
||||
}
|
||||
}
|
||||
#if HAS_EXTRUDERS
|
||||
LOOP_L_N(e, EXTRUDERS) {
|
||||
const uint8_t a = INDEX_OF_AXIS(E_AXIS, e);
|
||||
if (TEST(shall_enable, a)) {
|
||||
stepper.ENABLE_EXTRUDER(e);
|
||||
DEBUG_ECHOLNPGM("Enabled E", AS_DIGIT(e), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... ", hex_word(stepper.axis_enabled.bits));
|
||||
also_enabled |= enable_overlap[a];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((also_enabled &= ~(shall_enable | was_enabled))) {
|
||||
SERIAL_CHAR('(');
|
||||
LOOP_LINEAR_AXES(a) if (TEST(also_enabled, a)) SERIAL_CHAR(axis_codes[a], ' ');
|
||||
#if HAS_EXTRUDERS
|
||||
#define _EN_ALSO(N) if (TEST(also_enabled, INDEX_OF_AXIS(E_AXIS, N))) SERIAL_CHAR('E', '0' + N, ' ');
|
||||
REPEAT(EXTRUDERS, _EN_ALSO)
|
||||
#endif
|
||||
SERIAL_ECHOLNPGM("also enabled)");
|
||||
}
|
||||
|
||||
DEBUG_ECHOLNPGM("Enabled Now: ", hex_word(stepper.axis_enabled.bits));
|
||||
}
|
||||
|
||||
/**
|
||||
* M18, M84: Disable stepper motors
|
||||
* M17: Enable stepper motor power for one or more axes.
|
||||
* Print warnings for axes that share an ENABLE_PIN.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* M17 XZ ; Enable X and Z axes
|
||||
* M17 E ; Enable all E steppers
|
||||
* M17 E1 ; Enable just the E1 stepper
|
||||
*/
|
||||
void GcodeSuite::M17() {
|
||||
if (parser.seen_axis()) {
|
||||
if (any_enable_overlap())
|
||||
do_enable(selected_axis_bits());
|
||||
else {
|
||||
#if HAS_EXTRUDERS
|
||||
if (parser.seen('E')) {
|
||||
if (parser.has_value()) {
|
||||
const uint8_t e = parser.value_int();
|
||||
if (e < EXTRUDERS) stepper.ENABLE_EXTRUDER(e);
|
||||
}
|
||||
else
|
||||
stepper.enable_e_steppers();
|
||||
}
|
||||
#endif
|
||||
LINEAR_AXIS_CODE(
|
||||
if (parser.seen_test('X')) stepper.enable_axis(X_AXIS),
|
||||
if (parser.seen_test('Y')) stepper.enable_axis(Y_AXIS),
|
||||
if (parser.seen_test('Z')) stepper.enable_axis(Z_AXIS),
|
||||
if (parser.seen_test(AXIS4_NAME)) stepper.enable_axis(I_AXIS),
|
||||
if (parser.seen_test(AXIS5_NAME)) stepper.enable_axis(J_AXIS),
|
||||
if (parser.seen_test(AXIS6_NAME)) stepper.enable_axis(K_AXIS)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LCD_MESSAGEPGM(MSG_NO_MOVE);
|
||||
stepper.enable_all_steppers();
|
||||
}
|
||||
}
|
||||
|
||||
void try_to_disable(const axis_flags_t to_disable) {
|
||||
ena_mask_t still_enabled = to_disable.bits & stepper.axis_enabled.bits;
|
||||
|
||||
DEBUG_ECHOLNPGM("Enabled: ", hex_word(stepper.axis_enabled.bits), " To Disable: ", hex_word(to_disable.bits), " | ", hex_word(still_enabled));
|
||||
|
||||
if (!still_enabled) return;
|
||||
|
||||
// Attempt to disable all flagged axes
|
||||
LOOP_LINEAR_AXES(a)
|
||||
if (TEST(to_disable.bits, a)) {
|
||||
DEBUG_ECHOPGM("Try to disable ", axis_codes[a], " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... ");
|
||||
if (stepper.disable_axis(AxisEnum(a))) { // Mark the requested axis and request to disable
|
||||
DEBUG_ECHOPGM("OK");
|
||||
still_enabled &= ~(_BV(a) | enable_overlap[a]); // If actually disabled, clear one or more tracked bits
|
||||
}
|
||||
else
|
||||
DEBUG_ECHOPGM("OVERLAP");
|
||||
DEBUG_ECHOLNPGM(" ... still_enabled=", hex_word(still_enabled));
|
||||
}
|
||||
#if HAS_EXTRUDERS
|
||||
LOOP_L_N(e, EXTRUDERS) {
|
||||
const uint8_t a = INDEX_OF_AXIS(E_AXIS, e);
|
||||
if (TEST(to_disable.bits, a)) {
|
||||
DEBUG_ECHOPGM("Try to disable E", AS_DIGIT(e), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... ");
|
||||
if (stepper.DISABLE_EXTRUDER(e)) {
|
||||
DEBUG_ECHOPGM("OK");
|
||||
still_enabled &= ~(_BV(a) | enable_overlap[a]);
|
||||
}
|
||||
else
|
||||
DEBUG_ECHOPGM("OVERLAP");
|
||||
DEBUG_ECHOLNPGM(" ... still_enabled=", hex_word(still_enabled));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
auto overlap_warning = [](const ena_mask_t axis_bits) {
|
||||
SERIAL_ECHOPGM(" not disabled. Shared with");
|
||||
LOOP_LINEAR_AXES(a) if (TEST(axis_bits, a)) SERIAL_CHAR(' ', axis_codes[a]);
|
||||
#if HAS_EXTRUDERS
|
||||
#define _EN_STILLON(N) if (TEST(axis_bits, INDEX_OF_AXIS(E_AXIS, N))) SERIAL_CHAR(' ', 'E', '0' + N);
|
||||
REPEAT(EXTRUDERS, _EN_STILLON)
|
||||
#endif
|
||||
SERIAL_ECHOLNPGM(".");
|
||||
};
|
||||
|
||||
// If any of the requested axes are still enabled, give a warning
|
||||
LOOP_LINEAR_AXES(a) {
|
||||
if (TEST(still_enabled, a)) {
|
||||
SERIAL_CHAR(axis_codes[a]);
|
||||
overlap_warning(stepper.axis_enabled.bits & enable_overlap[a]);
|
||||
}
|
||||
}
|
||||
#if HAS_EXTRUDERS
|
||||
LOOP_L_N(e, EXTRUDERS) {
|
||||
const uint8_t a = INDEX_OF_AXIS(E_AXIS, e);
|
||||
if (TEST(still_enabled, a)) {
|
||||
SERIAL_CHAR('E', '0' + e);
|
||||
overlap_warning(stepper.axis_enabled.bits & enable_overlap[a]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
DEBUG_ECHOLNPGM("Enabled Now: ", hex_word(stepper.axis_enabled.bits));
|
||||
}
|
||||
|
||||
/**
|
||||
* M18, M84: Disable stepper motor power for one or more axes.
|
||||
* Print warnings for axes that share an ENABLE_PIN.
|
||||
*/
|
||||
void GcodeSuite::M18_M84() {
|
||||
if (parser.seenval('S')) {
|
||||
|
@ -61,16 +218,27 @@ void GcodeSuite::M18_M84() {
|
|||
else {
|
||||
if (parser.seen_axis()) {
|
||||
planner.synchronize();
|
||||
LOGICAL_AXIS_CODE(
|
||||
if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) disable_e_steppers(),
|
||||
if (parser.seen_test('X')) DISABLE_AXIS_X(),
|
||||
if (parser.seen_test('Y')) DISABLE_AXIS_Y(),
|
||||
if (parser.seen_test('Z')) DISABLE_AXIS_Z(),
|
||||
if (parser.seen_test(AXIS4_NAME)) DISABLE_AXIS_I(),
|
||||
if (parser.seen_test(AXIS5_NAME)) DISABLE_AXIS_J(),
|
||||
if (parser.seen_test(AXIS6_NAME)) DISABLE_AXIS_K()
|
||||
if (any_enable_overlap())
|
||||
try_to_disable(selected_axis_bits());
|
||||
else {
|
||||
#if HAS_EXTRUDERS
|
||||
if (parser.seen('E')) {
|
||||
if (E_TERN0(parser.has_value()))
|
||||
stepper.DISABLE_EXTRUDER(parser.value_int());
|
||||
else
|
||||
stepper.disable_e_steppers();
|
||||
}
|
||||
#endif
|
||||
LINEAR_AXIS_CODE(
|
||||
if (parser.seen_test('X')) stepper.disable_axis(X_AXIS),
|
||||
if (parser.seen_test('Y')) stepper.disable_axis(Y_AXIS),
|
||||
if (parser.seen_test('Z')) stepper.disable_axis(Z_AXIS),
|
||||
if (parser.seen_test(AXIS4_NAME)) stepper.disable_axis(I_AXIS),
|
||||
if (parser.seen_test(AXIS5_NAME)) stepper.disable_axis(J_AXIS),
|
||||
if (parser.seen_test(AXIS6_NAME)) stepper.disable_axis(K_AXIS)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
planner.finish_and_disable();
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
* G10 - Retract filament according to settings of M207
|
||||
* TODO: Handle 'G10 P' for tool settings and 'G10 L' for workspace settings
|
||||
*/
|
||||
void GcodeSuite::G10() { fwretract.retract(true OPTARG(HAS_MULTI_EXTRUDER, parser.boolval('S'))); }
|
||||
void GcodeSuite::G10() { fwretract.retract(true E_OPTARG(parser.boolval('S'))); }
|
||||
|
||||
/**
|
||||
* G11 - Recover filament according to settings of M208
|
||||
|
|
|
@ -879,7 +879,7 @@ private:
|
|||
|
||||
#if ENABLED(PIDTEMP)
|
||||
static void M301();
|
||||
static void M301_report(const bool forReplay=true, const int8_t eindex=-1);
|
||||
static void M301_report(const bool forReplay=true E_OPTARG(const int8_t eindex=-1));
|
||||
#endif
|
||||
|
||||
#if ENABLED(PREVENT_COLD_EXTRUSION)
|
||||
|
|
|
@ -587,6 +587,8 @@
|
|||
* HOTENDS - Number of hotends, whether connected or separate
|
||||
* E_STEPPERS - Number of actual E stepper motors
|
||||
* E_MANUAL - Number of E steppers for LCD move options
|
||||
*
|
||||
* These defines must be simple constants for use in REPEAT, etc.
|
||||
*/
|
||||
#if EXTRUDERS
|
||||
#define HAS_EXTRUDERS 1
|
||||
|
@ -605,9 +607,14 @@
|
|||
#undef DISABLE_E
|
||||
#endif
|
||||
|
||||
#define E_OPTARG(N) OPTARG(HAS_MULTI_EXTRUDER, N)
|
||||
#define E_TERN_(N) TERN_(HAS_MULTI_EXTRUDER, N)
|
||||
#define E_TERN0(N) TERN0(HAS_MULTI_EXTRUDER, N)
|
||||
|
||||
#if ENABLED(E_DUAL_STEPPER_DRIVERS) // E0/E1 steppers act in tandem as E0
|
||||
|
||||
#define E_STEPPERS 2
|
||||
#define E_MANUAL 1
|
||||
|
||||
#elif ENABLED(SWITCHING_EXTRUDER) // One stepper for every two EXTRUDERS
|
||||
|
||||
|
@ -638,6 +645,7 @@
|
|||
#elif HAS_PRUSA_MMU2 // Průša Multi-Material Unit v2
|
||||
|
||||
#define E_STEPPERS 1
|
||||
#define E_MANUAL 1
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "FileNavigator.h"
|
||||
|
||||
#include "../../../gcode/queue.h"
|
||||
#include "../../../module/stepper.h"
|
||||
#include "../../../sd/cardreader.h"
|
||||
#include "../../../libs/numtostr.h"
|
||||
#include "../../../MarlinCore.h"
|
||||
|
@ -665,7 +666,7 @@ void ChironTFT::PanelAction(uint8_t req) {
|
|||
|
||||
case 19: // A19 Motors off
|
||||
if (!isPrinting()) {
|
||||
disable_all_steppers(); // from marlincore.h
|
||||
stepper.disable_all_steppers();
|
||||
SendtoTFTLN(AC_msg_ready);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "../ui_api.h"
|
||||
|
||||
#include "../../../libs/numtostr.h"
|
||||
#include "../../../module/stepper.h" // for disable_all_steppers
|
||||
#include "../../../module/motion.h" // for quickstop_stepper, A20 read printing speed, feedrate_percentage
|
||||
#include "../../../MarlinCore.h" // for disable_steppers
|
||||
#include "../../../inc/MarlinConfig.h"
|
||||
|
@ -738,7 +739,7 @@ void AnycubicTFTClass::GetCommandFromTFT() {
|
|||
case 19: // A19 stop stepper drivers - sent on stop extrude command and on turn motors off command
|
||||
if (!isPrinting()) {
|
||||
quickstop_stepper();
|
||||
disable_all_steppers();
|
||||
stepper.disable_all_steppers();
|
||||
}
|
||||
|
||||
SENDLINE_PGM("");
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "../../../core/language.h"
|
||||
#include "../../../module/temperature.h"
|
||||
#include "../../../module/printcounter.h"
|
||||
#include "../../../module/stepper.h"
|
||||
#include "../../../gcode/queue.h"
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
#include "../../../feature/pause.h"
|
||||
|
@ -375,10 +376,10 @@ void DGUSRxHandler::Steppers(DGUS_VP &vp, void *data_ptr) {
|
|||
|
||||
switch (control) {
|
||||
case DGUS_Data::Control::ENABLE:
|
||||
enable_all_steppers();
|
||||
stepper.enable_all_steppers();
|
||||
break;
|
||||
case DGUS_Data::Control::DISABLE:
|
||||
disable_all_steppers();
|
||||
stepper.disable_all_steppers();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -553,7 +554,7 @@ void DGUSRxHandler::FilamentSelect(DGUS_VP &vp, void *data_ptr) {
|
|||
default: return;
|
||||
case DGUS_Data::Extruder::CURRENT:
|
||||
case DGUS_Data::Extruder::E0:
|
||||
TERN_(HAS_MULTI_EXTRUDER, case DGUS_Data::Extruder::E1:)
|
||||
E_TERN_(case DGUS_Data::Extruder::E1:)
|
||||
dgus_screen_handler.filament_extruder = extruder;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -286,14 +286,8 @@ void DGUSTxHandler::TempMax(DGUS_VP &vp) {
|
|||
}
|
||||
|
||||
void DGUSTxHandler::StepperStatus(DGUS_VP &vp) {
|
||||
if (X_ENABLE_READ() == X_ENABLE_ON
|
||||
&& Y_ENABLE_READ() == Y_ENABLE_ON
|
||||
&& Z_ENABLE_READ() == Z_ENABLE_ON) {
|
||||
dgus_display.Write((uint16_t)vp.addr, Swap16((uint16_t)DGUS_Data::Status::ENABLED));
|
||||
}
|
||||
else {
|
||||
dgus_display.Write((uint16_t)vp.addr, Swap16((uint16_t)DGUS_Data::Status::DISABLED));
|
||||
}
|
||||
const bool motor_on = stepper.axis_enabled.bits & (_BV(LINEAR_AXES) - 1);
|
||||
dgus_display.Write((uint16_t)vp.addr, Swap16(uint16_t(motor_on ? DGUS_Data::Status::ENABLED : DGUS_Data::Status::DISABLED)));
|
||||
}
|
||||
|
||||
void DGUSTxHandler::StepIcons(DGUS_VP &vp) {
|
||||
|
|
|
@ -125,7 +125,7 @@ void StressTestScreen::onIdle() {
|
|||
injectCommands_P(PSTR(
|
||||
"G0 X100 Y100 Z100 F6000\n"
|
||||
"T0\nG4 S1"
|
||||
TERN_(HAS_MULTI_EXTRUDER, "\nT1\nG4 S1")
|
||||
E_TERN_("\nT1\nG4 S1")
|
||||
"\nG0 X150 Y150 Z150"
|
||||
));
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "../../../MarlinCore.h"
|
||||
#include "../../../feature/pause.h"
|
||||
#include "../../../module/stepper.h"
|
||||
#include "../../../gcode/queue.h"
|
||||
#include "../../../libs/numtostr.h"
|
||||
#include "../../../sd/cardreader.h"
|
||||
|
@ -536,7 +537,7 @@ void NextionTFT::PanelAction(uint8_t req) {
|
|||
|
||||
case 57: // Disable Motors
|
||||
if (!isPrinting()) {
|
||||
disable_all_steppers(); // from marlincore.h
|
||||
stepper.disable_all_steppers();
|
||||
SEND_TXT("tmppage.M117", "Motors disabled");
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue