Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2021-07-24 13:04:13 +0300
committerDavid Crocker <dcrocker@eschertech.com>2021-07-24 13:04:13 +0300
commit745c9baea0c8d6b3987d0a8795c74afa5ae4da03 (patch)
tree0e1f2f27d7c5f2585e809ec5deb2eb4d5966ebc7 /src
parent107551283f1f69e607125b75bb8cfebf4cb8cd5d (diff)
Finished converting time units to step clocks, pending testing
Diffstat (limited to 'src')
-rw-r--r--src/Accelerometers/LIS3DH.cpp2
-rw-r--r--src/Configuration.h1
-rw-r--r--src/Endstops/ZProbe.cpp16
-rw-r--r--src/Fans/LedStripDriver.cpp2
-rw-r--r--src/Fans/LocalFan.cpp4
-rw-r--r--src/FilamentMonitors/Duet3DFilamentMonitor.cpp2
-rw-r--r--src/GCodes/GCodeBuffer/GCodeBuffer.cpp52
-rw-r--r--src/GCodes/GCodeBuffer/GCodeBuffer.h4
-rw-r--r--src/GCodes/GCodeMachineState.cpp2
-rw-r--r--src/GCodes/GCodes.cpp10
-rw-r--r--src/GCodes/GCodes2.cpp23
-rw-r--r--src/GCodes/GCodes3.cpp4
-rw-r--r--src/GCodes/RestorePoint.cpp4
-rw-r--r--src/Heating/Sensors/DhtSensor.cpp2
-rw-r--r--src/Libraries/Fatfs/diskio.cpp4
-rw-r--r--src/Movement/AxisShaper.cpp114
-rw-r--r--src/Movement/DDA.cpp29
-rw-r--r--src/Movement/DDA.h28
-rw-r--r--src/Movement/DDARing.cpp4
-rw-r--r--src/Movement/DriveMovement.cpp16
-rw-r--r--src/Movement/Move.cpp14
-rw-r--r--src/Movement/StepTimer.h13
-rw-r--r--src/Movement/StepperDrivers/TMC51xx.cpp6
-rw-r--r--src/Networking/Network.cpp2
-rw-r--r--src/Platform/Platform.cpp26
-rw-r--r--src/Platform/Platform.h14
-rw-r--r--src/Platform/PortControl.cpp15
-rw-r--r--src/Platform/RepRap.cpp10
-rw-r--r--src/RepRapFirmware.h55
29 files changed, 252 insertions, 226 deletions
diff --git a/src/Accelerometers/LIS3DH.cpp b/src/Accelerometers/LIS3DH.cpp
index 65dcc52f..c783de83 100644
--- a/src/Accelerometers/LIS3DH.cpp
+++ b/src/Accelerometers/LIS3DH.cpp
@@ -224,7 +224,7 @@ unsigned int LIS3DH::CollectData(const uint16_t **collectedData, uint16_t &dataR
const uint32_t interval = lastInterruptTime - firstInterruptTime;
dataRate = (totalNumRead == 0 || interval == 0)
? 0
- : (totalNumRead * StepTimer::StepClockRate)/interval;
+ : (totalNumRead * StepClockRate)/interval;
totalNumRead += numToRead;
}
return numToRead;
diff --git a/src/Configuration.h b/src/Configuration.h
index e2ec0db2..72b18337 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -51,6 +51,7 @@ constexpr float DefaultEInstantDv = 2.0;
constexpr float DefaultMinFeedrate = 0.5; // the default minimum movement speed in mm/sec (extruding moves will go slower than this if the extrusion rate demands it)
constexpr float AbsoluteMinFeedrate = 0.01; // the absolute minimum movement speed in mm/sec
constexpr float MinimumJerk = 0.1; // the minimum jerk in mm/sec
+constexpr float MinimumAcceleration = 0.1; // he minimum acceleration in mm/sec^2
constexpr float DefaultAxisMinimum = 0.0;
constexpr float DefaultAxisMaximum = 200.0;
diff --git a/src/Endstops/ZProbe.cpp b/src/Endstops/ZProbe.cpp
index 293bcde8..2147b664 100644
--- a/src/Endstops/ZProbe.cpp
+++ b/src/Endstops/ZProbe.cpp
@@ -56,7 +56,7 @@ constexpr ObjectModelArrayDescriptor ZProbe::speedsArrayDescriptor =
nullptr,
[] (const ObjectModel *self, const ObjectExplorationContext&) noexcept -> size_t { return ARRAY_SIZE(ZProbe::probeSpeeds); },
[] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue
- { return ExpressionValue(GCodeBuffer::InverseConvertSpeedToMm(((const ZProbe*)self)->probeSpeeds[context.GetLastIndex()], false), 1); }
+ { return ExpressionValue(InverseConvertSpeedToMmPerMin(((const ZProbe*)self)->probeSpeeds[context.GetLastIndex()]), 1); }
};
constexpr ObjectModelTableEntry ZProbe::objectModelTable[] =
@@ -71,13 +71,13 @@ constexpr ObjectModelTableEntry ZProbe::objectModelTable[] =
{ "maxProbeCount", OBJECT_MODEL_FUNC((int32_t)self->misc.parts.maxTaps), ObjectModelEntryFlags::none },
{ "offsets", OBJECT_MODEL_FUNC_NOSELF(&offsetsArrayDescriptor), ObjectModelEntryFlags::none },
{ "recoveryTime", OBJECT_MODEL_FUNC(self->recoveryTime, 1), ObjectModelEntryFlags::none },
- { "speed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->probeSpeeds[1], false), 1), ObjectModelEntryFlags::obsolete },
+ { "speed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->probeSpeeds[1]), 1), ObjectModelEntryFlags::obsolete },
{ "speeds", OBJECT_MODEL_FUNC_NOSELF(&speedsArrayDescriptor), ObjectModelEntryFlags::none },
{ "temperatureCoefficient", OBJECT_MODEL_FUNC(self->temperatureCoefficients[0], 5), ObjectModelEntryFlags::obsolete },
{ "temperatureCoefficients", OBJECT_MODEL_FUNC_NOSELF(&temperatureCoefficientsArrayDescriptor), ObjectModelEntryFlags::none },
{ "threshold", OBJECT_MODEL_FUNC((int32_t)self->adcValue), ObjectModelEntryFlags::none },
{ "tolerance", OBJECT_MODEL_FUNC(self->tolerance, 3), ObjectModelEntryFlags::none },
- { "travelSpeed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->travelSpeed, false), 1), ObjectModelEntryFlags::none },
+ { "travelSpeed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->travelSpeed), 1), ObjectModelEntryFlags::none },
{ "triggerHeight", OBJECT_MODEL_FUNC(-self->offsets[Z_AXIS], 3), ObjectModelEntryFlags::none },
{ "type", OBJECT_MODEL_FUNC((int32_t)self->type), ObjectModelEntryFlags::none },
{ "value", OBJECT_MODEL_FUNC_NOSELF(&valueArrayDescriptor), ObjectModelEntryFlags::live },
@@ -386,8 +386,8 @@ GCodeResult ZProbe::Configure(GCodeBuffer& gb, const StringRef &reply, bool& see
float userProbeSpeeds[2];
size_t numSpeeds = 2;
gb.GetFloatArray(userProbeSpeeds, numSpeeds, true);
- probeSpeeds[0] = GCodeBuffer::ConvertSpeedFromMm(userProbeSpeeds[0], false);
- probeSpeeds[1] = GCodeBuffer::ConvertSpeedFromMm(userProbeSpeeds[1], false);
+ probeSpeeds[0] = ConvertSpeedFromMmPerMin(userProbeSpeeds[0]);
+ probeSpeeds[1] = ConvertSpeedFromMmPerMin(userProbeSpeeds[1]);
seen = true;
}
@@ -422,9 +422,9 @@ GCodeResult ZProbe::Configure(GCodeBuffer& gb, const StringRef &reply, bool& see
const GCodeResult rslt = AppendPinNames(reply);
reply.catf(", dive height %.1fmm, probe speeds %d,%dmm/min, travel speed %dmm/min, recovery time %.2f sec, heaters %s, max taps %u, max diff %.2f",
(double)diveHeight,
- (int)GCodeBuffer::InverseConvertSpeedToMm(probeSpeeds[0], false),
- (int)GCodeBuffer::InverseConvertSpeedToMm(probeSpeeds[1], false),
- (int)GCodeBuffer::InverseConvertSpeedToMm(travelSpeed, false),
+ (int)InverseConvertSpeedToMmPerMin(probeSpeeds[0]),
+ (int)InverseConvertSpeedToMmPerMin(probeSpeeds[1]),
+ (int)InverseConvertSpeedToMmPerMin(travelSpeed),
(double)recoveryTime,
(misc.parts.turnHeatersOff) ? "suspended" : "normal",
misc.parts.maxTaps, (double)tolerance);
diff --git a/src/Fans/LedStripDriver.cpp b/src/Fans/LedStripDriver.cpp
index 1fe44f62..647302d3 100644
--- a/src/Fans/LedStripDriver.cpp
+++ b/src/Fans/LedStripDriver.cpp
@@ -53,7 +53,7 @@ namespace LedStripDriver
{
constexpr uint32_t DefaultDotStarSpiClockFrequency = 1000000; // 1MHz default
constexpr uint32_t DefaultNeoPixelSpiClockFrequency = 2500000; // must be between about 2MHz and about 4MHz
- constexpr uint32_t MinNeoPixelResetTicks = (250 * StepTimer::StepClockRate)/1000000; // 250us minimum Neopixel reset time on later chips
+ constexpr uint32_t MinNeoPixelResetTicks = (250 * StepClockRate)/1000000; // 250us minimum Neopixel reset time on later chips
// Define the size of the buffer used to accumulate a sequence of colours to send to the string
#if defined(DUET3_V06)
diff --git a/src/Fans/LocalFan.cpp b/src/Fans/LocalFan.cpp
index eb461670..bef4ccad 100644
--- a/src/Fans/LocalFan.cpp
+++ b/src/Fans/LocalFan.cpp
@@ -215,8 +215,8 @@ int32_t LocalFan::GetRPM() const noexcept
// When the fan stops, we get no interrupts and fanInterval stops getting updated. We must recognise this and return zero.
return (!tachoPort.IsValid())
? -1 // we return -1 if there is no tacho configured
- : (fanInterval != 0 && StepTimer::GetTimerTicks() - fanLastResetTime < 3 * StepTimer::StepClockRate) // if we have a reading and it is less than 3 seconds old
- ? (StepTimer::StepClockRate * fanMaxInterruptCount * (60/2))/fanInterval // then calculate RPM assuming 2 interrupts per rev
+ : (fanInterval != 0 && StepTimer::GetTimerTicks() - fanLastResetTime < 3 * StepClockRate) // if we have a reading and it is less than 3 seconds old
+ ? (StepClockRate * fanMaxInterruptCount * (60/2))/fanInterval // then calculate RPM assuming 2 interrupts per rev
: 0; // else assume fan is off or tacho not connected
}
diff --git a/src/FilamentMonitors/Duet3DFilamentMonitor.cpp b/src/FilamentMonitors/Duet3DFilamentMonitor.cpp
index 41c957c9..cc91f0d9 100644
--- a/src/FilamentMonitors/Duet3DFilamentMonitor.cpp
+++ b/src/FilamentMonitors/Duet3DFilamentMonitor.cpp
@@ -85,7 +85,7 @@ Duet3DFilamentMonitor::PollResult Duet3DFilamentMonitor::PollReceiveBuffer(uint1
{
// For the Duet3D sensors we need to decode the received data from the transition times recorded in the edgeCaptures array
static constexpr uint32_t BitsPerSecond = 1000; // the nominal bit rate that the data is transmitted at
- static constexpr uint32_t NominalBitLength = StepTimer::StepClockRate/BitsPerSecond; // the nominal bit length in step clocks
+ static constexpr uint32_t NominalBitLength = StepClockRate/BitsPerSecond; // the nominal bit length in step clocks
static constexpr uint32_t MinBitLength = (NominalBitLength * 10)/13; // allow 30% clock speed tolerance
static constexpr uint32_t MaxBitLength = (NominalBitLength * 13)/10; // allow 30% clock speed tolerance
static constexpr uint32_t ErrorRecoveryDelayBits = 8; // before a start bit we want the line to be low for this long
diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp
index a6200a76..117df375 100644
--- a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp
+++ b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp
@@ -50,17 +50,17 @@ constexpr ObjectModelTableEntry GCodeBuffer::objectModelTable[] =
{
// Within each group, these entries must be in alphabetical order
// 0. inputs[] root
- { "axesRelative", OBJECT_MODEL_FUNC((bool)self->machineState->axesRelative), ObjectModelEntryFlags::none },
- { "compatibility", OBJECT_MODEL_FUNC(self->machineState->compatibility.ToString()), ObjectModelEntryFlags::none },
- { "distanceUnit", OBJECT_MODEL_FUNC(self->GetDistanceUnits()), ObjectModelEntryFlags::none },
- { "drivesRelative", OBJECT_MODEL_FUNC((bool)self->machineState->drivesRelative), ObjectModelEntryFlags::none },
- { "feedRate", OBJECT_MODEL_FUNC(self->machineState->feedRate, 1), ObjectModelEntryFlags::live },
- { "inMacro", OBJECT_MODEL_FUNC((bool)self->machineState->doingFileMacro), ObjectModelEntryFlags::none },
- { "lineNumber", OBJECT_MODEL_FUNC((int32_t)self->GetLineNumber()), ObjectModelEntryFlags::live },
- { "name", OBJECT_MODEL_FUNC(self->codeChannel.ToString()), ObjectModelEntryFlags::none },
- { "stackDepth", OBJECT_MODEL_FUNC((int32_t)self->GetStackDepth()), ObjectModelEntryFlags::none },
- { "state", OBJECT_MODEL_FUNC(self->GetStateText()), ObjectModelEntryFlags::live },
- { "volumetric", OBJECT_MODEL_FUNC((bool)self->machineState->volumetricExtrusion), ObjectModelEntryFlags::none },
+ { "axesRelative", OBJECT_MODEL_FUNC((bool)self->machineState->axesRelative), ObjectModelEntryFlags::none },
+ { "compatibility", OBJECT_MODEL_FUNC(self->machineState->compatibility.ToString()), ObjectModelEntryFlags::none },
+ { "distanceUnit", OBJECT_MODEL_FUNC(self->GetDistanceUnits()), ObjectModelEntryFlags::none },
+ { "drivesRelative", OBJECT_MODEL_FUNC((bool)self->machineState->drivesRelative), ObjectModelEntryFlags::none },
+ { "feedRate", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerSec(self->machineState->feedRate), 1), ObjectModelEntryFlags::live },
+ { "inMacro", OBJECT_MODEL_FUNC((bool)self->machineState->doingFileMacro), ObjectModelEntryFlags::none },
+ { "lineNumber", OBJECT_MODEL_FUNC((int32_t)self->GetLineNumber()), ObjectModelEntryFlags::live },
+ { "name", OBJECT_MODEL_FUNC(self->codeChannel.ToString()), ObjectModelEntryFlags::none },
+ { "stackDepth", OBJECT_MODEL_FUNC((int32_t)self->GetStackDepth()), ObjectModelEntryFlags::none },
+ { "state", OBJECT_MODEL_FUNC(self->GetStateText()), ObjectModelEntryFlags::live },
+ { "volumetric", OBJECT_MODEL_FUNC((bool)self->machineState->volumetricExtrusion), ObjectModelEntryFlags::none },
};
constexpr uint8_t GCodeBuffer::objectModelTableDescriptor[] = { 1, 11 };
@@ -389,19 +389,19 @@ float GCodeBuffer::GetDistance() THROWS(GCodeException)
return ConvertDistance(GetFValue());
}
-// Get a speed in mm/min or inches/min or optionally /sec and convert it to mm/step_clock
+// Get a speed in mm/min or inches/min and convert it to mm/step_clock
float GCodeBuffer::GetSpeed() THROWS(GCodeException)
{
return ConvertSpeed(GetFValue());
}
-// Get a speed in mm/min or inches/min or optionally /sec and convert it to mm/step_clock
+// Get a speed in mm/min mm/sec and convert it to mm/step_clock
float GCodeBuffer::GetSpeedFromMm(bool useSeconds) THROWS(GCodeException)
{
return ConvertSpeedFromMm(GetFValue(), useSeconds);
}
-// Get an acceleration in mm/sec^2 or inches/sec^2 and convert it to mm/step_clock^2
+// Get an acceleration in mm/sec^2 and convert it to mm/step_clock^2
float GCodeBuffer::GetAcceleration() THROWS(GCodeException)
{
return ConvertAcceleration(GetFValue());
@@ -755,34 +755,14 @@ float GCodeBuffer::InverseConvertDistance(float distance) const noexcept
return (UsingInches()) ? distance/InchToMm : distance;
}
-/*static*/ float GCodeBuffer::ConvertAcceleration(float accel) noexcept
-{
- return accel * (1.0/StepTimer::StepClockRateSquared);
-}
-
-/*static */float GCodeBuffer::InverseConvertAcceleration(float accel) noexcept
-{
- return accel * StepTimer::StepClockRateSquared;
-}
-
float GCodeBuffer::ConvertSpeed(float speed) const noexcept
{
- return speed * ((UsingInches()) ? InchToMm/StepTimer::StepClockRate : 1.0/StepTimer::StepClockRate);
-}
-
-/*static*/ float GCodeBuffer::ConvertSpeedFromMm(float speed, bool useSeconds) noexcept
-{
- return speed * ((useSeconds) ? 1.0/StepTimer::StepClockRate : MinutesToSeconds/StepTimer::StepClockRate);
+ return speed * ((UsingInches()) ? InchToMm/StepClockRate : 1.0/StepClockRate);
}
float GCodeBuffer::InverseConvertSpeed(float speed) const noexcept
{
- return speed * ((UsingInches()) ? StepTimer::StepClockRate/InchToMm : (float)StepTimer::StepClockRate);
-}
-
-/*static*/ float GCodeBuffer::InverseConvertSpeedToMm(float speed, bool useSeconds) noexcept
-{
- return speed * ((useSeconds) ? StepTimer::StepClockRate : StepTimer::StepClockRate * SecondsToMinutes);
+ return speed * ((UsingInches()) ? StepClockRate/InchToMm : (float)StepClockRate);
}
const char *GCodeBuffer::GetDistanceUnits() const noexcept
diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.h b/src/GCodes/GCodeBuffer/GCodeBuffer.h
index 946f93c4..59e86b72 100644
--- a/src/GCodes/GCodeBuffer/GCodeBuffer.h
+++ b/src/GCodes/GCodeBuffer/GCodeBuffer.h
@@ -134,12 +134,8 @@ public:
bool UsingInches() const noexcept { return machineState->usingInches; }
float ConvertDistance(float distance) const noexcept;
float InverseConvertDistance(float distance) const noexcept;
- static float ConvertAcceleration(float accel) noexcept;
- static float InverseConvertAcceleration(float accel) noexcept;
float ConvertSpeed(float speed) const noexcept;
- static float ConvertSpeedFromMm(float speed, bool useSeconds) noexcept;
float InverseConvertSpeed(float speed) const noexcept;
- static float InverseConvertSpeedToMm(float speed, bool useSeconds) noexcept;
const char *GetDistanceUnits() const noexcept;
unsigned int GetStackDepth() const noexcept;
bool PushState(bool withinSameFile) noexcept; // Push state returning true if successful (i.e. stack not overflowed)
diff --git a/src/GCodes/GCodeMachineState.cpp b/src/GCodes/GCodeMachineState.cpp
index 1af502d1..1e6e6dda 100644
--- a/src/GCodes/GCodeMachineState.cpp
+++ b/src/GCodes/GCodeMachineState.cpp
@@ -12,7 +12,7 @@
// Create a default initialised GCodeMachineState
GCodeMachineState::GCodeMachineState() noexcept
- : feedRate(DefaultFeedRate * SecondsToMinutes),
+ : feedRate(ConvertSpeedFromMmPerMin(DefaultFeedRate)),
#if HAS_LINUX_INTERFACE
fileId(NoFileId),
#endif
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index 94fb82a0..005b5018 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -1492,7 +1492,7 @@ void GCodes::SaveResumeInfo(bool wasPowerFailure) noexcept
buf.catf("\nG0 F6000 Z%.3f\n", (double)pauseRestorePoint.moveCoords[Z_AXIS]);
// Set the feed rate
- buf.catf("G1 F%.1f", (double)(pauseRestorePoint.feedRate * MinutesToSeconds));
+ buf.catf("G1 F%.1f", (double)InverseConvertSpeedToMmPerMin(pauseRestorePoint.feedRate));
#if SUPPORT_LASER
if (machineType == MachineType::laser)
{
@@ -1630,7 +1630,7 @@ const char * GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isP
moveBuffer.applyM220M221 = (moveBuffer.moveType == 0 && isPrintingMove && !gb.IsDoingFileMacro());
if (gb.Seen(feedrateLetter))
{
- gb.LatestMachineState().feedRate = gb.GetDistance() * SecondsToMinutes; // update requested speed, not allowing for speed factor
+ gb.LatestMachineState().feedRate = gb.GetSpeed(); // update requested speed, not allowing for speed factor
}
moveBuffer.feedRate = (moveBuffer.applyM220M221)
? speedFactor * gb.LatestMachineState().feedRate
@@ -1640,7 +1640,7 @@ const char * GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isP
else
{
moveBuffer.applyM220M221 = false;
- moveBuffer.feedRate = DefaultG0FeedRate; // use maximum feed rate, the M203 parameters will limit it
+ moveBuffer.feedRate = ConvertSpeedFromMmPerMin(DefaultG0FeedRate); // use maximum feed rate, the M203 parameters will limit it
moveBuffer.usingStandardFeedrate = false;
}
@@ -1650,11 +1650,11 @@ const char * GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isP
moveBuffer.coords[drive] = 0.0;
}
moveBuffer.hasPositiveExtrusion = false;
- moveBuffer.virtualExtruderPosition = virtualExtruderPosition; // save this before we update it
+ moveBuffer.virtualExtruderPosition = virtualExtruderPosition; // save this before we update it
ExtrudersBitmap extrudersMoving;
// Check if we are extruding
- if (gb.Seen(extrudeLetter)) // DC 2018-08-07: at E3D's request, extrusion is now recognised even on uncoordinated moves
+ if (gb.Seen(extrudeLetter)) // DC 2018-08-07: at E3D's request, extrusion is now recognised even on uncoordinated moves
{
// Check that we have a tool to extrude with
Tool* const tool = reprap.GetCurrentTool();
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 34a8dd1e..22510e8a 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -2083,7 +2083,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
gb.GetFloatArray(eVals, eCount, true);
for (size_t e = 0; e < eCount; e++)
{
- platform.SetAcceleration(ExtruderToLogicalDrive(e), GCodeBuffer::ConvertAcceleration(eVals[e]));
+ platform.SetAcceleration(ExtruderToLogicalDrive(e), ConvertAcceleration(eVals[e]));
}
}
@@ -2096,13 +2096,13 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
reply.copy("Accelerations (mm/sec^2): ");
for (size_t axis = 0; axis < numTotalAxes; ++axis)
{
- reply.catf("%c: %.1f, ", axisLetters[axis], (double)GCodeBuffer::InverseConvertAcceleration(platform.Acceleration(axis)));
+ reply.catf("%c: %.1f, ", axisLetters[axis], (double)InverseConvertAcceleration(platform.Acceleration(axis)));
}
reply.cat("E:");
char sep = ' ';
for (size_t extruder = 0; extruder < numExtruders; extruder++)
{
- reply.catf("%c%.1f", sep, (double)GCodeBuffer::InverseConvertAcceleration(platform.Acceleration(ExtruderToLogicalDrive(extruder))));
+ reply.catf("%c%.1f", sep, (double)InverseConvertAcceleration(platform.Acceleration(ExtruderToLogicalDrive(extruder))));
sep = ':';
}
}
@@ -2139,7 +2139,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
gb.GetFloatArray(eVals, eCount, true);
for (size_t e = 0; e < eCount; e++)
{
- platform.SetMaxFeedrate(ExtruderToLogicalDrive(e), gb.ConvertSpeedFromMm(eVals[e], usingMmPerSec));
+ platform.SetMaxFeedrate(ExtruderToLogicalDrive(e), ConvertSpeedFromMm(eVals[e], usingMmPerSec));
}
}
@@ -2152,16 +2152,16 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
reply.printf("Max speeds (%s)): ", (usingMmPerSec) ? "mm/sec" : "mm/min");
for (size_t axis = 0; axis < numTotalAxes; ++axis)
{
- reply.catf("%c: %.1f, ", axisLetters[axis], (double)gb.InverseConvertSpeedToMm(platform.MaxFeedrate(axis), usingMmPerSec));
+ reply.catf("%c: %.1f, ", axisLetters[axis], (double)InverseConvertSpeedToMm(platform.MaxFeedrate(axis), usingMmPerSec));
}
reply.cat("E:");
char sep = ' ';
for (size_t extruder = 0; extruder < numExtruders; extruder++)
{
- reply.catf("%c%.1f", sep, (double)gb.InverseConvertSpeedToMm(platform.MaxFeedrate(ExtruderToLogicalDrive(extruder)), usingMmPerSec));
+ reply.catf("%c%.1f", sep, (double)InverseConvertSpeedToMm(platform.MaxFeedrate(ExtruderToLogicalDrive(extruder)), usingMmPerSec));
sep = ':';
}
- reply.catf(", min. speed %.2f", (double)gb.InverseConvertSpeedToMm(platform.MinMovementSpeed(), usingMmPerSec));
+ reply.catf(", min. speed %.2f", (double)InverseConvertSpeedToMm(platform.MinMovementSpeed(), usingMmPerSec));
}
}
break;
@@ -3298,7 +3298,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
gb.GetFloatArray(eVals, eCount, true);
for (size_t e = 0; e < eCount; e++)
{
- platform.SetInstantDv(ExtruderToLogicalDrive(e), gb.ConvertSpeedFromMm(eVals[e], useMmPerSec));
+ platform.SetInstantDv(ExtruderToLogicalDrive(e), ConvertSpeedFromMm(eVals[e], useMmPerSec));
}
}
@@ -3317,13 +3317,13 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
reply.printf("Maximum jerk rates (%s): ", (useMmPerSec) ? "mm/sec" : "mm/min");
for (size_t axis = 0; axis < numTotalAxes; ++axis)
{
- reply.catf("%c: %.1f, ", axisLetters[axis], (double)gb.InverseConvertSpeedToMm(platform.GetInstantDv(axis), useMmPerSec));
+ reply.catf("%c: %.1f, ", axisLetters[axis], (double)InverseConvertSpeedToMm(platform.GetInstantDv(axis), useMmPerSec));
}
reply.cat("E:");
char sep = ' ';
for (size_t extruder = 0; extruder < numExtruders; extruder++)
{
- reply.catf("%c%.1f", sep, (double)gb.InverseConvertSpeedToMm(platform.GetInstantDv(ExtruderToLogicalDrive(extruder)), useMmPerSec));
+ reply.catf("%c%.1f", sep, (double)InverseConvertSpeedToMm(platform.GetInstantDv(ExtruderToLogicalDrive(extruder)), useMmPerSec));
sep = ':';
}
if (code == 566)
@@ -3962,8 +3962,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
// Get the feedrate (if any) and kick off a new move
if (gb.Seen(feedrateLetter))
{
- const float rate = gb.ConvertDistance(gb.GetFValue());
- gb.LatestMachineState().feedRate = rate * SecondsToMinutes; // don't apply the speed factor
+ gb.LatestMachineState().feedRate = gb.GetSpeed(); // don't apply the speed factor
}
moveBuffer.feedRate = gb.LatestMachineState().feedRate;
moveBuffer.usingStandardFeedrate = true;
diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp
index b48ae06b..7fc6069c 100644
--- a/src/GCodes/GCodes3.cpp
+++ b/src/GCodes/GCodes3.cpp
@@ -915,7 +915,7 @@ GCodeResult GCodes::ProbeTool(GCodeBuffer& gb, const StringRef& reply) THROWS(GC
// Get the feed rate and axis
gb.MustSee(feedrateLetter);
- m585Settings.feedRate = gb.LatestMachineState().feedRate = gb.GetDistance() * SecondsToMinutes; // don't apply the speed factor to homing and other special moves
+ m585Settings.feedRate = gb.LatestMachineState().feedRate = gb.GetSpeed(); // don't apply the speed factor to homing and other special moves
m585Settings.axisNumber = FindAxisLetter(gb);
m585Settings.offset = gb.GetDistance();
@@ -1006,7 +1006,7 @@ GCodeResult GCodes::FindCenterOfCavity(GCodeBuffer& gb, const StringRef& reply)
// Get the feed rate, backoff distance, and axis
gb.MustSee(feedrateLetter);
- m675Settings.feedRate = gb.LatestMachineState().feedRate = gb.GetDistance() * SecondsToMinutes; // don't apply the speed factor to homing and other special moves
+ m675Settings.feedRate = gb.LatestMachineState().feedRate = gb.GetSpeed(); // don't apply the speed factor to homing and other special moves
m675Settings.backoffDistance = gb.Seen('R') ? gb.GetDistance() : 5.0;
m675Settings.axisNumber = FindAxisLetter(gb);
diff --git a/src/GCodes/RestorePoint.cpp b/src/GCodes/RestorePoint.cpp
index edbfbf71..f197b25d 100644
--- a/src/GCodes/RestorePoint.cpp
+++ b/src/GCodes/RestorePoint.cpp
@@ -34,7 +34,7 @@ constexpr ObjectModelTableEntry RestorePoint::objectModelTable[] =
{ "coords", OBJECT_MODEL_FUNC_NOSELF(&coordinatesArrayDescriptor), ObjectModelEntryFlags::none },
{ "extruderPos", OBJECT_MODEL_FUNC(self->virtualExtruderPosition, 1), ObjectModelEntryFlags::none },
{ "fanPwm", OBJECT_MODEL_FUNC(self->fanSpeed, 2), ObjectModelEntryFlags::none },
- { "feedRate", OBJECT_MODEL_FUNC(self->feedRate, 1), ObjectModelEntryFlags::none },
+ { "feedRate", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerSec(self->feedRate), 1), ObjectModelEntryFlags::none },
#if SUPPORT_IOBITS
{ "ioBits", OBJECT_MODEL_FUNC_IF(reprap.GetGCodes().GetMachineType() != MachineType::laser,
(int32_t)self->laserPwmOrIoBits.ioBits), ObjectModelEntryFlags::none },
@@ -64,7 +64,7 @@ void RestorePoint::Init() noexcept
moveCoords[i] = 0.0;
}
- feedRate = DefaultFeedRate * SecondsToMinutes;
+ feedRate = ConvertSpeedFromMmPerMin(DefaultFeedRate);
virtualExtruderPosition = 0.0;
filePos = noFilePosition;
proportionDone = 0.0;
diff --git a/src/Heating/Sensors/DhtSensor.cpp b/src/Heating/Sensors/DhtSensor.cpp
index 82ddae7c..521e25bb 100644
--- a/src/Heating/Sensors/DhtSensor.cpp
+++ b/src/Heating/Sensors/DhtSensor.cpp
@@ -17,7 +17,7 @@
constexpr uint16_t MinimumReadInterval = 2000; // ms
constexpr uint8_t MaximumReadTime = 20; // ms
constexpr uint8_t MinimumOneBitLength = 50; // microseconds
-constexpr uint32_t MinimumOneBitStepClocks = (StepTimer::StepClockRate * MinimumOneBitLength)/1000000;
+constexpr uint32_t MinimumOneBitStepClocks = (StepClockRate * MinimumOneBitLength)/1000000;
// Pulse ISR
void DhtDataTransition(CallbackParameter cp) noexcept
diff --git a/src/Libraries/Fatfs/diskio.cpp b/src/Libraries/Fatfs/diskio.cpp
index 41b8e7fb..22687235 100644
--- a/src/Libraries/Fatfs/diskio.cpp
+++ b/src/Libraries/Fatfs/diskio.cpp
@@ -67,14 +67,14 @@ unsigned int DiskioGetAndClearMaxRetryCount() noexcept
float DiskioGetAndClearLongestReadTime() noexcept
{
- const float ret = (float)longestReadTime * StepTimer::StepClocksToMillis;
+ const float ret = (float)longestReadTime * StepClocksToMillis;
longestReadTime = 0;
return ret;
}
float DiskioGetAndClearLongestWriteTime() noexcept
{
- const float ret = (float)longestWriteTime * StepTimer::StepClocksToMillis;
+ const float ret = (float)longestWriteTime * StepClocksToMillis;
longestWriteTime = 0;
return ret;
}
diff --git a/src/Movement/AxisShaper.cpp b/src/Movement/AxisShaper.cpp
index d6eb636b..0b7d5d4f 100644
--- a/src/Movement/AxisShaper.cpp
+++ b/src/Movement/AxisShaper.cpp
@@ -39,7 +39,7 @@ AxisShaper::AxisShaper() noexcept
: numExtraImpulses(0),
frequency(DefaultFrequency),
zeta(DefaultDamping),
- minimumAcceleration(DefaultMinimumAcceleration/StepTimer::StepClockRateSquared),
+ minimumAcceleration(ConvertAcceleration(DefaultMinimumAcceleration)),
type(InputShaperType::none)
{
}
@@ -47,7 +47,7 @@ AxisShaper::AxisShaper() noexcept
// Process M593
GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException)
{
- constexpr float MinimumInputShapingFrequency = (float)StepTimer::StepClockRate/(2 * 65535); // we use a 16-bit number of step clocks to represent half the input shaping period
+ constexpr float MinimumInputShapingFrequency = (float)StepClockRate/(2 * 65535); // we use a 16-bit number of step clocks to represent half the input shaping period
constexpr float MaximumInputShapingFrequency = 1000.0;
bool seen = false;
if (gb.Seen('F'))
@@ -58,7 +58,7 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW
if (gb.Seen('L'))
{
seen = true;
- minimumAcceleration = max<float>(gb.GetFValue(), 1.0)/StepTimer::StepClockRateSquared; // very low accelerations cause problems with the maths
+ minimumAcceleration = ConvertAcceleration(max<float>(gb.GetFValue(), 1.0)); // very low accelerations cause problems with the maths
}
if (gb.Seen('S'))
{
@@ -93,7 +93,7 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW
{
const float sqrtOneMinusZetaSquared = fastSqrtf(1.0 - fsquare(zeta));
const float dampedFrequency = frequency * sqrtOneMinusZetaSquared;
- const float dampedPeriod = StepTimer::StepClockRate/dampedFrequency;
+ const float dampedPeriod = StepClockRate/dampedFrequency;
const float k = expf(-zeta * Pi/sqrtOneMinusZetaSquared);
switch (type.RawValue())
{
@@ -123,7 +123,7 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW
}
for (unsigned int i = 0; i < numAmplitudes; ++i)
{
- durations[i] *= StepTimer::StepClockRate; // convert from seconds to step clocks
+ durations[i] *= StepClockRate; // convert from seconds to step clocks
}
}
else
@@ -219,9 +219,9 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW
}
}
- minimumShapingStartOriginalClocks = totalShapingClocks - extraClocksAtStart + (MinimumMiddleSegmentTime * StepTimer::StepClockRate);
- minimumShapingEndOriginalClocks = totalShapingClocks - extraClocksAtEnd + (MinimumMiddleSegmentTime * StepTimer::StepClockRate);
- minimumNonOverlappedOriginalClocks = (totalShapingClocks * 2) - extraClocksAtStart - extraClocksAtEnd + (MinimumMiddleSegmentTime * StepTimer::StepClockRate);
+ minimumShapingStartOriginalClocks = totalShapingClocks - extraClocksAtStart + (MinimumMiddleSegmentTime * StepClockRate);
+ minimumShapingEndOriginalClocks = totalShapingClocks - extraClocksAtEnd + (MinimumMiddleSegmentTime * StepClockRate);
+ minimumNonOverlappedOriginalClocks = (totalShapingClocks * 2) - extraClocksAtStart - extraClocksAtEnd + (MinimumMiddleSegmentTime * StepClockRate);
{
float v = 0.0;
@@ -278,7 +278,7 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW
else
{
reply.printf("Input shaping '%s' at %.1fHz damping factor %.2f, min. acceleration %.1f",
- type.ToString(), (double)frequency, (double)zeta, (double)(minimumAcceleration * StepTimer::StepClockRateSquared));
+ type.ToString(), (double)frequency, (double)zeta, (double)InverseConvertAcceleration(minimumAcceleration));
if (numExtraImpulses != 0)
{
reply.cat(", impulses");
@@ -289,7 +289,7 @@ GCodeResult AxisShaper::Configure(GCodeBuffer& gb, const StringRef& reply) THROW
reply.cat(" with durations (ms)");
for (unsigned int i = 0; i < numExtraImpulses; ++i)
{
- reply.catf(" %.2f", (double)(durations[i] * (1000.0/StepTimer::StepClockRate)));
+ reply.catf(" %.2f", (double)(durations[i] * StepClocksToMillis));
}
}
}
@@ -485,17 +485,17 @@ void AxisShaper::PlanShaping(DDA& dda, PrepParams& params, bool shapingEnabled)
if (params.shapingPlan.shapeAccelStart || params.shapingPlan.shapeAccelEnd || params.shapingPlan.shapeAccelOverlapped)
{
const float speedIncrease = dda.topSpeed - dda.startSpeed;
- params.accelClocks = 2 * (dda.topSpeed * params.accelClocks - params.accelDistance * StepTimer::StepClockRate)/speedIncrease;
- params.accelDistance = (dda.startSpeed + dda.topSpeed) * params.accelClocks/(2 * StepTimer::StepClockRate);
- dda.acceleration = (speedIncrease * StepTimer::StepClockRate)/params.accelClocks;
+ params.accelClocks = 2 * (dda.topSpeed * params.accelClocks - params.accelDistance)/speedIncrease;
+ params.accelDistance = (dda.startSpeed + dda.topSpeed) * params.accelClocks * 0.5;
+ dda.acceleration = speedIncrease/params.accelClocks;
}
if (params.shapingPlan.shapeDecelStart || params.shapingPlan.shapeDecelEnd || params.shapingPlan.shapeDecelOverlapped)
{
const float speedDecrease = dda.endSpeed - dda.startSpeed;
- params.decelClocks = 2 * (params.decelDistance * StepTimer::StepClockRate - dda.topSpeed * params.decelClocks)/speedDecrease;
- params.decelDistance = (dda.topSpeed + dda.endSpeed) * params.decelClocks/(2 * StepTimer::StepClockRate);
+ params.decelClocks = 2 * (params.decelDistance - dda.topSpeed * params.decelClocks)/speedDecrease;
+ params.decelDistance = (dda.topSpeed + dda.endSpeed) * params.decelClocks * 0.5;
params.decelStartDistance = dda.totalDistance - params.decelDistance;
- dda.deceleration = (speedDecrease * StepTimer::StepClockRate)/params.decelClocks;
+ dda.deceleration = speedDecrease/params.decelClocks;
}
}
else
@@ -548,20 +548,20 @@ void AxisShaper::TryShapeAccelEnd(const DDA& dda, PrepParams& params) const noex
void AxisShaper::TryShapeAccelBoth(DDA& dda, PrepParams& params) const noexcept
{
- if ((dda.topSpeed - dda.startSpeed)/StepTimer::StepClockRate <= overlappedDeltaVPerA * (dda.acceleration/StepTimer::StepClockRateSquared))
+ if (dda.topSpeed - dda.startSpeed <= overlappedDeltaVPerA * dda.acceleration)
{
// We can use overlapped shaping
- const float newAcceleration = ((dda.topSpeed - dda.startSpeed)/StepTimer::StepClockRate)/overlappedDeltaVPerA;
+ const float newAcceleration = (dda.topSpeed - dda.startSpeed)/overlappedDeltaVPerA;
if (newAcceleration < minimumAcceleration)
{
return;
}
- const float newAccelDistance = ((dda.startSpeed/StepTimer::StepClockRate) * overlappedShapingClocks) + (newAcceleration * overlappedDistancePerA);
+ const float newAccelDistance = (dda.startSpeed * overlappedShapingClocks) + (newAcceleration * overlappedDistancePerA);
if (newAccelDistance >= params.decelStartDistance)
{
return;
}
- dda.acceleration = newAcceleration * StepTimer::StepClockRateSquared;
+ dda.acceleration = newAcceleration;
params.accelDistance = newAccelDistance;
params.accelClocks = overlappedShapingClocks;
params.shapingPlan.shapeAccelOverlapped = true;
@@ -572,13 +572,13 @@ void AxisShaper::TryShapeAccelBoth(DDA& dda, PrepParams& params) const noexcept
{
// The speed change is too high to allow overlapping, but non-overlapped shaping will give a very short steady acceleration segment.
// If we have enough spare distance, reduce the acceleration slightly to lengthen that segment.
- const float newAcceleration = (dda.acceleration/StepTimer::StepClockRateSquared) * params.accelClocks/minimumNonOverlappedOriginalClocks;
- const float newAccelDistance = ((dda.startSpeed/StepTimer::StepClockRate) + (0.5 * newAcceleration * minimumNonOverlappedOriginalClocks)) * minimumNonOverlappedOriginalClocks;
+ const float newAcceleration = (dda.acceleration * params.accelClocks)/minimumNonOverlappedOriginalClocks;
+ const float newAccelDistance = (dda.startSpeed + (0.5 * newAcceleration * minimumNonOverlappedOriginalClocks)) * minimumNonOverlappedOriginalClocks;
if (newAccelDistance >= params.decelStartDistance)
{
return;
}
- dda.acceleration = newAcceleration * StepTimer::StepClockRateSquared;
+ dda.acceleration = newAcceleration;
params.accelDistance = newAccelDistance;
params.accelClocks = minimumNonOverlappedOriginalClocks;
}
@@ -631,21 +631,21 @@ void AxisShaper::TryShapeDecelEnd(const DDA& dda, PrepParams& params) const noex
void AxisShaper::TryShapeDecelBoth(DDA& dda, PrepParams& params) const noexcept
{
- if ((dda.topSpeed - dda.endSpeed)/StepTimer::StepClockRate <= overlappedDeltaVPerA * (dda.deceleration/StepTimer::StepClockRateSquared))
+ if (dda.topSpeed - dda.endSpeed <= overlappedDeltaVPerA * dda.deceleration)
{
// We can use overlapped shaping
- const float newDeceleration = ((dda.topSpeed - dda.endSpeed)/StepTimer::StepClockRate)/overlappedDeltaVPerA;
+ const float newDeceleration = (dda.topSpeed - dda.endSpeed)/overlappedDeltaVPerA;
if (newDeceleration < minimumAcceleration)
{
return;
}
- const float newDecelDistance = ((dda.topSpeed/StepTimer::StepClockRate) * overlappedShapingClocks) - (newDeceleration * overlappedDistancePerA);
+ const float newDecelDistance = (dda.topSpeed * overlappedShapingClocks) - (newDeceleration * overlappedDistancePerA);
const float newDecelStartDistance = dda.totalDistance - newDecelDistance;
if (newDecelStartDistance < params.accelDistance)
{
return;
}
- dda.deceleration = newDeceleration * StepTimer::StepClockRateSquared;
+ dda.deceleration = newDeceleration;
params.decelDistance = newDecelDistance;
params.decelStartDistance = newDecelStartDistance;
params.decelClocks = overlappedShapingClocks;
@@ -657,14 +657,14 @@ void AxisShaper::TryShapeDecelBoth(DDA& dda, PrepParams& params) const noexcept
{
// The speed change is too high to allow overlapping, but non-overlapped shaping will give a very short steady acceleration segment.
// If we have enough spare distance, reduce the acceleration slightly to lengthen that segment.
- const float newDeceleration = (dda.deceleration/StepTimer::StepClockRateSquared) * params.decelClocks/minimumNonOverlappedOriginalClocks;
- const float newDecelDistance = ((dda.endSpeed/StepTimer::StepClockRate) + (0.5 * newDeceleration * minimumNonOverlappedOriginalClocks)) * minimumNonOverlappedOriginalClocks;
+ const float newDeceleration = (dda.deceleration * params.decelClocks)/minimumNonOverlappedOriginalClocks;
+ const float newDecelDistance = (dda.endSpeed + (0.5 * newDeceleration * minimumNonOverlappedOriginalClocks)) * minimumNonOverlappedOriginalClocks;
const float newDecelStartDistance = dda.totalDistance - newDecelDistance;
if (newDecelStartDistance <= params.accelDistance)
{
return;
}
- dda.deceleration = newDeceleration * StepTimer::StepClockRateSquared;
+ dda.deceleration = newDeceleration;
params.decelStartDistance = newDecelStartDistance;
params.decelClocks = overlappedShapingClocks;
}
@@ -678,15 +678,14 @@ MoveSegment *AxisShaper::GetAccelerationSegments(const DDA& dda, const PrepParam
{
if (dda.beforePrepare.accelDistance > 0.0)
{
- const float peakAcceleration = dda.acceleration/StepTimer::StepClockRateSquared;
if (params.shapingPlan.shapeAccelOverlapped)
{
MoveSegment *accelSegs = nullptr;
- float segStartSpeed = dda.topSpeed/StepTimer::StepClockRate;
+ float segStartSpeed = dda.topSpeed;
for (int i = (2 * numExtraImpulses) - 1; i >= 0; --i)
{
accelSegs = MoveSegment::Allocate(accelSegs);
- const float acceleration = peakAcceleration * overlappedCoefficients[i];
+ const float acceleration = dda.acceleration * overlappedCoefficients[i];
const float segTime = overlappedDurations[i];
segStartSpeed -= acceleration * segTime;
const float b = segStartSpeed/(-acceleration);
@@ -703,11 +702,11 @@ MoveSegment *AxisShaper::GetAccelerationSegments(const DDA& dda, const PrepParam
if (params.shapingPlan.shapeAccelEnd)
{
// Shape the end of the acceleration
- float segStartSpeed = dda.topSpeed/StepTimer::StepClockRate;
+ float segStartSpeed = dda.topSpeed;
for (int i = numExtraImpulses - 1; i >= 0; --i)
{
endAccelSegs = MoveSegment::Allocate(endAccelSegs);
- const float acceleration = peakAcceleration * (1.0 - coefficients[i]);
+ const float acceleration = dda.acceleration * (1.0 - coefficients[i]);
const float segTime = durations[i];
segStartSpeed -= acceleration * segTime;
const float b = segStartSpeed/(-acceleration);
@@ -720,7 +719,7 @@ MoveSegment *AxisShaper::GetAccelerationSegments(const DDA& dda, const PrepParam
}
float startDistance = 0.0;
- float startSpeed = dda.startSpeed/StepTimer::StepClockRate;
+ float startSpeed = dda.startSpeed;
MoveSegment *startAccelSegs = nullptr;
if (params.shapingPlan.shapeAccelStart)
{
@@ -728,7 +727,7 @@ MoveSegment *AxisShaper::GetAccelerationSegments(const DDA& dda, const PrepParam
for (unsigned int i = 0; i < numExtraImpulses; ++i)
{
MoveSegment *seg = MoveSegment::Allocate(nullptr);
- const float acceleration = peakAcceleration * coefficients[i];
+ const float acceleration = dda.acceleration * coefficients[i];
const float segTime = durations[i];
const float b = startSpeed/(-acceleration);
const float c = 2.0/acceleration;
@@ -752,8 +751,8 @@ MoveSegment *AxisShaper::GetAccelerationSegments(const DDA& dda, const PrepParam
if (endDistance > startDistance)
{
endAccelSegs = MoveSegment::Allocate(endAccelSegs);
- const float b = startSpeed/(-peakAcceleration);
- const float c = 2.0/peakAcceleration;
+ const float b = startSpeed/(-dda.acceleration);
+ const float c = 2.0/dda.acceleration;
endAccelSegs->SetNonLinear(endDistance - startDistance, params.accelClocks - accumulatedSegTime, b, c);
}
@@ -777,15 +776,14 @@ MoveSegment *AxisShaper::GetDecelerationSegments(const DDA& dda, const PrepParam
{
if (dda.beforePrepare.decelDistance > 0.0)
{
- const float peakDeceleration = dda.deceleration/StepTimer::StepClockRateSquared;
if (params.shapingPlan.shapeDecelOverlapped)
{
MoveSegment *decelSegs = nullptr;
- float segStartSpeed = dda.endSpeed/StepTimer::StepClockRate;
+ float segStartSpeed = dda.endSpeed;
for (int i = (2 * numExtraImpulses) - 1; i >= 0; --i)
{
decelSegs = MoveSegment::Allocate(decelSegs);
- const float deceleration = peakDeceleration * overlappedCoefficients[i];
+ const float deceleration = dda.deceleration * overlappedCoefficients[i];
const float segTime = overlappedDurations[i];
segStartSpeed += deceleration * segTime;
const float b = segStartSpeed/deceleration;
@@ -802,11 +800,11 @@ MoveSegment *AxisShaper::GetDecelerationSegments(const DDA& dda, const PrepParam
if (params.shapingPlan.shapeDecelEnd)
{
// Shape the end of the deceleration
- float segStartSpeed = dda.endSpeed/StepTimer::StepClockRate;
+ float segStartSpeed = dda.endSpeed;
for (int i = numExtraImpulses - 1; i >= 0; --i)
{
endDecelSegs = MoveSegment::Allocate(endDecelSegs);
- const float deceleration = peakDeceleration * (1.0 - coefficients[i]);
+ const float deceleration = dda.deceleration * (1.0 - coefficients[i]);
const float segTime = durations[i];
segStartSpeed += deceleration * segTime;
const float b = segStartSpeed/deceleration;
@@ -819,7 +817,7 @@ MoveSegment *AxisShaper::GetDecelerationSegments(const DDA& dda, const PrepParam
}
float startDistance = params.decelStartDistance;
- float startSpeed = dda.topSpeed/StepTimer::StepClockRate;
+ float startSpeed = dda.topSpeed;
MoveSegment *startDecelSegs = nullptr;
if (params.shapingPlan.shapeDecelStart)
{
@@ -827,7 +825,7 @@ MoveSegment *AxisShaper::GetDecelerationSegments(const DDA& dda, const PrepParam
for (unsigned int i = 0; i < numExtraImpulses; ++i)
{
MoveSegment *seg = MoveSegment::Allocate(nullptr);
- const float deceleration = peakDeceleration * coefficients[i];
+ const float deceleration = dda.deceleration * coefficients[i];
const float segTime = durations[i];
const float b = startSpeed/deceleration;
const float c = -2.0/deceleration;
@@ -851,8 +849,8 @@ MoveSegment *AxisShaper::GetDecelerationSegments(const DDA& dda, const PrepParam
if (endDistance > startDistance)
{
endDecelSegs = MoveSegment::Allocate(endDecelSegs);
- const float b = startSpeed/peakDeceleration;
- const float c = -2.0/peakDeceleration;
+ const float b = startSpeed/dda.deceleration;
+ const float c = -2.0/dda.deceleration;
endDecelSegs->SetNonLinear(endDistance - startDistance, params.decelClocks - accumulatedSegTime, b, c);
}
@@ -879,7 +877,7 @@ MoveSegment *AxisShaper::FinishSegments(const DDA& dda, const PrepParams& params
{
// Insert a steady speed segment before the deceleration segments
decelSegs = MoveSegment::Allocate(decelSegs);
- const float c = StepTimer::StepClockRate/dda.topSpeed;
+ const float c = 1.0/dda.topSpeed;
decelSegs->SetLinear(params.decelStartDistance - params.accelDistance, params.steadyClocks, c);
}
@@ -898,24 +896,24 @@ MoveSegment *AxisShaper::FinishSegments(const DDA& dda, const PrepParams& params
// Calculate the additional acceleration distance needed if we shape the start of acceleration
inline float AxisShaper::GetExtraAccelStartDistance(const DDA& dda) const noexcept
{
- return ((extraClocksAtStart * dda.startSpeed)/StepTimer::StepClockRate) + ((extraDistanceAtStart * dda.acceleration)/StepTimer::StepClockRateSquared);
+ return (extraClocksAtStart * dda.startSpeed) + (extraDistanceAtStart * dda.acceleration);
}
// Calculate the additional acceleration distance needed if we shape the end of acceleration
inline float AxisShaper::GetExtraAccelEndDistance(const DDA& dda) const noexcept
{
- return ((extraClocksAtEnd * dda.topSpeed)/StepTimer::StepClockRate) + ((extraDistanceAtEnd * dda.acceleration)/StepTimer::StepClockRateSquared);
+ return (extraClocksAtEnd * dda.topSpeed) + (extraDistanceAtEnd * dda.acceleration);
}
inline float AxisShaper::GetExtraDecelStartDistance(const DDA& dda) const noexcept
{
- return ((extraClocksAtStart * dda.topSpeed)/StepTimer::StepClockRate) - ((extraDistanceAtStart * dda.deceleration)/StepTimer::StepClockRateSquared);
+ return (extraClocksAtStart * dda.topSpeed) - (extraDistanceAtStart * dda.deceleration);
}
// Calculate the additional deceleration distance needed if we shape the end of deceleration
inline float AxisShaper::GetExtraDecelEndDistance(const DDA& dda) const noexcept
{
- return ((extraClocksAtEnd * dda.endSpeed)/StepTimer::StepClockRate) - ((extraDistanceAtEnd * dda.deceleration)/StepTimer::StepClockRateSquared);
+ return (extraClocksAtEnd * dda.endSpeed) - (extraDistanceAtEnd * dda.deceleration);
}
/*static*/ MoveSegment *AxisShaper::GetUnshapedSegments(DDA& dda, const PrepParams& params) noexcept
@@ -925,8 +923,8 @@ inline float AxisShaper::GetExtraDecelEndDistance(const DDA& dda) const noexcept
if (params.decelClocks > 0.0)
{
tempSegments = MoveSegment::Allocate(nullptr);
- const float b = (dda.topSpeed * StepTimer::StepClockRate)/dda.deceleration;
- const float c = (2 * StepTimer::StepClockRateSquared)/(-dda.deceleration);
+ const float b = dda.topSpeed/dda.deceleration;
+ const float c = -2.0/dda.deceleration;
tempSegments->SetNonLinear(params.decelDistance, params.decelClocks, b, c);
}
else
@@ -938,7 +936,7 @@ inline float AxisShaper::GetExtraDecelEndDistance(const DDA& dda) const noexcept
if (params.steadyClocks > 0.0)
{
tempSegments = MoveSegment::Allocate(tempSegments);
- const float c = StepTimer::StepClockRate/dda.topSpeed;
+ const float c = 1.0/dda.topSpeed;
tempSegments->SetLinear(params.decelStartDistance - params.accelDistance, params.steadyClocks, c);
}
@@ -946,8 +944,8 @@ inline float AxisShaper::GetExtraDecelEndDistance(const DDA& dda) const noexcept
if (params.accelClocks > 0.0)
{
tempSegments = MoveSegment::Allocate(tempSegments);
- const float b = (dda.startSpeed * StepTimer::StepClockRate)/(-dda.acceleration);
- const float c = (2 * StepTimer::StepClockRateSquared)/dda.acceleration;
+ const float b = dda.startSpeed/(-dda.acceleration);
+ const float c = 2.0/dda.acceleration;
tempSegments->SetNonLinear(params.accelDistance, params.accelClocks, b, c);
}
diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp
index c084b6b1..f3596640 100644
--- a/src/Movement/DDA.cpp
+++ b/src/Movement/DDA.cpp
@@ -123,8 +123,8 @@ void PrepParams::SetFromDDA(const DDA& dda) noexcept
// Due to rounding error, for an accelerate-decelerate move we may have accelDistance+decelDistance slightly greater than totalDistance.
// We need to make sure that accelDistance <= decelStartDistance for subsequent calculations to work.
accelDistance = min<float>(dda.beforePrepare.accelDistance, decelStartDistance);
- accelClocks = ((dda.topSpeed - dda.startSpeed) * StepTimer::StepClockRate)/dda.acceleration;
- decelClocks = ((dda.topSpeed - dda.endSpeed) * StepTimer::StepClockRate)/dda.deceleration;
+ accelClocks = (dda.topSpeed - dda.startSpeed)/dda.acceleration;
+ decelClocks = (dda.topSpeed - dda.endSpeed)/dda.deceleration;
#if SUPPORT_CAN_EXPANSION
initialSpeedFraction = dda.startSpeed/dda.topSpeed;
@@ -136,7 +136,7 @@ void PrepParams::SetFromDDA(const DDA& dda) noexcept
void PrepParams::Finalise(DDA& dda) noexcept
{
const float steadyDistance = decelStartDistance - accelDistance;
- steadyClocks = (steadyDistance <= 0.0) ? 0.0 : (steadyDistance * StepTimer::StepClockRate)/dda.topSpeed;
+ steadyClocks = (steadyDistance <= 0.0) ? 0.0 : steadyDistance/dda.topSpeed;
dda.clocksNeeded = (uint32_t)(accelClocks + decelClocks + steadyClocks);
}
@@ -700,16 +700,16 @@ bool DDA::InitFromRemote(const CanMessageMovementLinear& msg) noexcept
// Normalise the move to unit distance and convert time units from step clocks to seconds
totalDistance = 1.0;
- topSpeed = (2.0 * StepTimer::StepClockRate)/(2 * msg.steadyClocks + (msg.initialSpeedFraction + 1.0) * msg.accelerationClocks + (msg.finalSpeedFraction + 1.0) * msg.decelClocks);
+ topSpeed = 2.0/(2 * msg.steadyClocks + (msg.initialSpeedFraction + 1.0) * msg.accelerationClocks + (msg.finalSpeedFraction + 1.0) * msg.decelClocks);
startSpeed = topSpeed * msg.initialSpeedFraction;
endSpeed = topSpeed * msg.finalSpeedFraction;
- acceleration = (msg.accelerationClocks == 0) ? 0.0 : (topSpeed * (1.0 - msg.initialSpeedFraction) * StepTimer::StepClockRate)/msg.accelerationClocks;
- deceleration = (msg.decelClocks == 0) ? 0.0 : (topSpeed * (1.0 - msg.finalSpeedFraction) * StepTimer::StepClockRate)/msg.decelClocks;
+ acceleration = (msg.accelerationClocks == 0) ? 0.0 : (topSpeed * (1.0 - msg.initialSpeedFraction))/msg.accelerationClocks;
+ deceleration = (msg.decelClocks == 0) ? 0.0 : (topSpeed * (1.0 - msg.finalSpeedFraction))/msg.decelClocks;
PrepParams params;
- params.accelDistance = topSpeed * (1.0 + msg.initialSpeedFraction) * msg.accelerationClocks/(2 * StepTimer::StepClockRate);
- params.decelDistance = topSpeed * (1.0 + msg.finalSpeedFraction) * msg.decelClocks/(2 * StepTimer::StepClockRate);
+ params.accelDistance = topSpeed * (1.0 + msg.initialSpeedFraction) * msg.accelerationClocks * 0.5;
+ params.decelDistance = topSpeed * (1.0 + msg.finalSpeedFraction) * msg.decelClocks * 0.5;
params.decelStartDistance = 1.0 - params.decelDistance;
params.accelClocks = msg.accelerationClocks;
params.steadyClocks = msg.steadyClocks;
@@ -1187,7 +1187,7 @@ void DDA::RecalculateMove(DDARing& ring) noexcept
const float totalTime = (topSpeed - startSpeed)/acceleration
+ (topSpeed - endSpeed)/deceleration
+ (totalDistance - beforePrepare.accelDistance - beforePrepare.decelDistance)/topSpeed;
- clocksNeeded = (uint32_t)(totalTime * StepTimer::StepClockRate);
+ clocksNeeded = (uint32_t)totalTime;
}
// Decide what speed we would really like this move to end at.
@@ -1523,7 +1523,7 @@ void DDA::Prepare(uint8_t simMode) noexcept
if (platform.GetExtrusionCoefficients(extruder, a, b, limit))
{
float& dv = directionVector[drive];
- const float averageExtrusionSpeed = (totalDistance * dv * StepTimer::StepClockRate)/clocksNeeded;
+ const float averageExtrusionSpeed = (totalDistance * dv)/clocksNeeded;
const float factor = 1.0 + min<float>((averageExtrusionSpeed * a) + (averageExtrusionSpeed * averageExtrusionSpeed * b), limit);
dv *= factor;
}
@@ -2249,8 +2249,7 @@ uint32_t DDA::ManageLaserPower() const noexcept
return LaserPwmIntervalMillis;
}
- const float timeMoving = (float)clocksMoving * (1.0/(float)StepTimer::StepClockRate);
- const float accelSpeed = startSpeed + acceleration * timeMoving;
+ const float accelSpeed = startSpeed + acceleration * clocksMoving;
if (accelSpeed < topSpeed)
{
// Acceleration phase
@@ -2260,7 +2259,7 @@ uint32_t DDA::ManageLaserPower() const noexcept
}
const uint32_t clocksLeft = clocksNeeded - clocksMoving;
- const float decelSpeed = endSpeed + deceleration * (float)clocksLeft * (1.0/(float)StepTimer::StepClockRate);
+ const float decelSpeed = endSpeed + deceleration * clocksLeft;
if (decelSpeed < topSpeed)
{
// Deceleration phase
@@ -2271,13 +2270,13 @@ uint32_t DDA::ManageLaserPower() const noexcept
// We must be in the constant speed phase
platform.SetLaserPwm(laserPwmOrIoBits.laserPwm);
- const uint32_t decelClocks = ((topSpeed - endSpeed)/deceleration) * StepTimer::StepClockRate;
+ const uint32_t decelClocks = (topSpeed - endSpeed)/deceleration;
if (clocksLeft <= decelClocks)
{
return LaserPwmIntervalMillis;
}
const uint32_t clocksToDecel = clocksLeft - decelClocks;
- return lrintf((float)clocksToDecel * StepTimer::StepClocksToMillis) + LaserPwmIntervalMillis;
+ return lrintf((float)clocksToDecel * StepClocksToMillis) + LaserPwmIntervalMillis;
}
#endif
diff --git a/src/Movement/DDA.h b/src/Movement/DDA.h
index ae11df2e..d9c06a45 100644
--- a/src/Movement/DDA.h
+++ b/src/Movement/DDA.h
@@ -187,25 +187,25 @@ public:
// Note: the above measurements were taken some time ago, before some firmware optimisations.
#if SAME70
// Use the same defaults as for the SAM4E for now.
- static constexpr uint32_t MinCalcInterval = (40 * StepTimer::StepClockRate)/1000000; // same as delta for now, but could be lower
- static constexpr uint32_t HiccupTime = (30 * StepTimer::StepClockRate)/1000000; // how long we hiccup for in step timer clocks
+ static constexpr uint32_t MinCalcInterval = (40 * StepClockRate)/1000000; // same as delta for now, but could be lower
+ static constexpr uint32_t HiccupTime = (30 * StepClockRate)/1000000; // how long we hiccup for in step timer clocks
#elif SAM4E || SAM4S || SAME5x
- static constexpr uint32_t MinCalcIntervalDelta = (40 * StepTimer::StepClockRate)/1000000; // the smallest sensible interval between calculations (40us) in step timer clocks
- static constexpr uint32_t MinCalcInterval = (40 * StepTimer::StepClockRate)/1000000; // same as delta for now, but could be lower
- static constexpr uint32_t HiccupTime = (30 * StepTimer::StepClockRate)/1000000; // how long we hiccup for in step timer clocks
+ static constexpr uint32_t MinCalcIntervalDelta = (40 * StepClockRate)/1000000; // the smallest sensible interval between calculations (40us) in step timer clocks
+ static constexpr uint32_t MinCalcInterval = (40 * StepClockRate)/1000000; // same as delta for now, but could be lower
+ static constexpr uint32_t HiccupTime = (30 * StepClockRate)/1000000; // how long we hiccup for in step timer clocks
#elif defined(__LPC17xx__)
- static constexpr uint32_t MinCalcInterval = (40 * StepTimer::StepClockRate)/1000000; // same as delta for now, but could be lower
- static constexpr uint32_t HiccupTime = (30 * StepTimer::StepClockRate)/1000000; // how long we hiccup for in step timer clocks
+ static constexpr uint32_t MinCalcInterval = (40 * StepClockRate)/1000000; // same as delta for now, but could be lower
+ static constexpr uint32_t HiccupTime = (30 * StepClockRate)/1000000; // how long we hiccup for in step timer clocks
#else // SAM3X
- static constexpr uint32_t MinCalcInterval = (60 * StepTimer::StepClockRate)/1000000; // same as delta for now, but could be lower
- static constexpr uint32_t HiccupTime = (40 * StepTimer::StepClockRate)/1000000; // how long we hiccup for in step timer clocks
+ static constexpr uint32_t MinCalcInterval = (60 * StepClockRate)/1000000; // same as delta for now, but could be lower
+ static constexpr uint32_t HiccupTime = (40 * StepClockRate)/1000000; // how long we hiccup for in step timer clocks
#endif
- static constexpr uint32_t MaxStepInterruptTime = 10 * StepTimer::MinInterruptInterval; // the maximum time we spend looping in the ISR , in step clocks
- static constexpr uint32_t WakeupTime = (100 * StepTimer::StepClockRate)/1000000; // stop resting 100us before the move is due to end
- static constexpr uint32_t HiccupIncrement = HiccupTime/2; // how much we increase the hiccup time by on each attempt
+ static constexpr uint32_t MaxStepInterruptTime = 10 * StepTimer::MinInterruptInterval; // the maximum time we spend looping in the ISR , in step clocks
+ static constexpr uint32_t WakeupTime = (100 * StepClockRate)/1000000; // stop resting 100us before the move is due to end
+ static constexpr uint32_t HiccupIncrement = HiccupTime/2; // how much we increase the hiccup time by on each attempt
- static constexpr uint32_t UsualMinimumPreparedTime = StepTimer::StepClockRate/10; // 100ms
- static constexpr uint32_t AbsoluteMinimumPreparedTime = StepTimer::StepClockRate/20; // 50ms
+ static constexpr uint32_t UsualMinimumPreparedTime = StepClockRate/10; // 100ms
+ static constexpr uint32_t AbsoluteMinimumPreparedTime = StepClockRate/20; // 50ms
#if DDA_LOG_PROBE_CHANGES
static const size_t MaxLoggedProbePositions = 40;
diff --git a/src/Movement/DDARing.cpp b/src/Movement/DDARing.cpp
index ea4341fa..03789657 100644
--- a/src/Movement/DDARing.cpp
+++ b/src/Movement/DDARing.cpp
@@ -212,7 +212,7 @@ bool DDARing::CanAddMove() const noexcept
prevMoveTime = dda->GetClocksNeeded();
}
- return (unPreparedTime < StepTimer::StepClockRate/2 || unPreparedTime + prevMoveTime < 2 * StepTimer::StepClockRate);
+ return (unPreparedTime < StepClockRate/2 || unPreparedTime + prevMoveTime < 2 * StepClockRate);
}
return false;
}
@@ -266,7 +266,7 @@ void DDARing::Spin(uint8_t simulationMode, bool shouldStartMove) noexcept
// Do this here rather than at the end, so that when simulating, currentDda is non-null for most of the time and IsExtruding() returns the correct value
if (simulationMode != 0 && cdda != nullptr)
{
- simulationTime += (float)cdda->GetClocksNeeded()/StepTimer::StepClockRate;
+ simulationTime += (float)cdda->GetClocksNeeded() * (1.0/StepClockRate);
cdda->Complete();
CurrentMoveCompleted();
cdda = currentDda;
diff --git a/src/Movement/DriveMovement.cpp b/src/Movement/DriveMovement.cpp
index d071595a..73f5327a 100644
--- a/src/Movement/DriveMovement.cpp
+++ b/src/Movement/DriveMovement.cpp
@@ -382,10 +382,8 @@ bool DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params) no
if (dda.flags.usePressureAdvance && shaper.GetK() > 0.0)
{
// We are using nonzero pressure advance. Movement must be forwards.
- const float acceleration = dda.acceleration * (1.0/StepTimer::StepClockRateSquared);
- const float deceleration = dda.deceleration * (1.0/StepTimer::StepClockRateSquared);
- mp.cart.pressureAdvanceK = shaper.GetK() * StepTimer::StepClockRate;
- mp.cart.extraExtrusionDistance = mp.cart.pressureAdvanceK * acceleration * params.accelClocks;
+ mp.cart.pressureAdvanceK = shaper.GetK() * StepClockRate;
+ mp.cart.extraExtrusionDistance = mp.cart.pressureAdvanceK * dda.acceleration * params.accelClocks;
forwardDistance += mp.cart.extraExtrusionDistance;
// Check if there is a reversal in the deceleration segment
@@ -403,12 +401,12 @@ bool DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params) no
}
else
{
- const float initialDecelSpeed = (dda.topSpeed * (1.0/StepTimer::StepClockRate)) - mp.cart.pressureAdvanceK * deceleration;
+ const float initialDecelSpeed = dda.topSpeed - mp.cart.pressureAdvanceK * dda.deceleration;
if (initialDecelSpeed <= 0.0)
{
// The entire deceleration segment is in reverse
forwardDistance += params.decelStartDistance;
- reverseDistance = ((0.5 * deceleration * params.decelClocks) - initialDecelSpeed) * params.decelClocks;
+ reverseDistance = ((0.5 * dda.deceleration * params.decelClocks) - initialDecelSpeed) * params.decelClocks;
}
else
{
@@ -416,14 +414,14 @@ bool DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params) no
if (timeToReverse < params.decelClocks)
{
// There is a reversal
- const float distanceToReverse = 0.5 * deceleration * fsquare(timeToReverse);
+ const float distanceToReverse = 0.5 * dda.deceleration * fsquare(timeToReverse);
forwardDistance += params.decelStartDistance + distanceToReverse;
- reverseDistance = 0.5 * deceleration * fsquare(params.decelClocks - timeToReverse);
+ reverseDistance = 0.5 * dda.deceleration * fsquare(params.decelClocks - timeToReverse);
}
else
{
// No reversal
- forwardDistance += dda.totalDistance - (mp.cart.pressureAdvanceK * deceleration * params.decelClocks);
+ forwardDistance += dda.totalDistance - (mp.cart.pressureAdvanceK * dda.deceleration * params.decelClocks);
reverseDistance = 0.0;
}
}
diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp
index c01098f8..94707367 100644
--- a/src/Movement/Move.cpp
+++ b/src/Movement/Move.cpp
@@ -94,11 +94,11 @@ constexpr ObjectModelTableEntry Move::objectModelTable[] =
{ "extruders", OBJECT_MODEL_FUNC_NOSELF(&extrudersArrayDescriptor), ObjectModelEntryFlags::live },
{ "idle", OBJECT_MODEL_FUNC(self, 1), ObjectModelEntryFlags::none },
{ "kinematics", OBJECT_MODEL_FUNC(self->kinematics), ObjectModelEntryFlags::none },
- { "printingAcceleration", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertAcceleration(self->maxPrintingAcceleration), 1), ObjectModelEntryFlags::none },
+ { "printingAcceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->maxPrintingAcceleration), 1), ObjectModelEntryFlags::none },
{ "queue", OBJECT_MODEL_FUNC_NOSELF(&queueArrayDescriptor), ObjectModelEntryFlags::none },
{ "shaping", OBJECT_MODEL_FUNC(&self->axisShaper, 0), ObjectModelEntryFlags::none },
{ "speedFactor", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetSpeedFactor(), 2), ObjectModelEntryFlags::none },
- { "travelAcceleration", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertAcceleration(self->maxTravelAcceleration), 1), ObjectModelEntryFlags::none },
+ { "travelAcceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->maxTravelAcceleration), 1), ObjectModelEntryFlags::none },
{ "virtualEPos", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetVirtualExtruderPosition(), 5), ObjectModelEntryFlags::live },
{ "workplaceNumber", OBJECT_MODEL_FUNC_NOSELF((int32_t)reprap.GetGCodes().GetWorkplaceCoordinateSystemNumber() - 1), ObjectModelEntryFlags::none },
{ "workspaceNumber", OBJECT_MODEL_FUNC_NOSELF((int32_t)reprap.GetGCodes().GetWorkplaceCoordinateSystemNumber()), ObjectModelEntryFlags::obsolete },
@@ -108,14 +108,14 @@ constexpr ObjectModelTableEntry Move::objectModelTable[] =
{ "timeout", OBJECT_MODEL_FUNC(0.001f * (float)self->idleTimeout, 1), ObjectModelEntryFlags::none },
// 2. move.currentMove members
- { "acceleration", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertAcceleration(self->GetAcceleration()), 1), ObjectModelEntryFlags::live },
- { "deceleration", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertAcceleration(self->GetDeceleration()), 1), ObjectModelEntryFlags::live },
+ { "acceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->GetAcceleration()), 1), ObjectModelEntryFlags::live },
+ { "deceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->GetDeceleration()), 1), ObjectModelEntryFlags::live },
# if SUPPORT_LASER
{ "laserPwm", OBJECT_MODEL_FUNC_IF_NOSELF(reprap.GetGCodes().GetMachineType() == MachineType::laser,
reprap.GetPlatform().GetLaserPwm(), 2), ObjectModelEntryFlags::live },
# endif
- { "requestedSpeed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->GetRequestedSpeed(), true), 1), ObjectModelEntryFlags::live },
- { "topSpeed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->GetTopSpeed(), true), 1), ObjectModelEntryFlags::live },
+ { "requestedSpeed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMm(self->GetRequestedSpeed(), true), 1), ObjectModelEntryFlags::live },
+ { "topSpeed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMm(self->GetTopSpeed(), true), 1), ObjectModelEntryFlags::live },
// 3. move.calibration members
{ "final", OBJECT_MODEL_FUNC(self, 5), ObjectModelEntryFlags::none },
@@ -993,7 +993,7 @@ GCodeResult Move::ConfigureAccelerations(GCodeBuffer&gb, const StringRef& reply)
else
{
reply.printf("Maximum printing acceleration %.1f, maximum travel acceleration %.1f mm/sec^2",
- (double)gb.InverseConvertAcceleration(maxPrintingAcceleration), (double)gb.InverseConvertAcceleration(maxTravelAcceleration));
+ (double)InverseConvertAcceleration(maxPrintingAcceleration), (double)InverseConvertAcceleration(maxTravelAcceleration));
}
return GCodeResult::ok;
}
diff --git a/src/Movement/StepTimer.h b/src/Movement/StepTimer.h
index 8a2fcda6..f0080cd7 100644
--- a/src/Movement/StepTimer.h
+++ b/src/Movement/StepTimer.h
@@ -63,18 +63,7 @@ public:
// ISR called from StepTimer
static void Interrupt() noexcept;
-#if SAME70 || SAME5x
- // All Duet 3 boards use a common step clock rate of 750kHz so that we can sync the clocks over CAN
- static constexpr uint32_t StepClockRate = 48000000/64; // 750kHz
-#elif defined(__LPC17xx__)
- static constexpr uint32_t StepClockRate = 1000000; // 1MHz
-#else
- static constexpr uint32_t StepClockRate = SystemCoreClockFreq/128; // Duet 2 and Maestro: use just under 1MHz
-#endif
-
- static constexpr uint64_t StepClockRateSquared = (uint64_t)StepClockRate * StepClockRate;
- static constexpr float StepClocksToMillis = 1000.0/(float)StepClockRate;
- static constexpr uint32_t MinInterruptInterval = 6; // about 6us
+ static constexpr uint32_t MinInterruptInterval = 6; // Minimum interval between step timer interrupts, in step clocks; about 6us
#if SUPPORT_REMOTE_COMMANDS
static uint32_t GetLocalTimeOffset() noexcept { return localTimeOffset; }
diff --git a/src/Movement/StepperDrivers/TMC51xx.cpp b/src/Movement/StepperDrivers/TMC51xx.cpp
index 5f1c72ed..e796a0f4 100644
--- a/src/Movement/StepperDrivers/TMC51xx.cpp
+++ b/src/Movement/StepperDrivers/TMC51xx.cpp
@@ -829,7 +829,7 @@ void TmcDriverState::SetStallDetectFilter(bool sgFilter) noexcept
void TmcDriverState::SetStallMinimumStepsPerSecond(unsigned int stepsPerSecond) noexcept
{
//TODO use hardware facility instead
- maxStallStepInterval = StepTimer::StepClockRate/max<unsigned int>(stepsPerSecond, 1);
+ maxStallStepInterval = StepClockRate/max<unsigned int>(stepsPerSecond, 1);
}
void TmcDriverState::AppendStallConfig(const StringRef& reply) const noexcept
@@ -840,7 +840,7 @@ void TmcDriverState::AppendStallConfig(const StringRef& reply) const noexcept
{
threshold -= 128;
}
- const uint32_t fullstepsPerSecond = StepTimer::StepClockRate/maxStallStepInterval;
+ const uint32_t fullstepsPerSecond = StepClockRate/maxStallStepInterval;
const float speed1 = ((fullstepsPerSecond << microstepShiftFactor)/reprap.GetPlatform().DriveStepsPerUnit(axisNumber));
const uint32_t tcoolthrs = writeRegisters[WriteTcoolthrs] & ((1ul << 20) - 1u);
bool bdummy;
@@ -929,7 +929,7 @@ void TmcDriverState::TransferSucceeded(const uint8_t *rcvDataBlock) noexcept
{
if ( (regVal & TMC_RR_STST) != 0
|| interval == 0
- || interval > StepTimer::StepClockRate/MinimumOpenLoadFullStepsPerSec
+ || interval > StepClockRate/MinimumOpenLoadFullStepsPerSec
|| motorCurrent < MinimumOpenLoadMotorCurrent
)
{
diff --git a/src/Networking/Network.cpp b/src/Networking/Network.cpp
index 3da1528c..887b3f78 100644
--- a/src/Networking/Network.cpp
+++ b/src/Networking/Network.cpp
@@ -551,7 +551,7 @@ void Network::Diagnostics(MessageType mtype) noexcept
#if HAS_NETWORKING
platform.Message(mtype, "=== Network ===\n");
- platform.MessageF(mtype, "Slowest loop: %.2fms; fastest: %.2fms\n", (double)(slowLoop * StepTimer::StepClocksToMillis), (double)(fastLoop * StepTimer::StepClocksToMillis));
+ platform.MessageF(mtype, "Slowest loop: %.2fms; fastest: %.2fms\n", (double)(slowLoop * StepClocksToMillis), (double)(fastLoop * StepClocksToMillis));
fastLoop = UINT32_MAX;
slowLoop = 0;
diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp
index f532f322..e2c4091a 100644
--- a/src/Platform/Platform.cpp
+++ b/src/Platform/Platform.cpp
@@ -265,12 +265,12 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] =
#endif
// 3. move.axes[] members
- { "acceleration", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertAcceleration(self->Acceleration(context.GetLastIndex())), 1), ObjectModelEntryFlags::none },
+ { "acceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->Acceleration(context.GetLastIndex())), 1), ObjectModelEntryFlags::none },
{ "babystep", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetTotalBabyStepOffset(context.GetLastIndex()), 3), ObjectModelEntryFlags::none },
{ "current", OBJECT_MODEL_FUNC((int32_t)lrintf(self->GetMotorCurrent(context.GetLastIndex(), 906))), ObjectModelEntryFlags::none },
{ "drivers", OBJECT_MODEL_FUNC_NOSELF(&axisDriversArrayDescriptor), ObjectModelEntryFlags::none },
{ "homed", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().IsAxisHomed(context.GetLastIndex())), ObjectModelEntryFlags::none },
- { "jerk", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->GetInstantDv(context.GetLastIndex()), false), 1), ObjectModelEntryFlags::none },
+ { "jerk", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->GetInstantDv(context.GetLastIndex())), 1), ObjectModelEntryFlags::none },
{ "letter", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetAxisLetters()[context.GetLastIndex()]), ObjectModelEntryFlags::none },
{ "machinePosition", OBJECT_MODEL_FUNC_NOSELF(reprap.GetMove().LiveCoordinate(context.GetLastIndex(), reprap.GetCurrentTool()), 3), ObjectModelEntryFlags::live },
{ "max", OBJECT_MODEL_FUNC(self->AxisMaximum(context.GetLastIndex()), 2), ObjectModelEntryFlags::none },
@@ -278,7 +278,7 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] =
{ "microstepping", OBJECT_MODEL_FUNC(self, 7), ObjectModelEntryFlags::none },
{ "min", OBJECT_MODEL_FUNC(self->AxisMinimum(context.GetLastIndex()), 2), ObjectModelEntryFlags::none },
{ "minProbed", OBJECT_MODEL_FUNC(self->axisMinimaProbed.IsBitSet(context.GetLastIndex())), ObjectModelEntryFlags::none },
- { "speed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->MaxFeedrate(context.GetLastIndex()), false), 1), ObjectModelEntryFlags::none },
+ { "speed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->MaxFeedrate(context.GetLastIndex())), 1), ObjectModelEntryFlags::none },
{ "stepsPerMm", OBJECT_MODEL_FUNC(self->driveStepsPerUnit[context.GetLastIndex()], 2), ObjectModelEntryFlags::none },
{ "userPosition", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetUserCoordinate(context.GetLastIndex()), 3), ObjectModelEntryFlags::live },
{ "visible", OBJECT_MODEL_FUNC_NOSELF(context.GetLastIndex() < (int32_t)reprap.GetGCodes().GetVisibleAxes()), ObjectModelEntryFlags::none },
@@ -290,13 +290,13 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] =
{ "driver", OBJECT_MODEL_FUNC(self->extruderDrivers[context.GetLastIndex()]), ObjectModelEntryFlags::none },
{ "factor", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetExtrusionFactor(context.GetLastIndex()), 2), ObjectModelEntryFlags::none },
{ "filament", OBJECT_MODEL_FUNC_NOSELF(GetFilamentName(context.GetLastIndex())), ObjectModelEntryFlags::none },
- { "jerk", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->GetInstantDv(ExtruderToLogicalDrive(context.GetLastIndex())), false), 1), ObjectModelEntryFlags::none },
+ { "jerk", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->GetInstantDv(ExtruderToLogicalDrive(context.GetLastIndex()))), 1), ObjectModelEntryFlags::none },
{ "microstepping", OBJECT_MODEL_FUNC(self, 8), ObjectModelEntryFlags::none },
{ "nonlinear", OBJECT_MODEL_FUNC(self, 5), ObjectModelEntryFlags::none },
{ "position", OBJECT_MODEL_FUNC_NOSELF(ExpressionValue(reprap.GetMove().LiveCoordinate(ExtruderToLogicalDrive(context.GetLastIndex()), reprap.GetCurrentTool()), 1)), ObjectModelEntryFlags::live },
{ "pressureAdvance", OBJECT_MODEL_FUNC_NOSELF(reprap.GetMove().GetPressureAdvance(context.GetLastIndex()), 2), ObjectModelEntryFlags::none },
{ "rawPosition", OBJECT_MODEL_FUNC_NOSELF(ExpressionValue(reprap.GetGCodes().GetRawExtruderTotalByDrive(context.GetLastIndex()), 1)), ObjectModelEntryFlags::live },
- { "speed", OBJECT_MODEL_FUNC(GCodeBuffer::InverseConvertSpeedToMm(self->MaxFeedrate(ExtruderToLogicalDrive(context.GetLastIndex())), false), 1), ObjectModelEntryFlags::none },
+ { "speed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->MaxFeedrate(ExtruderToLogicalDrive(context.GetLastIndex()))), 1), ObjectModelEntryFlags::none },
{ "stepsPerMm", OBJECT_MODEL_FUNC(self->driveStepsPerUnit[ExtruderToLogicalDrive(context.GetLastIndex())], 2), ObjectModelEntryFlags::none },
// 5. move.extruders[].nonlinear members
@@ -590,7 +590,7 @@ void Platform::Init() noexcept
instantDvs[drive] = DefaultEInstantDv;
}
- minimumMovementSpeed = DefaultMinFeedrate/StepTimer::StepClockRate;
+ minimumMovementSpeed = ConvertSpeedFromMmPerSec(DefaultMinFeedrate);
axisMaximaProbed.Clear();
axisMinimaProbed.Clear();
idleCurrentFactor = DefaultIdleCurrentFactor;
@@ -3185,7 +3185,7 @@ void Platform::SetDriverStepTiming(size_t driver, const float microseconds[4]) n
if (microseconds[i] > MinStepPulseTiming)
{
slowDriversBitmap |= StepPins::CalcDriverBitmap(driver); // this drive does need extended timing
- const uint32_t clocks = (uint32_t)(((float)StepTimer::StepClockRate * microseconds[i] * 0.000001) + 0.99); // convert microseconds to step clocks, rounding up
+ const uint32_t clocks = (uint32_t)(((float)StepClockRate * microseconds[i] * 0.000001) + 0.99); // convert microseconds to step clocks, rounding up
if (clocks > slowDriverStepTimingClocks[i])
{
slowDriverStepTimingClocks[i] = clocks;
@@ -3201,7 +3201,7 @@ bool Platform::GetDriverStepTiming(size_t driver, float microseconds[4]) const n
for (size_t i = 0; i < 4; ++i)
{
microseconds[i] = (isSlowDriver)
- ? (float)slowDriverStepTimingClocks[i] * 1000000.0/(float)StepTimer::StepClockRate
+ ? (float)slowDriverStepTimingClocks[i] * 1000000.0/(float)StepClockRate
: 0.0;
}
return isSlowDriver;
@@ -4173,16 +4173,6 @@ void Platform::SetAxisMinimum(size_t axis, float value, bool byProbing) noexcept
reprap.MoveUpdated();
}
-void Platform::SetInstantDv(size_t drive, float value) noexcept
-{
- instantDvs[drive] = max<float>(value, MinimumJerk/StepTimer::StepClockRate); // don't allow zero or negative values, they causes Move to loop indefinitely
-}
-
-void Platform::SetMinMovementSpeed(float value) noexcept
-{
- minimumMovementSpeed = max<float>(value, AbsoluteMinFeedrate/StepTimer::StepClockRate);
-}
-
void Platform::InitZProbeFilters() noexcept
{
zProbeOnFilter.Init(0);
diff --git a/src/Platform/Platform.h b/src/Platform/Platform.h
index 4a025cd1..02200faf 100644
--- a/src/Platform/Platform.h
+++ b/src/Platform/Platform.h
@@ -917,7 +917,7 @@ inline const float* Platform::Accelerations() const noexcept
inline void Platform::SetAcceleration(size_t drive, float value) noexcept
{
- accelerations[drive] = max<float>(value, 1.0); // don't allow zero or negative
+ accelerations[drive] = max<float>(value, ConvertAcceleration(MinimumAcceleration)); // don't allow zero or negative
}
inline float Platform::MaxFeedrate(size_t drive) const noexcept
@@ -927,7 +927,17 @@ inline float Platform::MaxFeedrate(size_t drive) const noexcept
inline void Platform::SetMaxFeedrate(size_t drive, float value) noexcept
{
- maxFeedrates[drive] = max<float>(value, minimumMovementSpeed); // don't allow zero or negative, but do allow small values
+ maxFeedrates[drive] = max<float>(value, minimumMovementSpeed); // don't allow zero or negative, but do allow small values
+}
+
+inline void Platform::SetInstantDv(size_t drive, float value) noexcept
+{
+ instantDvs[drive] = max<float>(value, ConvertSpeedFromMmPerSec(MinimumJerk)); // don't allow zero or negative values, they causes Move to loop indefinitely
+}
+
+inline void Platform::SetMinMovementSpeed(float value) noexcept
+{
+ minimumMovementSpeed = max<float>(value, ConvertSpeedFromMmPerSec(AbsoluteMinFeedrate));
}
inline float Platform::GetInstantDv(size_t drive) const noexcept
diff --git a/src/Platform/PortControl.cpp b/src/Platform/PortControl.cpp
index 0632f0a5..26256efe 100644
--- a/src/Platform/PortControl.cpp
+++ b/src/Platform/PortControl.cpp
@@ -60,7 +60,7 @@ uint32_t PortControl::UpdatePorts() noexcept
{
SetBasePriority(0);
UpdatePorts(cdda->GetIoBits());
- return (moveEndTime - now + StepTimer::StepClockRate/1000 - 1)/(StepTimer::StepClockRate/1000);
+ return (moveEndTime - now + StepClockRate/1000 - 1)/(StepClockRate/1000);
}
cdda = cdda->GetNext();
st = cdda->GetState();
@@ -96,7 +96,18 @@ bool PortControl::Configure(GCodeBuffer& gb, const StringRef& reply)
{
seen = true;
advanceMillis = (unsigned int)constrain<int>(gb.GetIValue(), 0, 1000);
- advanceClocks = (advanceMillis * (uint64_t)StepTimer::StepClockRate)/1000;
+ if constexpr (StepClockRate % 1000 == 0)
+ {
+ advanceClocks = advanceMillis * (StepClockRate/1000);
+ }
+ else if constexpr (StepClockRate % 500 == 0)
+ {
+ advanceClocks = (advanceMillis * (StepClockRate/500))/2;
+ }
+ else
+ {
+ advanceClocks = (advanceMillis * (uint64_t)StepClockRate)/1000;
+ }
}
if (!seen)
{
diff --git a/src/Platform/RepRap.cpp b/src/Platform/RepRap.cpp
index 8854614b..aad77b7a 100644
--- a/src/Platform/RepRap.cpp
+++ b/src/Platform/RepRap.cpp
@@ -839,7 +839,7 @@ void RepRap::Spin() noexcept
void RepRap::Timing(MessageType mtype) noexcept
{
- platform->MessageF(mtype, "Slowest loop: %.2fms; fastest: %.2fms\n", (double)(slowLoop * StepTimer::StepClocksToMillis), (double)(fastLoop * StepTimer::StepClocksToMillis));
+ platform->MessageF(mtype, "Slowest loop: %.2fms; fastest: %.2fms\n", (double)(slowLoop * StepClocksToMillis), (double)(fastLoop * StepClocksToMillis));
fastLoop = UINT32_MAX;
slowLoop = 0;
}
@@ -1356,7 +1356,7 @@ OutputBuffer *RepRap::GetStatusResponse(uint8_t type, ResponseSource source) con
AppendFloatArray(response, "extr", GetExtrudersInUse(), [this](size_t extruder) noexcept { return move->LiveCoordinate(ExtruderToLogicalDrive(extruder), currentTool); }, 1);
// Current speeds
- response->catf("},\"speeds\":{\"requested\":%.1f,\"top\":%.1f}", (double)GCodeBuffer::InverseConvertSpeedToMm(move->GetRequestedSpeed(), true), (double)GCodeBuffer::InverseConvertSpeedToMm(move->GetTopSpeed(), true));
+ response->catf("},\"speeds\":{\"requested\":%.1f,\"top\":%.1f}", (double)InverseConvertSpeedToMmPerSec(move->GetRequestedSpeed()), (double)InverseConvertSpeedToMmPerSec(move->GetTopSpeed()));
// Current tool number
response->catf(",\"currentTool\":%d", GetCurrentToolNumber());
@@ -1839,7 +1839,7 @@ OutputBuffer *RepRap::GetConfigResponse() noexcept
// Accelerations
response->cat(',');
- AppendFloatArray(response, "accelerations", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return GCodeBuffer::InverseConvertAcceleration(platform->Acceleration(drive)); }, 2);
+ AppendFloatArray(response, "accelerations", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return InverseConvertAcceleration(platform->Acceleration(drive)); }, 2);
// Motor currents
response->cat(',');
@@ -1886,11 +1886,11 @@ OutputBuffer *RepRap::GetConfigResponse() noexcept
response->catf(",\"idleTimeout\":%.1f,", (double)(move->IdleTimeout()));
// Minimum feedrates
- AppendFloatArray(response, "minFeedrates", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return GCodeBuffer::InverseConvertSpeedToMm(platform->GetInstantDv(drive), true); }, 2);
+ AppendFloatArray(response, "minFeedrates", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return InverseConvertSpeedToMmPerSec(platform->GetInstantDv(drive)); }, 2);
// Maximum feedrates
response->cat(',');
- AppendFloatArray(response, "maxFeedrates", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return GCodeBuffer::InverseConvertSpeedToMm(platform->MaxFeedrate(drive), true); }, 2);
+ AppendFloatArray(response, "maxFeedrates", MaxAxesPlusExtruders, [this](size_t drive) noexcept { return InverseConvertSpeedToMmPerSec(platform->MaxFeedrate(drive)); }, 2);
// Config file is no longer included, because we can use rr_configfile or M503 instead
response->cat('}');
diff --git a/src/RepRapFirmware.h b/src/RepRapFirmware.h
index edc921e0..53019c85 100644
--- a/src/RepRapFirmware.h
+++ b/src/RepRapFirmware.h
@@ -503,6 +503,61 @@ constexpr float TwoPi = 3.141592653589793 * 2;
constexpr float DegreesToRadians = 3.141592653589793/180.0;
constexpr float RadiansToDegrees = 180.0/3.141592653589793;
+// The step clock is used for timing step pulses and oyther fine-resolution timer purposes
+
+#if SAME70 || SAME5x
+// All Duet 3 boards use a common step clock rate of 750kHz so that we can sync the clocks over CAN
+constexpr uint32_t StepClockRate = 48000000/64; // 750kHz
+#elif defined(__LPC17xx__)
+constexpr uint32_t StepClockRate = 1000000; // 1MHz
+#else
+constexpr uint32_t StepClockRate = SystemCoreClockFreq/128; // Duet 2 and Maestro: use just under 1MHz
+#endif
+
+constexpr uint64_t StepClockRateSquared = (uint64_t)StepClockRate * StepClockRate;
+constexpr float StepClocksToMillis = 1000.0/(float)StepClockRate;
+
+// Functions to convert speeds and accelerations between seconds and step clocks
+static inline constexpr float ConvertSpeedFromMmPerSec(float speed) noexcept
+{
+ return speed * 1.0/StepClockRate;
+}
+
+static inline constexpr float ConvertSpeedFromMmPerMin(float speed) noexcept
+{
+ return speed * (MinutesToSeconds/StepClockRate);
+}
+
+static inline constexpr float ConvertSpeedFromMm(float speed, bool useSeconds) noexcept
+{
+ return speed * ((useSeconds) ? 1.0/StepClockRate : MinutesToSeconds/StepClockRate);
+}
+
+static inline constexpr float InverseConvertSpeedToMmPerSec(float speed) noexcept
+{
+ return speed * StepClockRate;
+}
+
+static inline constexpr float InverseConvertSpeedToMmPerMin(float speed) noexcept
+{
+ return speed * (StepClockRate * SecondsToMinutes);
+}
+
+static inline constexpr float InverseConvertSpeedToMm(float speed, bool useSeconds) noexcept
+{
+ return speed * ((useSeconds) ? StepClockRate : StepClockRate * SecondsToMinutes);
+}
+
+static inline constexpr float ConvertAcceleration(float accel) noexcept
+{
+ return accel * (1.0/StepClockRateSquared);
+}
+
+static inline constexpr float InverseConvertAcceleration(float accel) noexcept
+{
+ return accel * StepClockRateSquared;
+}
+
constexpr unsigned int MaxFloatDigitsDisplayedAfterPoint = 7;
const char *GetFloatFormatString(unsigned int numDigitsAfterPoint) noexcept;