Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2021-12-15 00:43:10 +0300
committerDavid Crocker <dcrocker@eschertech.com>2021-12-15 00:43:10 +0300
commite4cabdd5e3aa1d339118351efc1271de999ddf83 (patch)
treec118cbe5e84784c43287bdd0d1a07f53b89b7a6b
parent73ae2eda574d40925856688af3721fe1f650372f (diff)
Handle driver warnings and errors via the event handling system
Also removed delay to reporting driver OTPW when a fan has just been turned on Also bug fixes to event handling system
-rw-r--r--src/CAN/CanInterface.cpp4
-rw-r--r--src/CAN/CommandProcessor.cpp5
-rw-r--r--src/Fans/LocalFan.cpp28
-rw-r--r--src/Platform/Event.cpp13
-rw-r--r--src/Platform/Event.h6
-rw-r--r--src/Platform/Platform.cpp194
-rw-r--r--src/Platform/Platform.h9
-rw-r--r--src/Version.h2
8 files changed, 104 insertions, 157 deletions
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp
index 9249dfc5..20c36877 100644
--- a/src/CAN/CanInterface.cpp
+++ b/src/CAN/CanInterface.cpp
@@ -350,8 +350,8 @@ void CanInterface::SendAnnounce(CanMessageBuffer *buf) noexcept
void CanInterface::RaiseEvent(EventType type, uint16_t param, uint8_t device, const char *format, va_list vargs) noexcept
{
CanMessageBuffer buf(nullptr);
- auto msg = buf.SetupStatusMessage<CanMessageEvent>(CanInterface::GetCanAddress(), CanId::MasterAddress);
- msg->eventType = EventType::heater_fault;
+ auto msg = buf.SetupStatusMessage<CanMessageEvent>(GetCanAddress(), GetCurrentMasterAddress());
+ msg->eventType = type.ToBaseType();;
msg->deviceNumber = device;
msg->eventParam = param;
msg->zero = 0;
diff --git a/src/CAN/CommandProcessor.cpp b/src/CAN/CommandProcessor.cpp
index 43d99b58..b74c4750 100644
--- a/src/CAN/CommandProcessor.cpp
+++ b/src/CAN/CommandProcessor.cpp
@@ -13,6 +13,7 @@
#include <CanMessageBuffer.h>
#include <Platform/RepRap.h>
#include <Platform/Platform.h>
+#include <Platform/Event.h>
#include <Heating/Heat.h>
#include "ExpansionManager.h"
# include <ClosedLoop/ClosedLoop.h>
@@ -655,6 +656,10 @@ void CommandProcessor::ProcessReceivedMessage(CanMessageBuffer *buf) noexcept
ClosedLoop::ProcessReceivedData(buf->id.Src(), buf->msg.closedLoopData, buf->dataLength);
break;
+ case CanMessageType::event:
+ Event::Add(buf->msg.event, buf->id.Src(), buf->dataLength);
+ break;
+
#if SUPPORT_ACCELEROMETERS
case CanMessageType::accelerometerData:
Accelerometers::ProcessReceivedData(buf->id.Src(), buf->msg.accelerometerData, buf->dataLength);
diff --git a/src/Fans/LocalFan.cpp b/src/Fans/LocalFan.cpp
index 3acfce43..5e404258 100644
--- a/src/Fans/LocalFan.cpp
+++ b/src/Fans/LocalFan.cpp
@@ -70,9 +70,6 @@ void LocalFan::SetHardwarePwm(float pwmVal) noexcept
void LocalFan::InternalRefresh(bool checkSensors) noexcept
{
float reqVal;
-#if HAS_SMART_DRIVERS
- DriverChannelsBitmap driverChannelsMonitored;
-#endif
if (sensorsMonitored.IsEmpty())
{
@@ -87,11 +84,7 @@ void LocalFan::InternalRefresh(bool checkSensors) noexcept
reqVal = 0.0;
const bool bangBangMode = (triggerTemperatures[1] <= triggerTemperatures[0]);
sensorsMonitored.Iterate
- ([&reqVal, bangBangMode, this
-#if HAS_SMART_DRIVERS
- , &driverChannelsMonitored
-#endif
- ](unsigned int sensorNum, unsigned int) noexcept
+ ([&reqVal, bangBangMode, this](unsigned int sensorNum, unsigned int) noexcept
{
const auto sensor = reprap.GetHeat().FindSensor(sensorNum);
if (sensor.IsNotNull())
@@ -120,13 +113,6 @@ void LocalFan::InternalRefresh(bool checkSensors) noexcept
reqVal = newVal;
}
}
-#if HAS_SMART_DRIVERS
- const int channel = sensor->GetSmartDriversChannel();
- if (channel >= 0)
- {
- driverChannelsMonitored.SetBit((unsigned int)channel);
- }
-#endif
}
}
);
@@ -137,12 +123,6 @@ void LocalFan::InternalRefresh(bool checkSensors) noexcept
if (lastVal <= 0.0)
{
// We are turning this fan on
-#if HAS_SMART_DRIVERS
- if (driverChannelsMonitored.IsNonEmpty())
- {
- reprap.GetPlatform().DriverCoolingFansOnOff(driverChannelsMonitored, true); // tell Platform that we have started a fan that cools drivers
- }
-#endif
if (reqVal < 1.0 && blipTime != 0)
{
// Starting the fan from standstill, so blip the fan
@@ -158,12 +138,6 @@ void LocalFan::InternalRefresh(bool checkSensors) noexcept
else
{
blipping = false;
-#if HAS_SMART_DRIVERS
- if (driverChannelsMonitored.IsNonEmpty() && lastVal > 0.0)
- {
- reprap.GetPlatform().DriverCoolingFansOnOff(driverChannelsMonitored, false); // tell Platform that we have stopped a fan that cools drivers
- }
-#endif
}
lastVal = reqVal;
diff --git a/src/Platform/Event.cpp b/src/Platform/Event.cpp
index e6cc33b5..022836db 100644
--- a/src/Platform/Event.cpp
+++ b/src/Platform/Event.cpp
@@ -60,6 +60,19 @@ inline Event::Event(Event *_ecv_null p_next, EventType et, uint16_t p_param, uin
return true;
}
+#if SUPPORT_CAN_EXPANSION
+
+// Queue an event received via CAN
+/*static*/ void Event::Add(const CanMessageEvent& msg, CanAddress src, size_t msgLen) noexcept
+{
+ // We need to make sure that the text is null terminated
+ String<StringLength100> msgText;
+ msgText.copy(msg.text, msg.GetMaxTextLength(msgLen));
+ (void)AddEvent((EventType)msg.eventType, msg.eventParam, src, msg.deviceNumber, "%s", msgText.c_str());
+}
+
+#endif
+
// Get the highest priority event and mark it as being serviced
/*static*/ bool Event::StartProcessing() noexcept
{
diff --git a/src/Platform/Event.h b/src/Platform/Event.h
index 81fb2a60..7e120095 100644
--- a/src/Platform/Event.h
+++ b/src/Platform/Event.h
@@ -32,6 +32,7 @@
#include <Platform/PrintPausedReason.h>
class VariableSet;
+class CanMessageEvent;
class Event
{
@@ -48,6 +49,11 @@ public:
// Queue an event, or release it if we have a similar event pending already. Returns true if the event was added, false if it was released.
static bool AddEventV(EventType et, uint16_t p_param, CanAddress p_ba, uint8_t devNum, const char *_ecv_array format, va_list vargs) noexcept;
+#if SUPPORT_CAN_EXPANSION
+ // Queue an event received via CAN
+ static void Add(const CanMessageEvent& msg, CanAddress src, size_t msgLen) noexcept;
+#endif
+
// Get the highest priority event if there is one start processing it
static bool StartProcessing() noexcept;
diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp
index 58dc2a2a..7c8b9a8b 100644
--- a/src/Platform/Platform.cpp
+++ b/src/Platform/Platform.cpp
@@ -725,14 +725,9 @@ void Platform::Init() noexcept
temperatureShutdownDrivers.Clear();
temperatureWarningDrivers.Clear();
shortToGroundDrivers.Clear();
- openLoadADrivers.Clear();
- openLoadBDrivers.Clear();
- notOpenLoadADrivers.Clear();
- notOpenLoadBDrivers.Clear();
#endif
#if HAS_STALL_DETECT
- stalledDrivers.Clear();
logOnStallDrivers.Clear();
eventOnStallDrivers.Clear();
#endif
@@ -1088,16 +1083,25 @@ void Platform::Spin() noexcept
// Check one TMC2660 or TMC2224 for temperature warning or temperature shutdown
if (enableValues[nextDriveToPoll] >= 0) // don't poll driver if it is flagged "no poll"
{
- const StandardDriverStatus stat = SmartDrivers::GetStatus(nextDriveToPoll, true, true);
+ StandardDriverStatus stat = SmartDrivers::GetStatus(nextDriveToPoll, true, true);
const DriversBitmap mask = DriversBitmap::MakeFromBits(nextDriveToPoll);
if (stat.ot)
{
temperatureShutdownDrivers |= mask;
}
- else if (stat.otpw)
+ else
{
- temperatureWarningDrivers |= mask;
+ temperatureShutdownDrivers &= ~mask;
+ if (stat.otpw)
+ {
+ temperatureWarningDrivers |= mask;
+ }
+ else
+ {
+ temperatureWarningDrivers &= ~mask;
+ }
}
+
if (stat.s2ga || stat.s2gb || stat.s2vsa || stat.s2vsb)
{
shortToGroundDrivers |= mask;
@@ -1107,73 +1111,80 @@ void Platform::Spin() noexcept
shortToGroundDrivers &= ~mask;
}
+ // Deal with the open load bits
// The driver often produces a transient open-load error, especially in stealthchop mode, so we require the condition to persist before we report it.
- // Also, false open load indications persist when in standstill, if the phase has zero current in that position
- if (stat.ola)
+ // So clear them unless they have been active for the minimum time.
+ MillisTimer& timer = openLoadTimers[nextDriveToPoll];
+ if (stat.IsAnyOpenLoadBitSet())
{
- if (!openLoadATimer.IsRunning())
+ if (timer.IsRunning())
{
- openLoadATimer.Start();
- openLoadADrivers.Clear();
- notOpenLoadADrivers.Clear();
+ if (!timer.Check(OpenLoadTimeout))
+ {
+ stat.ClearOpenLoadBits();
+ }
}
- openLoadADrivers |= mask;
- }
- else if (openLoadATimer.IsRunning())
- {
- notOpenLoadADrivers |= mask;
- if (openLoadADrivers.Disjoint(~notOpenLoadADrivers))
+ else
{
- openLoadATimer.Stop();
+ timer.Start();
+ stat.ClearOpenLoadBits();
}
}
+ else
+ {
+ timer.Stop();
+ }
- if (stat.olb)
+ const StandardDriverStatus oldStatus = lastEventStatus[nextDriveToPoll];
+ lastEventStatus[nextDriveToPoll] = stat;
+ if (stat.HasNewErrorSince(oldStatus))
{
- if (!openLoadBTimer.IsRunning())
+ // It's a new error
+# if SUPPORT_REMOTE_COMMANDS
+ if (CanInterface::InExpansionMode())
{
- openLoadBTimer.Start();
- openLoadBDrivers.Clear();
- notOpenLoadBDrivers.Clear();
+ CanInterface::RaiseEvent(EventType::driver_error, stat.AsU16(), nextDriveToPoll, "", va_list());
+ }
+ else
+#endif
+ {
+ Event::AddEvent(EventType::driver_error, stat.AsU16(), CanInterface::GetCanAddress(), nextDriveToPoll, "");
}
- openLoadBDrivers |= mask;
}
- else if (openLoadBTimer.IsRunning())
+ else if (stat.HasNewWarningSince(oldStatus))
{
- notOpenLoadBDrivers |= mask;
- if (openLoadBDrivers.Disjoint(~notOpenLoadBDrivers))
+ // It's a new warning
+# if SUPPORT_REMOTE_COMMANDS
+ if (CanInterface::InExpansionMode())
{
- openLoadBTimer.Stop();
+ CanInterface::RaiseEvent(EventType::driver_warning, stat.AsU16(), nextDriveToPoll, "", va_list());
+ }
+ else
+#endif
+ {
+ Event::AddEvent(EventType::driver_warning, stat.AsU16(), CanInterface::GetCanAddress(), nextDriveToPoll, "");
}
}
# if HAS_STALL_DETECT
- if (stat.stall)
+ if (stat.HasNewStallSince(oldStatus) && reprap.GetGCodes().IsReallyPrinting())
{
- if (stalledDrivers.Disjoint(mask) && reprap.GetGCodes().IsReallyPrinting())
- {
- // This stall is new so check whether we need to perform some action in response to the stall
+ // This stall is new so check whether we need to perform some action in response to the stall
# if SUPPORT_REMOTE_COMMANDS
- if (CanInterface::InExpansionMode())
- {
- CanInterface::RaiseEvent(EventType::driver_stall, 0, nextDriveToPoll, "", va_list());
- }
- else
+ if (CanInterface::InExpansionMode())
+ {
+ CanInterface::RaiseEvent(EventType::driver_stall, 0, nextDriveToPoll, "", va_list());
+ }
+ else
# endif
- if (eventOnStallDrivers.Intersects(mask))
- {
- Event::AddEvent(EventType::driver_stall, 0, CanInterface::GetCanAddress(), nextDriveToPoll, "");
- }
- else if (logOnStallDrivers.Intersects(mask))
- {
- MessageF(WarningMessage, "Driver %u stalled at Z height %.2f", nextDriveToPoll, (double)reprap.GetMove().LiveCoordinate(Z_AXIS, reprap.GetCurrentTool()));
- }
+ if (eventOnStallDrivers.Intersects(mask))
+ {
+ Event::AddEvent(EventType::driver_stall, 0, CanInterface::GetCanAddress(), nextDriveToPoll, "");
+ }
+ else if (logOnStallDrivers.Intersects(mask))
+ {
+ MessageF(WarningMessage, "Driver %u stalled at Z height %.2f", nextDriveToPoll, (double)reprap.GetMove().LiveCoordinate(Z_AXIS, reprap.GetCurrentTool()));
}
- stalledDrivers |= mask;
- }
- else
- {
- stalledDrivers &= ~mask;
}
# endif
}
@@ -1207,15 +1218,13 @@ void Platform::Spin() noexcept
{
driversPowered = true;
#if HAS_SMART_DRIVERS
- openLoadATimer.Stop();
- openLoadBTimer.Stop();
+ for (size_t i= 0; i < MaxSmartDrivers; ++i)
+ {
+ openLoadTimers[i].Stop();
+ }
temperatureShutdownDrivers.Clear();
temperatureWarningDrivers.Clear();
shortToGroundDrivers.Clear();
- openLoadADrivers.Clear();
- openLoadBDrivers.Clear();
- notOpenLoadADrivers.Clear();
- notOpenLoadBDrivers.Clear();
#endif
}
@@ -1249,43 +1258,6 @@ void Platform::Spin() noexcept
if (now - lastDriverPollMillis > MinimumWarningInterval)
{
bool reported = false;
-#if HAS_SMART_DRIVERS
- ReportDrivers(ErrorMessage, shortToGroundDrivers, "short-to-ground", reported);
- ReportDrivers(ErrorMessage, temperatureShutdownDrivers, "over temperature shutdown", reported);
- if (openLoadATimer.CheckAndStop(OpenLoadTimeout))
- {
- ReportDrivers(WarningMessage, openLoadADrivers, "motor phase A may be disconnected", reported);
- }
- if (openLoadBTimer.CheckAndStop(OpenLoadTimeout))
- {
- ReportDrivers(WarningMessage, openLoadBDrivers, "motor phase B may be disconnected", reported);
- }
-
- // Don't warn about a hot driver if we recently turned on a fan to cool it
- if (temperatureWarningDrivers.IsNonEmpty())
- {
- const DriversBitmap driversMonitored[NumTmcDriversSenseChannels] =
-# ifdef DUET_NG
- { DriversBitmap::MakeLowestNBits(5), DriversBitmap::MakeLowestNBits(5).ShiftUp(5) }; // first channel is Duet, second is DueX5
-# elif defined(DUET_M)
- { DriversBitmap::MakeLowestNBits(5), DriversBitmap::MakeLowestNBits(2).ShiftUp(5) }; // first channel is Duet, second is daughter board
-# else
- { DriversBitmap::MakeLowestNBits(NumDirectDrivers) };
-# endif
- for (unsigned int i = 0; i < NumTmcDriversSenseChannels; ++i)
- {
- if (driversFanTimers[i].IsRunning())
- {
- const bool timedOut = driversFanTimers[i].CheckAndStop(DriverCoolingTimeout);
- if (!timedOut)
- {
- temperatureWarningDrivers &= ~driversMonitored[i];
- }
- }
- }
- ReportDrivers(WarningMessage, temperatureWarningDrivers, "high temperature", reported);
- }
-#endif
#if HAS_VOLTAGE_MONITOR
if (numVinOverVoltageEvents != previousVinOverVoltageEvents)
@@ -2374,28 +2346,6 @@ GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, Ou
return GCodeResult::ok;
}
-#if HAS_SMART_DRIVERS
-
-// This is called when a fan that monitors driver temperatures is turned on when it was off
-void Platform::DriverCoolingFansOnOff(DriverChannelsBitmap driverChannelsMonitored, bool on) noexcept
-{
- driverChannelsMonitored.Iterate
- ([this, on](unsigned int i, unsigned int) noexcept
- {
- if (on)
- {
- this->driversFanTimers[i].Start();
- }
- else
- {
- this->driversFanTimers[i].Stop();
- }
- }
- );
-}
-
-#endif
-
// Get the index of the averaging filter for an analog port.
// Note, the Thermistor code assumes that this is also the thermistor input number
int Platform::GetAveragingFilterIndex(const IoPort& port) const noexcept
@@ -3005,8 +2955,10 @@ void Platform::SetEnableValue(size_t driver, int8_t eVal) noexcept
temperatureShutdownDrivers &= mask;
temperatureWarningDrivers &= mask;
shortToGroundDrivers &= mask;
- openLoadADrivers &= mask;
- openLoadBDrivers &= mask;
+ if (driver < MaxSmartDrivers)
+ {
+ openLoadTimers[driver].Stop();
+ }
}
#endif
}
@@ -5044,7 +4996,7 @@ void Platform::SendDriversStatus(CanMessageBuffer& buf) noexcept
msg->SetStandardFields(MaxSmartDrivers);
for (size_t driver = 0; driver < MaxSmartDrivers; ++driver)
{
- msg->data[driver] = SmartDrivers::GetStatus(driver);
+ msg->data[driver] = SmartDrivers::GetStatus(driver).AsU32();
}
# else
msg->SetStandardFields(NumDrivers);
diff --git a/src/Platform/Platform.h b/src/Platform/Platform.h
index 2ccf6acc..fca11c6a 100644
--- a/src/Platform/Platform.h
+++ b/src/Platform/Platform.h
@@ -583,7 +583,6 @@ public:
#if HAS_SMART_DRIVERS
float GetTmcDriversTemperature(unsigned int boardNumber) const noexcept;
- void DriverCoolingFansOnOff(DriverChannelsBitmap driverChannelsMonitored, bool on) noexcept;
unsigned int GetNumSmartDrivers() const noexcept { return numSmartDrivers; }
#endif
@@ -758,11 +757,10 @@ private:
float minimumMovementSpeed; // minimum allowed movement speed in mm per step clock
#if HAS_SMART_DRIVERS
- size_t numSmartDrivers; // the number of TMC drivers we have, the remaining are simple enable/step/dir drivers
+ size_t numSmartDrivers; // the number of TMC drivers we have, the remaining are simple enable/step/dir drivers
DriversBitmap temperatureShutdownDrivers, temperatureWarningDrivers, shortToGroundDrivers;
- DriversBitmap openLoadADrivers, openLoadBDrivers, notOpenLoadADrivers, notOpenLoadBDrivers;
- MillisTimer openLoadATimer, openLoadBTimer;
- MillisTimer driversFanTimers[NumTmcDriversSenseChannels]; // driver cooling fan timers
+ MillisTimer openLoadTimers[MaxSmartDrivers];
+ StandardDriverStatus lastEventStatus[MaxSmartDrivers];
uint8_t nextDriveToPoll;
#endif
@@ -774,7 +772,6 @@ private:
#if HAS_STALL_DETECT
DriversBitmap logOnStallDrivers, eventOnStallDrivers;
- DriversBitmap stalledDrivers;
#endif
#if defined(__LPC17xx__)
diff --git a/src/Version.h b/src/Version.h
index fa5b9479..df884df1 100644
--- a/src/Version.h
+++ b/src/Version.h
@@ -10,7 +10,7 @@
#ifndef VERSION
// Note: the complete VERSION string must be in standard version number format and must not contain spaces! This is so that DWC can parse it.
-# define MAIN_VERSION "3.4.0beta6+3"
+# define MAIN_VERSION "3.4.0beta7"
# ifdef USE_CAN0
# define VERSION_SUFFIX "(CAN0)"
# else