diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp index b7825949c0..04fe5a83f5 100644 --- a/Marlin/src/lcd/menu/menu_advanced.cpp +++ b/Marlin/src/lcd/menu/menu_advanced.cpp @@ -523,12 +523,12 @@ void menu_backlash(); // M204 T Travel Acceleration EDIT_ITEM_FAST(float5_25, MSG_A_TRAVEL, &planner.settings.travel_acceleration, 25, max_accel); - #define EDIT_AMAX(Q,L) EDIT_ITEM_FAST_N(long5_25, _AXIS(Q), MSG_AMAX_N, &planner.settings.max_acceleration_mm_per_s2[_AXIS(Q)], L, max_accel_edit_scaled[_AXIS(Q)], []{ planner.refresh_acceleration_rates(); }) - NUM_AXIS_CODE( - EDIT_AMAX(A, 100), EDIT_AMAX(B, 100), EDIT_AMAX(C, 10), - EDIT_AMAX(I, 10), EDIT_AMAX(J, 10), EDIT_AMAX(K, 10), - EDIT_AMAX(U, 10), EDIT_AMAX(V, 10), EDIT_AMAX(W, 10) - ); + //#define EDIT_AMAX(Q,L) EDIT_ITEM_FAST_N(long5_25, _AXIS(Q), MSG_AMAX_N, &planner.settings.max_acceleration_mm_per_s2[_AXIS(Q)], L, max_accel_edit_scaled[_AXIS(Q)], []{ planner.refresh_acceleration_rates(); }) + //NUM_AXIS_CODE( + // EDIT_AMAX(A, 100), EDIT_AMAX(B, 100), EDIT_AMAX(C, 10), + // EDIT_AMAX(I, 10), EDIT_AMAX(J, 10), EDIT_AMAX(K, 10), + // EDIT_AMAX(U, 10), EDIT_AMAX(V, 10), EDIT_AMAX(W, 10) + //); #if ENABLED(DISTINCT_E_FACTORS) EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(active_extruder)], 100, max_accel_edit_scaled.e, []{ planner.refresh_acceleration_rates(); }); @@ -538,7 +538,7 @@ void menu_backlash(); planner.refresh_acceleration_rates(); }); #elif E_STEPPERS - EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS], 100, max_accel_edit_scaled.e, []{ planner.refresh_acceleration_rates(); }); + //EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS], 100, max_accel_edit_scaled.e, []{ planner.refresh_acceleration_rates(); }); #endif #ifdef XY_FREQUENCY_LIMIT diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index 34d856670d..b06d9ecc96 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -149,7 +149,7 @@ planner_settings_t Planner::settings; // Initialized by settings.load( const uint8_t laser_power_floor = cutter.pct_to_ocr(SPEED_POWER_MIN); #endif -uint32_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2 +uint64_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2 #if HAS_JUNCTION_DEVIATION float Planner::junction_deviation_mm; // (mm) M205 J @@ -169,7 +169,7 @@ uint32_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) D #endif #if ENABLED(DIRECT_STEPPING) - uint32_t Planner::last_page_step_rate = 0; + uint64_t Planner::last_page_step_rate = 0; AxisBits Planner::last_page_dir; // = 0 #endif @@ -219,7 +219,7 @@ uint32_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) D xyze_long_t Planner::position{0}; -uint32_t Planner::acceleration_long_cutoff; +uint64_t Planner::acceleration_long_cutoff; xyze_float_t Planner::previous_speed; float Planner::previous_nominal_speed; @@ -247,7 +247,7 @@ float Planner::previous_nominal_speed; #endif #if HAS_WIRED_LCD - volatile uint32_t Planner::block_buffer_runtime_us = 0; + volatile uint64_t Planner::block_buffer_runtime_us = 0; #endif /** @@ -337,7 +337,7 @@ void Planner::init() { * // Compute initial estimation of 0x1000000/x - * // Get most significant bit set on divider * uint8_t idx = 0; - * uint32_t nr = d; + * uint64_t nr = d; * if (!(nr & 0xFF0000)) { * nr <<= 8; idx += 8; * if (!(nr & 0xFF0000)) { nr <<= 8; idx += 8; } @@ -347,16 +347,16 @@ void Planner::init() { * if (!(nr & 0x800000)) { nr <<= 1; idx += 1; } * * // Isolate top 9 bits of the denominator, to be used as index into the initial estimation table - * uint32_t tidx = nr >> 15, // top 9 bits. bit8 is always set + * uint64_t tidx = nr >> 15, // top 9 bits. bit8 is always set * ie = inv_tab[tidx & 0xFF] + 256, // Get the table value. bit9 is always set * x = idx <= 8 ? (ie >> (8 - idx)) : (ie << (idx - 8)); // Position the estimation at the proper place * - * x = uint32_t((x * uint64_t(_BV(25) - x * d)) >> 24); // Refine estimation by newton-raphson. 1 iteration is enough - * const uint32_t r = _BV(24) - x * d; // Estimate remainder + * x = uint64_t((x * uint64_t(_BV(25) - x * d)) >> 24); // Refine estimation by newton-raphson. 1 iteration is enough + * const uint64_t r = _BV(24) - x * d; // Estimate remainder * if (r >= d) x++; // Check whether to adjust result - * return uint32_t(x); // x holds the proper estimation + * return uint64_t(x); // x holds the proper estimation */ - static uint32_t get_period_inverse(uint32_t d) { + static uint64_t get_period_inverse(uint64_t d) { static const uint8_t inv_tab[256] PROGMEM = { 255,253,252,250,248,246,244,242,240,238,236,234,233,231,229,227, @@ -380,7 +380,7 @@ void Planner::init() { // For small denominators, it is cheaper to directly store the result. // For bigger ones, just ONE Newton-Raphson iteration is enough to get // maximum precision we need - static const uint32_t small_inv_tab[111] PROGMEM = { + static const uint64_t small_inv_tab[111] PROGMEM = { 16777216,16777216,8388608,5592405,4194304,3355443,2796202,2396745,2097152,1864135,1677721,1525201,1398101,1290555,1198372,1118481, 1048576,986895,932067,883011,838860,798915,762600,729444,699050,671088,645277,621378,599186,578524,559240,541200, 524288,508400,493447,479349,466033,453438,441505,430185,419430,409200,399457,390167,381300,372827,364722,356962, @@ -717,13 +717,13 @@ void Planner::init() { ); // Return the result - return r11 | (uint16_t(r12) << 8) | (uint32_t(r13) << 16); + return r11 | (uint16_t(r12) << 8) | (uint64_t(r13) << 16); } #else // All other 32-bit MPUs can easily do inverse using hardware division, // so we don't need to reduce precision or to use assembly language at all. // This routine, for all other archs, returns 0x100000000 / d ~= 0xFFFFFFFF / d - FORCE_INLINE static uint32_t get_period_inverse(const uint32_t d) { + FORCE_INLINE static uint64_t get_period_inverse(const uint64_t d) { return d ? 0xFFFFFFFF / d : 0xFFFFFFFF; } #endif @@ -791,15 +791,15 @@ block_t* Planner::get_current_block() { void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t entry_speed, const_float_t exit_speed) { const float spmm = block->steps_per_mm; - uint32_t initial_rate = entry_speed ? _MAX(long(MINIMAL_STEP_RATE), LROUND(entry_speed * spmm)) : block->initial_rate, + uint64_t initial_rate = entry_speed ? _MAX(long(MINIMAL_STEP_RATE), LROUND(entry_speed * spmm)) : block->initial_rate, final_rate = _MAX(long(MINIMAL_STEP_RATE), LROUND(exit_speed * spmm)); // Legacy check against supposed timer overflow. However Stepper::calc_timer_interval() already // should protect against it. But removing this code produces judder in direction-switching // moves. This is because the current discrete stepping math diverges from physical motion under // constant acceleration when acceleration_steps_per_s2 is large compared to initial/final_rate. - NOLESS(initial_rate, uint32_t(MINIMAL_STEP_RATE)); // Enforce the minimum speed - NOLESS(final_rate, uint32_t(MINIMAL_STEP_RATE)); + NOLESS(initial_rate, uint64_t(MINIMAL_STEP_RATE)); // Enforce the minimum speed + NOLESS(final_rate, uint64_t(MINIMAL_STEP_RATE)); NOLESS(block->nominal_rate, MINIMAL_STEP_RATE); NOMORE(initial_rate, block->nominal_rate); // NOTE: The nominal rate may be less than MINIMAL_STEP_RATE! @@ -807,7 +807,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t #if ANY(S_CURVE_ACCELERATION, LIN_ADVANCE) // If we have some plateau time, the cruise rate will be the nominal rate - uint32_t cruise_rate = block->nominal_rate; + uint64_t cruise_rate = block->nominal_rate; #endif // Steps for acceleration, plateau and deceleration @@ -849,7 +849,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t #if ENABLED(S_CURVE_ACCELERATION) const float rate_factor = inverse_accel * (STEPPER_TIMER_RATE); // Jerk controlled speed requires to express speed versus time, NOT steps - uint32_t acceleration_time = rate_factor * float(cruise_rate - initial_rate), + uint64_t acceleration_time = rate_factor * float(cruise_rate - initial_rate), deceleration_time = rate_factor * float(cruise_rate - final_rate), // And to offload calculations from the ISR, we also calculate the inverse of those times here acceleration_time_inverse = get_period_inverse(acceleration_time), @@ -1909,9 +1909,9 @@ bool Planner::_populate_block( #if HAS_EXTRUDERS dm.e = (dist.e > 0); const float esteps_float = dist.e * e_factor[extruder]; - const uint32_t esteps = ABS(esteps_float); + const uint64_t esteps = ABS(esteps_float); #else - constexpr uint32_t esteps = 0; + constexpr uint64_t esteps = 0; #endif // Clear all flags, including the "busy" bit @@ -2351,7 +2351,7 @@ bool Planner::_populate_block( // Compute and limit the acceleration rate for the trapezoid generator. const float steps_per_mm = block->step_event_count * inverse_millimeters; block->steps_per_mm = steps_per_mm; - uint32_t accel; + uint64_t accel; #if ENABLED(LIN_ADVANCE) bool use_advance_lead = false; #endif @@ -2361,7 +2361,7 @@ bool Planner::_populate_block( else { #define LIMIT_ACCEL_LONG(AXIS,INDX) do{ \ if (block->steps[AXIS] && max_acceleration_steps_per_s2[AXIS+INDX] < accel) { \ - const uint32_t max_possible = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count / block->steps[AXIS]; \ + const uint64_t max_possible = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count / block->steps[AXIS]; \ NOMORE(accel, max_possible); \ } \ }while(0) @@ -2405,7 +2405,7 @@ bool Planner::_populate_block( use_advance_lead = false; else { // Scale E acceleration so that it will be possible to jump to the advance speed. - const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[E_INDEX_N(extruder)] * e_D_ratio) * steps_per_mm; + const uint64_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[E_INDEX_N(extruder)] * e_D_ratio) * steps_per_mm; if (accel > max_accel_steps_per_s2) { accel = max_accel_steps_per_s2; if (ENABLED(LA_DEBUG)) SERIAL_ECHOLNPGM("Acceleration limited."); @@ -2435,7 +2435,7 @@ bool Planner::_populate_block( block->acceleration_steps_per_s2 = accel; block->acceleration = accel / steps_per_mm; #if DISABLED(S_CURVE_ACCELERATION) - block->acceleration_rate = (uint32_t)(accel * (float(1UL << 24) / (STEPPER_TIMER_RATE))); + block->acceleration_rate = (uint64_t)(accel * (float(1UL << 24) / (STEPPER_TIMER_RATE))); #endif #if ENABLED(LIN_ADVANCE) @@ -2448,7 +2448,7 @@ bool Planner::_populate_block( // reduce LA ISR frequency by calling it only often enough to ensure that there will // never be more than four extruder steps per call - for (uint32_t dividend = block->steps.e << 1; dividend <= (block->step_event_count >> 2); dividend <<= 1) + for (uint64_t dividend = block->steps.e << 1; dividend <= (block->step_event_count >> 2); dividend <<= 1) block->la_scaling++; #if ENABLED(LA_DEBUG) @@ -2687,7 +2687,7 @@ bool Planner::_populate_block( // Advance affects E_AXIS speed and therefore jerk. Add a speed correction whenever // LA is turned OFF. No correction is applied when LA is turned ON (because it didn't // perform well; it takes more time/effort to push/melt filament than the reverse). - static uint32_t previous_advance_rate; + static uint64_t previous_advance_rate; static float previous_e_mm_per_step; if (dist.e < 0 && previous_advance_rate) { // Retract move after a segment with LA that ended with an E speed decrease. @@ -3192,7 +3192,7 @@ void Planner::set_position_mm(const xyze_pos_t &xyze) { // Recalculate the steps/s^2 acceleration rates, based on the mm/s^2 void Planner::refresh_acceleration_rates() { - uint32_t highest_rate = 1; + uint64_t highest_rate = 1; LOOP_DISTINCT_AXES(i) { max_acceleration_steps_per_s2[i] = settings.max_acceleration_mm_per_s2[i] * settings.axis_steps_per_mm[i]; if (TERN1(DISTINCT_E_FACTORS, i < E_AXIS || i == E_AXIS_N(active_extruder))) @@ -3305,7 +3305,7 @@ void Planner::set_max_feedrate(const AxisEnum axis, float inMaxFeedrateMMS) { const bool was_enabled = stepper.suspend(); #endif - uint32_t bbru = block_buffer_runtime_us; + uint64_t bbru = block_buffer_runtime_us; #ifdef __AVR__ // Reenable Stepper ISR diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index 5813a442a5..9a350adb49 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -78,7 +78,7 @@ #include "../feature/closedloop.h" #endif -constexpr uint32_t MINIMAL_STEP_RATE = ( +constexpr uint64_t MINIMAL_STEP_RATE = ( #ifdef CPU_32_BIT _MAX((STEPPER_TIMER_RATE) / HAL_TIMER_TYPE_MAX, 1U) // 32-bit shouldn't go below 1 #else @@ -234,7 +234,7 @@ typedef struct PlannerBlock { abce_ulong_t steps; // Step count along each axis abce_long_t position; // New position to force when this sync block is executed }; - uint32_t step_event_count; // The number of step events required to complete this block + uint64_t step_event_count; // The number of step events required to complete this block #if HAS_MULTI_EXTRUDER uint8_t extruder; // The extruder to move (if E move) @@ -247,30 +247,30 @@ typedef struct PlannerBlock { #endif // Settings for the trapezoid generator - uint32_t accelerate_before, // The index of the step event on which to start cruising + uint64_t accelerate_before, // The index of the step event on which to start cruising decelerate_start; // The index of the step event on which to start decelerating #if ENABLED(S_CURVE_ACCELERATION) - uint32_t cruise_rate, // The actual cruise rate to use, between end of the acceleration phase and start of deceleration phase + uint64_t cruise_rate, // The actual cruise rate to use, between end of the acceleration phase and start of deceleration phase acceleration_time, // Acceleration time and deceleration time in STEP timer counts deceleration_time, acceleration_time_inverse, // Inverse of acceleration and deceleration periods, expressed as integer. Scale depends on CPU being used deceleration_time_inverse; #else - uint32_t acceleration_rate; // Acceleration rate in (2^24 steps)/timer_ticks*s + uint64_t acceleration_rate; // Acceleration rate in (2^24 steps)/timer_ticks*s #endif AxisBits direction_bits; // Direction bits set for this block, where 1 is negative motion // Advance extrusion #if ENABLED(LIN_ADVANCE) - uint32_t la_advance_rate; // The rate at which steps are added whilst accelerating + uint64_t la_advance_rate; // The rate at which steps are added whilst accelerating uint8_t la_scaling; // Scale ISR frequency down and step frequency up by 2 ^ la_scaling uint16_t max_adv_steps, // Max advance steps to get cruising speed pressure final_adv_steps; // Advance steps for exit speed pressure #endif - uint32_t nominal_rate, // The nominal step rate for this block in step_events/sec + uint64_t nominal_rate, // The nominal step rate for this block in step_events/sec initial_rate, // The jerk-adjusted step rate at start of block final_rate, // The minimal rate at exit acceleration_steps_per_s2; // acceleration steps/sec^2 @@ -292,11 +292,11 @@ typedef struct PlannerBlock { #endif #if HAS_WIRED_LCD - uint32_t segment_time_us; + uint64_t segment_time_us; #endif #if ENABLED(POWER_LOSS_RECOVERY) - uint32_t sdpos; + uint64_t sdpos; xyze_pos_t start_position; #endif @@ -347,7 +347,7 @@ constexpr uint8_t block_inc_mod(const uint8_t v1, const uint8_t v2) { #endif typedef struct PlannerSettings { - uint32_t max_acceleration_mm_per_s2[DISTINCT_AXES], // (mm/s^2) M201 XYZE + uint64_t max_acceleration_mm_per_s2[DISTINCT_AXES], // (mm/s^2) M201 XYZE min_segment_time_us; // (µs) M205 B // (steps) M92 XYZE - Steps per millimeter @@ -460,7 +460,7 @@ class Planner { #endif #if ENABLED(DIRECT_STEPPING) - static uint32_t last_page_step_rate; // Last page step rate given + static uint64_t last_page_step_rate; // Last page step rate given static AxisBits last_page_dir; // Last page direction given, where 1 represents forward or positive motion #endif @@ -487,7 +487,7 @@ class Planner { static laser_state_t laser_inline; #endif - static uint32_t max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2 + static uint64_t max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2 #if ENABLED(EDITABLE_STEPS_PER_UNIT) static float mm_per_step[DISTINCT_AXES]; // Millimeters per step @@ -577,7 +577,7 @@ class Planner { /** * Limit where 64bit math is necessary for acceleration calculation */ - static uint32_t acceleration_long_cutoff; + static uint64_t acceleration_long_cutoff; #ifdef MAX7219_DEBUG_SLOWDOWN friend class Max7219; @@ -594,7 +594,7 @@ class Planner { #endif #if HAS_WIRED_LCD - volatile static uint32_t block_buffer_runtime_us; // Theoretical block buffer runtime in µs + volatile static uint64_t block_buffer_runtime_us; // Theoretical block buffer runtime in µs #endif public: diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index ea3d252ba6..e9be3d2bf8 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -154,9 +154,9 @@ Stepper stepper; // Singleton #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM bool Stepper::initialized; // = false - uint32_t Stepper::motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load() + uint64_t Stepper::motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load() #if HAS_MOTOR_CURRENT_SPI - constexpr uint32_t Stepper::digipot_count[]; + constexpr uint64_t Stepper::digipot_count[]; #endif #endif @@ -194,7 +194,7 @@ bool Stepper::abort_current_block; #endif // In timer_ticks -uint32_t Stepper::acceleration_time, Stepper::deceleration_time; +uint64_t Stepper::acceleration_time, Stepper::deceleration_time; #if MULTISTEPPING_LIMIT > 1 uint8_t Stepper::steps_per_isr = 1; // Count of steps to perform per Stepper ISR call @@ -223,7 +223,7 @@ uint32_t Stepper::acceleration_time, Stepper::deceleration_time; xyze_long_t Stepper::delta_error{0}; xyze_long_t Stepper::advance_dividend{0}; -uint32_t Stepper::advance_divisor = 0, +uint64_t Stepper::advance_divisor = 0, Stepper::step_events_completed = 0, // The number of step events executed in the current block Stepper::accelerate_before, // The count at which to start cruising Stepper::decelerate_start, // The count at which to start decelerating @@ -239,8 +239,8 @@ uint32_t Stepper::advance_divisor = 0, int32_t __attribute__((used)) Stepper::bezier_A __asm__("bezier_A"); // A coefficient in Bézier speed curve with alias for assembler int32_t __attribute__((used)) Stepper::bezier_B __asm__("bezier_B"); // B coefficient in Bézier speed curve with alias for assembler int32_t __attribute__((used)) Stepper::bezier_C __asm__("bezier_C"); // C coefficient in Bézier speed curve with alias for assembler - uint32_t __attribute__((used)) Stepper::bezier_F __asm__("bezier_F"); // F coefficient in Bézier speed curve with alias for assembler - uint32_t __attribute__((used)) Stepper::bezier_AV __asm__("bezier_AV"); // AV coefficient in Bézier speed curve with alias for assembler + uint64_t __attribute__((used)) Stepper::bezier_F __asm__("bezier_F"); // F coefficient in Bézier speed curve with alias for assembler + uint64_t __attribute__((used)) Stepper::bezier_AV __asm__("bezier_AV"); // AV coefficient in Bézier speed curve with alias for assembler #ifdef __AVR__ bool __attribute__((used)) Stepper::A_negative __asm__("A_negative"); // If A coefficient was negative #endif @@ -260,7 +260,7 @@ uint32_t Stepper::advance_divisor = 0, ne_coeff_t Stepper::ne; ne_fix_t Stepper::ne_fix; int32_t Stepper::ne_edividend; - uint32_t Stepper::ne_scale; + uint64_t Stepper::ne_scale; #endif #if HAS_ZV_SHAPING @@ -297,7 +297,7 @@ uint32_t Stepper::advance_divisor = 0, hal_timer_t Stepper::ticks_nominal = 0; #if DISABLED(S_CURVE_ACCELERATION) - uint32_t Stepper::acc_step_rate; // needed for deceleration start point + uint64_t Stepper::acc_step_rate; // needed for deceleration start point #endif xyz_long_t Stepper::endstops_trigsteps; @@ -789,34 +789,34 @@ void Stepper::apply_directions() { * * And for each point, evaluate the curve with the following sequence: * - * void lsrs(uint32_t& d, uint32_t s, int cnt) { + * void lsrs(uint64_t& d, uint64_t s, int cnt) { * d = s >> cnt; * } - * void lsls(uint32_t& d, uint32_t s, int cnt) { + * void lsls(uint64_t& d, uint64_t s, int cnt) { * d = s << cnt; * } - * void lsrs(int32_t& d, uint32_t s, int cnt) { - * d = uint32_t(s) >> cnt; + * void lsrs(int32_t& d, uint64_t s, int cnt) { + * d = uint64_t(s) >> cnt; * } - * void lsls(int32_t& d, uint32_t s, int cnt) { - * d = uint32_t(s) << cnt; + * void lsls(int32_t& d, uint64_t s, int cnt) { + * d = uint64_t(s) << cnt; * } - * void umull(uint32_t& rlo, uint32_t& rhi, uint32_t op1, uint32_t op2) { + * void umull(uint64_t& rlo, uint64_t& rhi, uint64_t op1, uint64_t op2) { * uint64_t res = uint64_t(op1) * op2; - * rlo = uint32_t(res & 0xFFFFFFFF); - * rhi = uint32_t((res >> 32) & 0xFFFFFFFF); + * rlo = uint64_t(res & 0xFFFFFFFF); + * rhi = uint64_t((res >> 32) & 0xFFFFFFFF); * } * void smlal(int32_t& rlo, int32_t& rhi, int32_t op1, int32_t op2) { * int64_t mul = int64_t(op1) * op2; - * int64_t s = int64_t(uint32_t(rlo) | ((uint64_t(uint32_t(rhi)) << 32U))); + * int64_t s = int64_t(uint64_t(rlo) | ((uint64_t(uint64_t(rhi)) << 32U))); * mul += s; * rlo = int32_t(mul & 0xFFFFFFFF); * rhi = int32_t((mul >> 32) & 0xFFFFFFFF); * } - * int32_t _eval_bezier_curve_arm(uint32_t curr_step) { - * uint32_t flo = 0; - * uint32_t fhi = bezier_AV * curr_step; - * uint32_t t = fhi; + * int32_t _eval_bezier_curve_arm(uint64_t curr_step) { + * uint64_t flo = 0; + * uint64_t fhi = bezier_AV * curr_step; + * uint64_t t = fhi; * int32_t alo = bezier_F; * int32_t ahi = 0; * int32_t A = bezier_A; @@ -866,7 +866,7 @@ void Stepper::apply_directions() { * * And for each curve, estimate its coefficients with: * - * void _calc_bezier_curve_coeffs(int32_t v0, int32_t v1, uint32_t av) { + * void _calc_bezier_curve_coeffs(int32_t v0, int32_t v1, uint64_t av) { * // Calculate the Bézier coefficients * if (v1 < v0) { * A_negative = true; @@ -891,14 +891,14 @@ void Stepper::apply_directions() { * } * // unsigned multiplication of 16 bits x 16bits, return upper 16 bits * void umul16x16to16hi(uint16_t& r, uint16_t op1, uint16_t op2) { - * r = (uint32_t(op1) * op2) >> 16; + * r = (uint64_t(op1) * op2) >> 16; * } * // unsigned multiplication of 16 bits x 24bits, return upper 24 bits * void umul16x24to24hi(uint24_t& r, uint16_t op1, uint24_t op2) { * r = uint24_t((uint64_t(op1) * op2) >> 16); * } * - * int32_t _eval_bezier_curve(uint32_t curr_step) { + * int32_t _eval_bezier_curve(uint64_t curr_step) { * // To save computing, the first step is always the initial speed * if (!curr_step) * return bezier_F; @@ -940,7 +940,7 @@ void Stepper::apply_directions() { #ifdef __AVR__ // For AVR we use assembly to maximize speed - void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av) { + void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint64_t av) { // Store advance bezier_AV = av; @@ -1042,7 +1042,7 @@ void Stepper::apply_directions() { ); } - FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint32_t curr_step) { + FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint64_t curr_step) { // If dealing with the first step, save expensive computing and return the initial speed if (!curr_step) @@ -1424,13 +1424,13 @@ void Stepper::apply_directions() { : :"cc","r0","r1" ); - return (r2 | (uint16_t(r3) << 8)) | (uint32_t(r4) << 16); + return (r2 | (uint16_t(r3) << 8)) | (uint64_t(r4) << 16); } #else // For all the other 32bit CPUs - FORCE_INLINE void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av) { + FORCE_INLINE void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint64_t av) { // Calculate the Bézier coefficients #ifndef S_CURVE_FACTOR bezier_A = 768 * (v1 - v0); @@ -1447,13 +1447,13 @@ void Stepper::apply_directions() { bezier_AV = av; } - FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint32_t curr_step) { + FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint64_t curr_step) { #if (defined(__arm__) || defined(__thumb__)) && __ARM_ARCH >= 6 && !defined(STM32G0B1xx) // TODO: Test define STM32G0xx versus STM32G0B1xx // For ARM Cortex M3/M4 CPUs, we have the optimized assembler version, that takes 43 cycles to execute - uint32_t flo = 0; - uint32_t fhi = bezier_AV * curr_step; - uint32_t t = fhi; + uint64_t flo = 0; + uint64_t fhi = bezier_AV * curr_step; + uint64_t t = fhi; int32_t alo = bezier_F; int32_t ahi = 0; int32_t A = bezier_A; @@ -1495,7 +1495,7 @@ void Stepper::apply_directions() { // For non ARM targets, we provide a fallback implementation. Really doubt it // will be useful, unless the processor is fast and 32bit - uint32_t t = bezier_AV * curr_step; // t: Range 32 bits + uint64_t t = bezier_AV * curr_step; // t: Range 32 bits uint64_t f = t; #ifndef S_CURVE_FACTOR f *= t; // Range 32*2 = 64 bits (unsigned) @@ -1504,13 +1504,13 @@ void Stepper::apply_directions() { f >>= 32; // Range 32 bits : f = t^3 (unsigned) #endif int64_t acc = (int64_t) bezier_F << 31; // Range 63 bits (signed) - acc += ((uint32_t) f >> 1) * (int64_t) bezier_C; // Range 29bits + 31 = 60bits (plus sign) + acc += ((uint64_t) f >> 1) * (int64_t) bezier_C; // Range 29bits + 31 = 60bits (plus sign) f *= t; // Range 32*2 = 64 bits f >>= 32; // Range 32 bits : f = t^3 (unsigned) - acc += ((uint32_t) f >> 1) * (int64_t) bezier_B; // Range 29bits + 31 = 60bits (plus sign) + acc += ((uint64_t) f >> 1) * (int64_t) bezier_B; // Range 29bits + 31 = 60bits (plus sign) f *= t; // Range 32*2 = 64 bits f >>= 32; // Range 32 bits : f = t^3 (unsigned) - acc += ((uint32_t) f >> 1) * (int64_t) bezier_A; // Range 28bits + 31 = 59bits (plus sign) + acc += ((uint64_t) f >> 1) * (int64_t) bezier_A; // Range 28bits + 31 = 59bits (plus sign) acc >>= (31 + 7); // Range 24bits (plus sign) return (int32_t) acc; @@ -1636,7 +1636,7 @@ void Stepper::isr() { #endif // Get the interval to the next ISR call - interval = _MIN(nextMainISR, uint32_t(HAL_TIMER_TYPE_MAX)); // Time until the next Pulse / Block phase + interval = _MIN(nextMainISR, uint64_t(HAL_TIMER_TYPE_MAX)); // Time until the next Pulse / Block phase TERN_(INPUT_SHAPING_X, NOMORE(interval, ShapingQueue::peek_x())); // Time until next input shaping echo for X TERN_(INPUT_SHAPING_Y, NOMORE(interval, ShapingQueue::peek_y())); // Time until next input shaping echo for Y TERN_(INPUT_SHAPING_Z, NOMORE(interval, ShapingQueue::peek_z())); // Time until next input shaping echo for Z @@ -1799,7 +1799,7 @@ void Stepper::pulse_phase_isr() { if (TERN0(FREEZE_FEATURE, frozen)) return; // Count of pending loops and events for this iteration - const uint32_t pending_events = step_event_count - step_events_completed; + const uint64_t pending_events = step_event_count - step_events_completed; uint8_t events_to_do = _MIN(pending_events, steps_per_isr); // Just update the value we will get at the end of the loop @@ -1996,7 +1996,7 @@ void Stepper::pulse_phase_isr() { if (!is_page) { // Give the compiler a clue to store advance_divisor in registers for what follows - const uint32_t advance_divisor_cached = advance_divisor; + const uint64_t advance_divisor_cached = advance_divisor; // Determine if pulses are needed #if HAS_X_STEP @@ -2227,14 +2227,14 @@ void Stepper::pulse_phase_isr() { #endif // HAS_ZV_SHAPING // Calculate timer interval, with all limits applied. -hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) { +hal_timer_t Stepper::calc_timer_interval(uint64_t step_rate) { - constexpr uint32_t min_step_rate = MINIMAL_STEP_RATE; + constexpr uint64_t min_step_rate = MINIMAL_STEP_RATE; #ifdef CPU_32_BIT // A fast processor can just do integer division - return step_rate > min_step_rate ? uint32_t(STEPPER_TIMER_RATE) / step_rate : HAL_TIMER_TYPE_MAX; + return step_rate > min_step_rate ? uint64_t(STEPPER_TIMER_RATE) / step_rate : HAL_TIMER_TYPE_MAX; #else @@ -2244,7 +2244,7 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) { // Handle it as quickly as possible. i.e., assume highest byte is zero // because non-zero would represent a step rate far beyond AVR capabilities. if (uint8_t(step_rate >> 16)) - return uint32_t(STEPPER_TIMER_RATE) / 0x10000; + return uint64_t(STEPPER_TIMER_RATE) / 0x10000; const uintptr_t table_address = uintptr_t(&speed_lookuptable_fast[uint8_t(step_rate >> 8)]); const uint16_t base = uint16_t(pgm_read_word(table_address)); @@ -2264,8 +2264,8 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) { } #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 + void Stepper::calc_nonlinear_e(uint64_t step_rate) { + const uint64_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) + (((((int64_t)ne_fix.B * velocity) >> 24) * velocity) >> 24); NOLESS(vd, 0); @@ -2274,19 +2274,19 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) { #endif // Get the timer interval and the number of loops to perform per tick -hal_timer_t Stepper::calc_multistep_timer_interval(uint32_t step_rate) { +hal_timer_t Stepper::calc_multistep_timer_interval(uint64_t step_rate) { #if ENABLED(OLD_ADAPTIVE_MULTISTEPPING) #if MULTISTEPPING_LIMIT == 1 // Just make sure the step rate is doable - NOMORE(step_rate, uint32_t(MAX_STEP_ISR_FREQUENCY_1X)); + NOMORE(step_rate, uint64_t(MAX_STEP_ISR_FREQUENCY_1X)); #else // The stepping frequency limits for each multistepping rate - static const uint32_t limit[] PROGMEM = { + static const uint64_t limit[] PROGMEM = { ( MAX_STEP_ISR_FREQUENCY_1X ) , (((F_CPU) / ISR_EXECUTION_CYCLES(1)) >> 1) #if MULTISTEPPING_LIMIT >= 4 @@ -2311,7 +2311,7 @@ hal_timer_t Stepper::calc_multistep_timer_interval(uint32_t step_rate) { // Find a doable step rate using multistepping uint8_t multistep = 1; - for (uint8_t i = 0; i < COUNT(limit) && step_rate > uint32_t(pgm_read_dword(&limit[i])); ++i) { + for (uint8_t i = 0; i < COUNT(limit) && step_rate > uint64_t(pgm_read_dword(&limit[i])); ++i) { step_rate >>= 1; multistep <<= 1; } @@ -2470,7 +2470,7 @@ hal_timer_t Stepper::block_phase_isr() { #if ENABLED(S_CURVE_ACCELERATION) // Get the next speed to use (Jerk limited!) - uint32_t acc_step_rate = acceleration_time < current_block->acceleration_time + uint64_t acc_step_rate = acceleration_time < current_block->acceleration_time ? _eval_bezier_curve(acceleration_time) : current_block->cruise_rate; #else @@ -2491,7 +2491,7 @@ hal_timer_t Stepper::block_phase_isr() { #if ENABLED(LIN_ADVANCE) if (la_active) { - const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0; + const uint64_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0; la_interval = calc_timer_interval((acc_step_rate + la_step_rate) >> current_block->la_scaling); } #endif @@ -2521,7 +2521,7 @@ hal_timer_t Stepper::block_phase_isr() { } // Are we in Deceleration phase ? else if (step_events_completed >= decelerate_start) { - uint32_t step_rate; + uint64_t step_rate; #if ENABLED(S_CURVE_ACCELERATION) // If this is the 1st time we process the 2nd half of the trapezoid... @@ -2556,7 +2556,7 @@ hal_timer_t Stepper::block_phase_isr() { #if ENABLED(LIN_ADVANCE) if (la_active) { - const uint32_t la_step_rate = la_advance_steps > current_block->final_adv_steps ? current_block->la_advance_rate : 0; + const uint64_t la_step_rate = la_advance_steps > current_block->final_adv_steps ? current_block->la_advance_rate : 0; if (la_step_rate != step_rate) { const bool forward_e = la_step_rate < step_rate; la_interval = calc_timer_interval((forward_e ? step_rate - la_step_rate : la_step_rate - step_rate) >> current_block->la_scaling); @@ -2828,7 +2828,7 @@ hal_timer_t Stepper::block_phase_isr() { // Decide if axis smoothing is possible if (stepper.adaptive_step_smoothing_enabled) { - uint32_t max_rate = current_block->nominal_rate; // Get the step event rate + uint64_t max_rate = current_block->nominal_rate; // Get the step event rate while (max_rate < MIN_STEP_ISR_FREQUENCY) { // As long as more ISRs are possible... max_rate <<= 1; // Try to double the rate if (max_rate < MIN_STEP_ISR_FREQUENCY) // Don't exceed the estimated ISR limit @@ -2979,7 +2979,7 @@ hal_timer_t Stepper::block_phase_isr() { #if ENABLED(LIN_ADVANCE) if (la_active) { - const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0; + const uint64_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0; la_interval = calc_timer_interval((current_block->initial_rate + la_step_rate) >> current_block->la_scaling); } #endif @@ -3399,7 +3399,7 @@ void Stepper::init() { const bool was_on = hal.isr_state(); hal.isr_off(); - const shaping_time_t delay = freq ? float(uint32_t(STEPPER_TIMER_RATE) / 2) / freq : shaping_time_t(-1); + const shaping_time_t delay = freq ? float(uint64_t(STEPPER_TIMER_RATE) / 2) / freq : shaping_time_t(-1); #define SHAPING_SET_FREQ_FOR_AXIS(AXISN, AXISL) \ if (axis == AXISN) { \ ShapingQueue::set_delay(AXISN, delay); \ @@ -3884,7 +3884,7 @@ void Stepper::report_positions() { #if EXTRA_CYCLES_BABYSTEP > 20 #define _SAVE_START() const hal_timer_t pulse_start = HAL_timer_get_count(MF_TIMER_PULSE) - #define _PULSE_WAIT() while (EXTRA_CYCLES_BABYSTEP > uint32_t(HAL_timer_get_count(MF_TIMER_PULSE) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ } + #define _PULSE_WAIT() while (EXTRA_CYCLES_BABYSTEP > uint64_t(HAL_timer_get_count(MF_TIMER_PULSE) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ } #else #define _SAVE_START() NOOP #if EXTRA_CYCLES_BABYSTEP > 0 diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 08830db86a..260a6d4d99 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -309,11 +309,11 @@ class Stepper { #endif #define MOTOR_CURRENT_COUNT 3 #elif HAS_MOTOR_CURRENT_SPI - static constexpr uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT; + static constexpr uint64_t digipot_count[] = DIGIPOT_MOTOR_CURRENT; #define MOTOR_CURRENT_COUNT COUNT(Stepper::digipot_count) #endif static bool initialized; - static uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load() + static uint64_t motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load() #endif // Last-moved extruder, as set when the last movement was fetched from planner @@ -363,7 +363,7 @@ class Stepper { ; #endif - static uint32_t acceleration_time, deceleration_time; // time measured in Stepper Timer ticks + static uint64_t acceleration_time, deceleration_time; // time measured in Stepper Timer ticks #if MULTISTEPPING_LIMIT == 1 static constexpr uint8_t steps_per_isr = 1; // Count of steps to perform per Stepper ISR call @@ -384,7 +384,7 @@ class Stepper { // Delta error variables for the Bresenham line tracer static xyze_long_t delta_error; static xyze_long_t advance_dividend; - static uint32_t advance_divisor, + static uint64_t advance_divisor, step_events_completed, // The number of step events executed in the current block accelerate_before, // The point from where we need to stop acceleration decelerate_start, // The point from where we need to start decelerating @@ -400,7 +400,7 @@ class Stepper { static int32_t bezier_A, // A coefficient in Bézier speed curve bezier_B, // B coefficient in Bézier speed curve bezier_C; // C coefficient in Bézier speed curve - static uint32_t bezier_F, // F/free coefficient in Bézier speed curve + static uint64_t bezier_F, // F/free coefficient in Bézier speed curve bezier_AV; // AV coefficient in Bézier speed curve #ifdef __AVR__ static bool A_negative; // If A coefficient was negative @@ -432,7 +432,7 @@ class Stepper { #if ENABLED(NONLINEAR_EXTRUSION) static int32_t ne_edividend; - static uint32_t ne_scale; + static uint64_t ne_scale; static ne_fix_t ne_fix; #endif @@ -447,7 +447,7 @@ class Stepper { static hal_timer_t ticks_nominal; #if DISABLED(S_CURVE_ACCELERATION) - static uint32_t acc_step_rate; // needed for deceleration start point + static uint64_t acc_step_rate; // needed for deceleration start point #endif // Exact steps at which an endstop was triggered @@ -677,21 +677,21 @@ class Stepper { static void _set_position(const abce_long_t &spos); // Calculate the timing interval for the given step rate - static hal_timer_t calc_timer_interval(uint32_t step_rate); + static hal_timer_t calc_timer_interval(uint64_t step_rate); // Calculate timing interval and steps-per-ISR for the given step rate - static hal_timer_t calc_multistep_timer_interval(uint32_t step_rate); + static hal_timer_t calc_multistep_timer_interval(uint64_t step_rate); // 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); + static void calc_nonlinear_e(uint64_t step_rate); #endif #if ENABLED(S_CURVE_ACCELERATION) - static void _calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av); - static int32_t _eval_bezier_curve(const uint32_t curr_step); + static void _calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint64_t av); + static int32_t _eval_bezier_curve(const uint64_t curr_step); #endif #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM