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/GCodes2.cpp')
-rw-r--r--src/GCodes/GCodes2.cpp261
1 files changed, 174 insertions, 87 deletions
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index d1773b4d..c861c3eb 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -20,6 +20,10 @@
#include "Tool.h"
#include "Version.h"
+#if SUPPORT_IOBITS
+# include "PortControl.h"
+#endif
+
#ifdef DUET_NG
# include "FirmwareUpdater.h"
#endif
@@ -94,49 +98,19 @@ bool GCodes::HandleGcode(GCodeBuffer& gb, StringRef& reply)
{
return false;
}
+ if (segmentsLeft != 0)
{
- // Check for 'R' parameter here to go back to the coordinates at which the print was paused
- // NOTE: restore point 2 (tool change) won't work when changing tools on dual axis machines because of X axis mapping.
- // We could possibly fix this by saving the virtual X axis position instead of the physical axis positions.
- // However, slicers normally command the tool to the correct place after a tool change, so we don't need this feature anyway.
- int rParam = (gb.Seen('R')) ? gb.GetIValue() : 0;
- RestorePoint *rp = (rParam == 1) ? &pauseRestorePoint : (rParam == 2) ? &toolChangeRestorePoint : nullptr;
- if (rp != nullptr)
- {
- if (segmentsLeft != 0)
- {
- return false;
- }
- for (size_t axis = 0; axis < numVisibleAxes; ++axis)
- {
- float offset = gb.Seen(axisLetters[axis]) ? gb.GetFValue() * distanceScale : 0.0;
- moveBuffer.coords[axis] = rp->moveCoords[axis] + offset;
- }
- // For now we don't handle extrusion at the same time
- for (size_t drive = numTotalAxes; drive < DRIVES; ++drive)
- {
- moveBuffer.coords[drive] = 0.0;
- }
- moveBuffer.feedRate = (gb.Seen(feedrateLetter)) ? gb.GetFValue() * SecondsToMinutes : gb.MachineState().feedrate;
- moveBuffer.filePos = noFilePosition;
- moveBuffer.usePressureAdvance = false;
- segmentsLeft = 1;
- }
- else
- {
- int res = SetUpMove(gb, reply);
- if (res == 2)
- {
- gb.SetState(GCodeState::waitingForMoveToComplete);
- }
- result = (res != 0);
- }
+ return false;
+ }
+ if (DoStraightMove(gb, reply))
+ {
+ error = true;
}
break;
case 2: // Clockwise arc
case 3: // Anti clockwise arc
- // We only support X and Y axes in these, but you can map them to other axes in the tool definitions
+ // We only support X and Y axes in these (and optionally Z for corkscrew moves), but you can map them to other axes in the tool definitions
if (!LockMovement(gb))
{
return false;
@@ -200,7 +174,7 @@ bool GCodes::HandleGcode(GCodeBuffer& gb, StringRef& reply)
return false;
}
{
- const int sparam = (gb.SeenAfterSpace('S')) ? gb.GetIValue() : 0;
+ const int sparam = (gb.Seen('S')) ? gb.GetIValue() : 0;
switch(sparam)
{
case 0: // probe and save height map
@@ -231,7 +205,7 @@ bool GCodes::HandleGcode(GCodeBuffer& gb, StringRef& reply)
else
{
ClearBabyStepping();
- result = SetSingleZProbeAtAPosition(gb, reply);
+ error = ExecuteG30(gb, reply);
}
break;
@@ -246,6 +220,13 @@ bool GCodes::HandleGcode(GCodeBuffer& gb, StringRef& reply)
}
ClearBabyStepping();
+
+ // We need to unlock the movement system here in case there is no Z probe and we are doing manual probing.
+ // Otherwise, even though the bed probing code calls UnlockAll when doing a manual bed probe, the movement system
+ // remains locked because the current MachineState object already held the lock when the macro file was started,
+ // which means that no gcode source other than the one that executed G32 is allowed to jog the Z axis.
+ UnlockAll(gb);
+
DoFileMacro(gb, BED_EQUATION_G, true); // Try to execute bed.g
break;
@@ -706,7 +687,9 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
else if (wasSimulating)
{
// Ending a simulation, so restore the position
- SetPositions(simulationRestorePoint.moveCoords);
+ RestorePosition(simulationRestorePoint, gb);
+ ToolOffsetTransform(currentUserPosition, moveBuffer.coords, true);
+ reprap.GetMove().SetNewPosition(simulationRestorePoint.moveCoords, true);
for (size_t i = 0; i < DRIVES; ++i)
{
moveBuffer.coords[i] = simulationRestorePoint.moveCoords[i];
@@ -768,7 +751,9 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
{
val = 1.0 - val;
}
- Platform::WriteAnalog(pin, val, DefaultPinWritePwmFreq);
+
+ const uint16_t freq = (gb.Seen('F')) ? (uint16_t)constrain<int32_t>(gb.GetIValue(), 1, 65536) : DefaultPinWritePwmFreq;
+ Platform::WriteAnalog(pin, val, freq);
}
// Ignore the command if no S parameter provided
}
@@ -821,11 +806,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
case 92: // Set/report steps/mm for some axes
{
- // Save the current positions as we may need them later
- float positionNow[DRIVES];
- Move& move = reprap.GetMove();
- move.GetCurrentUserPosition(positionNow, 0, reprap.GetCurrentXAxes());
-
bool seen = false;
for (size_t axis = 0; axis < numTotalAxes; axis++)
{
@@ -861,7 +841,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
if (seen)
{
// On a delta, if we change the drive steps/mm then we need to recalculate the motor positions
- SetPositions(positionNow);
+ reprap.GetMove().SetNewPosition(moveBuffer.coords, true);
}
else
{
@@ -1725,11 +1705,18 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
case 290: // Baby stepping
if (gb.Seen('S'))
{
- const float babystepAmount = gb.GetFValue();
- if (fabs(babystepAmount) <= 1.0) // limit babystepping to 1mm
+ if (!LockMovement(gb))
{
- pendingBabyStepZOffset += babystepAmount;
+ return false;
}
+ const float babyStepAmount = constrain<float>(gb.GetFValue(), -1.0, 1.0);
+ currentBabyStepZOffset += babyStepAmount;
+ const float amountPushed = reprap.GetMove().PushBabyStepping(babyStepAmount);
+ moveBuffer.initialCoords[Z_AXIS] += amountPushed;
+
+ // The following causes all the remaining baby stepping that we didn't manage to push to be added to the [remainder of the] currently-executing move, if there is one.
+ // This could result in an abrupt Z movement, however the move will be processed as normal so the jerk limit will be honoured.
+ moveBuffer.coords[Z_AXIS] += babyStepAmount;
}
else
{
@@ -1737,6 +1724,44 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
}
break;
+ case 291: // Display message, optionally wait for acknowledgement
+ {
+ char messageBuffer[80];
+ bool seen = false;
+ gb.TryGetQuotedString('P', messageBuffer, ARRAY_SIZE(messageBuffer), seen);
+ if (seen)
+ {
+ int32_t sParam = 0;
+ gb.TryGetIValue('S', sParam, seen);
+ float tParam = DefaultMessageTimeout;
+ gb.TryGetFValue('T', tParam, seen);
+ int32_t zParam = 0;
+ gb.TryGetIValue('Z', zParam, seen);
+
+ const MessageType mt = GetMessageBoxDevice(gb); // get the display device
+
+ // If we need to wait for an acknowledgement, save the state and set waiting
+ if (sParam == 1 && Push(gb)) // stack the machine state including the file position
+ {
+ gb.MachineState().fileState.Close(); // stop reading from file
+ gb.MachineState().waitingForAcknowledgement = true; // flag that we are waiting for acknowledgement
+ }
+
+ platform.SendAlert(mt, messageBuffer, (int)sParam, tParam, zParam == 1);
+ }
+ }
+ break;
+
+ case 292: // Acknowledge message
+ for (GCodeBuffer* targetGb : gcodeSources)
+ {
+ if (targetGb != nullptr)
+ {
+ targetGb->MessageAcknowledged();
+ }
+ }
+ break;
+
case 300: // Beep
{
const int ms = (gb.Seen('P')) ? gb.GetIValue() : 1000; // time in milliseconds
@@ -1810,7 +1835,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
case 307: // Set heater process model parameters
if (gb.Seen('H'))
{
- int heater = gb.GetIValue();
+ const int heater = gb.GetIValue();
if (heater >= 0 && heater < (int)Heaters)
{
const FopDt& model = reprap.GetHeat().GetHeaterModel(heater);
@@ -2970,7 +2995,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
++numTotalAxes;
}
numVisibleAxes = numTotalAxes; // assume all axes are visible unless there is a P parameter
- SetPositions(moveBuffer.coords); // tell the Move system where any new axes are
+ reprap.GetMove().SetNewPosition(moveBuffer.coords, true); // tell the Move system where any new axes are
platform.SetAxisDriversConfig(drive, config);
if (numTotalAxes + numExtruders > DRIVES)
{
@@ -3075,24 +3100,24 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
#ifdef DUET_WIFI
case 587: // Add WiFi network or list remembered networks
- if (gb.SeenAfterSpace('S'))
+ if (gb.Seen('S'))
{
WirelessConfigurationData config;
memset(&config, 0, sizeof(config));
bool ok = gb.GetQuotedString(config.ssid, ARRAY_SIZE(config.ssid));
if (ok)
{
- ok = gb.SeenAfterSpace('P') && gb.GetQuotedString(config.password, ARRAY_SIZE(config.password));
+ ok = gb.Seen('P') && gb.GetQuotedString(config.password, ARRAY_SIZE(config.password));
}
- if (ok && gb.SeenAfterSpace('I'))
+ if (ok && gb.Seen('I'))
{
ok = gb.GetIPAddress(config.ip);
}
- if (ok && gb.SeenAfterSpace('J'))
+ if (ok && gb.Seen('J'))
{
ok = gb.GetIPAddress(config.gateway);
}
- if (ok && gb.SeenAfterSpace('K'))
+ if (ok && gb.Seen('K'))
{
ok = gb.GetIPAddress(config.netmask);
}
@@ -3120,14 +3145,28 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
if (rslt >= 0)
{
char* const cbuf = reinterpret_cast<char *>(buffer);
- cbuf[declaredBufferLength] = 0;
+ cbuf[declaredBufferLength] = 0; // ensure null terminated
size_t len = strlen(cbuf);
+
+ // If there is a trailing newline, remove it
if (len != 0 && cbuf[len - 1] == '\n')
{
--len;
cbuf[len] = 0;
}
- if (len == 0)
+
+ // DuetWiFiServer 1.19beta7 and later include the SSID used in access point mode at the start
+ const char *bufp = strchr(cbuf, '\n');
+ if (bufp == nullptr)
+ {
+ bufp = cbuf; // must be an old version of DuetWiFiServer
+ }
+ else
+ {
+ ++bufp; // slip the first entry
+ }
+
+ if (strlen(bufp) == 0)
{
reply.copy("No remembered networks");
}
@@ -3139,7 +3178,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
return false; // try again later
}
response->copy("Remembered networks:\n");
- response->cat(cbuf);
+ response->cat(bufp);
HandleReply(gb, false, response);
return true;
}
@@ -3153,13 +3192,13 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
break;
case 588: // Forget WiFi network
- if (gb.SeenAfterSpace('S'))
+ if (gb.Seen('S'))
{
uint32_t ssid[NumDwords(SsidLength)];
if (gb.GetQuotedString(reinterpret_cast<char*>(ssid), SsidLength))
{
const char* const pssid = reinterpret_cast<const char*>(ssid);
- if (strcmp(pssid, "ALL") == 0)
+ if (strcmp(pssid, "*") == 0)
{
const int32_t rslt = reprap.GetNetwork().SendCommand(NetworkCommand::networkFactoryReset, 0, 0, nullptr, 0, nullptr, 0);
if (rslt != ResponseEmpty)
@@ -3187,22 +3226,37 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
break;
case 589: // Configure access point
- if (gb.SeenAfterSpace('S'))
+ if (gb.Seen('S'))
{
WirelessConfigurationData config;
memset(&config, 0, sizeof(config));
bool ok = gb.GetQuotedString(config.ssid, ARRAY_SIZE(config.ssid));
if (ok)
{
- ok = gb.SeenAfterSpace('P') && gb.GetQuotedString(config.password, ARRAY_SIZE(config.password));
- }
- if (ok && gb.SeenAfterSpace('I'))
- {
- ok = gb.GetIPAddress(config.ip);
+ if (strcmp(config.ssid, "*") == 0)
+ {
+ // Delete the access point details
+ memset(&config, 0xFF, sizeof(config));
+ }
+ else
+ {
+ ok = gb.Seen('P') && gb.GetQuotedString(config.password, ARRAY_SIZE(config.password));
+ if (ok)
+ {
+ if (gb.Seen('I'))
+ {
+ ok = gb.GetIPAddress(config.ip);
+ config.channel = (gb.Seen('C')) ? gb.GetIValue() : 0;
+ }
+ }
+ else
+ {
+ ok = false;
+ }
+ }
}
if (ok)
{
- config.channel = (gb.SeenAfterSpace('C')) ? gb.GetIValue() : 0;
const int32_t rslt = reprap.GetNetwork().SendCommand(NetworkCommand::networkConfigureAccessPoint, 0, 0, &config, sizeof(config), nullptr, 0);
if (rslt != ResponseEmpty)
{
@@ -3212,7 +3266,29 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
}
else
{
- reply.copy("Bad parameter in M589 command");
+ reply.copy("Bad or missing parameter in M589 command");
+ error = true;
+ }
+ }
+ else
+ {
+ const size_t declaredBufferLength = MaxRememberedNetworks * (SsidLength + 1) + 1; // enough for all the remembered SSIDs with null terminator, plus an extra null
+ uint32_t buffer[NumDwords(declaredBufferLength + 1)];
+ const int32_t rslt = reprap.GetNetwork().SendCommand(NetworkCommand::networkListSsids, 0, 0, nullptr, 0, buffer, declaredBufferLength);
+ if (rslt >= 0)
+ {
+ char* const cbuf = reinterpret_cast<char *>(buffer);
+ cbuf[declaredBufferLength] = 0; // ensure null terminated
+ char *p = strchr(cbuf, '\n');
+ if (p != nullptr)
+ {
+ *p = 0;
+ }
+ reply.printf("Own SSID: %s", (cbuf[0] == 0) ? "not configured" : cbuf);
+ }
+ else
+ {
+ reply.copy("Failed to remove SSID from remembered list");
error = true;
}
}
@@ -3226,8 +3302,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
}
{
Move& move = reprap.GetMove();
- float positionNow[DRIVES];
- move.GetCurrentUserPosition(positionNow, 0, reprap.GetCurrentXAxes()); // get the current position, we may need it later
bool changedMode = false;
if ((gb.Seen('L') || gb.Seen('D')) && move.GetKinematics().GetKinematicsType() != KinematicsType::linearDelta)
@@ -3239,11 +3313,16 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
const bool changed = move.GetKinematics().Configure(code, gb, reply, error);
if (changedMode)
{
- move.GetKinematics().GetAssumedInitialPosition(numVisibleAxes, positionNow);
+ move.GetKinematics().GetAssumedInitialPosition(numVisibleAxes, moveBuffer.coords);
+ ToolOffsetInverseTransform(moveBuffer.coords, currentUserPosition);
}
if (changed || changedMode)
{
- SetPositions(positionNow);
+ if (reprap.GetMove().GetKinematics().LimitPosition(moveBuffer.coords, numVisibleAxes, axesHomed))
+ {
+ ToolOffsetInverseTransform(moveBuffer.coords, currentUserPosition); // make sure the limits are reflected in the user position
+ }
+ reprap.GetMove().SetNewPosition(moveBuffer.coords, true);
SetAllAxesNotHomed();
}
}
@@ -3270,8 +3349,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
}
{
Move& move = reprap.GetMove();
- float positionNow[DRIVES];
- move.GetCurrentUserPosition(positionNow, 0, reprap.GetCurrentXAxes()); // get the current position, we may need it later
const KinematicsType oldK = move.GetKinematics().GetKinematicsType(); // get the current kinematics type so we can tell whether it changed
bool seen = false;
@@ -3316,9 +3393,14 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
// We changed something, so reset the positions and set all axes not homed
if (move.GetKinematics().GetKinematicsType() != oldK)
{
- move.GetKinematics().GetAssumedInitialPosition(numVisibleAxes, positionNow);
+ move.GetKinematics().GetAssumedInitialPosition(numVisibleAxes, moveBuffer.coords);
+ ToolOffsetInverseTransform(moveBuffer.coords, currentUserPosition);
}
- SetPositions(positionNow);
+ if (reprap.GetMove().GetKinematics().LimitPosition(moveBuffer.coords, numVisibleAxes, axesHomed))
+ {
+ ToolOffsetInverseTransform(moveBuffer.coords, currentUserPosition); // make sure the limits are reflected in the user position
+ }
+ reprap.GetMove().SetNewPosition(moveBuffer.coords, true);
SetAllAxesNotHomed();
}
}
@@ -3331,8 +3413,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
}
{
Move& move = reprap.GetMove();
- float positionNow[DRIVES];
- move.GetCurrentUserPosition(positionNow, 0, reprap.GetCurrentXAxes()); // get the current position, we may need it later
const KinematicsType oldK = move.GetKinematics().GetKinematicsType(); // get the current kinematics type so we can tell whether it changed
bool seen = false;
@@ -3357,14 +3437,25 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
// We changed something, so reset the positions and set all axes not homed
if (move.GetKinematics().GetKinematicsType() != oldK)
{
- move.GetKinematics().GetAssumedInitialPosition(numVisibleAxes, positionNow);
+ move.GetKinematics().GetAssumedInitialPosition(numVisibleAxes, moveBuffer.coords);
+ ToolOffsetInverseTransform(moveBuffer.coords, currentUserPosition);
}
- SetPositions(positionNow);
+ if (reprap.GetMove().GetKinematics().LimitPosition(moveBuffer.coords, numVisibleAxes, axesHomed))
+ {
+ ToolOffsetInverseTransform(moveBuffer.coords, currentUserPosition); // make sure the limits are reflected in the user position
+ }
+ reprap.GetMove().SetNewPosition(moveBuffer.coords, true);
SetAllAxesNotHomed();
}
}
break;
+#if SUPPORT_IOBITS
+ case 670:
+ error = reprap.GetPortControl().Configure(gb, reply);
+ break;
+#endif
+
#if SUPPORT_SCANNER
case 750: // Enable 3D scanner extension
reprap.GetScanner().Enable();
@@ -3815,11 +3906,7 @@ bool GCodes::HandleTcode(GCodeBuffer& gb, StringRef& reply)
newToolNumber = gb.GetIValue();
newToolNumber += gb.GetToolNumberAdjust();
- // TODO for the tool change restore point to be useful, we should undo any X axis mapping and remove any tool offsets
- for (size_t drive = 0; drive < DRIVES; ++drive)
- {
- toolChangeRestorePoint.moveCoords[drive] = moveBuffer.coords[drive];
- }
+ reprap.GetMove().GetCurrentUserPosition(toolChangeRestorePoint.moveCoords, 0, reprap.GetCurrentXAxes());
toolChangeRestorePoint.feedRate = gb.MachineState().feedrate;
if (simulationMode == 0) // we don't yet simulate any T codes