Skip to content

Commit

Permalink
✨ Permit Linear Advance with I2S Streaming (MarlinFirmware#24684)
Browse files Browse the repository at this point in the history
  • Loading branch information
tombrazier authored and thinkyhead committed Dec 16, 2022
1 parent 647d459 commit c996bfd
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 30 deletions.
7 changes: 4 additions & 3 deletions Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2063,11 +2063,12 @@
*/
//#define LIN_ADVANCE
#if ENABLED(LIN_ADVANCE)
//#define EXTRA_LIN_ADVANCE_K // Enable for second linear advance constants
//#define EXTRA_LIN_ADVANCE_K // Add a second linear advance constant, configurable with M900.
#define LIN_ADVANCE_K 0.22 // Unit: mm compression per 1mm/s extruder speed
//#define LA_DEBUG // If enabled, this will generate debug information output over USB.
//#define EXPERIMENTAL_SCURVE // Enable this option to permit S-Curve Acceleration
//#define LA_DEBUG // Print debug information to serial during operation. Disable for production use.
//#define EXPERIMENTAL_SCURVE // Allow S-Curve Acceleration to be used with LA.
//#define ALLOW_LOW_EJERK // Allow a DEFAULT_EJERK value of <10. Recommended for direct drive hotends.
//#define EXPERIMENTAL_I2S_LA // Allow I2S_STEPPER_STREAM to be used with LA. Performance degrades as the LA step rate reaches ~20kHz.
#endif

// @section leveling
Expand Down
32 changes: 25 additions & 7 deletions Marlin/src/HAL/ESP32/i2s.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,22 +139,40 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg) {
}

void stepperTask(void *parameter) {
uint32_t remaining = 0;
uint32_t nextMainISR = 0;
#if ENABLED(LIN_ADVANCE)
uint32_t nextAdvanceISR = Stepper::LA_ADV_NEVER;
#endif

while (1) {
for (;;) {
xQueueReceive(dma.queue, &dma.current, portMAX_DELAY);
dma.rw_pos = 0;

while (dma.rw_pos < DMA_SAMPLE_COUNT) {
// Fill with the port data post pulse_phase until the next step
if (remaining) {
if (nextMainISR && TERN1(LIN_ADVANCE, nextAdvanceISR))
i2s_push_sample();
remaining--;
}
else {

// i2s_push_sample() is also called from Stepper::pulse_phase_isr() and Stepper::advance_isr()
// in a rare case where both are called, we need to double decrement the counters
const uint8_t push_count = 1 + (!nextMainISR && TERN0(LIN_ADVANCE, !nextAdvanceISR));

#if ENABLED(LIN_ADVANCE)
if (!nextAdvanceISR) {
Stepper::advance_isr();
nextAdvanceISR = Stepper::la_interval;
}
else if (nextAdvanceISR == Stepper::LA_ADV_NEVER)
nextAdvanceISR = Stepper::la_interval;
#endif

if (!nextMainISR) {
Stepper::pulse_phase_isr();
remaining = Stepper::block_phase_isr();
nextMainISR = Stepper::block_phase_isr();
}

nextMainISR -= push_count;
TERN_(LIN_ADVANCE, nextAdvanceISR -= push_count);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/HAL/ESP32/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@
#error "PULLDOWN pin mode is not available on ESP32 boards."
#endif

#if BOTH(I2S_STEPPER_STREAM, LIN_ADVANCE)
#if BOTH(I2S_STEPPER_STREAM, LIN_ADVANCE) && DISABLED(EXPERIMENTAL_I2S_LA)
#error "I2S stream is currently incompatible with LIN_ADVANCE."
#endif
4 changes: 4 additions & 0 deletions Marlin/src/inc/Warnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
#warning "WARNING! Disable MARLIN_DEV_MODE for the final build!"
#endif

#if ENABLED(LA_DEBUG)
#warning "WARNING! Disable LA_DEBUG for the final build!"
#endif

#if NUM_AXES_WARNING
#warning "Note: NUM_AXES is now based on the *_DRIVER_TYPE settings so you can remove NUM_AXES from Configuration.h."
#endif
Expand Down
32 changes: 13 additions & 19 deletions Marlin/src/module/stepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ Stepper stepper; // Singleton
#include "../lcd/extui/ui_api.h"
#endif

#if ENABLED(I2S_STEPPER_STREAM)
#include "../HAL/ESP32/i2s.h"
#endif

// public:

#if EITHER(HAS_EXTRA_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
Expand Down Expand Up @@ -1558,14 +1562,7 @@ void Stepper::isr() {
* On AVR the ISR epilogue+prologue is estimated at 100 instructions - Give 8µs as margin
* On ARM the ISR epilogue+prologue is estimated at 20 instructions - Give 1µs as margin
*/
min_ticks = HAL_timer_get_count(MF_TIMER_STEP) + hal_timer_t(
#ifdef __AVR__
8
#else
1
#endif
* (STEPPER_TIMER_TICKS_PER_US)
);
min_ticks = HAL_timer_get_count(MF_TIMER_STEP) + hal_timer_t(TERN(__AVR__, 8, 1) * (STEPPER_TIMER_TICKS_PER_US));

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

// Set the STEP pulse ON
#if ENABLED(MIXING_EXTRUDER)
E_STEP_WRITE(mixer.get_next_stepper(), !INVERT_E_STEP_PIN);
#else
E_STEP_WRITE(stepper_extruder, !INVERT_E_STEP_PIN);
#endif
E_STEP_WRITE(TERN(MIXING_EXTRUDER, mixer.get_next_stepper(), stepper_extruder), !INVERT_E_STEP_PIN);
}

TERN_(I2S_STEPPER_STREAM, i2s_push_sample());

if (step_needed) {
// Enforce a minimum duration for STEP pulse ON
#if ISR_PULSE_CONTROL
USING_TIMED_PULSE();
Expand All @@ -2492,11 +2490,7 @@ uint32_t Stepper::block_phase_isr() {
#endif

// Set the STEP pulse OFF
#if ENABLED(MIXING_EXTRUDER)
E_STEP_WRITE(mixer.get_stepper(), INVERT_E_STEP_PIN);
#else
E_STEP_WRITE(stepper_extruder, INVERT_E_STEP_PIN);
#endif
E_STEP_WRITE(TERN(MIXING_EXTRUDER, mixer.get_stepper(), stepper_extruder), INVERT_E_STEP_PIN);
}
}

Expand Down
1 change: 1 addition & 0 deletions Marlin/src/module/stepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ constexpr ena_mask_t enable_overlap[] = {
class Stepper {
friend class KinematicSystem;
friend class DeltaKinematicSystem;
friend void stepperTask(void *);

public:

Expand Down

0 comments on commit c996bfd

Please sign in to comment.