diff options
author | David Crocker <dcrocker@eschertech.com> | 2021-12-13 13:10:01 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2021-12-13 13:10:01 +0300 |
commit | 71ffc1ed37f53fb0d3c94bba75d230d9c8ac5655 (patch) | |
tree | 48e83c92f8ab29ff3a6ab3974217d3fa994b54d1 | |
parent | 635a905a476f2a3a1d9069c75e7b6f27dd2d7a26 (diff) |
Finished first cut of new event handling. No heater fault timers yet.
-rw-r--r-- | src/Comms/FirmwareUpdater.cpp | 5 | ||||
-rw-r--r-- | src/GCodes/GCodeMachineState.h | 7 | ||||
-rw-r--r-- | src/GCodes/GCodes.cpp | 169 | ||||
-rw-r--r-- | src/GCodes/GCodes.h | 77 | ||||
-rw-r--r-- | src/GCodes/GCodes2.cpp | 9 | ||||
-rw-r--r-- | src/GCodes/GCodes3.cpp | 23 | ||||
-rw-r--r-- | src/GCodes/GCodes4.cpp | 60 | ||||
-rw-r--r-- | src/Platform/Event.cpp | 14 | ||||
-rw-r--r-- | src/Platform/Event.h | 11 | ||||
-rw-r--r-- | src/Platform/PrintPausedReason.h | 28 | ||||
-rw-r--r-- | src/SBC/SbcMessageFormats.h | 13 |
11 files changed, 134 insertions, 282 deletions
diff --git a/src/Comms/FirmwareUpdater.cpp b/src/Comms/FirmwareUpdater.cpp index a5283c67..32f0d7e4 100644 --- a/src/Comms/FirmwareUpdater.cpp +++ b/src/Comms/FirmwareUpdater.cpp @@ -7,7 +7,8 @@ #include "FirmwareUpdater.h" -#include <RepRapFirmware.h> +#if HAS_WIFI_NETWORKING || HAS_AUX_DEVICES || HAS_MASS_STORAGE || HAS_SBC_INTERFACE + #include <Platform/Platform.h> #include <Platform/RepRap.h> #include <GCodes/GCodes.h> @@ -141,4 +142,6 @@ namespace FirmwareUpdater } } +#endif + // End diff --git a/src/GCodes/GCodeMachineState.h b/src/GCodes/GCodeMachineState.h index c5ec5bbb..6219aa61 100644 --- a/src/GCodes/GCodeMachineState.h +++ b/src/GCodes/GCodeMachineState.h @@ -54,15 +54,16 @@ enum class GCodeState : uint8_t m109ToolChangeComplete, m109WaitForTemperature, + // These pairs must be contiguous pausing1, pausing2, + eventPausing1, + eventPausing2, + filamentChangePause1, filamentChangePause2, - filamentErrorPause1, - filamentErrorPause2, - resuming1, resuming2, resuming3, diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp index 01291c3f..e40bb387 100644 --- a/src/GCodes/GCodes.cpp +++ b/src/GCodes/GCodes.cpp @@ -69,7 +69,7 @@ GCodes::GCodes(Platform& p) noexcept : #if HAS_VOLTAGE_MONITOR , powerFailScript(nullptr) #endif - , isFlashing(false), isFlashingPanelDue(false), lastFilamentError(FilamentSensorStatus::ok), lastWarningMillis(0) + , isFlashing(false), isFlashingPanelDue(false), lastWarningMillis(0) #if HAS_MASS_STORAGE , sdTimingFile(nullptr) #endif @@ -183,8 +183,6 @@ void GCodes::Init() noexcept laserMaxPower = DefaultMaxLaserPower; laserPowerSticky = false; - heaterFaultState = HeaterFaultState::noFault; - heaterFaultTime = 0; heaterFaultTimeout = DefaultHeaterFaultTimeout; #if SUPPORT_SCANNER @@ -302,7 +300,6 @@ void GCodes::Reset() noexcept firmwareUpdateModuleMap.Clear(); isFlashing = false; isFlashingPanelDue = false; - lastFilamentError = FilamentSensorStatus::ok; currentZProbeNumber = 0; buildObjects.Init(); @@ -435,8 +432,6 @@ void GCodes::Spin() noexcept } CheckTriggers(); - CheckHeaterFault(); - CheckFilament(); // Get the GCodeBuffer that we want to process a command from. Use round-robin scheduling but give priority to auto-pause. GCodeBuffer *gbp = autoPauseGCode; @@ -849,7 +844,8 @@ void GCodes::CheckTriggers() noexcept else if (LockMovement(*triggerGCode)) // need to lock movement before executing the pause macro { triggersPending.ClearBit(lowestTriggerPending); // clear the trigger - DoPause(*triggerGCode, PauseReason::trigger, "Print paused by external trigger"); + DoPause(*triggerGCode, PrintPausedReason::trigger, GCodeState::pausing1); + platform.SendAlert(GenericMessage, "Print paused by external trigger", "Printing paused", 1, 0.0, AxesBitmap()); } } else @@ -863,34 +859,6 @@ void GCodes::CheckTriggers() noexcept } } -// Check for and respond to filament errors -void GCodes::CheckFilament() noexcept -{ - if ( lastFilamentError != FilamentSensorStatus::ok // check for a filament error - && IsReallyPrinting() - && autoPauseGCode->IsCompletelyIdle() - && LockMovement(*autoPauseGCode) // need to lock movement before executing the pause macro - ) - { - String<StringLength50> filamentErrorString; - filamentErrorString.printf("Extruder %u reported '%s'", lastFilamentErrorExtruder, lastFilamentError.ToString()); - DoPause(*autoPauseGCode, PauseReason::filamentError, filamentErrorString.c_str(), (uint16_t)lastFilamentErrorExtruder); - lastFilamentError = FilamentSensorStatus::ok; - filamentErrorString.cat('\n'); - platform.Message(LogWarn, filamentErrorString.c_str()); - } -} - -// Log a filament error. Called by Platform when a filament sensor reports an incorrect status and a print is in progress. -void GCodes::FilamentError(size_t extruder, FilamentSensorStatus fstat) noexcept -{ - if (lastFilamentError == FilamentSensorStatus::ok) - { - lastFilamentErrorExtruder = extruder; - lastFilamentError = fstat; - } -} - // Execute an emergency stop void GCodes::DoEmergencyStop() noexcept { @@ -899,8 +867,9 @@ void GCodes::DoEmergencyStop() noexcept platform.Message(GenericMessage, "Emergency Stop! Reset the controller to continue.\n"); } -// Pause the print. Before calling this, check that we are doing a file print that isn't already paused and get the movement lock. -void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, uint16_t param) noexcept +// Pause the print +// Before calling this, check that we are doing a file print that isn't already paused and get the movement lock. +void GCodes::DoPause(GCodeBuffer& gb, PrintPausedReason reason, GCodeState newState) noexcept { pausedInMacro = false; if (&gb == fileGCode) @@ -1007,68 +976,14 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, uint1 } #endif - GCodeState newState; - switch (reason) - { - case PauseReason::filamentChange: // M600 command - newState = GCodeState::filamentChangePause1; - break; - - case PauseReason::filamentError: // filament monitor - newState = GCodeState::filamentErrorPause1; - break; - - case PauseReason::user: // M25 command received - case PauseReason::gcode: // M25 or M226 command encountered in the file being printed - newState = (gb.Seen('P') && gb.GetUIValue() == 0) ? GCodeState::pausing2 : GCodeState::pausing1; - break; - - case PauseReason::trigger: // external switch - case PauseReason::heaterFault: // heater fault detected -#if HAS_SMART_DRIVERS - case PauseReason::stall: // motor stall detected -#endif - default: - newState = GCodeState::pausing1; - break; - } - gb.SetState(newState, param); + gb.SetState(newState); pauseState = PauseState::pausing; #if HAS_SBC_INTERFACE if (reprap.UsingSbcInterface()) { - // Get the print pause reason that is compatible with the API - PrintPausedReason pauseReason = PrintPausedReason::user; - switch (reason) - { - case PauseReason::gcode: - pauseReason = PrintPausedReason::gcode; - break; - case PauseReason::filamentChange: - pauseReason = PrintPausedReason::filamentChange; - break; - case PauseReason::trigger: - pauseReason = PrintPausedReason::trigger; - break; - case PauseReason::heaterFault: - pauseReason = PrintPausedReason::heaterFault; - break; - case PauseReason::filamentError: - pauseReason = PrintPausedReason::filamentError; - break; -# if HAS_SMART_DRIVERS - case PauseReason::stall: - pauseReason = PrintPausedReason::stall; - break; -# endif - default: - pauseReason = PrintPausedReason::user; - break; - } - // Prepare notification for the SBC - reprap.GetSbcInterface().SetPauseReason(pauseRestorePoint.filePos, pauseReason); + reprap.GetSbcInterface().SetPauseReason(pauseRestorePoint.filePos, reason); } #endif @@ -1077,11 +992,6 @@ void GCodes::DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, uint1 // Make sure we expose usable values (which noFilePosition is not) pauseRestorePoint.filePos = 0; } - - if (msg != nullptr) - { - platform.SendAlert(GenericMessage, msg, "Printing paused", 1, 0.0, AxesBitmap()); - } } // Check if a pause is pending, action it if so @@ -1296,7 +1206,8 @@ bool GCodes::PauseOnStall(DriversBitmap stalledDrivers) noexcept String<StringLength50> stallErrorString; stallErrorString.printf("Stall detected on driver(s)"); ListDrivers(stallErrorString.GetRef(), stalledDrivers); - DoPause(*autoPauseGCode, PauseReason::stall, stallErrorString.c_str()); + DoPause(*autoPauseGCode, PrintPausedReason::stall, GCodeState::pausing1); + platform.SendAlert(GenericMessage, stallErrorString.c_str(), "Printing paused", 1, 0.0, AxesBitmap()); stallErrorString.cat('\n'); platform.Message(LogWarn, stallErrorString.c_str()); return true; @@ -3318,7 +3229,6 @@ void GCodes::StartPrinting(bool fromStart) noexcept } fileGCode->StartNewFile(); - lastFilamentError = FilamentSensorStatus::ok; reprap.GetPrintMonitor().StartedPrint(); platform.MessageF(LogWarn, (IsSimulating()) ? "Started simulating printing file %s\n" : "Started printing file %s\n", @@ -4888,63 +4798,6 @@ const char* GCodes::GetMachineModeString() const noexcept } } -// Respond to a heater fault. The heater has already been turned off and its status set to 'fault' when this is called from the Heat module. -// The Heat module will generate an appropriate error message, so no need to do that here. -void GCodes::HandleHeaterFault() noexcept -{ - if (heaterFaultState == HeaterFaultState::noFault && fileGCode->OriginalMachineState().DoingFile()) - { - heaterFaultState = HeaterFaultState::pausePending; - heaterFaultTime = millis(); - } -} - -// Check for and respond to a heater fault -void GCodes::CheckHeaterFault() noexcept -{ - switch (heaterFaultState) - { - case HeaterFaultState::noFault: - default: - break; - - case HeaterFaultState::pausePending: - if ( IsReallyPrinting() - && autoPauseGCode->IsCompletelyIdle() - && LockMovement(*autoPauseGCode) // need to lock movement before executing the pause macro - ) - { - reprap.GetHeat().SwitchOffAll(false); // turn off all extruder heaters - DoPause(*autoPauseGCode, PauseReason::heaterFault, "Heater fault"); - heaterFaultState = HeaterFaultState::timing; - } - else if (pauseState == PauseState::pausing || pauseState == PauseState::paused) - { - heaterFaultState = HeaterFaultState::timing; - } - // no break - - case HeaterFaultState::timing: - if (millis() - heaterFaultTime >= heaterFaultTimeout) - { - StopPrint(StopPrintReason::abort); - reprap.GetHeat().SwitchOffAll(true); - platform.MessageF(ErrorMessage, "Shutting down due to un-cleared heater fault after %lu seconds\n", heaterFaultTimeout/1000); - heaterFaultState = HeaterFaultState::stopping; - heaterFaultTime = millis(); - } - break; - - case HeaterFaultState::stopping: - if (millis() - heaterFaultTime >= 1000) // wait 1 second for the message to be picked up by DWC and PanelDue - { - platform.AtxPowerOff(); - heaterFaultState = HeaterFaultState::stopped; - } - break; - } -} - // Return a current extrusion factor as a fraction float GCodes::GetExtrusionFactor(size_t extruder) noexcept { @@ -4986,7 +4839,7 @@ bool GCodes::CheckNetworkCommandAllowed(GCodeBuffer& gb, const StringRef& reply, { if (gb.LatestMachineState().runningM502) // when running M502 we don't execute network-related commands { - return false; // just ignore the command but report success + return false; // just ignore the command but report success } #if HAS_SBC_INTERFACE diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h index 3cbddcaa..093c1511 100644 --- a/src/GCodes/GCodes.h +++ b/src/GCodes/GCodes.h @@ -28,8 +28,10 @@ Licence: GPL #include <Movement/RawMove.h> #include <Libraries/sha1/sha1.h> #include <Platform/Platform.h> // for type EndStopHit +#include <Platform/PrintPausedReason.h> #include "GCodeChannel.h" #include "GCodeInput.h" +#include "GCodeMachineState.h" #include "Trigger.h" #include <Tools/Filament.h> #include <FilamentMonitors/FilamentMonitor.h> @@ -54,21 +56,7 @@ enum class MachineType : uint8_t cnc = 2 }; -enum class PauseReason -{ - user, // M25 command received - gcode, // M25 or M226 command encountered in the file being printed - filamentChange, // M600 command - trigger, // external switch - heaterFault, // heater fault detected - filamentError, // filament monitor -#if HAS_SMART_DRIVERS - stall, // motor stall detected -#endif -}; - -// Keep this in sync with PrintStopReason in SBC/SbcMessageFormats.h -enum class StopPrintReason +enum class StopPrintReason : uint8_t { normalCompletion, userCancelled, @@ -189,7 +177,6 @@ public: const char* GetMachineModeString() const noexcept; // Get the name of the current machine mode - void FilamentError(size_t extruder, FilamentSensorStatus fstat) noexcept; void HandleHeaterFault() noexcept; // Respond to a heater fault #if HAS_VOLTAGE_MONITOR @@ -437,62 +424,64 @@ private: GCodeResult ManageTool(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Create a new tool definition void SetToolHeaters(Tool *tool, float temperature, bool both) THROWS(GCodeException); // Set all a tool's heaters to the temperature, for M104/M109 bool ToolHeatersAtSetTemperatures(const Tool *tool, bool waitWhenCooling, float tolerance) const noexcept; - // Wait for the heaters associated with the specified tool to reach their set temperatures - void GenerateTemperatureReport(const StringRef& reply) const noexcept; // Store a standard-format temperature report in reply + // Wait for the heaters associated with the specified tool to reach their set temperatures + void GenerateTemperatureReport(const StringRef& reply) const noexcept; // Store a standard-format temperature report in reply OutputBuffer *GenerateJsonStatusResponse(int type, int seq, ResponseSource source) const noexcept; // Generate a M408 response void CheckReportDue(GCodeBuffer& gb, const StringRef& reply) const noexcept; // Check whether we need to report temperatures or status - void RestorePosition(const RestorePoint& rp, GCodeBuffer *gb) noexcept; // Restore user position from a restore point + void RestorePosition(const RestorePoint& rp, GCodeBuffer *gb) noexcept; // Restore user position from a restore point - void UpdateCurrentUserPosition(const GCodeBuffer& gb) noexcept; // Get the current position from the Move class + void UpdateCurrentUserPosition(const GCodeBuffer& gb) noexcept; // Get the current position from the Move class void ToolOffsetTransform(const float coordsIn[MaxAxes], float coordsOut[MaxAxes], AxesBitmap explicitAxes = AxesBitmap()) const noexcept; - // Convert user coordinates to head reference point coordinates + // Convert user coordinates to head reference point coordinates void ToolOffsetInverseTransform(const float coordsIn[MaxAxes], float coordsOut[MaxAxes]) const noexcept; // Convert head reference point coordinates to user coordinates - float GetCurrentToolOffset(size_t axis) const noexcept; // Get an axis offset of the current tool + float GetCurrentToolOffset(size_t axis) const noexcept; // Get an axis offset of the current tool - GCodeResult RetractFilament(GCodeBuffer& gb, bool retract); // Retract or un-retract filaments - GCodeResult LoadFilament(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Load the specified filament into a tool - GCodeResult UnloadFilament(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Unload the current filament from a tool + GCodeResult RetractFilament(GCodeBuffer& gb, bool retract); // Retract or un-retract filaments + GCodeResult LoadFilament(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Load the specified filament into a tool + GCodeResult UnloadFilament(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Unload the current filament from a tool bool ChangeMicrostepping(size_t axisOrExtruder, unsigned int microsteps, bool interp, const StringRef& reply) const noexcept; // Change microstepping on the specified drive - void CheckTriggers() noexcept; // Check for and execute triggers - void CheckFilament() noexcept; // Check for and respond to filament errors - void CheckHeaterFault() noexcept; // Check for and respond to a heater fault, returning true if we should exit - void DoEmergencyStop() noexcept; // Execute an emergency stop + void CheckTriggers() noexcept; // Check for and execute triggers + void DoEmergencyStop() noexcept; // Execute an emergency stop - void DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg, uint16_t param = 0) noexcept // Pause the print + void DoPause(GCodeBuffer& gb, PrintPausedReason reason, GCodeState newState) noexcept // Pause the print pre(resourceOwners[movementResource] == &gb); - void CheckForDeferredPause(GCodeBuffer& gb) noexcept; // Check if a pause is pending, action it if so - void ProcessEvent(GCodeBuffer& gb) noexcept; // Start processing a new event + void CheckForDeferredPause(GCodeBuffer& gb) noexcept; // Check if a pause is pending, action it if so + void ProcessEvent(GCodeBuffer& gb) noexcept; // Start processing a new event #if HAS_VOLTAGE_MONITOR || HAS_SMART_DRIVERS - bool DoEmergencyPause() noexcept; // Do an emergency pause following loss of power or a motor stall + bool DoEmergencyPause() noexcept; // Do an emergency pause following loss of power or a motor stall #endif - bool IsMappedFan(unsigned int fanNumber) noexcept; // Return true if this fan number is currently being used as a print cooling fan + bool IsMappedFan(unsigned int fanNumber) noexcept; // Return true if this fan number is currently being used as a print cooling fan GCodeResult DefineGrid(GCodeBuffer& gb, const StringRef &reply) THROWS(GCodeException); // Define the probing grid, returning true if error #if HAS_MASS_STORAGE || HAS_SBC_INTERFACE GCodeResult LoadHeightMap(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Load the height map from file - bool TrySaveHeightMap(const char *filename, const StringRef& reply) const noexcept; // Save the height map to the specified file - GCodeResult SaveHeightMap(GCodeBuffer& gb, const StringRef& reply) const; // Save the height map to the file specified by P parameter + bool TrySaveHeightMap(const char *filename, const StringRef& reply) const noexcept; // Save the height map to the specified file + GCodeResult SaveHeightMap(GCodeBuffer& gb, const StringRef& reply) const; // Save the height map to the file specified by P parameter #endif - void ClearBedMapping(); // Stop using bed compensation + void ClearBedMapping(); // Stop using bed compensation GCodeResult ProbeGrid(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Start probing the grid, returning true if we didn't because of an error ReadLockedPointer<ZProbe> SetZProbeNumber(GCodeBuffer& gb, char probeLetter) THROWS(GCodeException); // Set up currentZProbeNumber and return the probe GCodeResult ExecuteG30(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Probes at a given position - see the comment at the head of the function itself - void InitialiseTaps(bool fastThenSlow) noexcept; // Set up to do the first of a possibly multi-tap probe - void SetBedEquationWithProbe(int sParam, const StringRef& reply); // Probes a series of points and sets the bed equation + void InitialiseTaps(bool fastThenSlow) noexcept; // Set up to do the first of a possibly multi-tap probe + void SetBedEquationWithProbe(int sParam, const StringRef& reply); // Probes a series of points and sets the bed equation GCodeResult ConfigureTrigger(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Handle M581 GCodeResult CheckTrigger(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); // Handle M582 - GCodeResult UpdateFirmware(GCodeBuffer& gb, const StringRef &reply) THROWS(GCodeException); // Handle M997 GCodeResult SendI2c(GCodeBuffer& gb, const StringRef &reply) THROWS(GCodeException); // Handle M260 GCodeResult ReceiveI2c(GCodeBuffer& gb, const StringRef &reply) THROWS(GCodeException); // Handle M261 + GCodeResult WaitForPin(GCodeBuffer& gb, const StringRef &reply) THROWS(GCodeException); // Handle M577 + +#if HAS_WIFI_NETWORKING || HAS_AUX_DEVICES || HAS_MASS_STORAGE || HAS_SBC_INTERFACE + GCodeResult UpdateFirmware(GCodeBuffer& gb, const StringRef &reply) THROWS(GCodeException); // Handle M997 +#endif + #if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES GCodeResult SimulateFile(GCodeBuffer& gb, const StringRef &reply, const StringRef& file, bool updateFile) THROWS(GCodeException); // Handle M37 to simulate a whole file GCodeResult ChangeSimulationMode(GCodeBuffer& gb, const StringRef &reply, SimulationMode newSimMode) THROWS(GCodeException); // Handle M37 to change the simulation mode #endif - GCodeResult WaitForPin(GCodeBuffer& gb, const StringRef &reply) THROWS(GCodeException); // Handle M577 #if HAS_MASS_STORAGE || HAS_SBC_INTERFACE GCodeResult WriteConfigOverrideFile(GCodeBuffer& gb, const StringRef& reply) const noexcept; // Write the config-override file @@ -695,17 +684,11 @@ private: GCodeResult AdvanceHash(const StringRef &reply) noexcept; #endif - // Filament monitoring - FilamentSensorStatus lastFilamentError; - size_t lastFilamentErrorExtruder; - // Laser float laserMaxPower; bool laserPowerSticky; // true if G1 S parameters are remembered across G1 commands // Heater fault handler - HeaterFaultState heaterFaultState; // whether there is a heater fault and what we have done about it so far - uint32_t heaterFaultTime; // when the heater fault occurred uint32_t heaterFaultTimeout; // how long we wait for the user to fix it before turning everything off // Object cancellation diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index a04a106b..dee5ea47 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -988,7 +988,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx { return false; } - DoPause(gb, PauseReason::gcode, nullptr); + DoPause(gb, PrintPausedReason::gcode, (gb.Seen('P') && gb.GetUIValue() == 0) ? GCodeState::pausing2 : GCodeState::pausing1); } } break; @@ -1010,7 +1010,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx { return false; } - DoPause(gb, PauseReason::filamentChange, nullptr); + DoPause(gb, PrintPausedReason::filamentChange, GCodeState::filamentChangePause1); } } break; @@ -1043,7 +1043,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx { return false; } - DoPause(gb, PauseReason::user, nullptr); + DoPause(gb, PrintPausedReason::user, GCodeState::pausing1); } break; @@ -3330,7 +3330,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx result = max<GCodeResult>(result, reprap.ClearTemperatureFault(heater, reply)); } } - heaterFaultState = HeaterFaultState::noFault; break; case 563: // Define tool @@ -4525,9 +4524,11 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx break; #endif +#if HAS_WIFI_NETWORKING || HAS_AUX_DEVICES || HAS_MASS_STORAGE || HAS_SBC_INTERFACE case 997: // Perform firmware update result = UpdateFirmware(gb, reply); break; +#endif case 998: // The input handling code replaces the gcode by this when it detects a checksum error. diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp index 0783dc1d..0db8487a 100644 --- a/src/GCodes/GCodes3.cpp +++ b/src/GCodes/GCodes3.cpp @@ -19,7 +19,7 @@ #include <Platform/Tasks.h> #include <Hardware/I2C.h> -#if HAS_WIFI_NETWORKING || HAS_AUX_DEVICES +#if HAS_WIFI_NETWORKING || HAS_AUX_DEVICES || HAS_MASS_STORAGE || HAS_SBC_INTERFACE # include <Comms/FirmwareUpdater.h> #endif @@ -1123,6 +1123,8 @@ GCodeResult GCodes::SetDateTime(GCodeBuffer& gb, const StringRef& reply) THROWS( return GCodeResult::ok; } +#if HAS_WIFI_NETWORKING || HAS_AUX_DEVICES || HAS_MASS_STORAGE || HAS_SBC_INTERFACE + // Handle M997 GCodeResult GCodes::UpdateFirmware(GCodeBuffer& gb, const StringRef &reply) { @@ -1233,6 +1235,8 @@ GCodeResult GCodes::UpdateFirmware(GCodeBuffer& gb, const StringRef &reply) return GCodeResult::ok; } +#endif + // Handle M260 - send and possibly receive via I2C GCodeResult GCodes::SendI2c(GCodeBuffer& gb, const StringRef &reply) { @@ -1891,8 +1895,21 @@ void GCodes::ProcessEvent(GCodeBuffer& gb) noexcept } } - // We didn't execute the macro, so do the default action. It may need to wait for the movement lock, so do it in a new state. - gb.SetState(GCodeState::processingEvent); + // We didn't execute the macro, so do the default action + if (Event::GetDefaultPauseReason() == PrintPausedReason::dontPause) + { + Event::FinishedProcessing(); // nothing more to do + } + else + { + // It's a serious event that causes the print to pause by default, so send an alert + String<StringLength100> eventText; + Event::GetTextDescription(eventText.GetRef()); + platform.SendAlert(GenericMessage, eventText.c_str(), "Printing paused", 1, 0.0, AxesBitmap()); + + // We are going to pause. It may need to wait for the movement lock, so do it in a new state. + gb.SetState(GCodeState::processingEvent); + } } #if !HAS_MASS_STORAGE && !HAS_EMBEDDED_FILES && defined(DUET_NG) diff --git a/src/GCodes/GCodes4.cpp b/src/GCodes/GCodes4.cpp index 2e12fcd9..4324b419 100644 --- a/src/GCodes/GCodes4.cpp +++ b/src/GCodes/GCodes4.cpp @@ -409,6 +409,7 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept break; case GCodeState::pausing1: + case GCodeState::eventPausing1: if (LockMovementAndWaitForStandstill(gb)) { gb.AdvanceState(); @@ -433,28 +434,8 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept } break; - case GCodeState::filamentErrorPause1: - if (LockMovementAndWaitForStandstill(gb)) - { - gb.AdvanceState(); - if (AllAxesAreHomed()) - { - String<StringLength20> macroName; - macroName.printf(FILAMENT_ERROR "%u.g", gb.LatestMachineState().stateParameter); - if (!DoFileMacro(gb, macroName.c_str(), false, AsyncSystemMacroCode)) - { - if (!DoFileMacro(gb, FILAMENT_ERROR ".g", false, AsyncSystemMacroCode)) - { - DoFileMacro(gb, PAUSE_G, true, AsyncSystemMacroCode); - } - } - } - } - break; - case GCodeState::pausing2: case GCodeState::filamentChangePause2: - case GCodeState::filamentErrorPause2: if (LockMovementAndWaitForStandstill(gb)) { reply.printf((gb.GetState() == GCodeState::filamentChangePause2) ? "Printing paused for filament change at" : "Printing paused at"); @@ -471,6 +452,17 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept } break; + case GCodeState::eventPausing2: + if (LockMovementAndWaitForStandstill(gb)) + { + pauseState = PauseState::paused; +#if HAS_SBC_INTERFACE + reportPause = reprap.UsingSbcInterface(); +#endif + gb.SetState(GCodeState::finishedProcessingEvent); + } + break; + case GCodeState::resuming1: case GCodeState::resuming2: // Here when we have just finished running the resume macro file. @@ -1483,30 +1475,20 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept gb.SetState(GCodeState::normal); break; - // Here when we need to execute the default action for an event because the macro file was not found. We have already sent a message and logged the event. + // Here when we need to execute the default action for an event because the macro file was not found, the the default action involves pausing the print. + // We have already sent an alert. case GCodeState::processingEvent: + if (pauseState != PauseState::resuming) // if we are resuming, wait for the resume to complete { - const Event::DefaultAction action = Event::GetDefaultAction(); - if (action == Event::DefaultAction::none) + if (pauseState != PauseState::notPaused) { - // Nothing more to do - gb.SetState(GCodeState::finishedProcessingEvent); + gb.SetState(GCodeState::finishedProcessingEvent); // already paused or pausing } - else + else if (LockMovementAndWaitForStandstill(gb)) { - // We are going to pause - if (pauseState != PauseState::resuming) // if we are resuming, wait for the resume to complete - { - if (pauseState != PauseState::notPaused) - { - gb.SetState(GCodeState::finishedProcessingEvent); // already paused - } - else if (LockMovementAndWaitForStandstill(gb)) - { - gb.SetState(GCodeState::finishedProcessingEvent); - DoPause(gb, qq); - } - } + const PrintPausedReason pauseReason = Event::GetDefaultPauseReason(); + gb.SetState(GCodeState::finishedProcessingEvent); + DoPause(gb, pauseReason, (pauseReason == PrintPausedReason::driverError) ? GCodeState::eventPausing2 : GCodeState::eventPausing1); } } break; diff --git a/src/Platform/Event.cpp b/src/Platform/Event.cpp index 5cf95a67..825caf03 100644 --- a/src/Platform/Event.cpp +++ b/src/Platform/Event.cpp @@ -85,7 +85,7 @@ inline Event::Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint } // Get the default action for the current event -/*static*/ Event::DefaultAction Event::GetDefaultAction() noexcept +/*static*/ PrintPausedReason Event::GetDefaultPauseReason() noexcept { const Event * const ep = eventsPending; if (ep != nullptr && ep->isBeingProcessed) @@ -93,17 +93,19 @@ inline Event::Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint switch (ep->type.RawValue()) { case EventType::heater_fault: + return PrintPausedReason::heaterFault; + case EventType::filament_error: - return DefaultAction::pauseWithMacro; + return PrintPausedReason::filamentError; case EventType::driver_error: - return DefaultAction::pauseNoMacro; + return PrintPausedReason::driverError; default: break; } } - return DefaultAction::none; + return PrintPausedReason::dontPause; } // Mark the highest priority event as completed @@ -142,7 +144,7 @@ inline Event::Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint #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()); + str.printf("Driver %u error: %s", ep->deviceNumber, ep->text.c_str()); #endif return ErrorMessage; @@ -150,7 +152,7 @@ inline Event::Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint #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()); + str.printf("Driver %u warning: %s", ep->deviceNumber, ep->text.c_str()); #endif return WarningMessage; diff --git a/src/Platform/Event.h b/src/Platform/Event.h index 7fc78e14..3f10b4af 100644 --- a/src/Platform/Event.h +++ b/src/Platform/Event.h @@ -29,20 +29,13 @@ #include <General/String.h> #include <General/SafeVsnprintf.h> #include <Platform/MessageType.h> +#include <Platform/PrintPausedReason.h> class VariableSet; class Event { public: - // Type of default action for when there is no macro file to process the event - enum class DefaultAction - { - none, // do nothing other than logging ir - pauseNoMacro, // pause, but don't run pause.g - pauseWithMacro // pause, running pause.g - }; - void* operator new(size_t sz) noexcept { return FreelistManager::Allocate<Event>(); } void operator delete(void* p) noexcept { FreelistManager::Release<Event>(p); } @@ -62,7 +55,7 @@ public: static void GetParameters(VariableSet& vars) noexcept; // Get the default action for the current event - static DefaultAction GetDefaultAction() noexcept; + static PrintPausedReason GetDefaultPauseReason() noexcept; // Mark the highest priority event as completed static void FinishedProcessing() noexcept; diff --git a/src/Platform/PrintPausedReason.h b/src/Platform/PrintPausedReason.h new file mode 100644 index 00000000..bdb26a44 --- /dev/null +++ b/src/Platform/PrintPausedReason.h @@ -0,0 +1,28 @@ +/* + * PrintPausedReason.h + * + * Created on: 12 Dec 2021 + * Author: David + */ + +#ifndef SRC_PLATFORM_PRINTPAUSEDREASON_H_ +#define SRC_PLATFORM_PRINTPAUSEDREASON_H_ + +#include <cstdint> + +// The following values must be kept in sync with DSF! So don't change them unless making major changes to the SBC interface. +enum class PrintPausedReason : uint8_t +{ + dontPause = 0, // used by RRF but not by DSF + user = 1, + gcode = 2, + filamentChange = 3, + trigger = 4, + heaterFault = 5, + filamentError = 6, + stall = 7, + lowVoltage = 8, + driverError = 9 +}; + +#endif /* SRC_PLATFORM_PRINTPAUSEDREASON_H_ */ diff --git a/src/SBC/SbcMessageFormats.h b/src/SBC/SbcMessageFormats.h index 4dc45a96..a053e1f8 100644 --- a/src/SBC/SbcMessageFormats.h +++ b/src/SBC/SbcMessageFormats.h @@ -15,6 +15,7 @@ #include <ctime> #include <RepRapFirmware.h> +#include <Platform/PrintPausedReason.h> constexpr uint8_t SbcFormatCode = 0x5F; // standard format code for RRF SPI protocol constexpr uint8_t SbcFormatCodeStandalone = 0x60; // used to indicate that RRF is running in stand-alone mode @@ -226,18 +227,6 @@ enum class FirmwareRequest : uint16_t CloseFile = 24 // Close a file again }; -enum class PrintPausedReason : uint8_t -{ - user = 1, - gcode = 2, - filamentChange = 3, - trigger = 4, - heaterFault = 5, - filamentError = 6, - stall = 7, - lowVoltage = 8 -}; - struct PrintPausedHeader { uint32_t filePosition; |