diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-02-29 19:09:44 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-02-29 19:09:44 +0300 |
commit | 6e2e7164b031c14bf05869bf24a5a41e466d474a (patch) | |
tree | 058a8aa1e92924bc6d4f2a36192159798d2beb14 | |
parent | 894b670d9a0813cc4c7866645b82f94674018c0e (diff) |
Still 3.01-RC3 provisional
Got remote BLTouch working
Bug fix: when endstops were already triggered, homing moved could hang
Bug fix: external SD card didn't work on Duet Maestro
-rw-r--r-- | .cproject | 14 | ||||
-rw-r--r-- | src/CAN/CanInterface.cpp | 10 | ||||
-rw-r--r-- | src/CAN/CanInterface.h | 2 | ||||
-rw-r--r-- | src/CAN/CommandProcessor.cpp | 9 | ||||
-rw-r--r-- | src/DuetM/Pins_DuetM.h | 2 | ||||
-rw-r--r-- | src/Endstops/EndstopsManager.cpp | 20 | ||||
-rw-r--r-- | src/Endstops/EndstopsManager.h | 6 | ||||
-rw-r--r-- | src/Endstops/LocalZProbe.cpp | 4 | ||||
-rw-r--r-- | src/Endstops/LocalZProbe.h | 4 | ||||
-rw-r--r-- | src/Endstops/RemoteZProbe.cpp | 124 | ||||
-rw-r--r-- | src/Endstops/RemoteZProbe.h | 15 | ||||
-rw-r--r-- | src/Endstops/SwitchEndstop.cpp | 2 | ||||
-rw-r--r-- | src/Endstops/ZProbe.h | 17 | ||||
-rw-r--r-- | src/GCodes/GCodeResult.h | 7 | ||||
-rw-r--r-- | src/GCodes/GCodes.cpp | 108 | ||||
-rw-r--r-- | src/GCodes/GCodes.h | 2 | ||||
-rw-r--r-- | src/GCodes/GCodes2.cpp | 6 | ||||
-rw-r--r-- | src/Movement/DDARing.cpp | 21 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/LwipEthernetInterface.cpp | 10 | ||||
-rw-r--r-- | src/RepRap.cpp | 2 | ||||
-rw-r--r-- | src/Version.h | 2 |
21 files changed, 212 insertions, 175 deletions
@@ -876,7 +876,7 @@ <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/utils/preprocessor}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/thirdparty/CMSIS/Include}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/variants/same70}""/> - <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet/Lwip}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet/Lwip/src/include}""/> </option> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.1444560974" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols"> @@ -895,7 +895,7 @@ <option id="gnu.cpp.link.option.nostdlibs.1223355552" name="No startup or default libs (-nostdlib)" superClass="gnu.cpp.link.option.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.1386648874" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths"> <listOptionValue builtIn="false" value=""${workspace_loc:/RRFLibraries/SAME70_RTOS_Debug}""/> - <listOptionValue builtIn="false" value=""${workspace_loc:/CoreNG/SAME70_RTOS_Debug}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/CoreNG/SAME70}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/FreeRTOS/SAME70_Debug}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/CANlib/SAME70_RTOS_Debug}""/> </option> @@ -939,7 +939,7 @@ <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/variants/same70}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking}""/> - <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet/Lwip}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet/Lwip/src/include}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/DuetWiFiSocketServer/src/include}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/FreeRTOS/src/include}""/> @@ -961,7 +961,7 @@ </toolChain> </folderInfo> <sourceEntries> - <entry excluding="src/Duet3_V05|src/Duet3_V03|src/Networking/ESP8266WiFi|src/SAME70xpld|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Duet|src/Networking/LwipEthernet/Lwip/src/apps/httpd|/src/Networking/LwipEthernet/Lwip/test|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Alligator|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Display|src/Pccb|/src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/DuetM|src/RADDS|src/Networking/LwipEthernet/Lwip/doc" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/> + <entry excluding="src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Duet3_V05|src/Duet3_V03|src/Networking/ESP8266WiFi|src/SAME70xpld|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Duet|src/Networking/LwipEthernet/Lwip/src/apps/httpd|/src/Networking/LwipEthernet/Lwip/test|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Alligator|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Display|src/Pccb|/src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/DuetM|src/RADDS|src/Networking/LwipEthernet/Lwip/doc" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/> </sourceEntries> </configuration> </storageModule> @@ -1057,7 +1057,7 @@ <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/sam/utils/preprocessor}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/asf/thirdparty/CMSIS/Include}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/variants/same70}""/> - <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet/Lwip}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet/Lwip/src/include}""/> </option> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.1332495733" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols"> @@ -1124,7 +1124,7 @@ <listOptionValue builtIn="false" value=""${workspace_loc:/${CoreName}/variants/same70}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking}""/> - <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet/Lwip}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/Networking/LwipEthernet/Lwip/src/include}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/DuetWiFiSocketServer/src/include}""/> <listOptionValue builtIn="false" value=""${workspace_loc:/FreeRTOS/src/include}""/> @@ -1146,7 +1146,7 @@ </toolChain> </folderInfo> <sourceEntries> - <entry excluding="src/Duet3_V05|src/Duet3_V03|src/Networking/ESP8266WiFi|src/SAME70xpld|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Duet|src/Networking/LwipEthernet/Lwip/src/apps/httpd|/src/Networking/LwipEthernet/Lwip/test|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Alligator|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Display|src/Pccb|/src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/DuetM|src/RADDS|src/Networking/LwipEthernet/Lwip/doc" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/> + <entry excluding="src/Networking/LwipEthernet/Lwip/src/apps/smtp|src/Networking/LwipEthernet/Lwip/src/apps/http|src/Networking/LwipEthernet/Lwip/src/apps/altcp_tls|src/Duet3_V05|src/Duet3_V03|src/Networking/ESP8266WiFi|src/SAME70xpld|src/Networking/LwipEthernet/Lwip/src/apps/snmp|src/Duet|src/Networking/LwipEthernet/Lwip/src/apps/httpd|/src/Networking/LwipEthernet/Lwip/test|src/DuetNG|src/Networking/LwipEthernet/Lwip/src/apps/tftp|src/Networking/W5500Ethernet|src/Alligator|src/Networking/LwipEthernet/Lwip/src/netif/ppp|src/Networking/LwipEthernet/Lwip/src/apps/lwiperf|src/Networking/LwipEthernet/Lwip/src/apps/sntp|src/Display|src/Pccb|/src/Networking/LwipEthernet/Lwip/src/apps/mqtt|src/DuetM|src/RADDS|src/Networking/LwipEthernet/Lwip/doc" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/> </sourceEntries> </configuration> </storageModule> diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp index 5a0a1e7b..4a600b13 100644 --- a/src/CAN/CanInterface.cpp +++ b/src/CAN/CanInterface.cpp @@ -983,6 +983,12 @@ GCodeResult CanInterface::CreateHandle(CanAddress boardAddress, RemoteInputHandl static GCodeResult ChangeInputMonitor(CanAddress boardAddress, RemoteInputHandle h, uint8_t action, bool* currentState, const StringRef &reply) noexcept { + if (!h.IsValid()) + { + reply.copy("Invalid remote handle"); + return GCodeResult::error; + } + CanMessageBuffer * const buf = CanMessageBuffer::Allocate(); if (buf == nullptr) { @@ -1013,9 +1019,9 @@ GCodeResult CanInterface::GetHandlePinName(CanAddress boardAddress, RemoteInputH return ChangeInputMonitor(boardAddress, h, CanMessageChangeInputMonitor::actionReturnPinName, ¤tState, reply); } -GCodeResult CanInterface::EnableHandle(CanAddress boardAddress, RemoteInputHandle h, bool ¤tState, const StringRef &reply) noexcept +GCodeResult CanInterface::EnableHandle(CanAddress boardAddress, RemoteInputHandle h, bool enable, bool ¤tState, const StringRef &reply) noexcept { - return ChangeInputMonitor(boardAddress, h, CanMessageChangeInputMonitor::actionDoMonitor, ¤tState, reply); + return ChangeInputMonitor(boardAddress, h, (enable) ? CanMessageChangeInputMonitor::actionDoMonitor : CanMessageChangeInputMonitor::actionDontMonitor, ¤tState, reply); } void CanInterface::Diagnostics(MessageType mtype) noexcept diff --git a/src/CAN/CanInterface.h b/src/CAN/CanInterface.h index 7780b8b2..d26af255 100644 --- a/src/CAN/CanInterface.h +++ b/src/CAN/CanInterface.h @@ -97,7 +97,7 @@ namespace CanInterface GCodeResult CreateHandle(CanAddress boardAddress, RemoteInputHandle h, const char *pinName, uint16_t threshold, uint16_t minInterval, bool& currentState, const StringRef& reply) noexcept; GCodeResult DeleteHandle(CanAddress boardAddress, RemoteInputHandle h, const StringRef& reply) noexcept; GCodeResult GetHandlePinName(CanAddress boardAddress, RemoteInputHandle h, bool& currentState, const StringRef& reply) noexcept; - GCodeResult EnableHandle(CanAddress boardAddress, RemoteInputHandle h, bool& currentState, const StringRef& reply) noexcept; + GCodeResult EnableHandle(CanAddress boardAddress, RemoteInputHandle h, bool enable, bool& currentState, const StringRef& reply) noexcept; // Misc functions GCodeResult WriteGpio(CanAddress boardAddress, uint8_t portNumber, float pwm, bool isServo, const GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; diff --git a/src/CAN/CommandProcessor.cpp b/src/CAN/CommandProcessor.cpp index c3e37f99..93bd9221 100644 --- a/src/CAN/CommandProcessor.cpp +++ b/src/CAN/CommandProcessor.cpp @@ -248,7 +248,12 @@ static void HandleInputStateChanged(const CanMessageInputChanged& msg, CanAddres switch (handle.u.parts.type) { case RemoteInputHandle::typeEndstop: - reprap.GetPlatform().GetEndstops().HandleRemoteInputChange(src, handle.u.parts.major, handle.u.parts.minor, state); + reprap.GetPlatform().GetEndstops().HandleRemoteEndstopChange(src, handle.u.parts.major, handle.u.parts.minor, state); + endstopStatesChanged = true; + break; + + case RemoteInputHandle::typeZprobe: + reprap.GetPlatform().GetEndstops().HandleRemoteZProbeChange(src, handle.u.parts.major, handle.u.parts.minor, state); endstopStatesChanged = true; break; @@ -263,7 +268,7 @@ static void HandleInputStateChanged(const CanMessageInputChanged& msg, CanAddres if (endstopStatesChanged) { - reprap.GetPlatform().GetEndstops().OnEndstopStatesChanged(); + reprap.GetPlatform().GetEndstops().OnEndstopOrZProbeStatesChanged(); } } diff --git a/src/DuetM/Pins_DuetM.h b/src/DuetM/Pins_DuetM.h index 9ce4f5d1..60c1d58a 100644 --- a/src/DuetM/Pins_DuetM.h +++ b/src/DuetM/Pins_DuetM.h @@ -157,7 +157,7 @@ constexpr Pin DiagPin = Z_PROBE_MOD_PIN; constexpr size_t NumSdCards = 2; constexpr Pin SdCardDetectPins[NumSdCards] = { PortCPin(8), NoPin }; constexpr Pin SdWriteProtectPins[NumSdCards] = { NoPin, NoPin }; -constexpr Pin SdSpiCSPins[1] = { PortCPin(2) }; +constexpr Pin SdSpiCSPins[1] = { PortBPin(13) }; constexpr uint32_t ExpectedSdCardSpeed = 15000000; // 12864 LCD diff --git a/src/Endstops/EndstopsManager.cpp b/src/Endstops/EndstopsManager.cpp index 9953da8b..d23fa5b3 100644 --- a/src/Endstops/EndstopsManager.cpp +++ b/src/Endstops/EndstopsManager.cpp @@ -728,8 +728,7 @@ size_t EndstopsManager::GetNumProbesToReport() const noexcept #if SUPPORT_CAN_EXPANSION // Handle signalling of a remote switch change, when the handle indicates that it is being used as an endstop. -// We must re-use or free the buffer. -void EndstopsManager::HandleRemoteInputChange(CanAddress src, uint8_t handleMajor, uint8_t handleMinor, bool state) noexcept +void EndstopsManager::HandleRemoteEndstopChange(CanAddress src, uint8_t handleMajor, uint8_t handleMinor, bool state) noexcept { if (handleMajor < ARRAY_SIZE(axisEndstops)) { @@ -741,9 +740,22 @@ void EndstopsManager::HandleRemoteInputChange(CanAddress src, uint8_t handleMajo } } +// Handle signalling of a remote switch change, when the handle indicates that it is being used as a Z probe. +void EndstopsManager::HandleRemoteZProbeChange(CanAddress src, uint8_t handleMajor, uint8_t handleMinor, bool state) noexcept +{ + if (handleMajor < ARRAY_SIZE(zProbes)) + { + ZProbe * const zp = zProbes[handleMajor]; + if (zp != nullptr) + { + zp->HandleRemoteInputChange(src, handleMinor, state); + } + } +} + // This is called when we update endstop states because of a message from a remote board. // In time we may use it to help implement interrupt-driven local endstops too, but for now those are checked in the step ISR by a direct call to DDA::CheckEndstops(). -void EndstopsManager::OnEndstopStatesChanged() noexcept +void EndstopsManager::OnEndstopOrZProbeStatesChanged() noexcept { const uint32_t oldPrio = ChangeBasePriority(NvicPriorityStep); // shut out the step interrupt @@ -758,7 +770,7 @@ void EndstopsManager::OnEndstopStatesChanged() noexcept } } - RestoreBasePriority(oldPrio); // allow step interrupts again + RestoreBasePriority(oldPrio); // allow step interrupts again } #endif diff --git a/src/Endstops/EndstopsManager.h b/src/Endstops/EndstopsManager.h index bbd453bc..b85a3042 100644 --- a/src/Endstops/EndstopsManager.h +++ b/src/Endstops/EndstopsManager.h @@ -68,9 +68,9 @@ public: GCodeResult ProgramZProbe(GCodeBuffer& gb, const StringRef& reply) THROWS_GCODE_EXCEPTION; #if SUPPORT_CAN_EXPANSION - void HandleRemoteInputChange(CanAddress src, uint8_t handleMajor, uint8_t handleMinor, bool state) noexcept; - - void OnEndstopStatesChanged() noexcept; + void HandleRemoteEndstopChange(CanAddress src, uint8_t handleMajor, uint8_t handleMinor, bool state) noexcept; + void HandleRemoteZProbeChange(CanAddress src, uint8_t handleMajor, uint8_t handleMinor, bool state) noexcept; + void OnEndstopOrZProbeStatesChanged() noexcept; #endif #if HAS_MASS_STORAGE diff --git a/src/Endstops/LocalZProbe.cpp b/src/Endstops/LocalZProbe.cpp index d4239d5b..7f027000 100644 --- a/src/Endstops/LocalZProbe.cpp +++ b/src/Endstops/LocalZProbe.cpp @@ -104,7 +104,7 @@ uint16_t LocalZProbe::GetRawReading() const noexcept } } -void LocalZProbe::SetProbing(bool isProbing) const noexcept +void LocalZProbe::SetProbing(bool isProbing) noexcept { // For Z probe types other than 1/2/3 and bltouch we set the modulation pin high at the start of a probing move and low at the end // Don't do this for bltouch because on the Maestro, the MOD pin is normally used as the servo control output @@ -114,7 +114,7 @@ void LocalZProbe::SetProbing(bool isProbing) const noexcept } } -GCodeResult LocalZProbe::AppendPinNames(const StringRef& str) const noexcept +GCodeResult LocalZProbe::AppendPinNames(const StringRef& str) noexcept { if (type != ZProbeType::zMotorStall && type != ZProbeType::none) { diff --git a/src/Endstops/LocalZProbe.h b/src/Endstops/LocalZProbe.h index 89a5bb85..190bea1a 100644 --- a/src/Endstops/LocalZProbe.h +++ b/src/Endstops/LocalZProbe.h @@ -21,8 +21,8 @@ public: ~LocalZProbe() noexcept override; void SetIREmitter(bool on) const noexcept override; uint16_t GetRawReading() const noexcept override; - void SetProbing(bool isProbing) const noexcept override; - GCodeResult AppendPinNames(const StringRef& str) const noexcept override; + void SetProbing(bool isProbing) noexcept override; + GCodeResult AppendPinNames(const StringRef& str) noexcept override; GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, bool& seen) THROWS_GCODE_EXCEPTION override; GCodeResult SendProgram(const uint32_t zProbeProgram[], size_t len, const StringRef& reply) noexcept override; diff --git a/src/Endstops/RemoteZProbe.cpp b/src/Endstops/RemoteZProbe.cpp index 864347d5..541e1464 100644 --- a/src/Endstops/RemoteZProbe.cpp +++ b/src/Endstops/RemoteZProbe.cpp @@ -14,127 +14,105 @@ #include <CAN/CanMessageGenericConstructor.h> #include <RepRap.h> #include <Platform.h> +#include <GCodes/GCodeBuffer/GCodeBuffer.h> // Members of class RemoteZProbe RemoteZProbe::~RemoteZProbe() { - CanMessageBuffer * const buf = CanMessageBuffer::Allocate(); - if (buf != nullptr) + String<StringLength100> reply; + const GCodeResult rslt = CanInterface::DeleteHandle(boardAddress, handle, reply.GetRef()); + if (rslt != GCodeResult::ok) { - const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageDestroyZProbe>(rid, CanId::MasterAddress, boardAddress); - msg->number = number; - String<StringLength100> reply; - if (CanInterface::SendRequestAndGetStandardReply(buf, rid, reply.GetRef()) != GCodeResult::ok) - { - reply.cat('\n'); - reprap.GetPlatform().Message(ErrorMessage, reply.c_str()); - } + reply.cat('\n'); + reprap.GetPlatform().Message(GetGenericMessageType(rslt), reply.c_str()); } } -GCodeResult RemoteZProbe::AppendPinNames(const StringRef& str) const noexcept +GCodeResult RemoteZProbe::AppendPinNames(const StringRef& str) noexcept { - CanMessageBuffer * const buf = CanMessageBuffer::Allocate(); - if (buf == nullptr) - { - str.cat("[not available: no CAN buffer]"); - return GCodeResult::warning; - } - - const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageGetZProbePinNames>(rid, CanId::MasterAddress, boardAddress); - msg->number = number; - String<StringLength20> pinNames; - const GCodeResult rslt = CanInterface::SendRequestAndGetStandardReply(buf, rid, pinNames.GetRef()); + String<StringLength100> reply; + const GCodeResult rslt = CanInterface::GetHandlePinName(boardAddress, handle, state, reply.GetRef()); if (rslt == GCodeResult::ok) { - str.cat(pinNames.c_str()); + str.cat(", input pin "); + str.cat(reply.c_str()); } else { - str.catf("[not available: %s]", pinNames.c_str()); + str.copy(reply.c_str()); } return rslt; } -void RemoteZProbe::SetProbing(bool isProbing) const noexcept +uint16_t RemoteZProbe::GetRawReading() const noexcept { - CanMessageBuffer * const buf = CanMessageBuffer::Allocate(); - if (buf == nullptr) - { - reprap.GetPlatform().Message(ErrorMessage, "No CAN buffer\n"); - } - else + return (state) ? 1000 : 0; +} + +void RemoteZProbe::SetProbing(bool isProbing) noexcept +{ + String<StringLength100> reply; + const GCodeResult rslt = CanInterface::EnableHandle(boardAddress, handle, isProbing, state, reply.GetRef()); + if (rslt != GCodeResult::ok) { - const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageSetProbing>(rid, CanId::MasterAddress, boardAddress); - msg->number = number; - msg->isProbing = (isProbing) ? 1 : 0; - String<StringLength100> reply; - if (CanInterface::SendRequestAndGetStandardReply(buf, rid, reply.GetRef()) != GCodeResult::ok) - { - reply.cat('\n'); - reprap.GetPlatform().Message(ErrorMessage, reply.c_str()); - } + reply.cat('\n'); + reprap.GetPlatform().Message(GetGenericMessageType(rslt), reply.c_str()); } } // Create a remote Z probe GCodeResult RemoteZProbe::Create(const StringRef& pinNames, const StringRef& reply) noexcept { - CanMessageBuffer * const buf = CanMessageBuffer::Allocate(); - if (buf == nullptr) + if (type != ZProbeType::unfilteredDigital && type != ZProbeType::blTouch) { - reply.copy("No CAN buffer"); + reply.copy("M558: only Z probe types 8 and 9 are supported on expansion boards"); return GCodeResult::error; } - const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageCreateZProbe>(rid, CanId::MasterAddress, boardAddress); - msg->probeNumber = number; - msg->probeType = (uint8_t)type; - SafeStrncpy(msg->pinNames, pinNames.c_str(), ARRAY_SIZE(msg->pinNames)); - buf->dataLength = msg->GetActualDataLength(); + if (strchr(pinNames.c_str(), '+') != nullptr) + { + reply.copy("M558: output port not supported on expansion boards"); + return GCodeResult::error; + } - return CanInterface::SendRequestAndGetStandardReply(buf, rid, reply); + handle.Set(RemoteInputHandle::typeZprobe, number, 0); + return CanInterface::CreateHandle(boardAddress, handle, pinNames.c_str(), 0, MinimumProbeReportInterval, state, reply); } // Configure an existing remote Z probe GCodeResult RemoteZProbe::Configure(GCodeBuffer& gb, const StringRef &reply, bool& seen) { - GCodeResult rslt = ZProbe::Configure(gb, reply, seen); - if (seen && rslt == GCodeResult::ok) + if (gb.Seen('P')) { - CanMessageBuffer * const buf = CanMessageBuffer::Allocate(); - if (buf == nullptr) + seen = true; + const uint32_t newType = gb.GetUIValue(); + if (newType != (uint32_t)ZProbeType::unfilteredDigital && newType != (uint32_t)ZProbeType::blTouch) { - reply.copy("No CAN buffer"); - rslt = GCodeResult::error; - } - else - { - const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageConfigureZProbe>(rid, CanId::MasterAddress, boardAddress); - - msg->number = number; - msg->type = (uint8_t)type; - msg->adcValue = adcValue; - msg->invertReading_obsolete = false; - - rslt = CanInterface::SendRequestAndGetStandardReply(buf, rid, reply); + reply.copy("M558: only Z probe types 8 and 9 are supported on expansion boards"); + return GCodeResult::error; } + type = (ZProbeType)newType; } - return rslt; + + // No other configuration items affect remote probes differently from others, so just call the base class function + return ZProbe::Configure(gb, reply, seen); } GCodeResult RemoteZProbe::SendProgram(const uint32_t zProbeProgram[], size_t len, const StringRef& reply) noexcept { //TODO - reply.copy("Programming remote Z probes not yet supported"); + reply.copy("Programming remote Z probes not supported"); return GCodeResult::error; } +void RemoteZProbe::HandleRemoteInputChange(CanAddress src, uint8_t handleMinor, bool newState) noexcept +{ + if (src == boardAddress) + { + state = newState; + } +} + #endif // End diff --git a/src/Endstops/RemoteZProbe.h b/src/Endstops/RemoteZProbe.h index d35c68cd..2bb4bb36 100644 --- a/src/Endstops/RemoteZProbe.h +++ b/src/Endstops/RemoteZProbe.h @@ -12,25 +12,32 @@ #if SUPPORT_CAN_EXPANSION +#include <RemoteInputHandle.h> + class RemoteZProbe final : public ZProbe { public: void* operator new(size_t sz) noexcept { return FreelistManager::Allocate<RemoteZProbe>(); } void operator delete(void* p) noexcept { FreelistManager::Release<RemoteZProbe>(p); } - RemoteZProbe(unsigned int num, CanAddress bn, ZProbeType p_type) noexcept : ZProbe(num, p_type), boardAddress(bn) { } + RemoteZProbe(unsigned int num, CanAddress bn, ZProbeType p_type) noexcept : ZProbe(num, p_type), boardAddress(bn), state(false) { } ~RemoteZProbe() noexcept override; void SetIREmitter(bool on) const noexcept override { } - uint16_t GetRawReading() const noexcept override { return 0; } - void SetProbing(bool isProbing) const noexcept override; - GCodeResult AppendPinNames(const StringRef& str) const noexcept override; + uint16_t GetRawReading() const noexcept override; + void SetProbing(bool isProbing) noexcept override; + GCodeResult AppendPinNames(const StringRef& str) noexcept override; GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, bool& seen) THROWS_GCODE_EXCEPTION override; GCodeResult SendProgram(const uint32_t zProbeProgram[], size_t len, const StringRef& reply) noexcept override; + void HandleRemoteInputChange(CanAddress src, uint8_t handleMinor, bool newState) noexcept override; GCodeResult Create(const StringRef& pinNames, const StringRef& reply) noexcept; private: CanAddress boardAddress; + RemoteInputHandle handle; + bool state; + + static constexpr uint16_t MinimumProbeReportInterval = 5; }; #endif diff --git a/src/Endstops/SwitchEndstop.cpp b/src/Endstops/SwitchEndstop.cpp index fa4a903a..43f58b6d 100644 --- a/src/Endstops/SwitchEndstop.cpp +++ b/src/Endstops/SwitchEndstop.cpp @@ -145,7 +145,7 @@ bool SwitchEndstop::Prime(const Kinematics& kin, const AxisDriversConfig& axisDr { RemoteInputHandle h(RemoteInputHandle::typeEndstop, GetAxis(), i); String<StringLength100> reply; - if (CanInterface::EnableHandle(boardNumbers[i], h, states[i], reply.GetRef()) != GCodeResult::ok) + if (CanInterface::EnableHandle(boardNumbers[i], h, true, states[i], reply.GetRef()) != GCodeResult::ok) { reply.cat('\n'); reprap.GetPlatform().Message(ErrorMessage, reply.c_str()); diff --git a/src/Endstops/ZProbe.h b/src/Endstops/ZProbe.h index bbc129bc..9d43476e 100644 --- a/src/Endstops/ZProbe.h +++ b/src/Endstops/ZProbe.h @@ -18,11 +18,16 @@ public: virtual void SetIREmitter(bool on) const noexcept = 0; // Caution, this is called from within the tick ISR virtual uint16_t GetRawReading() const noexcept = 0; - virtual void SetProbing(bool isProbing) const noexcept = 0; - virtual GCodeResult AppendPinNames(const StringRef& str) const noexcept = 0; + virtual void SetProbing(bool isProbing) noexcept = 0; + virtual GCodeResult AppendPinNames(const StringRef& str) noexcept = 0; // not const because it may update the state too virtual GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, bool& seen) THROWS_GCODE_EXCEPTION; // 'seen' is an in-out parameter virtual GCodeResult SendProgram(const uint32_t zProbeProgram[], size_t len, const StringRef& reply) noexcept; +#if SUPPORT_CAN_EXPANSION + // Process a remote input change that relates to this Z probe + virtual void HandleRemoteInputChange(CanAddress src, uint8_t handleMinor, bool newState) noexcept { } +#endif + EndStopHit Stopped() const noexcept override; EndstopHitDetails CheckTriggered(bool goingSlow) noexcept override; bool Acknowledge(EndstopHitDetails what) noexcept override; @@ -101,8 +106,8 @@ public: ~MotorStallZProbe() noexcept override { } void SetIREmitter(bool on) const noexcept override { } uint16_t GetRawReading() const noexcept override { return 4000; } - void SetProbing(bool isProbing) const noexcept override { } - GCodeResult AppendPinNames(const StringRef& str) const noexcept override { return GCodeResult::ok; } + void SetProbing(bool isProbing) noexcept override { } + GCodeResult AppendPinNames(const StringRef& str) noexcept override { return GCodeResult::ok; } private: }; @@ -118,8 +123,8 @@ public: ~DummyZProbe() noexcept override { } void SetIREmitter(bool on) const noexcept override { } uint16_t GetRawReading() const noexcept override { return 4000; } - void SetProbing(bool isProbing) const noexcept override { } - GCodeResult AppendPinNames(const StringRef& str) const noexcept override { return GCodeResult::ok; } + void SetProbing(bool isProbing) noexcept override { } + GCodeResult AppendPinNames(const StringRef& str) noexcept override { return GCodeResult::ok; } private: }; diff --git a/src/GCodes/GCodeResult.h b/src/GCodes/GCodeResult.h index f67b9dea..b0b3afd5 100644 --- a/src/GCodes/GCodeResult.h +++ b/src/GCodes/GCodeResult.h @@ -9,6 +9,7 @@ #define SRC_GCODES_GCODERESULT_H_ #include <cctype> +#include <MessageType.h> // Enumeration to specify the result of attempting to process a GCode command enum class GCodeResult : uint8_t @@ -36,4 +37,10 @@ inline GCodeResult GetGCodeResultFromFinished(bool finished) noexcept return (finished) ? GCodeResult::ok : GCodeResult::notFinished; } +// Convert an error or warning result into a suitable generic message type. Should only be called with GCodeResult::warning or GCodeResult::error. +inline MessageType GetGenericMessageType(GCodeResult rslt) +{ + return (rslt == GCodeResult::warning) ? WarningMessage : ErrorMessage; +} + #endif /* SRC_GCODES_GCODERESULT_H_ */ diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp index 5b723d75..cce22ee9 100644 --- a/src/GCodes/GCodes.cpp +++ b/src/GCodes/GCodes.cpp @@ -490,7 +490,12 @@ void GCodes::StartNextGCode(GCodeBuffer& gb, const StringRef& reply) noexcept else if (&gb == daemonGCode) { // Delay 1 second, then try to open and run daemon.g. No error if it is not found. - if (!reprap.IsProcessingConfig() && gb.DoDwellTime(1000)) + if ( !reprap.IsProcessingConfig() +#if HAS_LINUX_INTERFACE + && !reprap.UsingLinuxInterface() // DSF gets confused by the daemon, so disable it for now +#endif + && gb.DoDwellTime(1000) + ) { DoFileMacro(gb, DAEMON_G, false, -1); } @@ -1670,9 +1675,12 @@ bool GCodes::CheckEnoughAxesHomed(AxesBitmap axesMoved) noexcept return (reprap.GetMove().GetKinematics().MustBeHomedAxes(axesMoved, noMovesBeforeHoming) & ~axesHomed).IsNonEmpty(); } -// Execute a straight move returning an error message if the command was rejected, else nullptr +// Execute a straight move +// If not ready, return false +// If we can't execute the move, return true with 'err' set to the error message +// Else return true with 'err' left alone (it is set to nullptr on entry) // We have already acquired the movement lock and waited for the previous move to be taken. -const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) +bool GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated, const char *& err) { if (moveFractionToSkip > 0.0) { @@ -1701,6 +1709,10 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) const int ival = gb.GetIValue(); if (ival >= 1 && ival <= 3) { + if (!LockMovementAndWaitForStandstill(gb)) + { + return false; + } moveBuffer.moveType = ival; moveBuffer.tool = nullptr; } @@ -1721,7 +1733,8 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) } else { - return "G0/G1: bad restore point number"; + err = "G0/G1: bad restore point number"; + return true; } } @@ -1791,7 +1804,8 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) // If it is a special move on a delta, movement must be relative. if (moveBuffer.moveType != 0 && !gb.MachineState().axesRelative && reprap.GetMove().GetKinematics().GetKinematicsType() == KinematicsType::linearDelta) { - return "G0/G1: attempt to move individual motors of a delta machine to absolute positions"; + err = "G0/G1: attempt to move individual motors of a delta machine to absolute positions"; + return true; } axesMentioned.SetBit(axis); @@ -1840,23 +1854,19 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) case 0: if (!doingManualBedProbe && CheckEnoughAxesHomed(axesMentioned)) { - return "G0/G1: insufficient axes homed"; - } - break; - - case 1: - if (!platform.GetEndstops().EnableAxisEndstops(axesMentioned & AxesBitmap::MakeLowestNBits(numTotalAxes), true)) - { - return "Failed to enable endstops"; + err = "G0/G1: insufficient axes homed"; + return true; } - moveBuffer.checkEndstops = true; break; case 3: axesToSenseLength = axesMentioned & AxesBitmap::MakeLowestNBits(numTotalAxes); - if (!platform.GetEndstops().EnableAxisEndstops(axesMentioned & AxesBitmap::MakeLowestNBits(numTotalAxes), false)) + // no break + case 1: + if (!platform.GetEndstops().EnableAxisEndstops(axesMentioned & AxesBitmap::MakeLowestNBits(numTotalAxes), moveBuffer.moveType == 1)) { - return "Failed to enable endstops"; + err = "Failed to enable endstops"; + return true; } moveBuffer.checkEndstops = true; break; @@ -1895,47 +1905,46 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) effectiveAxesHomed.ClearBit(Z_AXIS); // if doing a manual Z probe, don't limit the Z movement } - if (moveBuffer.moveType == 0) + const LimitPositionResult lp = reprap.GetMove().GetKinematics().LimitPosition(moveBuffer.coords, moveBuffer.initialCoords, numVisibleAxes, effectiveAxesHomed, moveBuffer.isCoordinated, limitAxes); + switch (lp) { - const LimitPositionResult lp = reprap.GetMove().GetKinematics().LimitPosition(moveBuffer.coords, moveBuffer.initialCoords, numVisibleAxes, effectiveAxesHomed, moveBuffer.isCoordinated, limitAxes); - switch (lp) + case LimitPositionResult::adjusted: + case LimitPositionResult::adjustedAndIntermediateUnreachable: + if (machineType != MachineType::fff) { - case LimitPositionResult::adjusted: - case LimitPositionResult::adjustedAndIntermediateUnreachable: - if (machineType != MachineType::fff) - { - return "G0/G1: target position outside machine limits"; // it's a laser or CNC so this is a definite error - } - ToolOffsetInverseTransform(moveBuffer.coords, currentUserPosition); // make sure the limits are reflected in the user position - if (lp == LimitPositionResult::adjusted) - { - break; // we can reach the intermediate positions, so nothing more to do - } - // no break + err = "G0/G1: target position outside machine limits"; // it's a laser or CNC so this is a definite error + return true; + } + ToolOffsetInverseTransform(moveBuffer.coords, currentUserPosition); // make sure the limits are reflected in the user position + if (lp == LimitPositionResult::adjusted) + { + break; // we can reach the intermediate positions, so nothing more to do + } + // no break - case LimitPositionResult::intermediateUnreachable: - if ( moveBuffer.isCoordinated - && ( (machineType == MachineType::fff && !moveBuffer.hasExtrusion) + case LimitPositionResult::intermediateUnreachable: + if ( moveBuffer.isCoordinated + && ( (machineType == MachineType::fff && !moveBuffer.hasExtrusion) #if SUPPORT_LASER || SUPPORT_IOBITS - || (machineType == MachineType::laser && moveBuffer.laserPwmOrIoBits.laserPwm == 0) + || (machineType == MachineType::laser && moveBuffer.laserPwmOrIoBits.laserPwm == 0) #endif - ) ) + ) + { + // It's a coordinated travel move on a 3D printer or laser cutter, so see whether an uncoordinated move will work + const LimitPositionResult lp2 = reprap.GetMove().GetKinematics().LimitPosition(moveBuffer.coords, moveBuffer.initialCoords, numVisibleAxes, effectiveAxesHomed, false, limitAxes); + if (lp2 == LimitPositionResult::ok) { - // It's a coordinated travel move on a 3D printer or laser cutter, so see whether an uncoordinated move will work - const LimitPositionResult lp2 = reprap.GetMove().GetKinematics().LimitPosition(moveBuffer.coords, moveBuffer.initialCoords, numVisibleAxes, effectiveAxesHomed, false, limitAxes); - if (lp2 == LimitPositionResult::ok) - { - moveBuffer.isCoordinated = false; // change it to an uncoordinated move - break; - } + moveBuffer.isCoordinated = false; // change it to an uncoordinated move + break; } - return "G0/G1: target position not reachable from current position"; // we can't bring the move within limits, so this is a definite error - - case LimitPositionResult::ok: - default: - break; } + err = "G0/G1: target position not reachable from current position"; // we can't bring the move within limits, so this is a definite error + return true; + + case LimitPositionResult::ok: + default: + break; } // If we are emulating Marlin for nanoDLP then we need to set a special end state @@ -1978,7 +1987,8 @@ const char* GCodes::DoStraightMove(GCodeBuffer& gb, bool isCoordinated) doingArcMove = false; FinaliseMove(gb); UnlockAll(gb); // allow pause - return nullptr; + err = nullptr; + return true; } // Execute an arc move, returning true if it was badly-formed diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h index 71016e80..b4d25824 100644 --- a/src/GCodes/GCodes.h +++ b/src/GCodes/GCodes.h @@ -307,7 +307,7 @@ private: void HandleReply(GCodeBuffer& gb, OutputBuffer *reply) noexcept; - const char* DoStraightMove(GCodeBuffer& gb, bool isCoordinated) __attribute__((hot)); // Execute a straight move returning any error message + bool DoStraightMove(GCodeBuffer& gb, bool isCoordinated, const char *& err) __attribute__((hot)); // Execute a straight move const char* DoArcMove(GCodeBuffer& gb, bool clockwise) // Execute an arc move returning any error message pre(segmentsLeft == 0; resourceOwners[MoveResource] == &gb); void FinaliseMove(GCodeBuffer& gb) noexcept; // Adjust the move parameters to account for segmentation and/or part of the move having been done already diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index cb79b9be..3c67ac06 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -133,7 +133,11 @@ bool GCodes::HandleGcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx return false; } { - const char* err = DoStraightMove(gb, code == 1); + const char* err = nullptr; + if (!DoStraightMove(gb, code == 1, err)) + { + return false; + } if (err != nullptr) { AbortPrint(gb); diff --git a/src/Movement/DDARing.cpp b/src/Movement/DDARing.cpp index 292a4526..425c2c74 100644 --- a/src/Movement/DDARing.cpp +++ b/src/Movement/DDARing.cpp @@ -208,15 +208,15 @@ void DDARing::Spin(uint8_t simulationMode, bool shouldStartMove) noexcept if (dda->GetState() == DDA::provisional) { PrepareMoves(dda, 0, 0, simulationMode); - while (dda->GetState() == DDA::completed) - { - // We prepared the move but found there was nothing to do because endstops are already triggered - getPointer = dda = dda->GetNext(); - completedMoves++; - } } - if (dda->GetState() == DDA::frozen) + if (dda->GetState() == DDA::completed) + { + // We prepared the move but found there was nothing to do because endstops are already triggered + getPointer = dda = dda->GetNext(); + completedMoves++; + } + else if (dda->GetState() == DDA::frozen) { if (simulationMode != 0) { @@ -764,8 +764,11 @@ bool DDARing::LowPowerOrStallPause(RestorePoint& rp) noexcept void DDARing::Diagnostics(MessageType mtype, const char *prefix) noexcept { - reprap.GetPlatform().MessageF(mtype, "=== %sDDARing ===\nScheduled moves: %" PRIu32 ", completed moves: %" PRIu32 ", StepErrors: %u, LaErrors: %u, Underruns: %u, %u\n", - prefix, scheduledMoves, completedMoves, stepErrors, numLookaheadErrors, numLookaheadUnderruns, numPrepareUnderruns); + const DDA * const cdda = currentDda; + reprap.GetPlatform().MessageF(mtype, + "=== %sDDARing ===\nScheduled moves: %" PRIu32 ", completed moves: %" PRIu32 ", StepErrors: %u, LaErrors: %u, Underruns: %u, %u CDDA state: %d\n", + prefix, scheduledMoves, completedMoves, stepErrors, numLookaheadErrors, numLookaheadUnderruns, numPrepareUnderruns, + (cdda == nullptr) ? -1 : (int)cdda->GetState()); stepErrors = numLookaheadUnderruns = numPrepareUnderruns = numLookaheadErrors = 0; } diff --git a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp index 819560ca..662d46a7 100644 --- a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp +++ b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp @@ -390,7 +390,7 @@ void LwipEthernetInterface::Spin() noexcept { // IP address is all zeros, so use DHCP state = NetworkState::obtainingIP; -// debugPrintf("Link established, getting IP address\n"); +// debugPrintf("Link established, getting IP address\n"); IPAddress nullAddress; ethernet_set_configuration(nullAddress, nullAddress, nullAddress); dhcp_start(&gs_net_if); @@ -399,7 +399,7 @@ void LwipEthernetInterface::Spin() noexcept { // Using static IP address state = NetworkState::connected; -// debugPrintf("Link established, network running\n"); +// debugPrintf("Link established, network running\n"); ethernet_set_configuration(platform.GetIPAddress(), platform.NetMask(), platform.GateWay()); } } @@ -417,12 +417,12 @@ void LwipEthernetInterface::Spin() noexcept { // Notify the mDNS responder about this state = NetworkState::connected; -// debugPrintf("IP address obtained, network running\n"); +// debugPrintf("IP address obtained, network running\n"); } } else { -// debugPrintf("Lost phy link\n"); +// debugPrintf("Lost phy link\n"); TerminateSockets(); state = NetworkState::establishingLink; } @@ -461,7 +461,7 @@ void LwipEthernetInterface::Spin() noexcept } else { -// debugPrintf("Lost phy link\n"); +// debugPrintf("Lost phy link\n"); TerminateSockets(); state = NetworkState::establishingLink; } diff --git a/src/RepRap.cpp b/src/RepRap.cpp index 95df79e4..55b685ae 100644 --- a/src/RepRap.cpp +++ b/src/RepRap.cpp @@ -914,7 +914,7 @@ ReadLockedPointer<Tool> RepRap::GetTool(int toolNumber) const noexcept { ReadLocker lock(toolListLock); Tool* tool = toolList; - while(tool != nullptr) + while (tool != nullptr) { if (tool->Number() == toolNumber) { diff --git a/src/Version.h b/src/Version.h index 6a4d88d6..c92fec4c 100644 --- a/src/Version.h +++ b/src/Version.h @@ -19,7 +19,7 @@ #endif #ifndef DATE -# define DATE "2020-02-27b1" +# define DATE "2020-02-29b3" #endif #define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman, printm3d" |