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
diff options
context:
space:
mode:
Diffstat (limited to 'src/GCodes')
-rw-r--r--src/GCodes/GCodeBuffer/GCodeBuffer.cpp16
-rw-r--r--src/GCodes/GCodeBuffer/GCodeBuffer.h6
-rw-r--r--src/GCodes/GCodeBuffer/StringParser.cpp22
-rw-r--r--src/GCodes/GCodes.cpp29
-rw-r--r--src/GCodes/GCodes.h2
-rw-r--r--src/GCodes/GCodes2.cpp59
-rw-r--r--src/GCodes/GCodes3.cpp12
-rw-r--r--src/GCodes/GCodes4.cpp15
8 files changed, 110 insertions, 51 deletions
diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp
index ba67c95b..87c126d6 100644
--- a/src/GCodes/GCodeBuffer/GCodeBuffer.cpp
+++ b/src/GCodes/GCodeBuffer/GCodeBuffer.cpp
@@ -84,7 +84,7 @@ const char *GCodeBuffer::GetStateText() const noexcept
// Create a default GCodeBuffer
GCodeBuffer::GCodeBuffer(GCodeChannel::RawType channel, GCodeInput *normalIn, FileGCodeInput *fileIn, MessageType mt, Compatibility::RawType c) noexcept
- : codeChannel(channel), normalInput(normalIn),
+ : codeChannel(channel), normalInput(normalIn), whenReportDueTimerStarted(millis()),
#if HAS_MASS_STORAGE
fileInput(fileIn),
#endif
@@ -167,6 +167,20 @@ bool GCodeBuffer::DoDwellTime(uint32_t dwellMillis) noexcept
return false;
}
+// Delay executing this GCodeBuffer for the specified time. Return true when the timer has expired.
+bool GCodeBuffer::IsReportDue() noexcept
+{
+ const uint32_t now = millis();
+
+ // Are we due?
+ if (now - whenReportDueTimerStarted >= reportDueInterval)
+ {
+ ResetReportDueTimer();
+ return true;
+ }
+ return false;
+}
+
// Write some debug info
void GCodeBuffer::Diagnostics(MessageType mtype) noexcept
{
diff --git a/src/GCodes/GCodeBuffer/GCodeBuffer.h b/src/GCodes/GCodeBuffer/GCodeBuffer.h
index bbd18dae..4b37981a 100644
--- a/src/GCodes/GCodeBuffer/GCodeBuffer.h
+++ b/src/GCodes/GCodeBuffer/GCodeBuffer.h
@@ -194,6 +194,9 @@ public:
void StopTimer() noexcept { timerRunning = false; }
bool DoDwellTime(uint32_t dwellMillis) noexcept; // Execute a dwell returning true if it has finished
+ void ResetReportDueTimer() noexcept { whenReportDueTimerStarted = millis(); };
+ bool IsReportDue() noexcept;
+
void RestartFrom(FilePosition pos) noexcept;
#if HAS_MASS_STORAGE
@@ -244,6 +247,9 @@ private:
bool timerRunning; // True if we are waiting
bool motionCommanded; // true if this GCode stream has commanded motion since it last waited for motion to stop
+ uint32_t whenReportDueTimerStarted; // When the report-due-timer has been started
+ static constexpr uint32_t reportDueInterval = 1000; // Interval in which we send in ms
+
#if HAS_LINUX_INTERFACE
alignas(4) char buffer[MaxCodeBufferSize]; // must be aligned because we do dword fetches from it
#else
diff --git a/src/GCodes/GCodeBuffer/StringParser.cpp b/src/GCodes/GCodeBuffer/StringParser.cpp
index d7ee0e7b..9978b658 100644
--- a/src/GCodes/GCodeBuffer/StringParser.cpp
+++ b/src/GCodes/GCodeBuffer/StringParser.cpp
@@ -749,42 +749,34 @@ void StringParser::DecodeCommand() noexcept
}
}
- // Find where the end of the command is. We assume that a G or M preceded by a space and not inside quotes or { } is the start of a new command.
+ // Find where the end of the command is. We assume that a G or M not inside quotes or { } is the start of a new command.
bool inQuotes = false;
- unsigned int braceCount = 0;
- bool primed = false;
+ unsigned int localBraceCount = 0;
for (commandEnd = parameterStart; commandEnd < gcodeLineEnd; ++commandEnd)
{
const char c = gb.buffer[commandEnd];
if (c == '"')
{
inQuotes = !inQuotes;
- primed = false;
}
else if (!inQuotes)
{
char c2;
if (c == '{')
{
- ++braceCount;
- primed = false;
+ ++localBraceCount;
}
- else if (c == '}')
+ else if (localBraceCount != 0)
{
- if (braceCount != 0)
+ if (c == '}')
{
- --braceCount;
+ --localBraceCount;
}
- primed = false;
}
- else if (primed && ((c2 = toupper(c)) == 'G' || c2 == 'M'))
+ else if ((c2 = toupper(c)) == 'G' || c2 == 'M')
{
break;
}
- else if (braceCount == 0)
- {
- primed = (c == ' ' || c == '\t');
- }
}
}
}
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index 23a8e48b..52682a5a 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -485,6 +485,10 @@ void GCodes::Spin() noexcept
{
RunStateMachine(gb, reply.GetRef()); // execute the state machine
}
+ if (gb.IsExecuting())
+ {
+ CheckReportDue(gb, reply.GetRef());
+ }
}
#if HAS_LINUX_INTERFACE
@@ -1688,7 +1692,7 @@ const char * GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isP
}
}
- if (moveBuffer.moveType == 1)
+ if (moveBuffer.moveType == 1 || moveBuffer.moveType == 4)
{
if (!platform.GetEndstops().EnableExtruderEndstops(extrudersMoving))
{
@@ -1737,7 +1741,7 @@ bool GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated, const char *& e
if (gb.Seen('H') || (machineType != MachineType::laser && gb.Seen('S')))
{
const int ival = gb.GetIValue();
- if (ival >= 1 && ival <= 3)
+ if (ival >= 1 && ival <= 4)
{
if (!LockMovementAndWaitForStandstill(gb))
{
@@ -1892,6 +1896,7 @@ bool GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated, const char *& e
axesToSenseLength = axesMentioned & AxesBitmap::MakeLowestNBits(numTotalAxes);
// no break
case 1:
+ case 4:
if (!platform.GetEndstops().EnableAxisEndstops(axesMentioned & AxesBitmap::MakeLowestNBits(numTotalAxes), moveBuffer.moveType == 1))
{
err = "Failed to enable endstops";
@@ -3368,15 +3373,15 @@ void GCodes::DisableDrives() noexcept
SetAllAxesNotHomed();
}
-bool GCodes::ChangeMicrostepping(size_t drive, unsigned int microsteps, bool interp, const StringRef& reply) const noexcept
+bool GCodes::ChangeMicrostepping(size_t axisOrExtruder, unsigned int microsteps, bool interp, const StringRef& reply) const noexcept
{
bool dummy;
- const unsigned int oldSteps = platform.GetMicrostepping(drive, dummy);
- const bool success = platform.SetMicrostepping(drive, microsteps, interp, reply);
+ const unsigned int oldSteps = platform.GetMicrostepping(axisOrExtruder, dummy);
+ const bool success = platform.SetMicrostepping(axisOrExtruder, microsteps, interp, reply);
if (success)
{
// We changed the microstepping, so adjust the steps/mm to compensate
- platform.SetDriveStepsPerUnit(drive, platform.DriveStepsPerUnit(drive), oldSteps);
+ platform.SetDriveStepsPerUnit(axisOrExtruder, platform.DriveStepsPerUnit(axisOrExtruder), oldSteps);
}
return success;
}
@@ -4378,16 +4383,17 @@ void GCodes::GenerateTemperatureReport(const StringRef& reply) const noexcept
// 'reply' is a convenient buffer that is free for us to use.
void GCodes::CheckReportDue(GCodeBuffer& gb, const StringRef& reply) const
{
- if (gb.DoDwellTime(1000))
+ if (gb.IsReportDue())
{
- if (gb.MachineState().compatibility == Compatibility::Marlin)
+ if (&gb == usbGCode && gb.MachineState().compatibility == Compatibility::Marlin)
{
// In Marlin emulation mode we should return a standard temperature report every second
GenerateTemperatureReport(reply);
reply.cat('\n');
platform.Message(UsbMessage, reply.c_str());
+ reply.Clear();
}
- if (lastAuxStatusReportType >= 0)
+ if (&gb == auxGCode && platform.IsAuxEnabled(0) && lastAuxStatusReportType >= 0)
{
// Send a standard status response for PanelDue
OutputBuffer * const statusBuf =
@@ -4397,9 +4403,12 @@ void GCodes::CheckReportDue(GCodeBuffer& gb, const StringRef& reply) const
if (statusBuf != nullptr)
{
platform.AppendAuxReply(0, statusBuf, true);
+ if (reprap.Debug(moduleGcodes))
+ {
+ reprap.GetPlatform().MessageF(DebugMessage, "%s: Sent unsolicited status report\n", gb.GetChannel().ToString());
+ }
}
}
- gb.StartTimer();
}
}
diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h
index cbaa7bfb..9c41de4b 100644
--- a/src/GCodes/GCodes.h
+++ b/src/GCodes/GCodes.h
@@ -384,7 +384,7 @@ private:
GCodeResult RetractFilament(GCodeBuffer& gb, bool retract); // Retract or un-retract filaments
GCodeResult LoadFilament(GCodeBuffer& gb, const StringRef& reply); // Load the specified filament into a tool
GCodeResult UnloadFilament(GCodeBuffer& gb, const StringRef& reply); // Unload the current filament from a tool
- bool ChangeMicrostepping(size_t drive, unsigned int microsteps, bool interp, const StringRef& reply) const noexcept; // Change microstepping on the specified drive
+ bool ChangeMicrostepping(size_t axisOrExtruder, unsigned int microsteps, bool interp, const StringRef& reply) const noexcept; // Change microstepping on the specified drive
void CheckTriggers() noexcept; // Check for and execute triggers
void CheckFilament() noexcept; // Check for and respond to filament errors
void CheckHeaterFault() noexcept; // Check for and respond to a heater fault, returning true if we should exit
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 189773af..a0b0d814 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -1212,6 +1212,9 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
gb.TryGetUIValue('S', ustepMultiplier, seenUstepMultiplier);
bool seen = false;
+#if SUPPORT_CAN_EXPANSION
+ AxesBitmap axesToUpdate;
+#endif
for (size_t axis = 0; axis < numTotalAxes; axis++)
{
if (gb.Seen(axisLetters[axis]))
@@ -1221,6 +1224,9 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
return false;
}
platform.SetDriveStepsPerUnit(axis, gb.GetFValue(), ustepMultiplier);
+#if SUPPORT_CAN_EXPANSION
+ axesToUpdate.SetBit(axis);
+#endif
seen = true;
}
}
@@ -1239,7 +1245,11 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
// The user may not have as many extruders as we allow for, so just set the ones for which a value is provided
for (size_t e = 0; e < eCount; e++)
{
- platform.SetDriveStepsPerUnit(ExtruderToLogicalDrive(e), eVals[e], ustepMultiplier);
+ const size_t drive = ExtruderToLogicalDrive(e);
+#if SUPPORT_CAN_EXPANSION
+ axesToUpdate.SetBit(drive);
+#endif
+ platform.SetDriveStepsPerUnit(drive, eVals[e], ustepMultiplier);
}
}
@@ -1247,6 +1257,9 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
{
// On a delta, if we change the drive steps/mm then we need to recalculate the motor positions
reprap.GetMove().SetNewPosition(moveBuffer.coords, true);
+#if SUPPORT_CAN_EXPANSION
+ result = platform.UpdateRemoteStepsPerMmAndMicrostepping(axesToUpdate, reply);
+#endif
}
else
{
@@ -1568,7 +1581,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
// Wait for the heaters associated with the specified tool to be ready
if (!ToolHeatersAtSetTemperatures(reprap.GetTool(gb.GetIValue()).Ptr(), true, tolerance))
{
- CheckReportDue(gb, reply); // check whether we need to send a temperature or status report
isWaiting = true;
return false;
}
@@ -1586,7 +1598,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
{
if (!reprap.GetHeat().HeaterAtSetTemperature(heaters[i], true, tolerance))
{
- CheckReportDue(gb, reply); // check whether we need to send a temperature or status report
isWaiting = true;
return false;
}
@@ -1609,7 +1620,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
const int8_t heater = reprap.GetHeat().GetChamberHeater(i);
if (heater >= 0 && !reprap.GetHeat().HeaterAtSetTemperature(heater, true, tolerance))
{
- CheckReportDue(gb, reply); // check whether we need to send a temperature or status report
isWaiting = true;
return false;
}
@@ -1625,7 +1635,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
const int8_t heater = reprap.GetHeat().GetChamberHeater(chamberIndices[i]);
if (heater >= 0 && !reprap.GetHeat().HeaterAtSetTemperature(heater, true, tolerance))
{
- CheckReportDue(gb, reply); // check whether we need to send a temperature or status report
isWaiting = true;
return false;
}
@@ -1638,7 +1647,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
// Wait for all heaters except chamber(s) to be ready
if (!seen && !reprap.GetHeat().AllHeatersAtSetTemperatures(true, tolerance))
{
- CheckReportDue(gb, reply); // check whether we need to send a temperature or status report
isWaiting = true;
return false;
}
@@ -1912,7 +1920,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
break;
}
- CheckReportDue(gb, reply); // check whether we need to send a temperature or status report
isWaiting = true;
return false;
}
@@ -2485,6 +2492,9 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
case 350: // Set/report microstepping
{
+#if SUPPORT_CAN_EXPANSION
+ AxesBitmap axesToUpdate;
+#endif
bool interp = (gb.Seen('I') && gb.GetIValue() > 0);
bool seen = false;
for (size_t axis = 0; axis < numTotalAxes; axis++)
@@ -2496,6 +2506,9 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
return false;
}
seen = true;
+#if SUPPORT_CAN_EXPANSION
+ axesToUpdate.SetBit(axis);
+#endif
const unsigned int microsteps = gb.GetUIValue();
if (ChangeMicrostepping(axis, microsteps, interp, reply))
{
@@ -2520,14 +2533,24 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
gb.GetUnsignedArray(eVals, eCount, true);
for (size_t e = 0; e < eCount; e++)
{
- if (!ChangeMicrostepping(ExtruderToLogicalDrive(e), eVals[e], interp, reply))
+ const size_t drive = ExtruderToLogicalDrive(e);
+#if SUPPORT_CAN_EXPANSION
+ axesToUpdate.SetBit(drive);
+#endif
+ if (!ChangeMicrostepping(drive, eVals[e], interp, reply))
{
result = GCodeResult::error;
}
}
}
- if (!seen)
+ if (seen)
+ {
+#if SUPPORT_CAN_EXPANSION
+ result = max(result, platform.UpdateRemoteStepsPerMmAndMicrostepping(axesToUpdate, reply));
+#endif
+ }
+ else
{
reply.copy("Microstepping - ");
for (size_t axis = 0; axis < numTotalAxes; ++axis)
@@ -2684,6 +2707,10 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
// We don't delay and retry here, in case the user asked for too much of the object model in one go for the output buffers to contain it
reply.copy("{\"err\":-1}\n");
}
+ if (&gb == auxGCode)
+ {
+ gb.ResetReportDueTimer();
+ }
}
}
break;
@@ -4090,10 +4117,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
{
if (gb.Seen(axisLetters[axis]))
{
- if (!platform.SetMotorCurrent(axis, gb.GetFValue(), code, reply))
- {
- result = GCodeResult::error;
- }
+ result = max(result, platform.SetMotorCurrent(axis, gb.GetFValue(), code, reply));
seen = true;
}
}
@@ -4106,10 +4130,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
gb.GetFloatArray(eVals, eCount, true);
for (size_t e = 0; e < eCount; e++)
{
- if (!platform.SetMotorCurrent(ExtruderToLogicalDrive(e), eVals[e], code, reply))
- {
- result = GCodeResult::error;
- }
+ result = max(result, platform.SetMotorCurrent(ExtruderToLogicalDrive(e), eVals[e], code, reply));
}
}
@@ -4344,14 +4365,14 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
reprap.EmergencyStop(); // this disables heaters and drives - Duet WiFi pre-production boards need drives disabled here
{
- uint16_t reason = (uint16_t)SoftwareResetReason::user;
+ SoftwareResetReason reason = SoftwareResetReason::user;
if (gb.Seen('P'))
{
String<StringLength20> eraseString;
gb.GetQuotedString(eraseString.GetRef());
if (eraseString.Equals("ERASE"))
{
- reason = (uint16_t)SoftwareResetReason::erase;
+ reason = SoftwareResetReason::erase;
}
}
SoftwareReset(reason); // doesn't return
diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp
index 369da43f..035b6250 100644
--- a/src/GCodes/GCodes3.cpp
+++ b/src/GCodes/GCodes3.cpp
@@ -542,6 +542,9 @@ GCodeResult GCodes::DoDriveMapping(GCodeBuffer& gb, const StringRef& reply) THRO
const char *lettersToTry = AllowedAxisLetters;
char c;
+#if SUPPORT_CAN_EXPANSION
+ AxesBitmap axesToUpdate;
+#endif
const bool newAxesAreContinuousRotation = (gb.Seen('R') && gb.GetIValue() > 0);
while ((c = *lettersToTry) != 0)
{
@@ -623,6 +626,9 @@ GCodeResult GCodes::DoDriveMapping(GCodeBuffer& gb, const StringRef& reply) THRO
reprap.MoveUpdated();
}
platform.SetAxisDriversConfig(drive, numValues, drivers);
+#if SUPPORT_CAN_EXPANSION
+ axesToUpdate.SetBit(drive);
+#endif
}
}
++lettersToTry;
@@ -638,6 +644,9 @@ GCodeResult GCodes::DoDriveMapping(GCodeBuffer& gb, const StringRef& reply) THRO
for (size_t i = 0; i < numValues; ++i)
{
platform.SetExtruderDriver(i, drivers[i]);
+#if SUPPORT_CAN_EXPANSION
+ axesToUpdate.SetBit(ExtruderToLogicalDrive(i));
+#endif
}
if (FilamentMonitor::CheckDriveAssignments(reply) && rslt == GCodeResult::ok)
{
@@ -670,6 +679,9 @@ GCodeResult GCodes::DoDriveMapping(GCodeBuffer& gb, const StringRef& reply) THRO
ToolOffsetTransform(currentUserPosition, moveBuffer.coords); // ensure that the position of any new axes are updated in moveBuffer
reprap.GetMove().SetNewPosition(moveBuffer.coords, true); // tell the Move system where the axes are
}
+#if SUPPORT_CAN_EXPANSION
+ rslt = max(rslt, platform.UpdateRemoteStepsPerMmAndMicrostepping(axesToUpdate, reply));
+#endif
return rslt;
}
diff --git a/src/GCodes/GCodes4.cpp b/src/GCodes/GCodes4.cpp
index 9858c68a..87dce185 100644
--- a/src/GCodes/GCodes4.cpp
+++ b/src/GCodes/GCodes4.cpp
@@ -29,6 +29,11 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept
// Perform the next operation of the state machine for this gcode source
GCodeResult stateMachineResult = GCodeResult::ok;
+ if (gb.GetState() != GCodeState::normal)
+ {
+ CheckReportDue(gb, reply);
+ }
+
switch (gb.GetState())
{
case GCodeState::waitingForSpecialMoveToComplete:
@@ -333,7 +338,6 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept
}
else
{
- CheckReportDue(gb, reply);
isWaiting = true;
}
break;
@@ -429,10 +433,11 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept
case GCodeState::flashing1:
#if HAS_WIFI_NETWORKING
- if (&gb == auxGCode) // if M997 S1 is sent from USB, don't keep sending temperature reports
- {
- CheckReportDue(gb, reply); // this is so that the ATE gets status reports and can tell when flashing is complete
- }
+// wilriker: This probably can be removed
+// if (&gb == auxGCode) // if M997 S1 is sent from USB, don't keep sending temperature reports
+// {
+// CheckReportDue(gb, reply); // this is so that the ATE gets status reports and can tell when flashing is complete
+// }
// Update additional modules before the main firmware
if (FirmwareUpdater::IsReady())