diff --git a/Marlin/src/HAL/GD32_MFL/timers.h b/Marlin/src/HAL/GD32_MFL/timers.h index 49d005b8cd..a5d36d9eca 100644 --- a/Marlin/src/HAL/GD32_MFL/timers.h +++ b/Marlin/src/HAL/GD32_MFL/timers.h @@ -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(); diff --git a/Marlin/src/gcode/feature/nonlinear/M592.cpp b/Marlin/src/gcode/feature/nonlinear/M592.cpp index 77a6258ddc..78c15443f8 100644 --- a/Marlin/src/gcode/feature/nonlinear/M592.cpp +++ b/Marlin/src/gcode/feature/nonlinear/M592.cpp @@ -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 diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 97cc2ed198..c70c5ce0ec 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -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 diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index fe497058d9..5e1c08f863 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -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(); diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index 0a3a35d922..c71a73c5be 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -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); diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 04c796acb3..a6931c8d0d 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -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; diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 3fb0b44884..9495a18139 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -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) diff --git a/README-PT-BR.md b/README-PT-BR.md index 8d8b18828f..3c730967ae 100644 --- a/README-PT-BR.md +++ b/README-PT-BR.md @@ -14,7 +14,7 @@ Siga MarlinFirmware no Mastodon

-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