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:
authorDavid Crocker <dcrocker@eschertech.com>2020-01-19 02:03:39 +0300
committerDavid Crocker <dcrocker@eschertech.com>2020-01-19 02:03:39 +0300
commitc812ce5e14cf476526d955edbce2effa9d922902 (patch)
treeda67dc55e46efdd38a0647318977a342da730345 /src/GCodes
parente0bbf71357b07c22e6d43be3cca5c7422163be32 (diff)
Major refactoring, bug fixes in function evaluation
Changed all bitmaps to use the bitmap class from RRFLibraries Fixed bugs in functoin evaluation
Diffstat (limited to 'src/GCodes')
-rw-r--r--src/GCodes/GCodeBuffer/StringParser.cpp22
-rw-r--r--src/GCodes/GCodeMachineState.cpp2
-rw-r--r--src/GCodes/GCodeMachineState.h2
-rw-r--r--src/GCodes/GCodes.cpp145
-rw-r--r--src/GCodes/GCodes.h4
-rw-r--r--src/GCodes/GCodes2.cpp6
-rw-r--r--src/GCodes/GCodes3.cpp26
-rw-r--r--src/GCodes/GCodes4.cpp12
-rw-r--r--src/GCodes/Trigger.cpp6
-rw-r--r--src/GCodes/Trigger.h8
10 files changed, 120 insertions, 113 deletions
diff --git a/src/GCodes/GCodeBuffer/StringParser.cpp b/src/GCodes/GCodeBuffer/StringParser.cpp
index 782bab0e..4036b4be 100644
--- a/src/GCodes/GCodeBuffer/StringParser.cpp
+++ b/src/GCodes/GCodeBuffer/StringParser.cpp
@@ -1646,7 +1646,7 @@ void StringParser::AppendAsString(ExpressionValue val, const StringRef& str)
break;
case TYPE_OF(float):
- str.catf((val.param == 3) ? "%.3f" : (val.param == 2) ? "%.2f" : "%.1f", (double)val.fVal);
+ str.catf(val.GetFloatFormatString(), (double)val.fVal);
break;
case TYPE_OF(uint32_t):
@@ -1667,7 +1667,7 @@ void StringParser::AppendAsString(ExpressionValue val, const StringRef& str)
case TYPE_OF(DateTime):
{
- const time_t time = val.Get40BitValue();
+ const time_t time = val.Get56BitValue();
tm timeInfo;
gmtime_r(&time, &timeInfo);
str.catf("%04u-%02u-%02u %02u:%02u:%02u",
@@ -1918,6 +1918,7 @@ ExpressionValue StringParser::ParseExpression(StringBuffer& stringBuffer, uint8_
if (val.type == TYPE_OF(float))
{
val.fVal += val2.fVal;
+ val.param = max(val.param, val2.param);
}
else
{
@@ -1930,6 +1931,7 @@ ExpressionValue StringParser::ParseExpression(StringBuffer& stringBuffer, uint8_
if (val.type == TYPE_OF(float))
{
val.fVal -= val2.fVal;
+ val.param = max(val.param, val2.param);
}
else
{
@@ -1942,6 +1944,7 @@ ExpressionValue StringParser::ParseExpression(StringBuffer& stringBuffer, uint8_
if (val.type == TYPE_OF(float))
{
val.fVal *= val2.fVal;
+ val.param = max(val.param, val2.param);
}
else
{
@@ -1953,6 +1956,7 @@ ExpressionValue StringParser::ParseExpression(StringBuffer& stringBuffer, uint8_
ConvertToFloat(val, evaluate);
ConvertToFloat(val2, evaluate);
val.fVal /= val2.fVal;
+ val.param = 0;
break;
case '>':
@@ -2128,6 +2132,7 @@ void StringParser::ConvertToFloat(ExpressionValue& val, bool evaluate)
case TYPE_OF(int32_t):
val.fVal = (float)val.iVal;
val.type = TYPE_OF(float);
+ val.param = 1;
break;
case TYPE_OF(float):
@@ -2263,6 +2268,7 @@ ExpressionValue StringParser::ParseNumber()
if (isFloat)
{
retvalue.type = TYPE_OF(float);
+ retvalue.param = constrain<long>(digitsAfterPoint, 1, MaxFloatDigitsDisplayedAfterPoint);
if (valueAfterPoint != 0)
{
if (valueBeforePoint == 0)
@@ -2385,6 +2391,7 @@ ExpressionValue StringParser::ParseIdentifierExpression(StringBuffer& stringBuff
if (gb.buffer[readPointer] == '(')
{
// It's a function call
+ ++readPointer;
ExpressionValue rslt = ParseExpression(stringBuffer, 0, evaluate);
if (id.Equals("abs"))
{
@@ -2410,31 +2417,37 @@ ExpressionValue StringParser::ParseIdentifierExpression(StringBuffer& stringBuff
{
ConvertToFloat(rslt, evaluate);
rslt.fVal = sinf(rslt.fVal);
+ rslt.param = MaxFloatDigitsDisplayedAfterPoint;
}
else if (id.Equals("cos"))
{
ConvertToFloat(rslt, evaluate);
rslt.fVal = cosf(rslt.fVal);
+ rslt.param = MaxFloatDigitsDisplayedAfterPoint;
}
else if (id.Equals("tan"))
{
ConvertToFloat(rslt, evaluate);
rslt.fVal = tanf(rslt.fVal);
+ rslt.param = MaxFloatDigitsDisplayedAfterPoint;
}
else if (id.Equals("asin"))
{
ConvertToFloat(rslt, evaluate);
rslt.fVal = asinf(rslt.fVal);
+ rslt.param = MaxFloatDigitsDisplayedAfterPoint;
}
else if (id.Equals("acos"))
{
ConvertToFloat(rslt, evaluate);
rslt.fVal = acosf(rslt.fVal);
+ rslt.param = MaxFloatDigitsDisplayedAfterPoint;
}
else if (id.Equals("atan"))
{
ConvertToFloat(rslt, evaluate);
rslt.fVal = atanf(rslt.fVal);
+ rslt.param = MaxFloatDigitsDisplayedAfterPoint;
}
else if (id.Equals("atan2"))
{
@@ -2449,11 +2462,13 @@ ExpressionValue StringParser::ParseIdentifierExpression(StringBuffer& stringBuff
ExpressionValue nextOperand = ParseExpression(stringBuffer, 0, evaluate);
ConvertToFloat(nextOperand, evaluate);
rslt.fVal = atan2f(rslt.fVal, nextOperand.fVal);
+ rslt.param = MaxFloatDigitsDisplayedAfterPoint;
}
else if (id.Equals("sqrt"))
{
ConvertToFloat(rslt, evaluate);
rslt.fVal = sqrtf(rslt.fVal);
+ rslt.param = MaxFloatDigitsDisplayedAfterPoint;
}
else if (id.Equals("isnan"))
{
@@ -2477,6 +2492,7 @@ ExpressionValue StringParser::ParseIdentifierExpression(StringBuffer& stringBuff
if (rslt.type == TYPE_OF(float))
{
rslt.fVal = max<float>(rslt.fVal, nextOperand.fVal);
+ rslt.param = max(rslt.param, nextOperand.param);
}
else
{
@@ -2500,6 +2516,7 @@ ExpressionValue StringParser::ParseIdentifierExpression(StringBuffer& stringBuff
if (rslt.type == TYPE_OF(float))
{
rslt.fVal = min<float>(rslt.fVal, nextOperand.fVal);
+ rslt.param = max(rslt.param, nextOperand.param);
}
else
{
@@ -2516,6 +2533,7 @@ ExpressionValue StringParser::ParseIdentifierExpression(StringBuffer& stringBuff
{
throw ConstructParseException("expected ')'");
}
+ ++readPointer;
return rslt;
}
diff --git a/src/GCodes/GCodeMachineState.cpp b/src/GCodes/GCodeMachineState.cpp
index 8412b4c3..e2bef1cf 100644
--- a/src/GCodes/GCodeMachineState.cpp
+++ b/src/GCodes/GCodeMachineState.cpp
@@ -20,7 +20,7 @@ GCodeMachineState::GCodeMachineState() noexcept
#if HAS_LINUX_INTERFACE
fileId(0),
#endif
- lockedResources(0), errorMessage(nullptr),
+ errorMessage(nullptr),
lineNumber(0),
compatibility(Compatibility::reprapFirmware), drivesRelative(false), axesRelative(false),
#if HAS_LINUX_INTERFACE
diff --git a/src/GCodes/GCodeMachineState.h b/src/GCodes/GCodeMachineState.h
index 303a3aa8..c348e63a 100644
--- a/src/GCodes/GCodeMachineState.h
+++ b/src/GCodes/GCodeMachineState.h
@@ -132,7 +132,7 @@ enum class BlockType : uint8_t
class GCodeMachineState
{
public:
- typedef uint32_t ResourceBitmap;
+ typedef Bitmap<uint32_t> ResourceBitmap;
// Class to record the state of blocks when using conditional GCode
class BlockState
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index 1df814ba..db69dc0c 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -265,7 +265,7 @@ void GCodes::Reset() noexcept
{
tr.Init();
}
- triggersPending = 0;
+ triggersPending.Clear();
simulationMode = 0;
exitSimulationWhenFileComplete = updateFileWhenSimulationComplete = false;
@@ -737,19 +737,19 @@ void GCodes::CheckTriggers() noexcept
{
for (unsigned int i = 0; i < MaxTriggers; ++i)
{
- if (!IsBitSet(triggersPending, i) && triggers[i].Check())
+ if (!triggersPending.IsBitSet(i) && triggers[i].Check())
{
- SetBit(triggersPending, i);
+ triggersPending.SetBit(i);
}
}
// If any triggers are pending, activate the one with the lowest number
- if (triggersPending != 0)
+ if (triggersPending.IsNonEmpty())
{
- const unsigned int lowestTriggerPending = LowestSetBitNumber(triggersPending);
+ const unsigned int lowestTriggerPending = triggersPending.LowestSetBit();
if (lowestTriggerPending == 0)
{
- ClearBit(triggersPending, lowestTriggerPending); // clear the trigger
+ triggersPending.ClearBit(lowestTriggerPending); // clear the trigger
DoEmergencyStop();
}
else if (!IsDaemonBusy() && daemonGCode->GetState() == GCodeState::normal) // if we are not already executing a trigger or config.g
@@ -758,17 +758,17 @@ void GCodes::CheckTriggers() noexcept
{
if (!IsReallyPrinting())
{
- ClearBit(triggersPending, lowestTriggerPending); // ignore a pause trigger if we are already paused or not printing
+ triggersPending.ClearBit(lowestTriggerPending); // ignore a pause trigger if we are already paused or not printing
}
else if (LockMovement(*daemonGCode)) // need to lock movement before executing the pause macro
{
- ClearBit(triggersPending, lowestTriggerPending); // clear the trigger
+ triggersPending.ClearBit(lowestTriggerPending); // clear the trigger
DoPause(*daemonGCode, PauseReason::trigger, "Print paused by external trigger");
}
}
else
{
- ClearBit(triggersPending, lowestTriggerPending); // clear the trigger
+ triggersPending.ClearBit(lowestTriggerPending); // clear the trigger
String<StringLength20> filename;
filename.printf("trigger%u.g", lowestTriggerPending);
DoFileMacro(*daemonGCode, filename.c_str(), true);
@@ -954,7 +954,7 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg) noexc
if (msg != nullptr)
{
- platform.SendAlert(GenericMessage, msg, "Printing paused", 1, 0.0, 0);
+ platform.SendAlert(GenericMessage, msg, "Printing paused", 1, 0.0, AxesBitmap());
}
}
@@ -1528,7 +1528,7 @@ bool GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isPrintingM
}
moveBuffer.hasExtrusion = false;
moveBuffer.virtualExtruderPosition = virtualExtruderPosition; // save this before we update it
- ExtrudersBitmap extrudersMoving = 0;
+ 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
@@ -1591,7 +1591,7 @@ bool GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isPrintingM
}
moveBuffer.coords[ExtruderToLogicalDrive(extruder)] = extrusionAmount * extrusionFactors[extruder];
- SetBit(extrudersMoving, extruder);
+ extrudersMoving.SetBit(extruder);
}
}
if (!isPrintingMove && moveBuffer.usingStandardFeedrate)
@@ -1623,7 +1623,7 @@ bool GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isPrintingM
rawExtruderTotal += extrusionAmount;
}
moveBuffer.coords[ExtruderToLogicalDrive(extruder)] = extrusionAmount * extrusionFactors[extruder] * volumetricExtrusionFactors[extruder];
- SetBit(extrudersMoving, extruder);
+ extrudersMoving.SetBit(extruder);
}
}
}
@@ -1651,7 +1651,7 @@ bool GCodes::LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isPrintingM
// Check that enough axes have been homed, returning true if insufficient axes homed
bool GCodes::CheckEnoughAxesHomed(AxesBitmap axesMoved) noexcept
{
- return (reprap.GetMove().GetKinematics().MustBeHomedAxes(axesMoved, noMovesBeforeHoming) & ~axesHomed) != 0;
+ return (reprap.GetMove().GetKinematics().MustBeHomedAxes(axesMoved, noMovesBeforeHoming) & ~axesHomed).IsNonEmpty();
}
// Execute a straight move returning an error message if the command was rejected, else nullptr
@@ -1676,7 +1676,7 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated)
moveBuffer.moveType = 0;
moveBuffer.tool = reprap.GetCurrentTool();
moveBuffer.usePressureAdvance = false;
- axesToSenseLength = 0;
+ axesToSenseLength.Clear();
// Check to see if the move is a 'homing' move that endstops are checked on.
// We handle H1 parameters affecting extrusion elsewhere.
@@ -1767,7 +1767,7 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated)
// Deal with axis movement
const float initialX = currentUserPosition[X_AXIS];
const float initialY = currentUserPosition[Y_AXIS];
- AxesBitmap axesMentioned = 0;
+ AxesBitmap axesMentioned;
for (size_t axis = 0; axis < numVisibleAxes; axis++)
{
if (gb.Seen(axisLetters[axis]))
@@ -1778,7 +1778,7 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated)
return "G0/G1: attempt to move individual motors of a delta machine to absolute positions";
}
- SetBit(axesMentioned, axis);
+ axesMentioned.SetBit(axis);
const float moveArg = gb.GetDistance();
if (moveBuffer.moveType != 0)
{
@@ -1829,7 +1829,7 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated)
break;
case 1:
- if (!platform.GetEndstops().EnableAxisEndstops(axesMentioned & LowestNBits<AxesBitmap>(numTotalAxes), true))
+ if (!platform.GetEndstops().EnableAxisEndstops(axesMentioned & AxesBitmap::MakeLowestNBits(numTotalAxes), true))
{
return "Failed to enable endstops";
}
@@ -1837,8 +1837,8 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated)
break;
case 3:
- axesToSenseLength = axesMentioned & LowestNBits<AxesBitmap>(numTotalAxes);
- if (!platform.GetEndstops().EnableAxisEndstops(axesMentioned & LowestNBits<AxesBitmap>(numTotalAxes), false))
+ axesToSenseLength = axesMentioned & AxesBitmap::MakeLowestNBits(numTotalAxes);
+ if (!platform.GetEndstops().EnableAxisEndstops(axesMentioned & AxesBitmap::MakeLowestNBits(numTotalAxes), false))
{
return "Failed to enable endstops";
}
@@ -1850,7 +1850,7 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated)
break;
}
- LoadExtrusionAndFeedrateFromGCode(gb, axesMentioned != 0); // for type 1 moves, this must be called after calling EnableAxisEndstops, because EnableExtruderEndstop assumes that
+ LoadExtrusionAndFeedrateFromGCode(gb, axesMentioned.IsNonEmpty()); // for type 1 moves, this must be called after calling EnableAxisEndstops, because EnableExtruderEndstop assumes that
// Set up the move. We must assign segmentsLeft last, so that when Move runs as a separate task the move won't be picked up by the Move process before it is complete.
// Note that if this is an extruder-only move, we don't do axis movements to allow for tool offset changes, we defer those until an axis moves.
@@ -1860,13 +1860,13 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated)
totalSegments = 1;
gb.SetState(GCodeState::waitingForSpecialMoveToComplete);
}
- else if (axesMentioned == 0)
+ else if (axesMentioned.IsEmpty())
{
totalSegments = 1;
}
else
{
- if (&gb == fileGCode && !gb.IsDoingFileMacro() && moveBuffer.hasExtrusion && (axesMentioned & ((1 << X_AXIS) | (1 << Y_AXIS))) != 0)
+ if (&gb == fileGCode && !gb.IsDoingFileMacro() && moveBuffer.hasExtrusion && axesMentioned.Intersects(XyAxes))
{
lastPrintingMoveHeight = currentUserPosition[Z_AXIS];
}
@@ -1876,7 +1876,7 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated)
AxesBitmap effectiveAxesHomed = axesHomed;
if (doingManualBedProbe)
{
- ClearBit(effectiveAxesHomed, Z_AXIS); // if doing a manual Z probe, don't limit the Z movement
+ effectiveAxesHomed.ClearBit(Z_AXIS); // if doing a manual Z probe, don't limit the Z movement
}
if (moveBuffer.moveType == 0)
@@ -1933,8 +1933,8 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated)
// The movement code will only apply pressure advance if there is forward extrusion, so we only need to check for XYU.. movement here.
{
AxesBitmap axesMentionedExceptZ = axesMentioned;
- ClearBit(axesMentionedExceptZ, Z_AXIS);
- moveBuffer.usePressureAdvance = moveBuffer.hasExtrusion && (axesMentionedExceptZ != 0);
+ axesMentionedExceptZ.ClearBit(Z_AXIS);
+ moveBuffer.usePressureAdvance = moveBuffer.hasExtrusion && axesMentionedExceptZ.IsNonEmpty();
}
// Apply segmentation if necessary. To speed up simulation on SCARA printers, we don't apply kinematics segmentation when simulating.
@@ -2093,7 +2093,7 @@ const char* GCodes::DoArcMove(GCodeBuffer& gb, bool clockwise)
const bool wholeCircle = (moveBuffer.initialUserX == currentUserPosition[X_AXIS] && moveBuffer.initialUserY == currentUserPosition[Y_AXIS]);
// Get any additional axes
- AxesBitmap axesMentioned = MakeBitmap<AxesBitmap>(X_AXIS) | MakeBitmap<AxesBitmap>(Y_AXIS);
+ AxesBitmap axesMentioned = XyAxes;
for (size_t axis = Z_AXIS; axis < numVisibleAxes; axis++)
{
if (gb.Seen(axisLetters[axis]))
@@ -2115,7 +2115,7 @@ const char* GCodes::DoArcMove(GCodeBuffer& gb, bool clockwise)
{
currentUserPosition[axis] = moveArg + GetWorkplaceOffset(axis);
}
- SetBit(axesMentioned, axis);
+ axesMentioned.SetBit(axis);
}
}
@@ -2150,11 +2150,11 @@ const char* GCodes::DoArcMove(GCodeBuffer& gb, bool clockwise)
const AxesBitmap yAxes = reprap.GetCurrentYAxes();
for (size_t axis = 0; axis < numVisibleAxes; ++axis)
{
- if (IsBitSet(xAxes, axis))
+ if (xAxes.IsBitSet(axis))
{
arcCentre[axis] = (userArcCentreX * axisScaleFactors[axis]) + currentBabyStepOffsets[axis] - Tool::GetOffset(reprap.GetCurrentTool(), X_AXIS);
}
- else if (IsBitSet(yAxes, axis))
+ else if (yAxes.IsBitSet(axis))
{
arcCentre[axis] = (userArcCentreY * axisScaleFactors[axis]) + currentBabyStepOffsets[axis] - Tool::GetOffset(reprap.GetCurrentTool(), Y_AXIS);
}
@@ -2315,12 +2315,12 @@ bool GCodes::ReadMove(RawMove& m) noexcept
for (size_t drive = 0; drive < numVisibleAxes; ++drive)
{
- if (doingArcMove && drive != Z_AXIS && IsBitSet(Tool::GetYAxes(moveBuffer.tool), drive))
+ if (doingArcMove && drive != Z_AXIS && Tool::GetYAxes(moveBuffer.tool).IsBitSet(drive))
{
// Y axis or a substitute Y axis
moveBuffer.initialCoords[drive] = arcCentre[drive] + arcRadius * axisScaleFactors[drive] * sinf(arcCurrentAngle);
}
- else if (doingArcMove && drive != Z_AXIS && IsBitSet(Tool::GetXAxes(moveBuffer.tool), drive))
+ else if (doingArcMove && drive != Z_AXIS && Tool::GetXAxes(moveBuffer.tool).IsBitSet(drive))
{
// X axis or a substitute X axis
moveBuffer.initialCoords[drive] = arcCentre[drive] + arcRadius * axisScaleFactors[drive] * cosf(arcCurrentAngle);
@@ -2516,20 +2516,20 @@ GCodeResult GCodes::DoHome(GCodeBuffer& gb, const StringRef& reply)
#endif
// Find out which axes we have been asked to home
- toBeHomed = 0;
+ toBeHomed.Clear();
for (size_t axis = 0; axis < numTotalAxes; ++axis)
{
if (gb.Seen(axisLetters[axis]))
{
- SetBit(toBeHomed, axis);
+ toBeHomed.SetBit(axis);
SetAxisNotHomed(axis);
}
}
- if (toBeHomed == 0)
+ if (toBeHomed.IsEmpty())
{
SetAllAxesNotHomed(); // homing everything
- toBeHomed = LowestNBits<AxesBitmap>(numVisibleAxes);
+ toBeHomed = AxesBitmap::MakeLowestNBits(numVisibleAxes);
}
gb.SetState(GCodeState::homing1);
@@ -2631,7 +2631,7 @@ void GCodes::DoManualProbe(GCodeBuffer& gb, const char *message, const char *tit
// Do a manual bed probe. On entry the state variable is the state we want to return to when the user has finished adjusting the height.
void GCodes::DoManualBedProbe(GCodeBuffer& gb)
{
- DoManualProbe(gb, "Adjust height until the nozzle just touches the bed, then press OK", "Manual bed probing", MakeBitmap<AxesBitmap>(Z_AXIS));
+ DoManualProbe(gb, "Adjust height until the nozzle just touches the bed, then press OK", "Manual bed probing", AxesBitmap::MakeFromBits(Z_AXIS));
}
// Start probing the grid, returning true if we didn't because of an error.
@@ -3082,7 +3082,7 @@ GCodeResult GCodes::ManageTool(GCodeBuffer& gb, const StringRef& reply)
uint32_t xMapping[MaxAxes];
size_t xCount = numVisibleAxes;
gb.GetUnsignedArray(xMapping, xCount, false);
- xMap = UnsignedArrayToBitMap<AxesBitmap>(xMapping, xCount) & LowestNBits<AxesBitmap>(numVisibleAxes);
+ xMap = AxesBitmap::MakeFromArray(xMapping, xCount) & AxesBitmap::MakeLowestNBits(numVisibleAxes);
seen = true;
}
else
@@ -3097,7 +3097,7 @@ GCodeResult GCodes::ManageTool(GCodeBuffer& gb, const StringRef& reply)
uint32_t yMapping[MaxAxes];
size_t yCount = numVisibleAxes;
gb.GetUnsignedArray(yMapping, yCount, false);
- yMap = UnsignedArrayToBitMap<AxesBitmap>(yMapping, yCount) & LowestNBits<AxesBitmap>(numVisibleAxes);
+ yMap = AxesBitmap::MakeFromArray(yMapping, yCount) & AxesBitmap::MakeLowestNBits(numVisibleAxes);
seen = true;
}
else
@@ -3105,7 +3105,7 @@ GCodeResult GCodes::ManageTool(GCodeBuffer& gb, const StringRef& reply)
yMap = DefaultYAxisMapping; // by default map X axis straight through
}
- if ((xMap & yMap) != 0)
+ if (xMap.Intersects(yMap))
{
reply.copy("Cannot map both X and Y to the same axis");
return GCodeResult::error;
@@ -3118,12 +3118,12 @@ GCodeResult GCodes::ManageTool(GCodeBuffer& gb, const StringRef& reply)
uint32_t fanMapping[MaxFans];
size_t fanCount = MaxFans;
gb.GetUnsignedArray(fanMapping, fanCount, false);
- fanMap = UnsignedArrayToBitMap<FansBitmap>(fanMapping, fanCount) & LowestNBits<FansBitmap>(MaxFans);
+ fanMap = FansBitmap::MakeFromArray(fanMapping, fanCount) & FansBitmap::MakeLowestNBits(MaxFans);
seen = true;
}
else
{
- fanMap = 1; // by default map fan 0 to fan 0
+ fanMap.SetBit(0); // by default map fan 0 to fan 0
}
if (seen)
@@ -3194,14 +3194,8 @@ void GCodes::SetMappedFanSpeed(float f) noexcept
}
else
{
- const uint32_t fanMap = ct->GetFanMapping();
- for (size_t i = 0; i < MaxFans; ++i)
- {
- if (IsBitSet(fanMap, i))
- {
- reprap.GetFansManager().SetFanValue(i, f);
- }
- }
+ const FansBitmap fanMap = ct->GetFanMapping();
+ fanMap.Iterate([f](unsigned int i) { reprap.GetFansManager().SetFanValue(i, f); });
}
}
@@ -3209,8 +3203,9 @@ void GCodes::SetMappedFanSpeed(float f) noexcept
bool GCodes::IsMappedFan(unsigned int fanNumber) noexcept
{
const Tool * const ct = reprap.GetCurrentTool();
- return (ct == nullptr) ? fanNumber == 0
- : IsBitSet(ct->GetFanMapping(), fanNumber);
+ return (ct == nullptr)
+ ? fanNumber == 0
+ : ct->GetFanMapping().IsBitSet(fanNumber);
}
// Save the speeds of all fans
@@ -3851,14 +3846,14 @@ void GCodes::ToolOffsetTransform(const float coordsIn[MaxAxes], float coordsOut[
const AxesBitmap yAxes = currentTool->GetYAxisMap();
for (size_t axis = 0; axis < numVisibleAxes; ++axis)
{
- if ( (axis != X_AXIS || IsBitSet(xAxes, X_AXIS))
- && (axis != Y_AXIS || IsBitSet(yAxes, Y_AXIS))
+ if ( (axis != X_AXIS || xAxes.IsBitSet(X_AXIS))
+ && (axis != Y_AXIS || yAxes.IsBitSet(Y_AXIS))
)
{
const float totalOffset = currentBabyStepOffsets[axis] - currentTool->GetOffset(axis);
- const size_t inputAxis = (IsBitSet(explicitAxes, axis)) ? axis
- : (IsBitSet(xAxes, axis)) ? X_AXIS
- : (IsBitSet(yAxes, axis)) ? Y_AXIS
+ const size_t inputAxis = (explicitAxes.IsBitSet(axis)) ? axis
+ : (xAxes.IsBitSet(axis)) ? X_AXIS
+ : (yAxes.IsBitSet(axis)) ? Y_AXIS
: axis;
coordsOut[axis] = (coordsIn[inputAxis] * axisScaleFactors[axis]) + totalOffset;
}
@@ -3881,8 +3876,8 @@ void GCodes::ToolOffsetInverseTransform(const float coordsIn[MaxAxes], float coo
}
else
{
- const uint32_t xAxes = reprap.GetCurrentXAxes();
- const uint32_t yAxes = reprap.GetCurrentYAxes();
+ const AxesBitmap xAxes = reprap.GetCurrentXAxes();
+ const AxesBitmap yAxes = reprap.GetCurrentYAxes();
float xCoord = 0.0, yCoord = 0.0;
size_t numXAxes = 0, numYAxes = 0;
for (size_t axis = 0; axis < numVisibleAxes; ++axis)
@@ -3890,12 +3885,12 @@ void GCodes::ToolOffsetInverseTransform(const float coordsIn[MaxAxes], float coo
const float totalOffset = currentBabyStepOffsets[axis] - currentTool->GetOffset(axis);
const float coord = (coordsIn[axis] - totalOffset)/axisScaleFactors[axis];
coordsOut[axis] = coord;
- if (IsBitSet(xAxes, axis))
+ if (xAxes.IsBitSet(axis))
{
xCoord += coord;
++numXAxes;
}
- if (IsBitSet(yAxes, axis))
+ if (yAxes.IsBitSet(axis))
{
yCoord += coord;
++numYAxes;
@@ -3981,20 +3976,20 @@ GCodeResult GCodes::AdvanceHash(const StringRef &reply) noexcept
bool GCodes::AllAxesAreHomed() const noexcept
{
- const AxesBitmap allAxes = LowestNBits<AxesBitmap>(numVisibleAxes);
+ const AxesBitmap allAxes = AxesBitmap::MakeLowestNBits(numVisibleAxes);
return (axesHomed & allAxes) == allAxes;
}
// Tell us that the axis is now homed
void GCodes::SetAxisIsHomed(unsigned int axis) noexcept
{
- SetBit(axesHomed, axis);
+ axesHomed.SetBit(axis);
}
// Tell us that the axis is not homed
void GCodes::SetAxisNotHomed(unsigned int axis) noexcept
{
- ClearBit(axesHomed, axis);
+ axesHomed.ClearBit(axis);
if (axis == Z_AXIS)
{
zDatumSetByProbing = false;
@@ -4004,7 +3999,7 @@ void GCodes::SetAxisNotHomed(unsigned int axis) noexcept
// Flag all axes as not homed
void GCodes::SetAllAxesNotHomed() noexcept
{
- axesHomed = 0;
+ axesHomed.Clear();
zDatumSetByProbing = false;
}
@@ -4240,7 +4235,7 @@ bool GCodes::LockResource(const GCodeBuffer& gb, Resource r) noexcept
if (resourceOwners[r] == nullptr)
{
resourceOwners[r] = &gb;
- SetBit(gb.MachineState().lockedResources, r);
+ gb.MachineState().lockedResources.SetBit(r);
return true;
}
return false;
@@ -4257,7 +4252,7 @@ void GCodes::GrabResource(const GCodeBuffer& gb, Resource r) noexcept
GCodeMachineState *m = &(resourceOwners[r]->MachineState());
do
{
- ClearBit(m->lockedResources, r);
+ m->lockedResources.ClearBit(r);
m = m->previous;
}
while (m != nullptr);
@@ -4296,7 +4291,7 @@ void GCodes::UnlockResource(const GCodeBuffer& gb, Resource r) noexcept
GCodeMachineState * mc = &gb.MachineState();
do
{
- ClearBit(mc->lockedResources, r);
+ mc->lockedResources.ClearBit(r);
mc = mc->previous;
} while (mc != nullptr);
resourceOwners[r] = nullptr;
@@ -4307,13 +4302,13 @@ void GCodes::UnlockResource(const GCodeBuffer& gb, Resource r) noexcept
void GCodes::UnlockAll(const GCodeBuffer& gb) noexcept
{
const GCodeMachineState * const mc = gb.MachineState().previous;
- const uint32_t resourcesToKeep = (mc == nullptr) ? 0 : mc->lockedResources;
+ const GCodeMachineState::ResourceBitmap resourcesToKeep = (mc == nullptr) ? GCodeMachineState::ResourceBitmap() : mc->lockedResources;
for (size_t i = 0; i < NumResources; ++i)
{
- if (resourceOwners[i] == &gb && !IsBitSet(resourcesToKeep, i))
+ if (resourceOwners[i] == &gb && !resourcesToKeep.IsBitSet(i))
{
resourceOwners[i] = nullptr;
- ClearBit(gb.MachineState().lockedResources, i);
+ gb.MachineState().lockedResources.ClearBit(i);
}
}
}
@@ -4321,13 +4316,7 @@ void GCodes::UnlockAll(const GCodeBuffer& gb) noexcept
// Append a list of axes to a string
void GCodes::AppendAxes(const StringRef& reply, AxesBitmap axes) const noexcept
{
- for (size_t axis = 0; axis < numVisibleAxes; ++axis)
- {
- if (IsBitSet(axes, axis))
- {
- reply.cat(axisLetters[axis]);
- }
- }
+ axes.Iterate([reply, this](unsigned int axis) { reply.cat(this->axisLetters[axis]); });
}
// Get the name of the current machine mode
diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h
index 3d08efa1..4d876db2 100644
--- a/src/GCodes/GCodes.h
+++ b/src/GCodes/GCodes.h
@@ -109,7 +109,7 @@ public:
bool IsDaemonBusy() const noexcept; // Return true if the daemon is busy running config.g or a trigger file
bool IsAxisHomed(unsigned int axis) const noexcept // Has the axis been homed?
- { return IsBitSet(axesHomed, axis); }
+ { return axesHomed.IsBitSet(axis); }
void SetAxisIsHomed(unsigned int axis) noexcept; // Tell us that the axis is now homed
void SetAxisNotHomed(unsigned int axis) noexcept; // Tell us that the axis is not homed
void SetAllAxesNotHomed() noexcept; // Flag all axes as not homed
@@ -294,7 +294,7 @@ private:
void SetMachinePosition(const float positionNow[MaxAxesPlusExtruders], bool doBedCompensation = true) noexcept; // Set the current position to be this
void UpdateCurrentUserPosition() noexcept; // Get the current position from the Move class
- void ToolOffsetTransform(const float coordsIn[MaxAxes], float coordsOut[MaxAxes], AxesBitmap explicitAxes = 0) const noexcept;
+ void ToolOffsetTransform(const float coordsIn[MaxAxes], float coordsOut[MaxAxes], AxesBitmap explicitAxes = AxesBitmap()) const noexcept;
// Convert user coordinates to head reference point coordinates
void ToolOffsetInverseTransform(const float coordsIn[MaxAxes], float coordsOut[MaxAxes]) const noexcept; // Convert head reference point coordinates to user coordinates
float GetCurrentToolOffset(size_t axis) const noexcept; // Get an axis offset of the current tool
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 2682321d..d4c68bcb 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -286,7 +286,7 @@ bool GCodes::HandleGcode(GCodeBuffer& gb, const StringRef& reply)
return false;
}
- if ((reprap.GetMove().GetKinematics().AxesToHomeBeforeProbing() & ~axesHomed) != 0)
+ if (reprap.GetMove().GetKinematics().AxesToHomeBeforeProbing().Intersects(~axesHomed))
{
reply.copy("Insufficient axes homed for bed probing");
result = GCodeResult::error;
@@ -2387,12 +2387,12 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply)
break;
}
- AxesBitmap axisControls = 0;
+ AxesBitmap axisControls;
for (size_t axis = 0; axis < numTotalAxes; axis++)
{
if (gb.Seen(axisLetters[axis]) && gb.GetIValue() > 0)
{
- SetBit(axisControls, axis);
+ axisControls.SetBit(axis);
}
}
diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp
index 4b07516a..cb7ffda6 100644
--- a/src/GCodes/GCodes3.cpp
+++ b/src/GCodes/GCodes3.cpp
@@ -59,20 +59,20 @@ GCodeResult GCodes::SetPositions(GCodeBuffer& gb)
{
// Don't wait for the machine to stop if only extruder drives are being reset.
// This avoids blobs and seams when the gcode uses absolute E coordinates and periodically includes G92 E0.
- AxesBitmap axesIncluded = 0;
+ AxesBitmap axesIncluded;
for (size_t axis = 0; axis < numVisibleAxes; ++axis)
{
if (gb.Seen(axisLetters[axis]))
{
const float axisValue = gb.GetFValue();
- if (axesIncluded == 0)
+ if (axesIncluded.IsEmpty())
{
if (!LockMovementAndWaitForStandstill(gb)) // lock movement and get current coordinates
{
return GCodeResult::notFinished;
}
}
- SetBit(axesIncluded, axis);
+ axesIncluded.SetBit(axis);
currentUserPosition[axis] = gb.ConvertDistance(axisValue);
}
}
@@ -83,10 +83,10 @@ GCodeResult GCodes::SetPositions(GCodeBuffer& gb)
virtualExtruderPosition = gb.GetDistance();
}
- if (axesIncluded != 0)
+ if (axesIncluded.IsNonEmpty())
{
ToolOffsetTransform(currentUserPosition, moveBuffer.coords);
- if (reprap.GetMove().GetKinematics().LimitPosition(moveBuffer.coords, nullptr, numVisibleAxes, LowestNBits<AxesBitmap>(numVisibleAxes), false, limitAxes)
+ if (reprap.GetMove().GetKinematics().LimitPosition(moveBuffer.coords, nullptr, numVisibleAxes, AxesBitmap::MakeLowestNBits(numVisibleAxes), false, limitAxes)
!= LimitPositionResult::ok // pretend that all axes are homed
)
{
@@ -94,7 +94,7 @@ GCodeResult GCodes::SetPositions(GCodeBuffer& gb)
}
reprap.GetMove().SetNewPosition(moveBuffer.coords, true);
axesHomed |= reprap.GetMove().GetKinematics().AxesAssumedHomed(axesIncluded);
- if (IsBitSet(axesIncluded, Z_AXIS))
+ if (axesIncluded.IsBitSet(Z_AXIS))
{
zDatumSetByProbing -= false;
}
@@ -383,7 +383,7 @@ GCodeResult GCodes::SimulateFile(GCodeBuffer& gb, const StringRef &reply, const
if (simulationMode == 0)
{
axesHomedBeforeSimulation = axesHomed;
- axesHomed = LowestNBits<AxesBitmap>(numVisibleAxes); // pretend all axes are homed
+ axesHomed = AxesBitmap::MakeLowestNBits(numVisibleAxes); // pretend all axes are homed
SavePosition(simulationRestorePoint, gb);
simulationRestorePoint.feedRate = gb.MachineState().feedRate;
}
@@ -421,7 +421,7 @@ GCodeResult GCodes::ChangeSimulationMode(GCodeBuffer& gb, const StringRef &reply
{
// Starting a new simulation, so save the current position
axesHomedBeforeSimulation = axesHomed;
- axesHomed = LowestNBits<AxesBitmap>(numVisibleAxes); // pretend all axes are homed
+ axesHomed = AxesBitmap::MakeLowestNBits(numVisibleAxes); // pretend all axes are homed
SavePosition(simulationRestorePoint, gb);
}
simulationTime = 0.0;
@@ -502,7 +502,7 @@ GCodeResult GCodes::ConfigureTrigger(GCodeBuffer& gb, const StringRef& reply, in
return GCodeResult::error;
}
- tr.inputStates = 0;
+ tr.inputStates.Clear();
(void)tr.Check(); // set up initial input states
return GCodeResult::ok;
}
@@ -542,10 +542,10 @@ GCodeResult GCodes::CheckTrigger(GCodeBuffer& gb, const StringRef& reply, int co
if (triggerNumber < MaxTriggers)
{
Trigger& tr = triggers[triggerNumber];
- tr.inputStates = 0;
+ tr.inputStates.Clear();
if (tr.Check())
{
- SetBit(triggersPending, triggerNumber);
+ triggersPending.SetBit(triggerNumber);
}
return GCodeResult::ok;
}
@@ -841,7 +841,7 @@ GCodeResult GCodes::ProbeTool(GCodeBuffer& gb, const StringRef& reply)
const bool probeOk = (useProbe)
? platform.GetEndstops().EnableZProbe(probeNumberToUse)
- : platform.GetEndstops().EnableAxisEndstops(MakeBitmap<AxesBitmap>(axis), false);
+ : platform.GetEndstops().EnableAxisEndstops(AxesBitmap::MakeFromBits(axis), false);
if (!probeOk)
{
reply.copy("Failed to prime endstop or probe");
@@ -905,7 +905,7 @@ GCodeResult GCodes::FindCenterOfCavity(GCodeBuffer& gb, const StringRef& reply,
const bool probeOk = (useProbe)
? platform.GetEndstops().EnableZProbe(probeNumberToUse)
- : platform.GetEndstops().EnableAxisEndstops(MakeBitmap<AxesBitmap>(axis), false);
+ : platform.GetEndstops().EnableAxisEndstops(AxesBitmap::MakeFromBits(axis), false);
if (!probeOk)
{
reply.copy("Failed to prime endstop or probe");
diff --git a/src/GCodes/GCodes4.cpp b/src/GCodes/GCodes4.cpp
index 33761417..23a31b52 100644
--- a/src/GCodes/GCodes4.cpp
+++ b/src/GCodes/GCodes4.cpp
@@ -37,7 +37,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply)
// Check whether we made any G1 S3 moves and need to set the axis limits
for (size_t axis = 0; axis < numTotalAxes; ++axis)
{
- if (IsBitSet<AxesBitmap>(axesToSenseLength, axis))
+ if (axesToSenseLength.IsBitSet(axis))
{
const EndStopPosition stopType = platform.GetEndstops().GetEndStopPosition(axis);
if (stopType == EndStopPosition::highEndStop)
@@ -172,7 +172,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply)
break;
case GCodeState::homing1:
- if (toBeHomed == 0)
+ if (toBeHomed.IsEmpty())
{
gb.SetState(GCodeState::normal);
}
@@ -180,7 +180,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply)
{
String<StringLength20> nextHomingFileName;
AxesBitmap mustHomeFirst = reprap.GetMove().GetKinematics().GetHomingFileName(toBeHomed, axesHomed, numVisibleAxes, nextHomingFileName.GetRef());
- if (mustHomeFirst != 0)
+ if (mustHomeFirst.IsNonEmpty())
{
// Error, can't home this axes
reply.copy("Must home these axes:");
@@ -188,7 +188,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply)
reply.cat(" before homing these:");
AppendAxes(reply, toBeHomed);
error = true;
- toBeHomed = 0;
+ toBeHomed.Clear();
gb.SetState(GCodeState::normal);
}
else
@@ -208,7 +208,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply)
if (LockMovementAndWaitForStandstill(gb)) // movement should already be locked, but we need to wait for the previous homing move to complete
{
// Test whether the previous homing move homed any axes
- if ((toBeHomed & axesHomed) == 0)
+ if (!toBeHomed.Intersects(axesHomed))
{
reply.copy("Homing failed");
error = true;
@@ -217,7 +217,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply)
else
{
toBeHomed &= ~axesHomed;
- gb.SetState((toBeHomed == 0) ? GCodeState::normal : GCodeState::homing1);
+ gb.SetState((toBeHomed.IsEmpty()) ? GCodeState::normal : GCodeState::homing1);
}
}
break;
diff --git a/src/GCodes/Trigger.cpp b/src/GCodes/Trigger.cpp
index 37cbeffb..7b193655 100644
--- a/src/GCodes/Trigger.cpp
+++ b/src/GCodes/Trigger.cpp
@@ -48,16 +48,16 @@ bool Trigger::Check() noexcept
break;
}
const bool b = ports[i].Read();
- if (b != IsBitSet(inputStates, i)) // if the input level has changed
+ if (b != inputStates.IsBitSet(i)) // if the input level has changed
{
if (b)
{
- SetBit(inputStates, i);
+ inputStates.SetBit(i);
triggered = true;
}
else
{
- ClearBit(inputStates, i);
+ inputStates.ClearBit(i);
}
}
}
diff --git a/src/GCodes/Trigger.h b/src/GCodes/Trigger.h
index 2683ffac..15d4781a 100644
--- a/src/GCodes/Trigger.h
+++ b/src/GCodes/Trigger.h
@@ -11,10 +11,10 @@
#include "RepRapFirmware.h"
#include "Hardware/IoPorts.h"
-typedef uint32_t TriggerNumbersBitmap; // Bitmap of trigger numbers
-typedef uint16_t TriggerInputStatesBitmap; // Bitmap of input states
-static_assert(MaxTriggers <= sizeof(TriggerNumbersBitmap) * CHAR_BIT, "need larger TriggerNumbersBitmap type");
-static_assert(MaxPortsPerTrigger <= sizeof(TriggerInputStatesBitmap) * CHAR_BIT, "need larger TriggerInputStatesBitmap");
+typedef Bitmap<uint32_t> TriggerNumbersBitmap; // Bitmap of trigger numbers
+typedef Bitmap<uint16_t> TriggerInputStatesBitmap; // Bitmap of input states
+static_assert(MaxTriggers <= TriggerNumbersBitmap::MaxBits(), "need larger TriggerNumbersBitmap type");
+static_assert(MaxPortsPerTrigger <= TriggerInputStatesBitmap::MaxBits(), "need larger TriggerInputStatesBitmap");
struct Trigger
{