mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2026-01-07 23:27:43 -07:00
🔧 Allow SMOOTH_LIN_ADVANCE + NONLINEAR_EXTRUSION (#27861)
This commit is contained in:
parent
af553d5fbd
commit
d5723fcafd
8 changed files with 74 additions and 48 deletions
|
|
@ -44,9 +44,9 @@
|
|||
extern uint32_t GetStepperTimerClkFreq();
|
||||
|
||||
// Timer prescaler calculations
|
||||
#define STEPPER_TIMER_PRESCALE (GetStepperTimerClkFreq() / STEPPER_TIMER_RATE) // Prescaler = 30
|
||||
#define STEPPER_TIMER_PRESCALE (GetStepperTimerClkFreq() / STEPPER_TIMER_RATE) // Prescaler = 30
|
||||
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // Stepper timer ticks per µs
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // Stepper timer ticks per µs
|
||||
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE
|
||||
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ extern uint32_t GetStepperTimerClkFreq();
|
|||
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
|
||||
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
|
||||
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
|
||||
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
|
||||
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
|
||||
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
|
||||
|
||||
extern void Step_Handler();
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ void GcodeSuite::M592() {
|
|||
if (parser.seenval('A')) stepper.ne.A = parser.value_float();
|
||||
if (parser.seenval('B')) stepper.ne.B = parser.value_float();
|
||||
if (parser.seenval('C')) stepper.ne.C = parser.value_float();
|
||||
|
||||
#if ENABLED(SMOOTH_LIN_ADVANCE)
|
||||
stepper.ne_q30.A = _BV32(30) * (stepper.ne.A * planner.mm_per_step[E_AXIS_N(0)] * planner.mm_per_step[E_AXIS_N(0)]);
|
||||
stepper.ne_q30.B = _BV32(30) * (stepper.ne.B * planner.mm_per_step[E_AXIS_N(0)]);
|
||||
stepper.ne_q30.C = _BV32(30) * stepper.ne.C;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // NONLINEAR_EXTRUSION
|
||||
|
|
|
|||
|
|
@ -868,8 +868,6 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
|
|||
#error "SMOOTH_LIN_ADVANCE requires a 32-bit CPU."
|
||||
#elif ENABLED(S_CURVE_ACCELERATION)
|
||||
#error "SMOOTH_LIN_ADVANCE is not compatible with S_CURVE_ACCELERATION."
|
||||
#elif ENABLED(NONLINEAR_EXTRUSION)
|
||||
#error "SMOOTH_LIN_ADVANCE doesn't currently support NONLINEAR_EXTRUSION."
|
||||
#elif ENABLED(INPUT_SHAPING_E_SYNC) && NONE(INPUT_SHAPING_X, INPUT_SHAPING_Y)
|
||||
#error "INPUT_SHAPING_E_SYNC requires INPUT_SHAPING_X or INPUT_SHAPING_Y."
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3252,6 +3252,10 @@ void Planner::refresh_acceleration_rates() {
|
|||
void Planner::refresh_positioning() {
|
||||
#if ENABLED(EDITABLE_STEPS_PER_UNIT)
|
||||
LOOP_DISTINCT_AXES(i) mm_per_step[i] = 1.0f / settings.axis_steps_per_mm[i];
|
||||
#if ALL(NONLINEAR_EXTRUSION, SMOOTH_LIN_ADVANCE)
|
||||
stepper.ne_q30.A = _BV32(30) * (stepper.ne.A * mm_per_step[E_AXIS_N(0)] * mm_per_step[E_AXIS_N(0)]);
|
||||
stepper.ne_q30.B = _BV32(30) * (stepper.ne.B * mm_per_step[E_AXIS_N(0)]);
|
||||
#endif
|
||||
#endif
|
||||
set_position_mm(current_position);
|
||||
refresh_acceleration_rates();
|
||||
|
|
|
|||
|
|
@ -531,9 +531,7 @@ class Planner {
|
|||
static void set_advance_k(const_float_t k, const uint8_t e=active_extruder) {
|
||||
UNUSED(e);
|
||||
extruder_advance_K[E_INDEX_N(e)] = k;
|
||||
#if ENABLED(SMOOTH_LIN_ADVANCE)
|
||||
extruder_advance_K_q27[E_INDEX_N(e)] = k * (1UL << 27);
|
||||
#endif
|
||||
TERN_(SMOOTH_LIN_ADVANCE, extruder_advance_K_q27[E_INDEX_N(e)] = k * _BV32(27));
|
||||
}
|
||||
static float get_advance_k(const uint8_t e=active_extruder) {
|
||||
UNUSED(e);
|
||||
|
|
|
|||
|
|
@ -257,9 +257,16 @@ uint32_t Stepper::advance_divisor = 0,
|
|||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
ne_coeff_t Stepper::ne;
|
||||
ne_fix_t Stepper::ne_fix;
|
||||
int32_t Stepper::ne_edividend;
|
||||
uint32_t Stepper::ne_scale;
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
ne_q24_t Stepper::ne_q24;
|
||||
#else
|
||||
ne_q30_t Stepper::ne_q30;
|
||||
#endif
|
||||
// private:
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
int32_t Stepper::ne_edividend;
|
||||
uint32_t Stepper::ne_scale_q24;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_ZV_SHAPING
|
||||
|
|
@ -2241,13 +2248,13 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) {
|
|||
#endif // !CPU_32_BIT
|
||||
}
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
void Stepper::calc_nonlinear_e(uint32_t step_rate) {
|
||||
const uint32_t velocity = ne_scale * step_rate; // Scale step_rate first so all intermediate values stay in range of 8.24 fixed point math
|
||||
int32_t vd = (((((int64_t)ne_fix.A * velocity) >> 24) * velocity) >> 24) + (((int64_t)ne_fix.B * velocity) >> 24);
|
||||
NOLESS(vd, 0);
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
void Stepper::calc_nonlinear_e(const uint32_t step_rate) {
|
||||
const uint32_t velocity_q24 = ne_scale_q24 * step_rate; // Scale step_rate first so all intermediate values stay in range of 8.24 fixed point math
|
||||
int32_t vd_q24 = (((((int64_t)ne_q24.A * velocity_q24) >> 24) * velocity_q24) >> 24) + (((int64_t)ne_q24.B * velocity_q24) >> 24);
|
||||
NOLESS(vd_q24, 0);
|
||||
|
||||
advance_dividend.e = (uint64_t(ne_fix.C + vd) * ne_edividend) >> 24;
|
||||
advance_dividend.e = (uint64_t(ne_q24.C + vd_q24) * ne_edividend) >> 24;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -2463,9 +2470,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
|||
acceleration_time += interval;
|
||||
deceleration_time = 0; // Reset since we're doing acceleration first.
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
calc_nonlinear_e(acc_step_rate << oversampling_factor);
|
||||
#endif
|
||||
calc_nonlinear_e(acc_step_rate << oversampling_factor);
|
||||
|
||||
#if HAS_ROUGH_LIN_ADVANCE
|
||||
if (la_active) {
|
||||
|
|
@ -2529,9 +2534,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
|||
interval = calc_multistep_timer_interval(step_rate << oversampling_factor);
|
||||
deceleration_time += interval;
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
calc_nonlinear_e(step_rate << oversampling_factor);
|
||||
#endif
|
||||
calc_nonlinear_e(step_rate << oversampling_factor);
|
||||
|
||||
#if HAS_ROUGH_LIN_ADVANCE
|
||||
if (la_active) {
|
||||
|
|
@ -2584,9 +2587,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
|||
TERN_(SMOOTH_LIN_ADVANCE, curr_step_rate = current_block->nominal_rate;)
|
||||
deceleration_time = ticks_nominal / 2;
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
calc_nonlinear_e(current_block->nominal_rate << oversampling_factor);
|
||||
#endif
|
||||
calc_nonlinear_e(current_block->nominal_rate << oversampling_factor);
|
||||
|
||||
#if HAS_ROUGH_LIN_ADVANCE
|
||||
if (la_active)
|
||||
|
|
@ -2836,18 +2837,18 @@ hal_timer_t Stepper::block_phase_isr() {
|
|||
acc_step_rate = current_block->initial_rate;
|
||||
#endif
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
ne_edividend = advance_dividend.e;
|
||||
const float scale = (float(ne_edividend) / advance_divisor) * planner.mm_per_step[E_AXIS_N(current_block->extruder)];
|
||||
ne_scale = (1L << 24) * scale;
|
||||
ne_scale_q24 = _BV32(24) * scale;
|
||||
if (current_block->direction_bits.e && ANY_AXIS_MOVES(current_block)) {
|
||||
ne_fix.A = (1L << 24) * ne.A;
|
||||
ne_fix.B = (1L << 24) * ne.B;
|
||||
ne_fix.C = (1L << 24) * ne.C;
|
||||
ne_q24.A = _BV32(24) * ne.A;
|
||||
ne_q24.B = _BV32(24) * ne.B;
|
||||
ne_q24.C = _BV32(24) * ne.C;
|
||||
}
|
||||
else {
|
||||
ne_fix.A = ne_fix.B = 0;
|
||||
ne_fix.C = (1L << 24);
|
||||
ne_q24.A = ne_q24.B = 0;
|
||||
ne_q24.C = _BV32(24);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -2856,9 +2857,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
|||
// Initialize ac/deceleration time as if half the time passed.
|
||||
acceleration_time = deceleration_time = interval / 2;
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
calc_nonlinear_e(current_block->initial_rate << oversampling_factor);
|
||||
#endif
|
||||
calc_nonlinear_e(current_block->initial_rate << oversampling_factor);
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
#if ENABLED(SMOOTH_LIN_ADVANCE)
|
||||
|
|
@ -2885,13 +2884,23 @@ hal_timer_t Stepper::block_phase_isr() {
|
|||
uint32_t Stepper::extruder_advance_tau_ticks[DISTINCT_E],
|
||||
Stepper::extruder_advance_alpha_q30[DISTINCT_E];
|
||||
|
||||
void Stepper::set_la_interval(const int32_t rate) {
|
||||
if (rate == 0) {
|
||||
void Stepper::set_la_interval(int32_t step_rate) {
|
||||
if (step_rate == 0) {
|
||||
la_interval = LA_ADV_NEVER;
|
||||
}
|
||||
else {
|
||||
const bool forward_e = rate > 0;
|
||||
la_interval = calc_timer_interval(uint32_t(ABS(rate)));
|
||||
const bool forward_e = step_rate > 0;
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
if (forward_e && ANY_AXIS_MOVES(current_block)) {
|
||||
// Maximum polynomial value is just above 1, like 1.05..1.2, less than 2 anyway, so we can use 30 bits for fractional part
|
||||
int32_t vd_q30 = ne_q30.A*step_rate*step_rate + ne_q30.B*step_rate;
|
||||
NOLESS(vd_q30, 0);
|
||||
step_rate = (int64_t(step_rate) * (ne_q30.C + vd_q30)) >> 30;
|
||||
}
|
||||
#endif
|
||||
|
||||
la_interval = calc_timer_interval(uint32_t(ABS(step_rate)));
|
||||
if (forward_e != motor_direction(E_AXIS)) {
|
||||
last_direction_bits.toggle(E_AXIS);
|
||||
count_direction.e = -count_direction.e;
|
||||
|
|
|
|||
|
|
@ -285,7 +285,12 @@ constexpr ena_mask_t enable_overlap[] = {
|
|||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
typedef struct { float A, B, C; void reset() { A = B = 0.0f; C = 1.0f; } } ne_coeff_t;
|
||||
typedef struct { int32_t A, B, C; } ne_fix_t;
|
||||
#if DISABLED(SMOOTH_LIN_ADVANCE)
|
||||
#define NONLINEAR_EXTRUSION_Q24 1
|
||||
typedef struct { int32_t A, B, C; } ne_q24_t;
|
||||
#else
|
||||
typedef struct { int32_t A, B, C; } ne_q30_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
|
|
@ -343,6 +348,11 @@ class Stepper {
|
|||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
static ne_coeff_t ne;
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
static ne_q24_t ne_q24;
|
||||
#else
|
||||
static ne_q30_t ne_q30;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(ADAPTIVE_STEP_SMOOTHING_TOGGLE)
|
||||
|
|
@ -467,10 +477,9 @@ class Stepper {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
static int32_t ne_edividend;
|
||||
static uint32_t ne_scale;
|
||||
static ne_fix_t ne_fix;
|
||||
static uint32_t ne_scale_q24;
|
||||
#endif
|
||||
|
||||
#if ENABLED(BABYSTEPPING)
|
||||
|
|
@ -531,7 +540,7 @@ class Stepper {
|
|||
// The Linear advance ISR phase
|
||||
static void advance_isr();
|
||||
#if ENABLED(SMOOTH_LIN_ADVANCE)
|
||||
static void set_la_interval(const int32_t rate);
|
||||
static void set_la_interval(int32_t step_rate);
|
||||
static hal_timer_t smooth_lin_adv_isr();
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -738,8 +747,10 @@ class Stepper {
|
|||
// Evaluate axis motions and set bits in axis_did_move
|
||||
static void set_axis_moved_for_current_block();
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
static void calc_nonlinear_e(uint32_t step_rate);
|
||||
#if NONLINEAR_EXTRUSION_Q24
|
||||
static void calc_nonlinear_e(const uint32_t step_rate);
|
||||
#else
|
||||
static void calc_nonlinear_e(const uint32_t) {}
|
||||
#endif
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
<a href="https://fosstodon.org/@marlinfirmware"><img alt="Siga MarlinFirmware no Mastodon" src="https://img.shields.io/mastodon/follow/109450200866020466?domain=https%3A%2F%2Ffosstodon.org&logoColor=%2300B&style=social"></a>
|
||||
</p>
|
||||
|
||||
Documentação adicional pode ser encontrada na [Página Inicial do Marlin](//marlinfw.org/).
|
||||
Documentação adicional pode ser encontrada na [Página Inicial do Marlin](//marlinfw.org/).
|
||||
Por favor, teste este firmware e nos avise se encontrar algum problema. Voluntários estão prontos para ajudar!
|
||||
|
||||
## Branch de Correções do Marlin 2.1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue