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:
Diffstat (limited to 'src/Platform/Event.cpp')
-rw-r--r--src/Platform/Event.cpp192
1 files changed, 145 insertions, 47 deletions
diff --git a/src/Platform/Event.cpp b/src/Platform/Event.cpp
index ddc17eb6..5cf95a67 100644
--- a/src/Platform/Event.cpp
+++ b/src/Platform/Event.cpp
@@ -7,78 +7,176 @@
#include <Platform/Event.h>
#include <RepRapFirmware.h>
+#include <ObjectModel/ObjectModel.h>
+#include <ObjectModel/Variable.h>
-Event::Event(Event *p_next, EventType et, EventParameter p_param, CanAddress p_ba, uint8_t devNum) noexcept
- : next(p_next), param(p_param), type(et), boardAddress(p_ba), deviceNumber(devNum)
+Event *_ecv_null Event::eventsPending = nullptr;
+
+inline Event::Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint8_t devNum, CanAddress p_ba, const char *_ecv_array format, va_list vargs) noexcept
+ : next(pnext), param(p_param), type(et), boardAddress(p_ba), deviceNumber(devNum), isBeingProcessed(false)
{
+ text.vprintf(format, vargs);
}
-void Event::AppendText(const StringRef &str) const noexcept
+// Queue an event unless we have a similar event pending already. Returns true if the event was added.
+// The event list is held in priority order, lowest numbered (highest priority) events first.
+/*static*/ bool Event::AddEvent(EventType et, uint16_t p_param, uint8_t devNum, CanAddress p_ba, const char *_ecv_array format, va_list vargs) noexcept
{
- // First append the event type with underscores changed to spaces
- const char *p = type.ToString();
- while (*p != 0)
- {
- str.cat((*p == '_') ? ' ' : *p);
- ++p;
- }
+ // Search for similar events already pending or being processed.
+ // An event is 'similar' if it has the same type, device number and parameter even if the text is different.
+ TaskCriticalSectionLocker lock;
- // Now append further details of the event
- switch (type.ToBaseType())
+ Event** pe = &eventsPending;
+ while (*pe != nullptr && (et >= (*pe)->type || (*pe)->isBeingProcessed)) // while the next event in the list has same or higher priority than the new one
{
- case EventType::Heater_fault:
- str.catf("on heater %u: %s", deviceNumber, HeaterFaultType(param.heaterFaultStatus).ToString());
- break;
-
- case EventType::Driver_error:
- case EventType::Driver_warning:
+ if (et == (*pe)->type && devNum == (*pe)->deviceNumber
#if SUPPORT_CAN_EXPANSION
- str.catf(" on %u.%u", boardAddress, deviceNumber);
-#else
- str.catf(" on %u", deviceNumber);
+ && p_ba == (*pe)->boardAddress
#endif
- param.driverStatus.AppendText(str, (type == EventType::Driver_error) ? 2 : 1);
- break;
+ )
+ {
+ return false; // there is a similar event already in the queue
+ }
+ pe = &((*pe)->next);
+ }
+
+ // We didn't find a similar event, so add the new one
+ *pe = new Event(*pe, et, p_param, p_ba, devNum, format, vargs);
+ return true;
+}
- case EventType::Filament_error:
- str.catf(" on extruder %u: %s", deviceNumber, FilamentSensorStatus(param.filamentStatus).ToString());
- break;
+// Get the highest priority event and mark it as being serviced
+/*static*/ bool Event::StartProcessing() noexcept
+{
+ TaskCriticalSectionLocker lock;
- case EventType::Main_board_power_failure:
- break;
+ Event * const ev = eventsPending;
+ if (ev == nullptr)
+ {
+ return false;
+ }
+ ev->isBeingProcessed = true;
+ return true;
+}
- case EventType::Trigger:
- str.catf(" %u activated", deviceNumber);
- break;
+// Get the name of the macro that we run when this event occurs
+/*static*/ void Event::GetMacroFileName(const StringRef& fname) noexcept
+{
+ const Event * const ep = eventsPending;
+ if (ep != nullptr && ep->isBeingProcessed)
+ {
+ fname.copy(ep->type.ToString());
+ fname.cat(".g");
+ }
+}
- case EventType::Mcu_temperature_warning:
+// Get the macro parameters for the current event, excluding the S parameter which the caller will add
+/*static*/ void Event::GetParameters(VariableSet& vars) noexcept
+{
+ const Event * const ep = eventsPending;
+ if (ep != nullptr && ep->isBeingProcessed)
+ {
+ vars.InsertNewParameter("D", ExpressionValue((int32_t)(ep->deviceNumber)));
#if SUPPORT_CAN_EXPANSION
- str.catf("on board %u: temperature %.1fC", boardAddress, (double)param.fVal);
-#else
- str.catf(": temperature %.1fC", (double)param.fVal);
+ vars.InsertNewParameter("B", ExpressionValue((int32_t)(ep->boardAddress)));
#endif
- break;
+ vars.InsertNewParameter("P", ExpressionValue((int32_t)(ep->param)));
}
}
-// Append the name of the macro that we run when this event occurs
-void Event::GetMacroFileName(const StringRef& fname) const noexcept
+// Get the default action for the current event
+/*static*/ Event::DefaultAction Event::GetDefaultAction() noexcept
{
- const char *p = type.ToString();
- fname.cat((char)tolower(*p++));
- while (*p != 0)
+ const Event * const ep = eventsPending;
+ if (ep != nullptr && ep->isBeingProcessed)
{
- if (*p == '_' && p[1] != 0)
+ switch (ep->type.RawValue())
{
- fname.cat(toupper(p[1]));
- p += 2;
+ case EventType::heater_fault:
+ case EventType::filament_error:
+ return DefaultAction::pauseWithMacro;
+
+ case EventType::driver_error:
+ return DefaultAction::pauseNoMacro;
+
+ default:
+ break;
}
- else
+ }
+ return DefaultAction::none;
+}
+
+// Mark the highest priority event as completed
+/*static*/ void Event::FinishedProcessing() noexcept
+{
+ TaskCriticalSectionLocker lock;
+
+ const Event *ev = eventsPending;
+ if (ev != nullptr && ev->isBeingProcessed)
+ {
+ eventsPending = ev->next;
+ delete ev;
+ }
+}
+
+// Get a description of the current event
+/*static*/ MessageType Event::GetTextDescription(const StringRef& str) noexcept
+{
+ const Event * const ep = eventsPending;
+ if (ep != nullptr && ep->isBeingProcessed)
+ {
+ switch (ep->type.RawValue())
{
- fname.cat(*p++);
+ case EventType::heater_fault:
+ {
+ const char *_ecv_array heaterFaultText = HeaterFaultText[max<size_t>(ep->param, ARRAY_SIZE(HeaterFaultText) - 1)];
+ str.printf("Heater %u fault: %s%s", ep->deviceNumber, heaterFaultText, ep->text.c_str());
+ }
+ return ErrorMessage;
+
+ case EventType::filament_error:
+ str.printf("Filament error on extruder %u: %s", ep->deviceNumber, FilamentSensorStatus(ep->param).ToString());
+ return ErrorMessage;
+
+ case EventType::driver_error:
+#if SUPPORT_CAN_EXPANSION
+ str.printf("Driver %u.%u error: %s", ep->boardAddress, ep->deviceNumber, ep->text.c_str());
+#else
+ str.printf("Driver %u error: %s", deviceNumber, ep->text.c_str());
+#endif
+ return ErrorMessage;
+
+ case EventType::driver_warning:
+#if SUPPORT_CAN_EXPANSION
+ str.printf("Driver %u.%u warning: %s", ep->boardAddress, ep->deviceNumber, ep->text.c_str());
+#else
+ str.printf("Driver %u warning: %s", deviceNumber, ep->text.c_str());
+#endif
+ return WarningMessage;
+
+ case EventType::driver_stall:
+#if SUPPORT_CAN_EXPANSION
+ str.printf("Driver %u.%u stall", ep->boardAddress, ep->deviceNumber);
+#else
+ str.printf("Driver %u stall", ep->deviceNumber);
+#endif
+ return WarningMessage;
+
+ case EventType::main_board_power_fail:
+ // This does not currently generate an event, so no text
+ return ErrorMessage;
+
+ case EventType::mcu_temperature_warning:
+#if SUPPORT_CAN_EXPANSION
+ str.printf("MCU temperature warning from board %u: temperature %.1fC", ep->boardAddress, (double)((float)ep->param/10));
+#else
+ str.printf("MCU temperature warning: temperature %.1fC", (double)((float)ep->param/10));
+#endif
+ return WarningMessage;
}
}
- fname.cat(".g");
+ str.copy("Internal error in Event");
+ return ErrorMessage;
}
// End