diff options
author | David Crocker <dcrocker@eschertech.com> | 2022-07-13 11:15:50 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2022-07-13 11:15:50 +0300 |
commit | 15e3851a9a308e4835312d0e7d241b28399197e1 (patch) | |
tree | 47d8f71de0dd6cf7d0be1aa5d07a84856a1f2f3f | |
parent | c69e90b589298f13aa7b7064749a6be8f5fc962d (diff) | |
parent | 4722b3af90f5c29fba30a493d84aadbca735c5b9 (diff) |
Merge branch '3.4-dev' into 3.4-spi-tft
-rw-r--r-- | src/CAN/CanInterface.cpp | 114 | ||||
-rw-r--r-- | src/CAN/CanInterface.h | 3 | ||||
-rw-r--r-- | src/CAN/CanMessageGenericConstructor.cpp | 13 | ||||
-rw-r--r-- | src/CAN/CanMessageGenericConstructor.h | 1 | ||||
-rw-r--r-- | src/CAN/CommandProcessor.cpp | 2 | ||||
-rw-r--r-- | src/Config/Configuration.h | 3 | ||||
-rw-r--r-- | src/Config/Pins_Duet3_MB6HC.h | 2 | ||||
-rw-r--r-- | src/Config/Pins_Duet3_MB6XD.h | 1 | ||||
-rw-r--r-- | src/FilamentMonitors/LaserFilamentMonitor.cpp | 2 | ||||
-rw-r--r-- | src/FilamentMonitors/RotatingMagnetFilamentMonitor.cpp | 2 | ||||
-rw-r--r-- | src/GCodes/GCodeBuffer/BinaryParser.cpp | 8 | ||||
-rw-r--r-- | src/GCodes/GCodeBuffer/ExpressionParser.cpp | 284 | ||||
-rw-r--r-- | src/GCodes/GCodeBuffer/StringParser.cpp | 2 | ||||
-rw-r--r-- | src/GCodes/GCodes.cpp | 2 | ||||
-rw-r--r-- | src/GCodes/GCodes2.cpp | 2 | ||||
-rw-r--r-- | src/ObjectModel/ObjectModel.cpp | 28 | ||||
-rw-r--r-- | src/ObjectModel/ObjectModel.h | 31 | ||||
-rw-r--r-- | src/Platform/Platform.cpp | 73 | ||||
-rw-r--r-- | src/Platform/Platform.h | 8 | ||||
-rw-r--r-- | src/RepRapFirmware.h | 6 |
20 files changed, 312 insertions, 275 deletions
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp index a44d757d..4c3a6739 100644 --- a/src/CAN/CanInterface.cpp +++ b/src/CAN/CanInterface.cpp @@ -99,6 +99,7 @@ static uint8_t currentTimeSyncMarker = 0xFF; #if SUPPORT_REMOTE_COMMANDS static bool inExpansionMode = false; +static bool inTestMode = false; static bool mainBoardAcknowledgedAnnounce = false; #endif @@ -311,6 +312,11 @@ bool CanInterface::InExpansionMode() noexcept return inExpansionMode; } +bool CanInterface::InTestMode() noexcept +{ + return inTestMode; +} + static void ReInit() noexcept { can0dev->Disable(); @@ -318,12 +324,13 @@ static void ReInit() noexcept can0dev->Enable(); } -void CanInterface::SwitchToExpansionMode(CanAddress addr) noexcept +void CanInterface::SwitchToExpansionMode(CanAddress addr, bool useTestMode) noexcept { TaskCriticalSectionLocker lock; myAddress = addr; inExpansionMode = true; + inTestMode = useTestMode; reprap.GetGCodes().SwitchToExpansionMode(); ReInit(); // reset the CAN filters to account for our new CAN address } @@ -482,71 +489,76 @@ extern "C" [[noreturn]] void CanClockLoop(void *) noexcept for (;;) { -#if SUPPORT_REMOTE_COMMANDS - if (!inExpansionMode) -#endif - { - CanMessageTimeSync * const msg = buf.SetupBroadcastMessage<CanMessageTimeSync>(CanInterface::GetCanAddress()); - msg->lastTimeSent = lastTimeSent; - msg->lastTimeAcknowledgeDelay = 0; // assume we don't have the transmit delay available + CanMessageTimeSync * const msg = buf.SetupBroadcastMessage<CanMessageTimeSync>(CanInterface::GetCanAddress()); + msg->lastTimeSent = lastTimeSent; + msg->lastTimeAcknowledgeDelay = 0; // assume we don't have the transmit delay available - currentTimeSyncMarker = ((currentTimeSyncMarker + 1) & 0x0F) | 0xA0; - buf.marker = currentTimeSyncMarker; - buf.reportInFifo = 1; + currentTimeSyncMarker = ((currentTimeSyncMarker + 1) & 0x0F) | 0xA0; + buf.marker = currentTimeSyncMarker; + buf.reportInFifo = 1; - if (gotTimeSyncTxTimeStamp) - { + if (gotTimeSyncTxTimeStamp) + { # if SAME70 - // On the SAME70 the step clock is also the external time stamp counter - const uint32_t timeSyncTxDelay = (timeSyncTxTimeStamp - (uint16_t)lastTimeSent) & 0xFFFF; + // On the SAME70 the step clock is also the external time stamp counter + const uint32_t timeSyncTxDelay = (timeSyncTxTimeStamp - (uint16_t)lastTimeSent) & 0xFFFF; # else - // On the SAME5x the time stamp counter counts CAN bit times divided by 64 - const uint32_t timeSyncTxDelay = (((timeSyncTxTimeStamp - lastTimeSyncTxPreparedStamp) & 0xFFFF) * CanInterface::GetTimeStampPeriod()) >> 6; + // On the SAME5x the time stamp counter counts CAN bit times divided by 64 + const uint32_t timeSyncTxDelay = (((timeSyncTxTimeStamp - lastTimeSyncTxPreparedStamp) & 0xFFFF) * CanInterface::GetTimeStampPeriod()) >> 6; # endif - if (timeSyncTxDelay > peakTimeSyncTxDelay) - { - peakTimeSyncTxDelay = timeSyncTxDelay; - } - - // Occasionally on the SAME70 we get very large delays reported. These delays are not genuine. - if (timeSyncTxDelay < MaxTimeSyncDelay) - { - msg->lastTimeAcknowledgeDelay = timeSyncTxDelay; - } - gotTimeSyncTxTimeStamp = false; - } - - msg->isPrinting = reprap.GetGCodes().IsReallyPrinting(); - - // Send the real time just once a second - const uint32_t realTime = (uint32_t)reprap.GetPlatform().GetDateTime(); - if (realTime != lastRealTimeSent) + if (timeSyncTxDelay > peakTimeSyncTxDelay) { - msg->realTime = realTime; - lastRealTimeSent = realTime; + peakTimeSyncTxDelay = timeSyncTxDelay; } - else + + // Occasionally on the SAME70 we get very large delays reported. These delays are not genuine. + if (timeSyncTxDelay < MaxTimeSyncDelay) { - buf.dataLength = CanMessageTimeSync::SizeWithoutRealTime; // send a short message to save CAN bandwidth + msg->lastTimeAcknowledgeDelay = timeSyncTxDelay; } + gotTimeSyncTxTimeStamp = false; + } + + msg->isPrinting = reprap.GetGCodes().IsReallyPrinting(); + + // Send the real time just once a second + const uint32_t realTime = (uint32_t)reprap.GetPlatform().GetDateTime(); + if (realTime != lastRealTimeSent) + { + msg->realTime = realTime; + lastRealTimeSent = realTime; + } + else + { + buf.dataLength = CanMessageTimeSync::SizeWithoutRealTime; // send a short message to save CAN bandwidth + } #if SAME70 - lastTimeSent = StepTimer::GetTimerTicks(); + lastTimeSent = StepTimer::GetTimerTicks(); #else - { - AtomicCriticalSectionLocker lock; - lastTimeSent = StepTimer::GetTimerTicks(); - lastTimeSyncTxPreparedStamp = CanInterface::GetTimeStampCounter(); - } -#endif - msg->timeSent = lastTimeSent; - SendCanMessage(TxBufferIndexTimeSync, 0, &buf); - ++timeSyncMessagesSent; + { + AtomicCriticalSectionLocker lock; + lastTimeSent = StepTimer::GetTimerTicks(); + lastTimeSyncTxPreparedStamp = CanInterface::GetTimeStampCounter(); } +#endif + msg->timeSent = lastTimeSent; + SendCanMessage(TxBufferIndexTimeSync, 0, &buf); + ++timeSyncMessagesSent; + + // Blink the LED at about 2Hz. Duet 3 expansion boards will blink in sync when they have established clock sync with us. + digitalWrite(DiagPin, XNor(DiagOnPolarity, lastTimeSent & (1u << 19)) != 0); // Delay until it is time again vTaskDelayUntil(&lastWakeTime, CanClockIntervalMillis); +#if SUPPORT_REMOTE_COMMANDS + if (inExpansionMode) + { + vTaskDelete(nullptr); // once in expansion mode we can't revert to main board mode, so we don't need this task any more + } +#endif + // Check that the message was sent and get the time stamp if (can0dev->IsSpaceAvailable((CanDevice::TxBufferNumber)TxBufferIndexTimeSync, 0)) // if the buffer is free already then the message was sent { @@ -555,8 +567,8 @@ extern "C" [[noreturn]] void CanClockLoop(void *) noexcept else { (void)can0dev->IsSpaceAvailable((CanDevice::TxBufferNumber)TxBufferIndexTimeSync, MaxTimeSyncSendWait); // free the buffer - can0dev->PollTxEventFifo(TxCallback); // empty the fifo - gotTimeSyncTxTimeStamp = false; // ignore any values read from it + can0dev->PollTxEventFifo(TxCallback); // empty the fifo + gotTimeSyncTxTimeStamp = false; // ignore any values read from it } } } diff --git a/src/CAN/CanInterface.h b/src/CAN/CanInterface.h index a1c320ac..ef322205 100644 --- a/src/CAN/CanInterface.h +++ b/src/CAN/CanInterface.h @@ -34,7 +34,8 @@ namespace CanInterface #if SUPPORT_REMOTE_COMMANDS bool InExpansionMode() noexcept; - void SwitchToExpansionMode(CanAddress addr) noexcept; + bool InTestMode() noexcept; + void SwitchToExpansionMode(CanAddress addr, bool useTestMode) noexcept; void SendAnnounce(CanMessageBuffer *buf) noexcept; void RaiseEvent(EventType type, uint16_t param, uint8_t device, const char *format, va_list vargs) noexcept; diff --git a/src/CAN/CanMessageGenericConstructor.cpp b/src/CAN/CanMessageGenericConstructor.cpp index ef61896e..a62f01bd 100644 --- a/src/CAN/CanMessageGenericConstructor.cpp +++ b/src/CAN/CanMessageGenericConstructor.cpp @@ -329,6 +329,19 @@ void CanMessageGenericConstructor::AddDriverIdParam(char c, DriverId did) THROWS InsertValue(&did.localDriver, sz, pos); } +void CanMessageGenericConstructor::AddFloatArrayParam(char c, const float *v, size_t numV) THROWS(GCodeException) +{ + ParamDescriptor::ParamType t; + size_t sz; + const unsigned int pos = FindInsertPoint(c, t, sz); + if (t != ParamDescriptor::float_array || numV != sz) + { + throw ConstructParseException("fval array wrong parameter type or length"); + } + InsertValue(&numV, sizeof(uint8_t), pos); + InsertValue(v, numV * sizeof(float), pos + sizeof(uint8_t)); +} + GCodeResult CanMessageGenericConstructor::SendAndGetResponse(CanMessageType msgType, CanAddress dest, const StringRef& reply) const noexcept { CanMessageBuffer * const buf = CanMessageBuffer::Allocate(); diff --git a/src/CAN/CanMessageGenericConstructor.h b/src/CAN/CanMessageGenericConstructor.h index d23447aa..d8f80f65 100644 --- a/src/CAN/CanMessageGenericConstructor.h +++ b/src/CAN/CanMessageGenericConstructor.h @@ -34,6 +34,7 @@ public: void AddCharParam(char c, char v) THROWS(GCodeException); void AddStringParam(char c, const char* v) THROWS(GCodeException); void AddDriverIdParam(char c, DriverId did) THROWS(GCodeException); + void AddFloatArrayParam(char c, const float *v, size_t numV) THROWS(GCodeException); GCodeResult SendAndGetResponse(CanMessageType msgType, CanAddress dest, const StringRef& reply) const noexcept; diff --git a/src/CAN/CommandProcessor.cpp b/src/CAN/CommandProcessor.cpp index 90e04e93..d27fa6aa 100644 --- a/src/CAN/CommandProcessor.cpp +++ b/src/CAN/CommandProcessor.cpp @@ -694,7 +694,7 @@ void CommandProcessor::ProcessReceivedMessage(CanMessageBuffer *buf) noexcept CanInterface::SendResponseNoFree(buf); delay(25); // allow time for the response to be sent before we re-initialise CAN - CanInterface::SwitchToExpansionMode(newAddress); + CanInterface::SwitchToExpansionMode(newAddress, true); } break; #endif diff --git a/src/Config/Configuration.h b/src/Config/Configuration.h index 1d216b43..aa02d818 100644 --- a/src/Config/Configuration.h +++ b/src/Config/Configuration.h @@ -154,11 +154,12 @@ constexpr size_t StringLength256 = 256; constexpr size_t MaxHeaterNameLength = StringLength20; // Maximum number of characters in a heater name constexpr size_t MaxFanNameLength = StringLength20; // Maximum number of characters in a fan name -constexpr size_t FormatStringLength = StringLength256; #ifdef DUET3_ATE constexpr size_t GCodeReplyLength = StringLength500; // Maximum number of characters in a GCode reply that doesn't use an OutputBuffer (ATE codes can generate long replies) +constexpr size_t FormatStringLength = StringLength500; // GCode replies are processed by Platform::MessageF which uses an intermediate buffer of this length #else constexpr size_t GCodeReplyLength = StringLength256; // Maximum number of characters in a GCode reply that doesn't use an OutputBuffer +constexpr size_t FormatStringLength = StringLength256; #endif constexpr size_t MachineNameLength = StringLength50; constexpr size_t RepRapPasswordLength = StringLength20; diff --git a/src/Config/Pins_Duet3_MB6HC.h b/src/Config/Pins_Duet3_MB6HC.h index c59559ec..5574ff1e 100644 --- a/src/Config/Pins_Duet3_MB6HC.h +++ b/src/Config/Pins_Duet3_MB6HC.h @@ -149,6 +149,8 @@ constexpr float V12MonitorVoltageRange = (60.4 + 4.7)/4.7 * 3.3; // voltage di // Digital pin number to turn the IR LED on (high) or off (low), also controls the DIAG LED constexpr Pin DiagPin = PortCPin(20); constexpr bool DiagOnPolarity = true; +constexpr Pin ActLedPin = NoPin; +constexpr bool ActOnPolarity = false; // SD cards constexpr size_t NumSdCards = 2; // we now allow one SPI-connected SD card to be configured at boot time diff --git a/src/Config/Pins_Duet3_MB6XD.h b/src/Config/Pins_Duet3_MB6XD.h index 70ec355d..514cb4ed 100644 --- a/src/Config/Pins_Duet3_MB6XD.h +++ b/src/Config/Pins_Duet3_MB6XD.h @@ -132,6 +132,7 @@ constexpr float V12MonitorVoltageRange = (60.4 + 4.7)/4.7 * 3.3; // voltage di constexpr Pin DiagPin = PortBPin(6); // diag/status LED constexpr Pin ActLedPin = PortBPin(7); // activityLED constexpr bool DiagOnPolarity = false; +constexpr bool ActOnPolarity = false; // SD cards constexpr size_t NumSdCards = 2; diff --git a/src/FilamentMonitors/LaserFilamentMonitor.cpp b/src/FilamentMonitors/LaserFilamentMonitor.cpp index de9eb207..aa0890fa 100644 --- a/src/FilamentMonitors/LaserFilamentMonitor.cpp +++ b/src/FilamentMonitors/LaserFilamentMonitor.cpp @@ -485,7 +485,7 @@ FilamentSensorStatus LaserFilamentMonitor::Clear() noexcept // Print diagnostic info for this sensor void LaserFilamentMonitor::Diagnostics(MessageType mtype, unsigned int extruder) noexcept { - String<FormatStringLength> buf; + String<StringLength256> buf; buf.printf("Extruder %u: ", extruder); if (dataReceived) { diff --git a/src/FilamentMonitors/RotatingMagnetFilamentMonitor.cpp b/src/FilamentMonitors/RotatingMagnetFilamentMonitor.cpp index d2e26b45..a6563d67 100644 --- a/src/FilamentMonitors/RotatingMagnetFilamentMonitor.cpp +++ b/src/FilamentMonitors/RotatingMagnetFilamentMonitor.cpp @@ -532,7 +532,7 @@ FilamentSensorStatus RotatingMagnetFilamentMonitor::Clear() noexcept // Print diagnostic info for this sensor void RotatingMagnetFilamentMonitor::Diagnostics(MessageType mtype, unsigned int extruder) noexcept { - String<FormatStringLength> buf; + String<StringLength256> buf; buf.printf("Extruder %u: ", extruder); if (dataReceived) { diff --git a/src/GCodes/GCodeBuffer/BinaryParser.cpp b/src/GCodes/GCodeBuffer/BinaryParser.cpp index b1e8e4fa..3dcb2650 100644 --- a/src/GCodes/GCodeBuffer/BinaryParser.cpp +++ b/src/GCodes/GCodeBuffer/BinaryParser.cpp @@ -841,7 +841,7 @@ void BinaryParser::AddParameters(VariableSet& vs, int codeRunning) noexcept case DataType::String: { StringHandle sh(seenParameterValue, param->intValue); - ev.Set(sh); + ev.SetStringHandle(sh); } break; @@ -855,15 +855,15 @@ void BinaryParser::AddParameters(VariableSet& vs, int codeRunning) noexcept break; case DataType::Float: - ev.Set(param->floatValue); + ev.SetFloat(param->floatValue); break; case DataType::Int: - ev.Set(param->intValue); + ev.SetInt(param->intValue); break; case DataType::UInt: - ev.Set((int32_t)param->uintValue); + ev.SetInt((int32_t)param->uintValue); break; default: diff --git a/src/GCodes/GCodeBuffer/ExpressionParser.cpp b/src/GCodes/GCodeBuffer/ExpressionParser.cpp index ce5e2fc5..f6b882b6 100644 --- a/src/GCodes/GCodeBuffer/ExpressionParser.cpp +++ b/src/GCodes/GCodeBuffer/ExpressionParser.cpp @@ -113,8 +113,7 @@ void ExpressionParser::ParseInternal(ExpressionValue& val, bool evaluate, uint8_ { case TypeCode::Uint32: // Convert enumeration to integer - val.iVal = (int32_t)val.uVal; - val.SetType(TypeCode::Int32); + val.SetInt((int32_t)val.uVal); break; case TypeCode::Int32: @@ -122,8 +121,7 @@ void ExpressionParser::ParseInternal(ExpressionValue& val, bool evaluate, uint8_ break; case TypeCode::DateTime_tc: // unary + converts a DateTime to a seconds count - val.iVal = (uint32_t)val.Get56BitValue(); - val.SetType(TypeCode::Int32); + val.SetInt((uint32_t)val.Get56BitValue()); break; default: @@ -146,11 +144,11 @@ void ExpressionParser::ParseInternal(ExpressionValue& val, bool evaluate, uint8_ ParseInternal(val, evaluate, UnaryPriority); if (val.GetType() == TypeCode::CString) { - val.Set((int32_t)strlen(val.sVal)); + val.SetInt((int32_t)strlen(val.sVal)); } else if (val.GetType() == TypeCode::HeapString) { - val.Set((int32_t)val.shVal.GetLength()); + val.SetInt((int32_t)val.shVal.GetLength()); } else { @@ -336,8 +334,7 @@ void ExpressionParser::ParseInternal(ExpressionValue& val, bool evaluate, uint8_ if (val2.GetType() == TypeCode::DateTime_tc) { // Difference of two data/times - val.SetType(TypeCode::Int32); - val.iVal = (int32_t)(val.Get56BitValue() - val2.Get56BitValue()); + val.SetInt((int32_t)(val.Get56BitValue() - val2.Get56BitValue())); } else if (val2.GetType() == TypeCode::Uint32) { @@ -389,133 +386,130 @@ void ExpressionParser::ParseInternal(ExpressionValue& val, bool evaluate, uint8_ case '>': BalanceTypes(val, val2, evaluate); - switch (val.GetType()) { - case TypeCode::Int32: - val.bVal = (val.iVal > val2.iVal); - break; + bool bResult; + switch (val.GetType()) + { + case TypeCode::Int32: + bResult = (val.iVal > val2.iVal); + break; - case TypeCode::Float: - val.bVal = (val.fVal > val2.fVal); - break; + case TypeCode::Float: + bResult = (val.fVal > val2.fVal); + break; - case TypeCode::DateTime_tc: - val.bVal = val.Get56BitValue() > val2.Get56BitValue(); - break; + case TypeCode::DateTime_tc: + bResult = val.Get56BitValue() > val2.Get56BitValue(); + break; - case TypeCode::Bool: - val.bVal = (val.bVal && !val2.bVal); - break; + case TypeCode::Bool: + bResult = (val.bVal && !val2.bVal); + break; - default: - if (evaluate) - { - ThrowParseException("expected numeric or Boolean operands to comparison operator"); + default: + if (evaluate) + { + ThrowParseException("expected numeric or Boolean operands to comparison operator"); + } + bResult = false; + break; } - val.bVal = false; - break; - } - val.SetType(TypeCode::Bool); - if (invert) - { - val.bVal = !val.bVal; + val.SetBool((invert) ? !bResult : bResult); } break; case '<': BalanceTypes(val, val2, evaluate); - switch (val.GetType()) { - case TypeCode::Int32: - val.bVal = (val.iVal < val2.iVal); - break; - - case TypeCode::Float: - val.bVal = (val.fVal < val2.fVal); - break; - - case TypeCode::DateTime_tc: - val.bVal = val.Get56BitValue() < val2.Get56BitValue(); - break; - - case TypeCode::Bool: - val.bVal = (!val.bVal && val2.bVal); - break; - - default: - if (evaluate) - { - ThrowParseException("expected numeric or Boolean operands to comparison operator"); - } - val.bVal = false; - break; - } - val.SetType(TypeCode::Bool); - if (invert) - { - val.bVal = !val.bVal; - } - break; - - case '=': - // Before balancing, handle comparisons with null - if (val.GetType() == TypeCode::None) - { - val.bVal = (val2.GetType() == TypeCode::None); - } - else if (val2.GetType() == TypeCode::None) - { - val.bVal = false; - } - else - { - BalanceTypes(val, val2, evaluate); + bool bResult; switch (val.GetType()) { - case TypeCode::ObjectModel_tc: - ThrowParseException("cannot compare objects"); - case TypeCode::Int32: - val.bVal = (val.iVal == val2.iVal); - break; - - case TypeCode::Uint32: - val.bVal = (val.uVal == val2.uVal); + bResult = (val.iVal < val2.iVal); break; case TypeCode::Float: - val.bVal = (val.fVal == val2.fVal); + bResult = (val.fVal < val2.fVal); break; case TypeCode::DateTime_tc: - val.bVal = val.Get56BitValue() == val2.Get56BitValue(); + bResult = val.Get56BitValue() < val2.Get56BitValue(); break; case TypeCode::Bool: - val.bVal = (val.bVal == val2.bVal); - break; - - case TypeCode::CString: - val.bVal = (strcmp(val.sVal, (val2.GetType() == TypeCode::HeapString) ? val2.shVal.Get().Ptr() : val2.sVal) == 0); - break; - - case TypeCode::HeapString: - val.bVal = (strcmp(val.shVal.Get().Ptr(), (val2.GetType() == TypeCode::HeapString) ? val2.shVal.Get().Ptr() : val2.sVal) == 0); + bResult = (!val.bVal && val2.bVal); break; default: if (evaluate) { - ThrowParseException("unexpected operand type to equality operator"); + ThrowParseException("expected numeric or Boolean operands to comparison operator"); } - val.bVal = false; + bResult = false; break; } + val.SetBool((invert) ? !bResult : bResult); } - val.SetType(TypeCode::Bool); - if (invert) + break; + + case '=': { - val.bVal = !val.bVal; + bool bResult; + // Before balancing, handle comparisons with null + if (val.GetType() == TypeCode::None) + { + bResult = (val2.GetType() == TypeCode::None); + } + else if (val2.GetType() == TypeCode::None) + { + bResult = false; + } + else + { + BalanceTypes(val, val2, evaluate); + switch (val.GetType()) + { + case TypeCode::ObjectModel_tc: + ThrowParseException("cannot compare objects"); + + case TypeCode::Int32: + bResult = (val.iVal == val2.iVal); + break; + + case TypeCode::Uint32: + bResult = (val.uVal == val2.uVal); + break; + + case TypeCode::Float: + bResult = (val.fVal == val2.fVal); + break; + + case TypeCode::DateTime_tc: + bResult = val.Get56BitValue() == val2.Get56BitValue(); + break; + + case TypeCode::Bool: + bResult = (val.bVal == val2.bVal); + break; + + case TypeCode::CString: + bResult = (strcmp(val.sVal, (val2.GetType() == TypeCode::HeapString) ? val2.shVal.Get().Ptr() : val2.sVal) == 0); + break; + + case TypeCode::HeapString: + bResult = (strcmp(val.shVal.Get().Ptr(), (val2.GetType() == TypeCode::HeapString) ? val2.shVal.Get().Ptr() : val2.sVal) == 0); + break; + + default: + if (evaluate) + { + ThrowParseException("unexpected operand type to equality operator"); + } + bResult = false; + break; + } + } + val.SetBool((invert) ? !bResult : bResult); } break; @@ -536,7 +530,7 @@ void ExpressionParser::ParseInternal(ExpressionValue& val, bool evaluate, uint8_ val.AppendAsString(str.GetRef()); val2.AppendAsString(str.GetRef()); StringHandle sh(str.c_str()); - val.Set(sh); + val.SetStringHandle(sh); } bool ExpressionParser::ParseBoolean() THROWS(GCodeException) @@ -673,8 +667,8 @@ void ExpressionParser::BalanceNumericTypes(ExpressionValue& val1, ExpressionValu { ThrowParseException("expected numeric operands"); } - val1.Set((int32_t)0); - val2.Set((int32_t)0); + val1.SetInt(0); + val2.SetInt(0); } } @@ -734,34 +728,29 @@ void ExpressionParser::BalanceTypes(ExpressionValue& val1, ExpressionValue& val2 { ThrowParseException("cannot convert operands to same type"); } - val1.Set((int32_t)0); - val2.Set((int32_t)0); + val1.SetInt(0); + val2.SetInt(0); } } void ExpressionParser::ConvertToFloat(ExpressionValue& val, bool evaluate) const THROWS(GCodeException) { + float fVal; switch (val.GetType()) { + case TypeCode::Float: + return; // no conversion needed, leave the precision alone + case TypeCode::Uint32: - val.SetType(TypeCode::Float); - val.fVal = (float)val.uVal; - val.param = 1; + fVal = (float)val.uVal; break; case TypeCode::Uint64: - val.SetType(TypeCode::Float); - val.fVal = (float)val.Get56BitValue(); - val.param = 1; + fVal = (float)val.Get56BitValue(); break; case TypeCode::Int32: - val.fVal = (float)val.iVal; - val.SetType(TypeCode::Float); - val.param = 1; - break; - - case TypeCode::Float: + fVal = (float)val.iVal; break; default: @@ -769,8 +758,10 @@ void ExpressionParser::ConvertToFloat(ExpressionValue& val, bool evaluate) const { ThrowParseException("expected numeric operand"); } - val.Set(0.0f, 1); + fVal = 0.0f; + break; } + val.SetFloat(fVal, 1); } void ExpressionParser::ConvertToBool(ExpressionValue& val, bool evaluate) const THROWS(GCodeException) @@ -781,7 +772,7 @@ void ExpressionParser::ConvertToBool(ExpressionValue& val, bool evaluate) const { ThrowParseException("expected Boolean operand"); } - val.Set(false); + val.SetBool(false); } } @@ -794,11 +785,11 @@ void ExpressionParser::ConvertToString(ExpressionValue& val, bool evaluate) noex String<MaxStringExpressionLength> str; val.AppendAsString(str.GetRef()); StringHandle sh(str.c_str()); - val.Set(sh); + val.SetStringHandle(sh); } else { - val.Set(""); + val.SetCString(""); } } } @@ -812,9 +803,9 @@ void ExpressionParser::ConvertToDriverId(ExpressionValue& val, bool evaluate) co case TypeCode::Int32: #if SUPPORT_CAN_EXPANSION - val.Set(DriverId(0, val.uVal)); + val.SetDriverId(DriverId(0, val.uVal)); #else - val.Set(DriverId(val.uVal)); + val.SetDriverId(DriverId(val.uVal)); #endif break; @@ -825,12 +816,12 @@ void ExpressionParser::ConvertToDriverId(ExpressionValue& val, bool evaluate) co #if SUPPORT_CAN_EXPANSION if (ival >= 0 && fabsf(f10val - (float)ival) <= 0.002) { - val.Set(DriverId(ival/10, ival % 10)); + val.SetDriverId(DriverId(ival/10, ival % 10)); } #else if (ival >= 0 && ival < 10 && fabsf(f10val - (float)ival) <= 0.002) { - val.Set(DriverId(ival % 10)); + val.SetDriverId(DriverId(ival % 10)); } #endif else @@ -874,11 +865,11 @@ void ExpressionParser::ParseNumber(ExpressionValue& rslt) noexcept if (conv.FitsInInt32()) { - rslt.Set(conv.GetInt32()); + rslt.SetInt(conv.GetInt32()); } else { - rslt.Set(conv.GetFloat(), constrain<unsigned int>(conv.GetDigitsAfterPoint(), 1, MaxFloatDigitsDisplayedAfterPoint)); + rslt.SetFloat(conv.GetFloat(), constrain<unsigned int>(conv.GetDigitsAfterPoint(), 1, MaxFloatDigitsDisplayedAfterPoint)); } } @@ -917,7 +908,7 @@ void ExpressionParser::ParseIdentifierExpression(ExpressionValue& rslt, bool eva { ThrowParseException("expected integer expression"); } - index.Set((int32_t)0); + index.SetInt(0); } AdvancePointer(); // skip the ']' context.ProvideIndex(index.iVal); @@ -941,19 +932,19 @@ void ExpressionParser::ParseIdentifierExpression(ExpressionValue& rslt, bool eva switch (whichConstant.RawValue()) { case NamedConstant::_true: - rslt.Set(true); + rslt.SetBool(true); return; case NamedConstant::_false: - rslt.Set(false); + rslt.SetBool(false); return; case NamedConstant::_null: - rslt.Set(nullptr); + rslt.SetNull(nullptr); return; case NamedConstant::pi: - rslt.Set(Pi); + rslt.SetFloat(Pi); return; case NamedConstant::iterations: @@ -963,7 +954,7 @@ void ExpressionParser::ParseIdentifierExpression(ExpressionValue& rslt, bool eva { ThrowParseException("'iterations' used when not inside a loop"); } - rslt.Set(v); + rslt.SetInt(v); } return; @@ -985,12 +976,12 @@ void ExpressionParser::ParseIdentifierExpression(ExpressionValue& rslt, bool eva res = 2; break; } - rslt.Set(res); + rslt.SetInt(res); } return; case NamedConstant::line: - rslt.Set((int32_t)gb.GetLineNumber()); + rslt.SetInt((int32_t)gb.GetLineNumber()); return; default: @@ -1043,7 +1034,7 @@ void ExpressionParser::ParseIdentifierExpression(ExpressionValue& rslt, bool eva { ThrowParseException("expected numeric operand"); } - rslt.Set((int32_t)0); + rslt.SetInt(0); } break; @@ -1122,8 +1113,7 @@ void ExpressionParser::ParseIdentifierExpression(ExpressionValue& rslt, bool eva case Function::isnan: ConvertToFloat(rslt, evaluate); - rslt.SetType(TypeCode::Bool); - rslt.bVal = (std::isnan(rslt.fVal) != 0); + rslt.SetBool(std::isnan(rslt.fVal) != 0); break; case Function::floor: @@ -1132,8 +1122,7 @@ void ExpressionParser::ParseIdentifierExpression(ExpressionValue& rslt, bool eva const float f = floorf(rslt.fVal); if (f <= (float)std::numeric_limits<int32_t>::max() && f >= (float)std::numeric_limits<int32_t>::min()) { - rslt.SetType(TypeCode::Int32); - rslt.iVal = (int32_t)f; + rslt.SetInt((int32_t)f); } else { @@ -1237,7 +1226,7 @@ void ExpressionParser::ParseIdentifierExpression(ExpressionValue& rslt, bool eva { ThrowParseException("expected positive integer"); } - rslt.Set((int32_t)random(limit)); + rslt.SetInt((int32_t)random(limit)); } break; @@ -1270,8 +1259,7 @@ void ExpressionParser::ParseIdentifierExpression(ExpressionValue& rslt, bool eva default: ThrowParseException("can't convert value to DateTime"); } - rslt.SetType(TypeCode::DateTime_tc); - rslt.Set56BitValue(val); + rslt.SetDateTime(val); } break; @@ -1316,7 +1304,7 @@ void ExpressionParser::ParseIdentifierExpression(ExpressionValue& rslt, bool eva // "exists(global)" will anyway because "global" is a root key in the object model. Handle the other two here. if (applyExists && (strcmp(id.c_str(), "param") == 0 || strcmp(id.c_str(), "var") == 0)) { - rslt.Set(true); + rslt.SetBool(true); return; } @@ -1329,7 +1317,7 @@ void ExpressionParser::ParseIdentifierExpression(ExpressionValue& rslt, bool eva } return; } - rslt.Set(nullptr); + rslt.SetNull(nullptr); } // Parse a string to a DateTime @@ -1349,7 +1337,7 @@ void ExpressionParser::GetVariableValue(ExpressionValue& rslt, const VariableSet const Variable* var = vars->Lookup(name); if (wantExists) { - rslt.Set(var != nullptr); + rslt.SetBool(var != nullptr); return; } @@ -1381,7 +1369,7 @@ void ExpressionParser::ParseQuotedString(ExpressionValue& rslt) THROWS(GCodeExce if (CurrentCharacter() != c) { StringHandle sh(str.c_str()); - rslt.Set(sh); + rslt.SetStringHandle(sh); return; } AdvancePointer(); diff --git a/src/GCodes/GCodeBuffer/StringParser.cpp b/src/GCodes/GCodeBuffer/StringParser.cpp index a4ea34a4..bd8b2c74 100644 --- a/src/GCodes/GCodeBuffer/StringParser.cpp +++ b/src/GCodes/GCodeBuffer/StringParser.cpp @@ -1929,7 +1929,7 @@ void StringParser::AddParameters(VariableSet& vs, int codeRunning) noexcept catch (const GCodeException&) { //TODO can we report the error anywhere? - ev.Set(nullptr); + ev.SetNull(nullptr); } char paramName[2] = { letter, 0 }; vs.InsertNewParameter(paramName, ev); diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp index bf545cd6..986c3482 100644 --- a/src/GCodes/GCodes.cpp +++ b/src/GCodes/GCodes.cpp @@ -1197,7 +1197,7 @@ void GCodes::SaveResumeInfo(bool wasPowerFailure) noexcept } else { - String<FormatStringLength> buf; + String<StringLength256> buf; // Write the header comment buf.printf("; File \"%s\" resume print after %s", printingFilename, (wasPowerFailure) ? "power failure" : "print paused"); diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 09686426..b63bad53 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -4518,7 +4518,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx case 954: // configure as expansion board { CanAddress addr = gb.GetLimitedUIValue('A', 1, CanId::MaxCanAddress + 1); - CanInterface::SwitchToExpansionMode(addr); + CanInterface::SwitchToExpansionMode(addr, false); } break; #endif diff --git a/src/ObjectModel/ObjectModel.cpp b/src/ObjectModel/ObjectModel.cpp index 5bffcd3c..e7f86716 100644 --- a/src/ObjectModel/ObjectModel.cpp +++ b/src/ObjectModel/ObjectModel.cpp @@ -193,6 +193,34 @@ void ExpressionValue::Release() noexcept } } +void ExpressionValue::SetBool(bool b) noexcept +{ + Release(); + type = (uint32_t)TypeCode::Bool; + bVal = b; +} + +void ExpressionValue::SetInt(int32_t i) noexcept +{ + Release(); + type = (uint32_t)TypeCode::Int32; + iVal = i; +} + +void ExpressionValue::SetFloat(float f, uint32_t digits) noexcept { Release(); type = (uint32_t)TypeCode::Float; fVal = f; param = digits; } + +void ExpressionValue::SetDriverId(DriverId did) noexcept +{ + Release(); + type = (uint32_t)TypeCode::DriverId_tc; +#if SUPPORT_CAN_EXPANSION + param = did.boardAddress; +#else + param = 0; +#endif + uVal = did.localDriver; +} + #if SUPPORT_CAN_EXPANSION // Given that this is a CanExpansionBoardDetails value, extract the part requested according to the parameter and append it to the string diff --git a/src/ObjectModel/ObjectModel.h b/src/ObjectModel/ObjectModel.h index a957aff6..3d05ac8c 100644 --- a/src/ObjectModel/ObjectModel.h +++ b/src/ObjectModel/ObjectModel.h @@ -153,32 +153,21 @@ struct ExpressionValue void Release() noexcept; // release any associated storage TypeCode GetType() const noexcept { return (TypeCode)type; } - void SetType(TypeCode t) noexcept { type = (uint32_t)t; } bool IsStringType() const noexcept { return type == (uint32_t)TypeCode::CString || type == (uint32_t)TypeCode::HeapString; } - void Set(bool b) noexcept { Release(); type = (uint32_t)TypeCode::Bool; bVal = b; } - void Set(char c) noexcept { Release(); type = (uint32_t)TypeCode::Char; cVal = c; } - void Set(int32_t i) noexcept { Release(); type = (uint32_t)TypeCode::Int32; iVal = i; } - void Set(float f) noexcept { Release(); type = (uint32_t)TypeCode::Float; fVal = f; param = MaxFloatDigitsDisplayedAfterPoint; } - void Set(float f, uint32_t digits) noexcept { Release(); type = (uint32_t)TypeCode::Float; fVal = f; param = digits; } - void Set(const char *_ecv_array s) noexcept { Release(); type = (uint32_t)TypeCode::CString; sVal = s; } - void Set(DriverId did) noexcept - { - Release(); - type = (uint32_t)TypeCode::DriverId_tc; -#if SUPPORT_CAN_EXPANSION - param = did.boardAddress; -#else - param = 0; -#endif - uVal = did.localDriver; - } + void SetBool(bool b) noexcept; + void SetInt(int32_t i) noexcept; + void SetFloat(float f, uint32_t digits) noexcept; + void SetFloat(float f) noexcept { SetFloat(f, MaxFloatDigitsDisplayedAfterPoint); } + void SetCString(const char *_ecv_array s) noexcept { Release(); type = (uint32_t)TypeCode::CString; sVal = s; } + void SetDriverId(DriverId did) noexcept; - void Set(StringHandle sh) noexcept { Release(); type = (uint32_t)TypeCode::HeapString; shVal = sh; } - void Set(std::nullptr_t dummy) noexcept { Release(); type = (uint32_t)TypeCode::None; } + void SetStringHandle(StringHandle sh) noexcept { Release(); type = (uint32_t)TypeCode::HeapString; shVal = sh; } + void SetNull(std::nullptr_t dummy) noexcept { Release(); type = (uint32_t)TypeCode::None; } + void SetDateTime(time_t t) noexcept { Release(); type = (uint32_t)TypeCode::DateTime_tc; Set56BitValue(t); } // Store a 56-bit value - void Set56BitValue(uint64_t v) { Release(); param = (uint32_t)(v >> 32) & 0x00FFFFFFu; uVal = (uint32_t)v; } + void Set56BitValue(uint64_t v) { param = (uint32_t)(v >> 32) & 0x00FFFFFFu; uVal = (uint32_t)v; } // Extract a 56-bit value that we have stored. Used to retrieve date/times and large bitmaps. uint64_t Get56BitValue() const noexcept { return ((uint64_t)param << 32) | uVal; } diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp index 4737d85a..98040d27 100644 --- a/src/Platform/Platform.cpp +++ b/src/Platform/Platform.cpp @@ -415,7 +415,7 @@ Platform::Platform() noexcept : #endif tickState(0), debugCode(0), lastDriverPollMillis(0), -#ifdef DUET3MINI +#if SUPPORT_CAN_EXPANSION whenLastCanMessageProcessed(0), #endif @@ -647,19 +647,9 @@ void Platform::Init() noexcept #ifdef DUET3_MB6XD driverErrPinsActiveLow = (numErrorHighDrivers >= NumDirectDrivers/2); // determine the error signal polarity by assuming most drivers are not in the error state - - // Set up the step gate timer - pmc_enable_periph_clk(STEP_GATE_TC_ID); - STEP_GATE_TC->TC_CHANNEL[STEP_GATE_TC_CHAN].TC_CCR = TC_CCR_CLKDIS; - STEP_GATE_TC->TC_CHANNEL[STEP_GATE_TC_CHAN].TC_CMR = TC_CMR_BSWTRG_SET // software trigger sets TIOB - | TC_CMR_BCPC_CLEAR // RC compare clears TIOB - | TC_CMR_WAVE // waveform mode - | TC_CMR_WAVSEL_UP // count up - | TC_CMR_CPCSTOP // counter clock is stopped when counter reaches RC - | TC_CMR_EEVT_XC0 // set external events from XC0 (this allows TIOB to be an output) - | TC_CMR_TCCLKS_TIMER_CLOCK2; // divide MCLK (150MHz) by 8 = 18.75MHz + pmc_enable_periph_clk(STEP_GATE_TC_ID); // need to do this before we set up the step gate TC + UpdateDriverTimings(); // this also initialises the step gate TC SetPinFunction(StepGatePin, StepGatePinFunction); - STEP_GATE_TC->TC_CHANNEL[STEP_GATE_TC_CHAN].TC_CCR = TC_CCR_CLKEN; #endif // Set up the axis+extruder arrays @@ -705,9 +695,7 @@ void Platform::Init() noexcept #endif } -#ifdef DUET3_MB6XD - UpdateDriverTimings(); -#else +#ifndef DUET3_MB6XD for (uint32_t& entry : slowDriverStepTimingClocks) { entry = 0; // reset all to zero as we have no known slow drivers yet @@ -989,8 +977,7 @@ void Platform::Spin() noexcept return; } -#if defined(DUET3) || defined(DUET3MINI) || defined(__LPC17xx__) -# if SUPPORT_REMOTE_COMMANDS +#if SUPPORT_REMOTE_COMMANDS if (CanInterface::InExpansionMode()) { if (StepTimer::IsSynced()) @@ -1002,21 +989,14 @@ void Platform::Spin() noexcept digitalWrite(DiagPin, XNor(DiagOnPolarity, StepTimer::GetTimerTicks() & (1u << 17)) != 0); } } - else -# endif - { - // Blink the LED at about 2Hz. Duet 3 expansion boards will blink in sync when they have established clock sync with us. - digitalWrite(DiagPin, XNor(DiagOnPolarity, StepTimer::GetTimerTicks() & (1u << 19)) != 0); - } #endif -#if defined(DUET3MINI) +#if SUPPORT_CAN_EXPANSION // Turn off the ACT LED if it is time to do so if (millis() - whenLastCanMessageProcessed > ActLedFlashTime) { digitalWrite(ActLedPin, !ActOnPolarity); } - #endif #if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES @@ -1094,7 +1074,8 @@ void Platform::Spin() noexcept { StandardDriverStatus stat = #if defined(DUET3_MB6XD) - StandardDriverStatus((HasDriverError(nextDriveToPoll)) ? (uint32_t)1u << StandardDriverStatus::ExternDriverErrorBitPos : 0); + // Don't raise driver error events while we are being tested by ATE + StandardDriverStatus((!CanInterface::InTestMode() && HasDriverError(nextDriveToPoll)) ? (uint32_t)1u << StandardDriverStatus::ExternDriverErrorBitPos : 0); #else SmartDrivers::GetStatus(nextDriveToPoll, true, true); #endif @@ -2778,15 +2759,31 @@ void Platform::UpdateDriverTimings() noexcept } // Convert the step pulse width to clocks of the step pulse gate timer. First define some constants. - constexpr uint32_t StepGateTcClockFrequency = (SystemCoreClockFreq/2)/8; - constexpr float StepGateClocksPerMicrosecond = (float)StepGateTcClockFrequency/1.0e6; + constexpr uint32_t StepGateTcBaseClockFrequency = (SystemCoreClockFreq/2)/8; // the step gate T clock frequency when we use a prescaler of 8 + constexpr float StepGateBaseClocksPerMicrosecond = (float)StepGateTcBaseClockFrequency * 1.0e-6; + const float fclocks = min<float>(ceilf(worstTimings[0] * StepGateBaseClocksPerMicrosecond), (float)(4 * 65535)); // the TC is only 16 bits wide, but we increase the prescaler to 32 if necessary - const float fclocks = ceilf(worstTimings[0] * StepGateClocksPerMicrosecond); - const uint32_t gateClocks = (uint32_t)fclocks; - STEP_GATE_TC->TC_CHANNEL[STEP_GATE_TC_CHAN].TC_RC = gateClocks; + uint32_t iclocks = (uint32_t)fclocks; + uint32_t clockPrescaler = TC_CMR_TCCLKS_TIMER_CLOCK2; // divide MCLK (150MHz) by 8 = 18.75MHz + if (iclocks > 65535) + { + clockPrescaler = TC_CMR_TCCLKS_TIMER_CLOCK3; // divide MCLK (150MHz) by 32 = 4.6875MHz + iclocks >>= 2; + } + + STEP_GATE_TC->TC_CHANNEL[STEP_GATE_TC_CHAN].TC_CCR = TC_CCR_CLKDIS; + STEP_GATE_TC->TC_CHANNEL[STEP_GATE_TC_CHAN].TC_CMR = TC_CMR_BSWTRG_SET // software trigger sets TIOB + | TC_CMR_BCPC_CLEAR // RC compare clears TIOB + | TC_CMR_WAVE // waveform mode + | TC_CMR_WAVSEL_UP // count up + | TC_CMR_CPCSTOP // counter clock is stopped when counter reaches RC + | TC_CMR_EEVT_XC0 // set external events from XC0 (this allows TIOB to be an output) + | clockPrescaler; // divide MCLK (150MHz) by 8 or 32 + STEP_GATE_TC->TC_CHANNEL[STEP_GATE_TC_CHAN].TC_RC = iclocks; + STEP_GATE_TC->TC_CHANNEL[STEP_GATE_TC_CHAN].TC_CCR = TC_CCR_CLKEN; // Convert the quantised step pulse width back to microseconds - const float actualStepPulseMicroseconds = fclocks/StepGateClocksPerMicrosecond; + const float actualStepPulseMicroseconds = fclocks/StepGateBaseClocksPerMicrosecond; // Now convert the other values from microseconds to step clocks stepPulseMinimumPeriodClocks = MicrosecondsToStepClocks(worstTimings[1] + actualStepPulseMicroseconds); @@ -2798,8 +2795,12 @@ void Platform::UpdateDriverTimings() noexcept void Platform::GetActualDriverTimings(float timings[4]) noexcept { - constexpr uint32_t StepGateTcClockFrequency = (SystemCoreClockFreq/2)/8; - constexpr float MicrosecondsPerStepGateClock = 1.0e6/(float)StepGateTcClockFrequency; + uint32_t StepGateTcClockFrequency = (SystemCoreClockFreq/2)/8; + if ((STEP_GATE_TC->TC_CHANNEL[STEP_GATE_TC_CHAN].TC_CMR & TC_CMR_TCCLKS_Msk) == TC_CMR_TCCLKS_TIMER_CLOCK3) + { + StepGateTcClockFrequency >>= 2;; + } + const float MicrosecondsPerStepGateClock = 1.0e6/(float)StepGateTcClockFrequency; constexpr float StepClocksToMicroseconds = 1.0e6/(float)StepClockRate; timings[0] = (float)STEP_GATE_TC->TC_CHANNEL[STEP_GATE_TC_CHAN].TC_RC * MicrosecondsPerStepGateClock; timings[1] = stepPulseMinimumPeriodClocks * StepClocksToMicroseconds - timings[0]; @@ -4543,7 +4544,7 @@ GCodeResult Platform::UpdateRemoteStepsPerMmAndMicrostepping(AxesBitmap axesAndE void Platform::OnProcessingCanMessage() noexcept { -#ifdef DUET3MINI // MB6HC doesn't yet have a ACT LED +#if SUPPORT_CAN_EXPANSION whenLastCanMessageProcessed = millis(); digitalWrite(ActLedPin, ActOnPolarity); // turn the ACT LED on #endif diff --git a/src/Platform/Platform.h b/src/Platform/Platform.h index 36462474..d8a782c8 100644 --- a/src/Platform/Platform.h +++ b/src/Platform/Platform.h @@ -705,12 +705,6 @@ private: void ReportDrivers(MessageType mt, DriversBitmap& whichDrivers, const char *_ecv_array text, bool& reported) noexcept; #endif - // Convert microseconds to step clocks, rounding up to the next step clock - static constexpr uint32_t MicrosecondsToStepClocks(float us) noexcept - { - return (uint32_t)ceilf((float)StepClockRate * 0.000001 * us); - } - #ifdef DUET3_MB6XD void UpdateDriverTimings() noexcept; #endif @@ -918,7 +912,7 @@ private: // Event handling uint32_t lastDriverPollMillis; // when we last checked the drivers and voltage monitoring -#ifdef DUET3MINI +#if SUPPORT_CAN_EXPANSION uint32_t whenLastCanMessageProcessed; #endif diff --git a/src/RepRapFirmware.h b/src/RepRapFirmware.h index 628deac2..233791a6 100644 --- a/src/RepRapFirmware.h +++ b/src/RepRapFirmware.h @@ -502,6 +502,12 @@ constexpr uint32_t StepClockRate = SystemCoreClockFreq/128; // Duet 2 and Ma constexpr uint64_t StepClockRateSquared = (uint64_t)StepClockRate * StepClockRate; constexpr float StepClocksToMillis = 1000.0/(float)StepClockRate; +// Convert microseconds to step clocks, rounding up to the next step clock +static inline constexpr uint32_t MicrosecondsToStepClocks(float us) noexcept +{ + return (uint32_t)ceilf((float)StepClockRate * 0.000001 * us); +} + // Functions to convert speeds and accelerations between seconds and step clocks static inline constexpr float ConvertSpeedFromMmPerSec(float speed) noexcept { |