Merge pull request #4454 from gudnimg/mmu-sync
MMU: Backport code changes from 32-bit firmware
This commit is contained in:
commit
e7f56118d1
|
|
@ -55,7 +55,7 @@ MMU2::MMU2()
|
||||||
void MMU2::Start() {
|
void MMU2::Start() {
|
||||||
mmu2Serial.begin(MMU_BAUD);
|
mmu2Serial.begin(MMU_BAUD);
|
||||||
|
|
||||||
PowerOn(); // I repurposed this to serve as our EEPROM disable toggle.
|
PowerOn();
|
||||||
mmu2Serial.flush(); // make sure the UART buffer is clear before starting communication
|
mmu2Serial.flush(); // make sure the UART buffer is clear before starting communication
|
||||||
|
|
||||||
extruder = MMU2_NO_TOOL;
|
extruder = MMU2_NO_TOOL;
|
||||||
|
|
@ -63,13 +63,13 @@ void MMU2::Start() {
|
||||||
|
|
||||||
// start the communication
|
// start the communication
|
||||||
logic.Start();
|
logic.Start();
|
||||||
|
|
||||||
logic.ResetRetryAttempts();
|
logic.ResetRetryAttempts();
|
||||||
|
logic.ResetCommunicationTimeoutAttempts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::Stop() {
|
void MMU2::Stop() {
|
||||||
StopKeepPowered();
|
StopKeepPowered();
|
||||||
PowerOff(); // This also disables the MMU in the EEPROM.
|
PowerOff();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::StopKeepPowered() {
|
void MMU2::StopKeepPowered() {
|
||||||
|
|
@ -125,11 +125,9 @@ void MMU2::TriggerResetPin() {
|
||||||
void MMU2::PowerCycle() {
|
void MMU2::PowerCycle() {
|
||||||
// cut the power to the MMU and after a while restore it
|
// cut the power to the MMU and after a while restore it
|
||||||
// Sadly, MK3/S/+ cannot do this
|
// Sadly, MK3/S/+ cannot do this
|
||||||
// NOTE: the below will toggle the EEPROM var. Should we
|
Stop();
|
||||||
// assert this function is never called in the MK3 FW? Do we even care?
|
|
||||||
PowerOff();
|
|
||||||
safe_delay_keep_alive(1000);
|
safe_delay_keep_alive(1000);
|
||||||
PowerOn();
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::PowerOff() {
|
void MMU2::PowerOff() {
|
||||||
|
|
@ -191,12 +189,7 @@ void MMU2::mmu_loop() {
|
||||||
|
|
||||||
void __attribute__((noinline)) MMU2::mmu_loop_inner(bool reportErrors) {
|
void __attribute__((noinline)) MMU2::mmu_loop_inner(bool reportErrors) {
|
||||||
logicStepLastStatus = LogicStep(reportErrors); // it looks like the mmu_loop doesn't need to be a blocking call
|
logicStepLastStatus = LogicStep(reportErrors); // it looks like the mmu_loop doesn't need to be a blocking call
|
||||||
|
CheckErrorScreenUserInput();
|
||||||
if (isErrorScreenRunning()) {
|
|
||||||
// Call this every iteration to keep the knob rotation responsive
|
|
||||||
// This includes when mmu_loop is called within manage_response
|
|
||||||
ReportErrorHook((CommandInProgress)logic.CommandInProgress(), lastErrorCode, uint8_t(lastErrorSource));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::CheckFINDARunout() {
|
void MMU2::CheckFINDARunout() {
|
||||||
|
|
@ -740,7 +733,8 @@ void MMU2::CheckUserInput() {
|
||||||
// ... but mmu2_power.cpp knows this and triggers a soft-reset instead.
|
// ... but mmu2_power.cpp knows this and triggers a soft-reset instead.
|
||||||
break;
|
break;
|
||||||
case Buttons::DisableMMU:
|
case Buttons::DisableMMU:
|
||||||
Stop(); // Poweroff handles updating the EEPROM shutoff.
|
Stop();
|
||||||
|
DisableMMUInSettings();
|
||||||
break;
|
break;
|
||||||
case Buttons::StopPrint:
|
case Buttons::StopPrint:
|
||||||
// @@TODO not sure if we shall handle this high level operation at this spot
|
// @@TODO not sure if we shall handle this high level operation at this spot
|
||||||
|
|
@ -840,45 +834,58 @@ bool MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
StepStatus MMU2::LogicStep(bool reportErrors) {
|
StepStatus MMU2::LogicStep(bool reportErrors) {
|
||||||
CheckUserInput(); // Process any buttons before proceeding with another MMU Query
|
// Process any buttons before proceeding with another MMU Query
|
||||||
StepStatus ss = logic.Step();
|
CheckUserInput();
|
||||||
|
|
||||||
|
const StepStatus ss = logic.Step();
|
||||||
switch (ss) {
|
switch (ss) {
|
||||||
|
|
||||||
case Finished:
|
case Finished:
|
||||||
// At this point it is safe to trigger a runout and not interrupt the MMU protocol
|
// At this point it is safe to trigger a runout and not interrupt the MMU protocol
|
||||||
CheckFINDARunout();
|
CheckFINDARunout();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Processing:
|
case Processing:
|
||||||
OnMMUProgressMsg(logic.Progress());
|
OnMMUProgressMsg(logic.Progress());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonPushed:
|
case ButtonPushed:
|
||||||
lastButton = logic.Button();
|
lastButton = logic.Button();
|
||||||
LogEchoEvent_P(PSTR("MMU Button pushed"));
|
LogEchoEvent_P(PSTR("MMU Button pushed"));
|
||||||
CheckUserInput(); // Process the button immediately
|
CheckUserInput(); // Process the button immediately
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Interrupted:
|
case Interrupted:
|
||||||
// can be silently handed over to a higher layer, no processing necessary at this spot
|
// can be silently handed over to a higher layer, no processing necessary at this spot
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (reportErrors) {
|
if (reportErrors) {
|
||||||
switch (ss) {
|
switch (ss) {
|
||||||
|
|
||||||
case CommandError:
|
case CommandError:
|
||||||
ReportError(logic.Error(), ErrorSourceMMU);
|
ReportError(logic.Error(), ErrorSourceMMU);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CommunicationTimeout:
|
case CommunicationTimeout:
|
||||||
state = xState::Connecting;
|
state = xState::Connecting;
|
||||||
ReportError(ErrorCode::MMU_NOT_RESPONDING, ErrorSourcePrinter);
|
ReportError(ErrorCode::MMU_NOT_RESPONDING, ErrorSourcePrinter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProtocolError:
|
case ProtocolError:
|
||||||
state = xState::Connecting;
|
state = xState::Connecting;
|
||||||
ReportError(ErrorCode::PROTOCOL_ERROR, ErrorSourcePrinter);
|
ReportError(ErrorCode::PROTOCOL_ERROR, ErrorSourcePrinter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VersionMismatch:
|
case VersionMismatch:
|
||||||
StopKeepPowered();
|
StopKeepPowered();
|
||||||
ReportError(ErrorCode::VERSION_MISMATCH, ErrorSourcePrinter);
|
ReportError(ErrorCode::VERSION_MISMATCH, ErrorSourcePrinter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PrinterError:
|
case PrinterError:
|
||||||
ReportError(logic.PrinterError(), ErrorSourcePrinter);
|
ReportError(logic.PrinterError(), ErrorSourcePrinter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -888,6 +895,7 @@ StepStatus MMU2::LogicStep(bool reportErrors) {
|
||||||
if (logic.Running()) {
|
if (logic.Running()) {
|
||||||
state = xState::Active;
|
state = xState::Active;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -160,9 +160,15 @@ public:
|
||||||
/// @returns Current error code
|
/// @returns Current error code
|
||||||
inline ErrorCode MMUCurrentErrorCode() const { return logic.Error(); }
|
inline ErrorCode MMUCurrentErrorCode() const { return logic.Error(); }
|
||||||
|
|
||||||
|
/// @returns Command in progress
|
||||||
|
inline uint8_t GetCommandInProgress() const { return logic.CommandInProgress(); }
|
||||||
|
|
||||||
/// @returns Last error source
|
/// @returns Last error source
|
||||||
inline ErrorSource MMULastErrorSource() const { return lastErrorSource; }
|
inline ErrorSource MMULastErrorSource() const { return lastErrorSource; }
|
||||||
|
|
||||||
|
/// @returns Last error code
|
||||||
|
inline ErrorCode GetLastErrorCode() const { return lastErrorCode; }
|
||||||
|
|
||||||
/// @returns the version of the connected MMU FW.
|
/// @returns the version of the connected MMU FW.
|
||||||
/// In the future we'll return the trully detected FW version
|
/// In the future we'll return the trully detected FW version
|
||||||
Version GetMMUFWVersion() const {
|
Version GetMMUFWVersion() const {
|
||||||
|
|
|
||||||
|
|
@ -186,20 +186,15 @@ const char * PrusaErrorButtonMore(){
|
||||||
return MSG_BTN_MORE;
|
return MSG_BTN_MORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ResetOnExit {
|
|
||||||
ResetOnExit() = default;
|
|
||||||
~ResetOnExit(){
|
|
||||||
buttonSelectedOperation = ButtonOperations::NoOperation;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Buttons ButtonPressed(ErrorCode ec) {
|
Buttons ButtonPressed(ErrorCode ec) {
|
||||||
if (buttonSelectedOperation == ButtonOperations::NoOperation) {
|
if (buttonSelectedOperation == ButtonOperations::NoOperation) {
|
||||||
return Buttons::NoButton; // no button
|
return Buttons::NoButton; // no button
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetOnExit ros; // clear buttonSelectedOperation on exit from this call
|
const auto result = ButtonAvailable(ec);
|
||||||
return ButtonAvailable(ec);
|
buttonSelectedOperation = ButtonOperations::NoOperation; // Reset operation
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buttons ButtonAvailable(ErrorCode ec) {
|
Buttons ButtonAvailable(ErrorCode ec) {
|
||||||
|
|
|
||||||
|
|
@ -4,25 +4,20 @@
|
||||||
#include "fastio.h"
|
#include "fastio.h"
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include "mmu2.h"
|
#include "mmu2.h"
|
||||||
#include "eeprom.h"
|
|
||||||
|
|
||||||
namespace MMU2 {
|
namespace MMU2 {
|
||||||
|
|
||||||
// sadly, on MK3 we cannot do actual power cycle on HW...
|
// On MK3 we cannot do actual power cycle on HW. Instead trigger a hardware reset.
|
||||||
// so we just block the MMU via EEPROM var instead.
|
|
||||||
void power_on() {
|
void power_on() {
|
||||||
#ifdef MMU_HWRESET
|
#ifdef MMU_HWRESET
|
||||||
WRITE(MMU_RST_PIN, 1);
|
WRITE(MMU_RST_PIN, 1);
|
||||||
SET_OUTPUT(MMU_RST_PIN); // setup reset pin
|
SET_OUTPUT(MMU_RST_PIN); // setup reset pin
|
||||||
#endif //MMU_HWRESET
|
#endif //MMU_HWRESET
|
||||||
|
|
||||||
eeprom_update_byte((uint8_t *)EEPROM_MMU_ENABLED, true);
|
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void power_off() {
|
void power_off() {
|
||||||
eeprom_update_byte((uint8_t *)EEPROM_MMU_ENABLED, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ StepStatus ProtocolLogic::ProcessVersionResponse(uint8_t stage) {
|
||||||
SendVersion(stage);
|
SendVersion(stage);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dataTO.Reset(); // got a meaningful response from the MMU, stop data layer timeout tracking
|
ResetCommunicationTimeoutAttempts(); // got a meaningful response from the MMU, stop data layer timeout tracking
|
||||||
SendVersion(stage + 1);
|
SendVersion(stage + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -774,7 +774,7 @@ void ProtocolLogic::LogResponse() {
|
||||||
StepStatus ProtocolLogic::SuppressShortDropOuts(const char *msg_P, StepStatus ss) {
|
StepStatus ProtocolLogic::SuppressShortDropOuts(const char *msg_P, StepStatus ss) {
|
||||||
if (dataTO.Record(ss)) {
|
if (dataTO.Record(ss)) {
|
||||||
LogError(msg_P);
|
LogError(msg_P);
|
||||||
dataTO.Reset(); // prepare for another run of consecutive retries before firing an error
|
ResetCommunicationTimeoutAttempts(); // prepare for another run of consecutive retries before firing an error
|
||||||
return dataTO.InitialCause();
|
return dataTO.InitialCause();
|
||||||
} else {
|
} else {
|
||||||
return Processing; // suppress short drop outs of communication
|
return Processing; // suppress short drop outs of communication
|
||||||
|
|
@ -865,6 +865,11 @@ void ProtocolLogic::ResetRetryAttempts() {
|
||||||
retryAttempts = MAX_RETRIES;
|
retryAttempts = MAX_RETRIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __attribute__((noinline)) ProtocolLogic::ResetCommunicationTimeoutAttempts() {
|
||||||
|
SERIAL_ECHOLNPGM("RSTCommTimeout");
|
||||||
|
dataTO.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
bool DropOutFilter::Record(StepStatus ss) {
|
bool DropOutFilter::Record(StepStatus ss) {
|
||||||
if (occurrences == maxOccurrences) {
|
if (occurrences == maxOccurrences) {
|
||||||
cause = ss;
|
cause = ss;
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,8 @@ public:
|
||||||
/// Reset the retryAttempts back to the default value
|
/// Reset the retryAttempts back to the default value
|
||||||
void ResetRetryAttempts();
|
void ResetRetryAttempts();
|
||||||
|
|
||||||
|
void ResetCommunicationTimeoutAttempts();
|
||||||
|
|
||||||
constexpr bool InAutoRetry() const { return inAutoRetry; }
|
constexpr bool InAutoRetry() const { return inAutoRetry; }
|
||||||
void SetInAutoRetry(bool iar) {
|
void SetInAutoRetry(bool iar) {
|
||||||
inAutoRetry = iar;
|
inAutoRetry = iar;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
|
#include "eeprom.h"
|
||||||
#include "mmu2.h"
|
#include "mmu2.h"
|
||||||
#include "mmu2_log.h"
|
#include "mmu2_log.h"
|
||||||
#include "mmu2_reporting.h"
|
#include "mmu2_reporting.h"
|
||||||
|
|
@ -221,8 +222,12 @@ static bool is_mmu_error_monitor_active;
|
||||||
// Set to false to allow the error screen to render again.
|
// Set to false to allow the error screen to render again.
|
||||||
static bool putErrorScreenToSleep;
|
static bool putErrorScreenToSleep;
|
||||||
|
|
||||||
bool isErrorScreenRunning() {
|
void CheckErrorScreenUserInput() {
|
||||||
return is_mmu_error_monitor_active;
|
if (is_mmu_error_monitor_active) {
|
||||||
|
// Call this every iteration to keep the knob rotation responsive
|
||||||
|
// This includes when mmu_loop is called within manage_response
|
||||||
|
ReportErrorHook((CommandInProgress)mmu2.GetCommandInProgress(), mmu2.GetLastErrorCode(), mmu2.MMULastErrorSource());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TuneMenuEntered() {
|
bool TuneMenuEntered() {
|
||||||
|
|
@ -336,6 +341,11 @@ void TryLoadUnloadReporter::DumpToSerial(){
|
||||||
MMU2_ECHO_MSGLN(buf);
|
MMU2_ECHO_MSGLN(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Disables MMU in EEPROM
|
||||||
|
void DisableMMUInSettings() {
|
||||||
|
eeprom_update_byte((uint8_t *)EEPROM_MMU_ENABLED, false);
|
||||||
|
}
|
||||||
|
|
||||||
void IncrementLoadFails(){
|
void IncrementLoadFails(){
|
||||||
eeprom_increment_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL);
|
eeprom_increment_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL);
|
||||||
eeprom_increment_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT);
|
eeprom_increment_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT);
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@ void BeginReport(CommandInProgress cip, ProgressCode ec);
|
||||||
/// Called at the end of every MMU operation
|
/// Called at the end of every MMU operation
|
||||||
void EndReport(CommandInProgress cip, ProgressCode ec);
|
void EndReport(CommandInProgress cip, ProgressCode ec);
|
||||||
|
|
||||||
/// Return true if the printer's LCD is drawing the error screen
|
/// Checks for error screen user input, if the error screen is open
|
||||||
bool isErrorScreenRunning();
|
void CheckErrorScreenUserInput();
|
||||||
|
|
||||||
/// Return true if the error screen is sleeping in the background
|
/// Return true if the error screen is sleeping in the background
|
||||||
/// Error screen sleeps when the firmware is rendering complementary
|
/// Error screen sleeps when the firmware is rendering complementary
|
||||||
|
|
@ -81,6 +81,9 @@ bool MMUAvailable();
|
||||||
/// Global Enable/Disable use MMU (to be stored in EEPROM)
|
/// Global Enable/Disable use MMU (to be stored in EEPROM)
|
||||||
bool UseMMU();
|
bool UseMMU();
|
||||||
|
|
||||||
|
/// Disables MMU in EEPROM
|
||||||
|
void DisableMMUInSettings();
|
||||||
|
|
||||||
/// Increments EEPROM cell - number of failed loads into the nozzle
|
/// Increments EEPROM cell - number of failed loads into the nozzle
|
||||||
/// Note: technically, this is not an MMU error but an error of the printer.
|
/// Note: technically, this is not an MMU error but an error of the printer.
|
||||||
void IncrementLoadFails();
|
void IncrementLoadFails();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue