Skip to content

Commit aa3a24a

Browse files
tombrazierimp67
authored andcommitted
✨ Permit Linear Advance with I2S Streaming (MarlinFirmware#24684)
1 parent 1b0c26a commit aa3a24a

File tree

5 files changed

+44
-27
lines changed

5 files changed

+44
-27
lines changed

Diff for: Marlin/src/HAL/ESP32/i2s.cpp

+25-7
Original file line numberDiff line numberDiff line change
@@ -139,22 +139,40 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg) {
139139
}
140140

141141
void stepperTask(void *parameter) {
142-
uint32_t remaining = 0;
142+
uint32_t nextMainISR = 0;
143+
#if ENABLED(LIN_ADVANCE)
144+
uint32_t nextAdvanceISR = Stepper::LA_ADV_NEVER;
145+
#endif
143146

144-
while (1) {
147+
for (;;) {
145148
xQueueReceive(dma.queue, &dma.current, portMAX_DELAY);
146149
dma.rw_pos = 0;
147150

148151
while (dma.rw_pos < DMA_SAMPLE_COUNT) {
149152
// Fill with the port data post pulse_phase until the next step
150-
if (remaining) {
153+
if (nextMainISR && TERN1(LIN_ADVANCE, nextAdvanceISR))
151154
i2s_push_sample();
152-
remaining--;
153-
}
154-
else {
155+
156+
// i2s_push_sample() is also called from Stepper::pulse_phase_isr() and Stepper::advance_isr()
157+
// in a rare case where both are called, we need to double decrement the counters
158+
const uint8_t push_count = 1 + (!nextMainISR && TERN0(LIN_ADVANCE, !nextAdvanceISR));
159+
160+
#if ENABLED(LIN_ADVANCE)
161+
if (!nextAdvanceISR) {
162+
Stepper::advance_isr();
163+
nextAdvanceISR = Stepper::la_interval;
164+
}
165+
else if (nextAdvanceISR == Stepper::LA_ADV_NEVER)
166+
nextAdvanceISR = Stepper::la_interval;
167+
#endif
168+
169+
if (!nextMainISR) {
155170
Stepper::pulse_phase_isr();
156-
remaining = Stepper::block_phase_isr();
171+
nextMainISR = Stepper::block_phase_isr();
157172
}
173+
174+
nextMainISR -= push_count;
175+
TERN_(LIN_ADVANCE, nextAdvanceISR -= push_count);
158176
}
159177
}
160178
}

Diff for: Marlin/src/HAL/ESP32/inc/SanityCheck.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,6 @@
4949
#error "PULLDOWN pin mode is not available on ESP32 boards."
5050
#endif
5151

52-
#if BOTH(I2S_STEPPER_STREAM, LIN_ADVANCE)
52+
#if BOTH(I2S_STEPPER_STREAM, LIN_ADVANCE) && DISABLED(EXPERIMENTAL_I2S_LA)
5353
#error "I2S stream is currently incompatible with LIN_ADVANCE."
5454
#endif

Diff for: Marlin/src/inc/Warnings.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
#warning "WARNING! Disable MARLIN_DEV_MODE for the final build!"
3636
#endif
3737

38+
#if ENABLED(LA_DEBUG)
39+
#warning "WARNING! Disable LA_DEBUG for the final build!"
40+
#endif
41+
3842
#if NUM_AXES_WARNING
3943
#warning "Note: NUM_AXES is now based on the *_DRIVER_TYPE settings so you can remove NUM_AXES from Configuration.h."
4044
#endif

Diff for: Marlin/src/module/stepper.cpp

+13-19
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ Stepper stepper; // Singleton
137137
#include "../lcd/extui/ui_api.h"
138138
#endif
139139

140+
#if ENABLED(I2S_STEPPER_STREAM)
141+
#include "../HAL/ESP32/i2s.h"
142+
#endif
143+
140144
// public:
141145

142146
#if EITHER(HAS_EXTRA_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
@@ -1558,14 +1562,7 @@ void Stepper::isr() {
15581562
* On AVR the ISR epilogue+prologue is estimated at 100 instructions - Give 8µs as margin
15591563
* On ARM the ISR epilogue+prologue is estimated at 20 instructions - Give 1µs as margin
15601564
*/
1561-
min_ticks = HAL_timer_get_count(MF_TIMER_STEP) + hal_timer_t(
1562-
#ifdef __AVR__
1563-
8
1564-
#else
1565-
1
1566-
#endif
1567-
* (STEPPER_TIMER_TICKS_PER_US)
1568-
);
1565+
min_ticks = HAL_timer_get_count(MF_TIMER_STEP) + hal_timer_t(TERN(__AVR__, 8, 1) * (STEPPER_TIMER_TICKS_PER_US));
15691566

15701567
/**
15711568
* NB: If for some reason the stepper monopolizes the MPU, eventually the
@@ -2472,18 +2469,19 @@ uint32_t Stepper::block_phase_isr() {
24722469
// the acceleration and speed values calculated in block_phase_isr().
24732470
// This helps keep LA in sync with, for example, S_CURVE_ACCELERATION.
24742471
la_delta_error += la_dividend;
2475-
if (la_delta_error >= 0) {
2472+
const bool step_needed = la_delta_error >= 0;
2473+
if (step_needed) {
24762474
count_position.e += count_direction.e;
24772475
la_advance_steps += count_direction.e;
24782476
la_delta_error -= advance_divisor;
24792477

24802478
// Set the STEP pulse ON
2481-
#if ENABLED(MIXING_EXTRUDER)
2482-
E_STEP_WRITE(mixer.get_next_stepper(), !INVERT_E_STEP_PIN);
2483-
#else
2484-
E_STEP_WRITE(stepper_extruder, !INVERT_E_STEP_PIN);
2485-
#endif
2479+
E_STEP_WRITE(TERN(MIXING_EXTRUDER, mixer.get_next_stepper(), stepper_extruder), !INVERT_E_STEP_PIN);
2480+
}
2481+
2482+
TERN_(I2S_STEPPER_STREAM, i2s_push_sample());
24862483

2484+
if (step_needed) {
24872485
// Enforce a minimum duration for STEP pulse ON
24882486
#if ISR_PULSE_CONTROL
24892487
USING_TIMED_PULSE();
@@ -2492,11 +2490,7 @@ uint32_t Stepper::block_phase_isr() {
24922490
#endif
24932491

24942492
// Set the STEP pulse OFF
2495-
#if ENABLED(MIXING_EXTRUDER)
2496-
E_STEP_WRITE(mixer.get_stepper(), INVERT_E_STEP_PIN);
2497-
#else
2498-
E_STEP_WRITE(stepper_extruder, INVERT_E_STEP_PIN);
2499-
#endif
2493+
E_STEP_WRITE(TERN(MIXING_EXTRUDER, mixer.get_stepper(), stepper_extruder), INVERT_E_STEP_PIN);
25002494
}
25012495
}
25022496

Diff for: Marlin/src/module/stepper.h

+1
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ constexpr ena_mask_t enable_overlap[] = {
318318
class Stepper {
319319
friend class KinematicSystem;
320320
friend class DeltaKinematicSystem;
321+
friend void stepperTask(void *);
321322

322323
public:
323324

0 commit comments

Comments
 (0)