Modify E-stepping macros for use in LINEAR_ADVANCE (#10887)

This commit is contained in:
Scott Lahteine 2018-05-28 19:33:54 -05:00 committed by GitHub
parent 2c4d8761ec
commit d6cd7d924c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 171 deletions

View File

@ -246,7 +246,7 @@ volatile int32_t Stepper::endstops_trigsteps[XYZ];
#endif
#if DISABLED(MIXING_EXTRUDER)
#define E_APPLY_STEP(v,Q) E_STEP_WRITE(v)
#define E_APPLY_STEP(v,Q) E_STEP_WRITE(current_block->active_extruder, v)
#endif
// intRes = longIn1 * longIn2 >> 24
@ -364,11 +364,11 @@ void Stepper::set_directions() {
#if DISABLED(LIN_ADVANCE)
if (motor_direction(E_AXIS)) {
REV_E_DIR();
REV_E_DIR(current_block->active_extruder);
count_direction[E_AXIS] = -1;
}
else {
NORM_E_DIR();
NORM_E_DIR(current_block->active_extruder);
count_direction[E_AXIS] = 1;
}
#endif // !LIN_ADVANCE
@ -402,7 +402,7 @@ void Stepper::set_directions() {
*
* V_f(t) = A*t^5 + B*t^4 + C*t^3 + D*t^2 + E*t + F
*
* Looking at the above B_0(t) through B_5(t) expanded forms, if we take the coefficients of t^5
* Looking at the above B_0(t) through B_5(t) expanded forms, if we take the coefficients of t^5
* through t of the Bézier form of V(t), we can determine that:
*
* A = -P_0 + 5*P_1 - 10*P_2 + 10*P_3 - 5*P_4 + P_5
@ -1386,7 +1386,7 @@ void Stepper::stepper_pulse_phase_isr() {
// Step mixing steppers (proportionally)
counter_m[j] += current_block->steps[E_AXIS];
// Step when the counter goes over zero
if (counter_m[j] >= 0) En_STEP_WRITE(j, !INVERT_E_STEP_PIN);
if (counter_m[j] >= 0) E_STEP_WRITE(j, !INVERT_E_STEP_PIN);
}
#else // !MIXING_EXTRUDER
PULSE_START(E);
@ -1428,7 +1428,7 @@ void Stepper::stepper_pulse_phase_isr() {
MIXING_STEPPERS_LOOP(j) {
if (counter_m[j] >= 0) {
counter_m[j] -= current_block->mix_event_count[j];
En_STEP_WRITE(j, INVERT_E_STEP_PIN);
E_STEP_WRITE(j, INVERT_E_STEP_PIN);
}
}
#else // !MIXING_EXTRUDER
@ -1709,10 +1709,10 @@ uint32_t Stepper::stepper_block_phase_isr() {
#endif
// Initialize Bresenham counters to 1/2 the ceiling, with proper roundup (as explained in the article linked above)
counter_X = counter_Y = counter_Z = counter_E = -int32_t((current_block->step_event_count >> 1) + (current_block->step_event_count & 1));
counter_X = counter_Y = counter_Z = counter_E = -int32_t((current_block->step_event_count + 1) >> 1);
#if ENABLED(MIXING_EXTRUDER)
MIXING_STEPPERS_LOOP(i)
counter_m[i] = -int32_t((current_block->mix_event_count[i] >> 1) + (current_block->mix_event_count[i] & 1));
counter_m[i] = -int32_t((current_block->mix_event_count[i] + 1) >> 1);
#endif
#if ENABLED(Z_LATE_ENABLE)
@ -1737,61 +1737,6 @@ uint32_t Stepper::stepper_block_phase_isr() {
uint32_t Stepper::advance_isr() {
uint32_t interval;
#if ENABLED(MK2_MULTIPLEXER) // For SNMM even-numbered steppers are reversed
#define SET_E_STEP_DIR(INDEX) do{ if (e_steps) E0_DIR_WRITE(e_steps < 0 ? !INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0) : INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0)); }while(0)
#elif ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
#define SET_E_STEP_DIR(INDEX) do{ if (e_steps) { if (e_steps < 0) REV_E_DIR(); else NORM_E_DIR(); } }while(0)
#elif ENABLED(SWITCHING_EXTRUDER)
#if EXTRUDERS > 4
#define SET_E_STEP_DIR(INDEX) do{ if (e_steps) { switch (INDEX) { \
case 0: case 1: E0_DIR_WRITE(!INVERT_E0_DIR ^ TEST(INDEX, 0) ^ (e_steps < 0)); break; \
case 2: case 3: E1_DIR_WRITE(!INVERT_E1_DIR ^ TEST(INDEX, 0) ^ (e_steps < 0)); break; \
case 4: E2_DIR_WRITE(!INVERT_E2_DIR ^ TEST(INDEX, 0) ^ (e_steps < 0)); \
} } }while(0)
#elif EXTRUDERS > 2
#define SET_E_STEP_DIR(INDEX) do{ if (e_steps) { switch (INDEX) { \
case 0: case 1: E0_DIR_WRITE(!INVERT_E0_DIR ^ TEST(INDEX, 0) ^ (e_steps < 0)); break; \
case 2: case 3: E1_DIR_WRITE(!INVERT_E1_DIR ^ TEST(INDEX, 0) ^ (e_steps < 0)); break; \
} } }while(0)
#else
#define SET_E_STEP_DIR(INDEX) do{ if (e_steps) E0_DIR_WRITE(!INVERT_E0_DIR ^ TEST(INDEX, 0) ^ (e_steps < 0)); }while(0)
#endif
#else
#define SET_E_STEP_DIR(INDEX) do{ if (e_steps) E## INDEX ##_DIR_WRITE(!INVERT_E## INDEX ##_DIR ^ (e_steps < 0)); }while(0)
#endif
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
#define START_E_PULSE(INDEX) do{ if (e_steps) E_STEP_WRITE(!INVERT_E_STEP_PIN); }while(0)
#define STOP_E_PULSE(INDEX) do{ if (e_steps) { e_steps < 0 ? ++e_steps : --e_steps; E_STEP_WRITE(INVERT_E_STEP_PIN); } }while(0)
#elif ENABLED(SWITCHING_EXTRUDER)
#if EXTRUDERS > 4
#define START_E_PULSE(INDEX) do{ if (e_steps) { switch (INDEX) { \
case 0: case 1: E0_STEP_WRITE(!INVERT_E_STEP_PIN); break; \
case 2: case 3: E1_STEP_WRITE(!INVERT_E_STEP_PIN); break; \
case 4: E2_STEP_WRITE(!INVERT_E_STEP_PIN); } \
} }while(0)
#define STOP_E_PULSE(INDEX) do{ if (e_steps) { \
e_steps < 0 ? ++e_steps : --e_steps; \
switch (INDEX) { \
case 0: case 1: E0_STEP_WRITE( INVERT_E_STEP_PIN); break; \
case 2: case 3: E1_STEP_WRITE( INVERT_E_STEP_PIN); break; \
case 4: E2_STEP_WRITE( INVERT_E_STEP_PIN); } \
} }while(0)
#elif EXTRUDERS > 2
#define START_E_PULSE(INDEX) do{ if (e_steps) { if (INDEX < 2) E0_STEP_WRITE(!INVERT_E_STEP_PIN); else E1_STEP_WRITE(!INVERT_E_STEP_PIN); } }while(0)
#define STOP_E_PULSE(INDEX) do{ if (e_steps) { \
e_steps < 0 ? ++e_steps : --e_steps; \
if (INDEX < 2) E0_STEP_WRITE(INVERT_E_STEP_PIN); else E1_STEP_WRITE(INVERT_E_STEP_PIN); \
} }while(0)
#else
#define START_E_PULSE(INDEX) do{ if (e_steps) E0_STEP_WRITE(!INVERT_E_STEP_PIN); }while(0)
#define STOP_E_PULSE(INDEX) do{ if (e_steps) { e_steps < 0 ? ++e_steps : --e_steps; E0_STEP_WRITE(INVERT_E_STEP_PIN); }while(0)
#endif
#else
#define START_E_PULSE(INDEX) do{ if (e_steps) E## INDEX ##_STEP_WRITE(!INVERT_E_STEP_PIN); }while(0)
#define STOP_E_PULSE(INDEX) do { if (e_steps) { e_steps < 0 ? ++e_steps : --e_steps; E## INDEX ##_STEP_WRITE(INVERT_E_STEP_PIN); } }while(0)
#endif
if (use_advance_lead) {
if (step_events_completed > LA_decelerate_after && current_adv_steps > final_adv_steps) {
e_steps--;
@ -1810,21 +1755,10 @@ uint32_t Stepper::stepper_block_phase_isr() {
else
interval = ADV_NEVER;
switch (LA_active_extruder) {
case 0: SET_E_STEP_DIR(0); break;
#if EXTRUDERS > 1
case 1: SET_E_STEP_DIR(1); break;
#if EXTRUDERS > 2
case 2: SET_E_STEP_DIR(2); break;
#if EXTRUDERS > 3
case 3: SET_E_STEP_DIR(3); break;
#if EXTRUDERS > 4
case 4: SET_E_STEP_DIR(4); break;
#endif // EXTRUDERS > 4
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
}
if (e_steps >= 0)
NORM_E_DIR(LA_active_extruder);
else
REV_E_DIR(LA_active_extruder);
// Step E stepper if we have steps
while (e_steps) {
@ -1833,21 +1767,7 @@ uint32_t Stepper::stepper_block_phase_isr() {
hal_timer_t pulse_start = HAL_timer_get_count(PULSE_TIMER_NUM);
#endif
switch (LA_active_extruder) {
case 0: START_E_PULSE(0); break;
#if EXTRUDERS > 1
case 1: START_E_PULSE(1); break;
#if EXTRUDERS > 2
case 2: START_E_PULSE(2); break;
#if EXTRUDERS > 3
case 3: START_E_PULSE(3); break;
#if EXTRUDERS > 4
case 4: START_E_PULSE(4); break;
#endif // EXTRUDERS > 4
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
}
E_STEP_WRITE(LA_active_extruder, !INVERT_E_STEP_PIN);
// For minimum pulse time wait before stopping pulses
#if EXTRA_CYCLES_E > 20
@ -1857,21 +1777,9 @@ uint32_t Stepper::stepper_block_phase_isr() {
DELAY_NS(EXTRA_CYCLES_E * NANOSECONDS_PER_CYCLE);
#endif
switch (LA_active_extruder) {
case 0: STOP_E_PULSE(0); break;
#if EXTRUDERS > 1
case 1: STOP_E_PULSE(1); break;
#if EXTRUDERS > 2
case 2: STOP_E_PULSE(2); break;
#if EXTRUDERS > 3
case 3: STOP_E_PULSE(3); break;
#if EXTRUDERS > 4
case 4: STOP_E_PULSE(4); break;
#endif // EXTRUDERS > 4
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
}
e_steps < 0 ? ++e_steps : --e_steps;
E_STEP_WRITE(LA_active_extruder, INVERT_E_STEP_PIN);
// For minimum pulse time wait before looping
#if EXTRA_CYCLES_E > 20
@ -2015,19 +1923,19 @@ void Stepper::init() {
AXIS_INIT(Z, Z);
#endif
#if HAS_E0_STEP
#if E_STEPPERS > 0 && HAS_E0_STEP
E_AXIS_INIT(0);
#endif
#if HAS_E1_STEP
#if E_STEPPERS > 1 && HAS_E1_STEP
E_AXIS_INIT(1);
#endif
#if HAS_E2_STEP
#if E_STEPPERS > 2 && HAS_E2_STEP
E_AXIS_INIT(2);
#endif
#if HAS_E3_STEP
#if E_STEPPERS > 3 && HAS_E3_STEP
E_AXIS_INIT(3);
#endif
#if HAS_E4_STEP
#if E_STEPPERS > 4 && HAS_E4_STEP
E_AXIS_INIT(4);
#endif

View File

@ -446,73 +446,54 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
/**
* Extruder indirection for the single E axis
*/
#if ENABLED(SWITCHING_EXTRUDER)
#if ENABLED(SWITCHING_EXTRUDER) // One stepper driver per two extruders, reversed on odd index
#if EXTRUDERS > 4
#define E_STEP_WRITE(v) do{ if (current_block->active_extruder < 2) { E0_STEP_WRITE(v); } else if (current_block->active_extruder < 4) { E1_STEP_WRITE(v); } else { E2_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); break; case 4: E2_DIR_WRITE(!INVERT_E2_DIR); } }while(0)
#define REV_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 4: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
#define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else if (E < 4) { E1_STEP_WRITE(V); } else { E2_STEP_WRITE(V); } }while(0)
#define NORM_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); break; case 4: E2_DIR_WRITE(!INVERT_E2_DIR); } }while(0)
#define REV_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 4: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
#elif EXTRUDERS > 3
#define E_STEP_WRITE(v) do{ if (current_block->active_extruder < 2) { E0_STEP_WRITE(v); } else { E1_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
#define REV_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
#define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
#define NORM_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
#define REV_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
#elif EXTRUDERS > 2
#define E_STEP_WRITE(v) do{ if (current_block->active_extruder < 2) { E0_STEP_WRITE(v); } else { E1_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
#define REV_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
#define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
#define NORM_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
#define REV_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
#else
#define E_STEP_WRITE(v) E0_STEP_WRITE(v)
#define NORM_E_DIR() do{ E0_DIR_WRITE(current_block->active_extruder ? INVERT_E0_DIR : !INVERT_E0_DIR); }while(0)
#define REV_E_DIR() do{ E0_DIR_WRITE(current_block->active_extruder ? !INVERT_E0_DIR : INVERT_E0_DIR); }while(0)
#define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
#define NORM_E_DIR(E) do{ E0_DIR_WRITE(E ? INVERT_E0_DIR : !INVERT_E0_DIR); }while(0)
#define REV_E_DIR(E) do{ E0_DIR_WRITE(E ? !INVERT_E0_DIR : INVERT_E0_DIR); }while(0)
#endif
#elif ENABLED(MK2_MULTIPLEXER) // Even-numbered steppers are reversed
#define E_STEP_WRITE(v) E0_STEP_WRITE(v)
#define NORM_E_DIR() do{ E0_DIR_WRITE(TEST(current_block->active_extruder, 0) ? !INVERT_E0_DIR: INVERT_E0_DIR); }while(0)
#define REV_E_DIR() do{ E0_DIR_WRITE(TEST(current_block->active_extruder, 0) ? INVERT_E0_DIR: !INVERT_E0_DIR); }while(0)
#elif EXTRUDERS > 4
#define E_STEP_WRITE(v) do{ switch (current_block->active_extruder) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); break; case 4: E4_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; case 4: E4_DIR_WRITE(!INVERT_E4_DIR); } }while(0)
#define REV_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); break; case 4: E4_DIR_WRITE( INVERT_E4_DIR); } }while(0)
#elif EXTRUDERS > 3
#define E_STEP_WRITE(v) do{ switch (current_block->active_extruder) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); } }while(0)
#define REV_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); } }while(0)
#elif EXTRUDERS > 2
#define E_STEP_WRITE(v) do{ switch (current_block->active_extruder) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); } }while(0)
#define REV_E_DIR() do{ switch (current_block->active_extruder) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
#elif EXTRUDERS > 1
#elif ENABLED(MK2_MULTIPLEXER) // One multiplexed stepper driver, reversed on odd index
#define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
#define NORM_E_DIR(E) do{ E0_DIR_WRITE(TEST(E, 0) ? !INVERT_E0_DIR: INVERT_E0_DIR); }while(0)
#define REV_E_DIR(E) do{ E0_DIR_WRITE(TEST(E, 0) ? INVERT_E0_DIR: !INVERT_E0_DIR); }while(0)
#elif E_STEPPERS > 4
#define E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); break; case 4: E4_STEP_WRITE(V); } }while(0)
#define NORM_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; case 4: E4_DIR_WRITE(!INVERT_E4_DIR); } }while(0)
#define REV_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); break; case 4: E4_DIR_WRITE( INVERT_E4_DIR); } }while(0)
#elif E_STEPPERS > 3
#define E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); } }while(0)
#define NORM_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); } }while(0)
#define REV_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); } }while(0)
#elif E_STEPPERS > 2
#define E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); } }while(0)
#define NORM_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); } }while(0)
#define REV_E_DIR(E) do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
#elif E_STEPPERS > 1
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
#define E_STEP_WRITE(v) do{ if (extruder_duplication_enabled) { E0_STEP_WRITE(v); E1_STEP_WRITE(v); } else if (current_block->active_extruder == 0) { E0_STEP_WRITE(v); } else { E1_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ if (extruder_duplication_enabled) { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); } else if (current_block->active_extruder == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
#define REV_E_DIR() do{ if (extruder_duplication_enabled) { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); } else if (current_block->active_extruder == 0) { E0_DIR_WRITE( INVERT_E0_DIR); } else { E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
#define E_STEP_WRITE(E,V) do{ if (extruder_duplication_enabled) { E0_STEP_WRITE(V); E1_STEP_WRITE(V); } else if (E == 0) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
#define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); } else if (E == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
#define REV_E_DIR(E) do{ if (extruder_duplication_enabled) { E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); } else if (E == 0) { E0_DIR_WRITE( INVERT_E0_DIR); } else { E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
#else
#define E_STEP_WRITE(v) do{ if (current_block->active_extruder == 0) { E0_STEP_WRITE(v); } else { E1_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ if (current_block->active_extruder == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
#define REV_E_DIR() do{ if (current_block->active_extruder == 0) { E0_DIR_WRITE( INVERT_E0_DIR); } else { E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
#endif
#elif ENABLED(MIXING_EXTRUDER)
#define E_STEP_WRITE(v) NOOP /* not used for mixing extruders! */
#if MIXING_STEPPERS > 4
#define En_STEP_WRITE(n,v) do{ switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); break; case 4: E4_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); E2_DIR_WRITE(!INVERT_E2_DIR); E3_DIR_WRITE(!INVERT_E3_DIR); E4_DIR_WRITE(!INVERT_E4_DIR); }while(0)
#define REV_E_DIR() do{ E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); E2_DIR_WRITE( INVERT_E2_DIR); E3_DIR_WRITE( INVERT_E3_DIR); E4_DIR_WRITE( INVERT_E4_DIR); }while(0)
#elif MIXING_STEPPERS > 3
#define En_STEP_WRITE(n,v) do{ switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); E2_DIR_WRITE(!INVERT_E2_DIR); E3_DIR_WRITE(!INVERT_E3_DIR); }while(0)
#define REV_E_DIR() do{ E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); E2_DIR_WRITE( INVERT_E2_DIR); E3_DIR_WRITE( INVERT_E3_DIR); }while(0)
#elif MIXING_STEPPERS > 2
#define En_STEP_WRITE(n,v) do{ switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); E2_DIR_WRITE(!INVERT_E2_DIR); }while(0)
#define REV_E_DIR() do{ E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); E2_DIR_WRITE( INVERT_E2_DIR); }while(0)
#else
#define En_STEP_WRITE(n,v) do{ switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); } }while(0)
#define NORM_E_DIR() do{ E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); }while(0)
#define REV_E_DIR() do{ E0_DIR_WRITE( INVERT_E0_DIR); E1_DIR_WRITE( INVERT_E1_DIR); }while(0)
#define E_STEP_WRITE(E,V) do{ if (E == 0) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
#define NORM_E_DIR(E) do{ if (E == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
#define REV_E_DIR(E) do{ if (E == 0) { E0_DIR_WRITE( INVERT_E0_DIR); } else { E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
#endif
#else
#define E_STEP_WRITE(v) E0_STEP_WRITE(v)
#define NORM_E_DIR() E0_DIR_WRITE(!INVERT_E0_DIR)
#define REV_E_DIR() E0_DIR_WRITE( INVERT_E0_DIR)
#define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
#define NORM_E_DIR(E) E0_DIR_WRITE(!INVERT_E0_DIR)
#define REV_E_DIR(E) E0_DIR_WRITE( INVERT_E0_DIR)
#endif
#endif // STEPPER_INDIRECTION_H