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:
authorChristian Hammacher <bmasterc@gmail.com>2021-07-29 20:04:19 +0300
committerChristian Hammacher <bmasterc@gmail.com>2021-07-29 20:04:19 +0300
commitd7fd1866ffbfbb87229fa89ae2c7add48307cd8a (patch)
tree571bd76255c3083a50bf198c0871b06bf629c328 /src/GCodes
parent448c585f89bb48fcb1b1e728001a0b2f4ca32197 (diff)
Further improvements
Added support for expression lists (untested in standalone mode) M23/M32 are invoked again by DSF in SBC mode Increased SBC task priority Bug fix: CAN diagnostics output extra NL Bug fix: M999 P"ERASE" was not working on the Mini5+ series
Diffstat (limited to 'src/GCodes')
-rw-r--r--src/GCodes/GCodeBuffer/BinaryParser.cpp121
-rw-r--r--src/GCodes/GCodeBuffer/BinaryParser.h2
-rw-r--r--src/GCodes/GCodeBuffer/ExpressionParser.cpp6
-rw-r--r--src/GCodes/GCodeBuffer/ExpressionParser.h2
-rw-r--r--src/GCodes/GCodeBuffer/StringParser.cpp8
-rw-r--r--src/GCodes/GCodes.cpp12
-rw-r--r--src/GCodes/GCodes2.cpp14
-rw-r--r--src/GCodes/GCodes3.cpp8
8 files changed, 128 insertions, 45 deletions
diff --git a/src/GCodes/GCodeBuffer/BinaryParser.cpp b/src/GCodes/GCodeBuffer/BinaryParser.cpp
index 78145ef1..de4b7b02 100644
--- a/src/GCodes/GCodeBuffer/BinaryParser.cpp
+++ b/src/GCodes/GCodeBuffer/BinaryParser.cpp
@@ -457,17 +457,17 @@ void BinaryParser::GetPossiblyQuotedString(const StringRef& str, bool allowEmpty
void BinaryParser::GetFloatArray(float arr[], size_t& length, bool doPad) THROWS(GCodeException)
{
- GetArray(arr, length, doPad);
+ GetArray(arr, length, doPad, DataType::Float);
}
void BinaryParser::GetIntArray(int32_t arr[], size_t& length, bool doPad) THROWS(GCodeException)
{
- GetArray(arr, length, doPad);
+ GetArray(arr, length, doPad, DataType::Int);
}
void BinaryParser::GetUnsignedArray(uint32_t arr[], size_t& length, bool doPad) THROWS(GCodeException)
{
- GetArray(arr, length, doPad);
+ GetArray(arr, length, doPad, DataType::UInt);
}
// Get a :-separated list of drivers after a key letter
@@ -498,6 +498,17 @@ void BinaryParser::GetDriverIdArray(DriverId arr[], size_t& length) THROWS(GCode
length = seenParameter->intValue;
break;
+ case DataType::Expression:
+ {
+ float temp[seenParameter->intValue];
+ GetArray(temp, length, false, DataType::Float);
+ for (int i = 0; i < seenParameter->intValue; i++)
+ {
+ SetDriverIdFromBinary(arr[i], temp[i]);
+ }
+ break;
+ }
+
default:
length = 0;
return;
@@ -562,7 +573,7 @@ void BinaryParser::AppendFullCommand(const StringRef &s) const noexcept
}
}
-template<typename T> void BinaryParser::GetArray(T arr[], size_t& length, bool doPad) THROWS(GCodeException)
+template<typename T> void BinaryParser::GetArray(T arr[], size_t& length, bool doPad, DataType type) THROWS(GCodeException)
{
if (seenParameter == nullptr)
{
@@ -617,34 +628,104 @@ template<typename T> void BinaryParser::GetArray(T arr[], size_t& length, bool d
break;
case DataType::Expression:
- //TODO need a way to pass multi-element array-valued expressions. For now we support only single-element expressions.
+ {
+ const char *pos = seenParameterValue, *endPos = seenParameterValue + seenParameter->intValue;
+
+ // Check if the whole expression is encapsulated in curly braces and remove them if necessary
+ if (*pos == '{' && pos != endPos)
{
- ExpressionParser parser(gb, seenParameterValue, seenParameterValue + seenParameter->intValue, -1);
- const ExpressionValue val = parser.Parse();
- switch ((TypeCode)val.type)
+ bool isEncapsulated = true, inQuotes = false;
+ size_t numBraces = 1;
+ for (const char *str = pos + 1; str < endPos; str++)
+ {
+ if (inQuotes)
+ {
+ inQuotes = (*str != '"');
+ }
+ else if (*str == '"')
+ {
+ inQuotes = true;
+ }
+ else if (*str == '{')
+ {
+ numBraces++;
+ }
+ else if (*str == '}')
+ {
+ numBraces--;
+ if (numBraces == 0)
+ {
+ const char *curPos = str;
+ while (str != endPos && strchr("\t ", *++str) != nullptr) { }
+ if (str == endPos)
+ {
+ endPos = curPos + 1;
+ }
+ else
+ {
+ isEncapsulated = false;
+ }
+ break;
+ }
+ }
+ }
+
+ if (isEncapsulated)
{
- case TypeCode::Int32:
- arr[0] = (T)val.iVal;
- lastIndex = 0;
+ pos++;
+ endPos--;
+ }
+ }
+
+ // Read array expression
+ for (;;)
+ {
+ if (lastIndex >= (int)length)
+ {
+ throw ConstructParseException("array too long, max length = %u", (uint32_t)length);
+ }
+
+ // Read the next expression value
+ ExpressionParser parser(gb, pos, endPos, -1);
+ switch (type)
+ {
+ case DataType::Int:
+ arr[++lastIndex] = (T)parser.ParseInteger();
break;
- case TypeCode::Float:
- arr[0] = (T)val.fVal;
- lastIndex = 0;
+ case DataType::UInt:
+ arr[++lastIndex] = (T)parser.ParseUnsigned();
break;
- case TypeCode::Uint32:
- case TypeCode::DriverId:
- arr[0] = (T)val.uVal;
- lastIndex = 0;
+ case DataType::Float:
+ arr[++lastIndex] = (T)parser.ParseFloat();
break;
default:
- throw ConstructParseException("invalid expression type");
+ throw ConstructParseException("Unsupported array data type");
+ }
+ parser.CheckForExtraCharacters(true);
+ pos = parser.GetEndptr();
+
+ if (pos++ >= endPos)
+ {
+ break;
+ }
+ }
+
+ if (doPad && lastIndex == 0)
+ {
+ for (size_t i = 1; i < length; i++)
+ {
+ arr[i] = arr[0];
}
- parser.CheckForExtraCharacters();
+ }
+ else
+ {
+ length = lastIndex + 1;
}
break;
+ }
default:
length = 0;
diff --git a/src/GCodes/GCodeBuffer/BinaryParser.h b/src/GCodes/GCodeBuffer/BinaryParser.h
index 5a4bcc38..3495d9c8 100644
--- a/src/GCodes/GCodeBuffer/BinaryParser.h
+++ b/src/GCodes/GCodeBuffer/BinaryParser.h
@@ -72,7 +72,7 @@ private:
GCodeException ConstructParseException(const char *str, uint32_t param) const noexcept;
size_t AddPadding(size_t bytesRead) const noexcept { return (bytesRead + 3u) & (~3u); }
- template<typename T> void GetArray(T arr[], size_t& length, bool doPad) THROWS(GCodeException) SPEED_CRITICAL;
+ template<typename T> void GetArray(T arr[], size_t& length, bool doPad, DataType type) THROWS(GCodeException) SPEED_CRITICAL;
void WriteParameters(const StringRef& s, bool quoteStrings) const noexcept;
size_t bufferLength;
diff --git a/src/GCodes/GCodeBuffer/ExpressionParser.cpp b/src/GCodes/GCodeBuffer/ExpressionParser.cpp
index 133ed763..0e3ac432 100644
--- a/src/GCodes/GCodeBuffer/ExpressionParser.cpp
+++ b/src/GCodes/GCodeBuffer/ExpressionParser.cpp
@@ -713,10 +713,12 @@ void ExpressionParser::SkipWhiteSpace() noexcept
}
}
-void ExpressionParser::CheckForExtraCharacters() THROWS(GCodeException)
+void ExpressionParser::CheckForExtraCharacters(bool isArrayExpression) THROWS(GCodeException)
{
SkipWhiteSpace();
- if (CurrentCharacter() != 0)
+
+ char c = CurrentCharacter();
+ if (c != 0 && (!isArrayExpression || (c != EXPRESSION_LIST_SEPARATOR && c != LIST_SEPARATOR)))
{
ThrowParseException("Unexpected characters after expression");
}
diff --git a/src/GCodes/GCodeBuffer/ExpressionParser.h b/src/GCodes/GCodeBuffer/ExpressionParser.h
index fc8dc1b3..bfd4de4e 100644
--- a/src/GCodes/GCodeBuffer/ExpressionParser.h
+++ b/src/GCodes/GCodeBuffer/ExpressionParser.h
@@ -26,7 +26,7 @@ public:
uint32_t ParseUnsigned() THROWS(GCodeException);
void SkipWhiteSpace() noexcept;
- void CheckForExtraCharacters() THROWS(GCodeException);
+ void CheckForExtraCharacters(bool isArrayExpression = false) THROWS(GCodeException);
const char *GetEndptr() const noexcept { return currentp; }
private:
diff --git a/src/GCodes/GCodeBuffer/StringParser.cpp b/src/GCodes/GCodeBuffer/StringParser.cpp
index 691be0ac..9247c577 100644
--- a/src/GCodes/GCodeBuffer/StringParser.cpp
+++ b/src/GCodes/GCodeBuffer/StringParser.cpp
@@ -1086,7 +1086,7 @@ void StringParser::GetFloatArray(float arr[], size_t& returnedLength, bool doPad
{
CheckArrayLength(length, returnedLength);
arr[length++] = ReadFloatValue();
- if (gb.buffer[readPointer] != LIST_SEPARATOR)
+ if (gb.buffer[readPointer] != EXPRESSION_LIST_SEPARATOR && gb.buffer[readPointer] != LIST_SEPARATOR)
{
break;
}
@@ -1123,7 +1123,7 @@ void StringParser::GetIntArray(int32_t arr[], size_t& returnedLength, bool doPad
CheckArrayLength(length, returnedLength);
arr[length] = ReadIValue();
length++;
- if (gb.buffer[readPointer] != LIST_SEPARATOR)
+ if (gb.buffer[readPointer] != EXPRESSION_LIST_SEPARATOR && gb.buffer[readPointer] != LIST_SEPARATOR)
{
break;
}
@@ -1159,7 +1159,7 @@ void StringParser::GetUnsignedArray(uint32_t arr[], size_t& returnedLength, bool
CheckArrayLength(length, returnedLength);
arr[length] = ReadUIValue();
length++;
- if (gb.buffer[readPointer] != LIST_SEPARATOR)
+ if (gb.buffer[readPointer] != EXPRESSION_LIST_SEPARATOR && gb.buffer[readPointer] != LIST_SEPARATOR)
{
break;
}
@@ -1196,7 +1196,7 @@ void StringParser::GetDriverIdArray(DriverId arr[], size_t& returnedLength) THRO
CheckArrayLength(length, returnedLength);
arr[length] = ReadDriverIdValue();
length++;
- if (gb.buffer[readPointer] != LIST_SEPARATOR)
+ if (gb.buffer[readPointer] != EXPRESSION_LIST_SEPARATOR && gb.buffer[readPointer] != LIST_SEPARATOR)
{
break;
}
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index 1a932bd0..9c716f3b 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -478,16 +478,10 @@ void GCodes::Spin() noexcept
#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+ // Need to check if the print has been stopped by the SBC
+ if (reprap.UsingLinuxInterface() && reprap.GetLinuxInterface().HasPrintStopped())
{
- if (reprap.GetLinuxInterface().HasPrintStarted())
- {
- StartPrinting(true);
- }
- else if (reprap.GetLinuxInterface().HasPrintStopped())
- {
- StopPrint(reprap.GetLinuxInterface().GetPrintStopReason());
- }
+ StopPrint(reprap.GetLinuxInterface().GetPrintStopReason());
}
#endif
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 894630b0..d5dc4af4 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -831,7 +831,9 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
result = MassStorage::Unmount(card, reply);
}
break;
+#endif
+#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
case 23: // Set file to print
case 32: // Select file and start SD print
// We now allow a file that is being printed to chain to another file. This is required for the resume-after-power-fail functionality.
@@ -849,7 +851,17 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
{
String<MaxFilenameLength> filename;
gb.GetUnprecedentedString(filename.GetRef());
- if (QueueFileToPrint(filename.c_str(), reply))
+ if (
+#if HAS_LINUX_INTERFACE
+ reprap.UsingLinuxInterface()
+# if HAS_MASS_STORAGE
+ ||
+# endif
+#endif
+#if HAS_MASS_STORAGE
+ QueueFileToPrint(filename.c_str(), reply)
+#endif
+ )
{
reprap.GetPrintMonitor().StartingPrint(filename.c_str());
if (gb.LatestMachineState().compatibility == Compatibility::Marlin)
diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp
index 3f991bf0..5bed126e 100644
--- a/src/GCodes/GCodes3.cpp
+++ b/src/GCodes/GCodes3.cpp
@@ -432,13 +432,7 @@ GCodeResult GCodes::SimulateFile(GCodeBuffer& gb, const StringRef &reply, const
simulationMode = 1;
reprap.GetMove().Simulate(simulationMode);
reprap.GetPrintMonitor().StartingPrint(file.c_str());
-# if HAS_LINUX_INTERFACE
- if (!reprap.UsingLinuxInterface())
-# endif
- {
- // If using a SBC, this is already called when the print file info is set
- StartPrinting(true);
- }
+ StartPrinting(true);
reply.printf("Simulating print of file %s", file.c_str());
return GCodeResult::ok;
}