uint64_t planner test

This commit is contained in:
InsanityAutomation
2024-05-29 12:21:04 -04:00
parent 7c6dfc4ec2
commit 721209a898
5 changed files with 119 additions and 119 deletions
+7 -7
View File
@@ -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
+28 -28
View File
@@ -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
+14 -14
View File
@@ -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:
+58 -58
View File
@@ -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
+12 -12
View File
@@ -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