diff --git a/Firmware/mmu2.cpp b/Firmware/mmu2.cpp index dcc070ce0..045d9deff 100644 --- a/Firmware/mmu2.cpp +++ b/Firmware/mmu2.cpp @@ -237,7 +237,7 @@ bool MMU2::WaitForMMUReady() { } } -bool MMU2::RetryIfPossible(uint16_t ec) { +bool MMU2::RetryIfPossible(ErrorCode ec) { if (logic.RetryAttempts()) { SetButtonResponse(ButtonOperations::Retry); // check, that Retry is actually allowed on that operation @@ -713,7 +713,7 @@ void MMU2::ResumeUnpark() { } void MMU2::CheckUserInput() { - auto btn = ButtonPressed((uint16_t)lastErrorCode); + auto btn = ButtonPressed(lastErrorCode); // Was a button pressed on the MMU itself instead of the LCD? if (btn == Buttons::NoButton && lastButton != Buttons::NoButton) { @@ -976,7 +976,7 @@ void MMU2::ReportError(ErrorCode ec, ErrorSource res) { if (ec != lastErrorCode) { // deduplicate: only report changes in error codes into the log lastErrorCode = ec; lastErrorSource = res; - LogErrorEvent_P(_O(PrusaErrorTitle(PrusaErrorCodeIndex((uint16_t)ec)))); + LogErrorEvent_P(_O(PrusaErrorTitle(PrusaErrorCodeIndex(ec)))); if (ec != ErrorCode::OK && ec != ErrorCode::FILAMENT_EJECTED && ec != ErrorCode::FILAMENT_CHANGE) { IncrementMMUFails(); @@ -999,7 +999,7 @@ void MMU2::ReportError(ErrorCode ec, ErrorSource res) { } } - if (!mmu2.RetryIfPossible((uint16_t)ec)) { + if (!mmu2.RetryIfPossible(ec)) { // If retry attempts are all used up // or if 'Retry' operation is not available // raise the MMU error sceen and wait for user input diff --git a/Firmware/mmu2.h b/Firmware/mmu2.h index 0c4df18e1..6040eebb9 100644 --- a/Firmware/mmu2.h +++ b/Firmware/mmu2.h @@ -182,7 +182,7 @@ public: /// Automagically "press" a Retry button if we have any retry attempts left /// @param ec ErrorCode enum value /// @returns true if auto-retry is ongoing, false when retry is unavailable or retry attempts are all used up - bool RetryIfPossible(uint16_t ec); + bool RetryIfPossible(ErrorCode ec); /// @return count for toolchange in current print inline uint16_t ToolChangeCounter() const { return toolchange_counter; }; diff --git a/Firmware/mmu2_error_converter.cpp b/Firmware/mmu2_error_converter.cpp index 20edb0336..1c760b94b 100644 --- a/Firmware/mmu2_error_converter.cpp +++ b/Firmware/mmu2_error_converter.cpp @@ -35,116 +35,125 @@ static_assert( FindErrorIndex(ERR_MECHANICAL_FINDA_FILAMENT_STUCK) == 1); static_assert( FindErrorIndex(ERR_MECHANICAL_FSENSOR_DIDNT_TRIGGER) == 2); static_assert( FindErrorIndex(ERR_MECHANICAL_FSENSOR_FILAMENT_STUCK) == 3); -uint8_t PrusaErrorCodeIndex(uint16_t ec) { +constexpr ErrorCode operator&(ErrorCode a, ErrorCode b){ + return (ErrorCode)((uint16_t)a & (uint16_t)b); +} + +constexpr bool ContainsBit(ErrorCode ec, ErrorCode mask){ + return (uint16_t)ec & (uint16_t)mask; +} + +uint8_t PrusaErrorCodeIndex(ErrorCode ec) { switch (ec) { - case (uint16_t)ErrorCode::FINDA_DIDNT_SWITCH_ON: + case ErrorCode::FINDA_DIDNT_SWITCH_ON: return FindErrorIndex(ERR_MECHANICAL_FINDA_DIDNT_TRIGGER); - case (uint16_t)ErrorCode::FINDA_DIDNT_SWITCH_OFF: + case ErrorCode::FINDA_DIDNT_SWITCH_OFF: return FindErrorIndex(ERR_MECHANICAL_FINDA_FILAMENT_STUCK); - case (uint16_t)ErrorCode::FSENSOR_DIDNT_SWITCH_ON: + case ErrorCode::FSENSOR_DIDNT_SWITCH_ON: return FindErrorIndex(ERR_MECHANICAL_FSENSOR_DIDNT_TRIGGER); - case (uint16_t)ErrorCode::FSENSOR_DIDNT_SWITCH_OFF: + case ErrorCode::FSENSOR_DIDNT_SWITCH_OFF: return FindErrorIndex(ERR_MECHANICAL_FSENSOR_FILAMENT_STUCK); - case (uint16_t)ErrorCode::FSENSOR_TOO_EARLY: + case ErrorCode::FSENSOR_TOO_EARLY: return FindErrorIndex(ERR_MECHANICAL_FSENSOR_TOO_EARLY); - case (uint16_t)ErrorCode::FINDA_FLICKERS: + case ErrorCode::FINDA_FLICKERS: return FindErrorIndex(ERR_MECHANICAL_INSPECT_FINDA); - case (uint16_t)ErrorCode::LOAD_TO_EXTRUDER_FAILED: + case ErrorCode::LOAD_TO_EXTRUDER_FAILED: return FindErrorIndex(ERR_MECHANICAL_LOAD_TO_EXTRUDER_FAILED); - case (uint16_t)ErrorCode::FILAMENT_EJECTED: + case ErrorCode::FILAMENT_EJECTED: return FindErrorIndex(ERR_SYSTEM_FILAMENT_EJECTED); - case (uint16_t)ErrorCode::FILAMENT_CHANGE: + case ErrorCode::FILAMENT_CHANGE: return FindErrorIndex(ERR_SYSTEM_FILAMENT_CHANGE); - case (uint16_t)ErrorCode::STALLED_PULLEY: - case (uint16_t)ErrorCode::MOVE_PULLEY_FAILED: + case ErrorCode::STALLED_PULLEY: + case ErrorCode::MOVE_PULLEY_FAILED: return FindErrorIndex(ERR_MECHANICAL_PULLEY_CANNOT_MOVE); - case (uint16_t)ErrorCode::HOMING_SELECTOR_FAILED: + case ErrorCode::HOMING_SELECTOR_FAILED: return FindErrorIndex(ERR_MECHANICAL_SELECTOR_CANNOT_HOME); - case (uint16_t)ErrorCode::MOVE_SELECTOR_FAILED: + case ErrorCode::MOVE_SELECTOR_FAILED: return FindErrorIndex(ERR_MECHANICAL_SELECTOR_CANNOT_MOVE); - case (uint16_t)ErrorCode::HOMING_IDLER_FAILED: + case ErrorCode::HOMING_IDLER_FAILED: return FindErrorIndex(ERR_MECHANICAL_IDLER_CANNOT_HOME); - case (uint16_t)ErrorCode::MOVE_IDLER_FAILED: + case ErrorCode::MOVE_IDLER_FAILED: return FindErrorIndex(ERR_MECHANICAL_IDLER_CANNOT_MOVE); - case (uint16_t)ErrorCode::MMU_NOT_RESPONDING: + case ErrorCode::MMU_NOT_RESPONDING: return FindErrorIndex(ERR_CONNECT_MMU_NOT_RESPONDING); - case (uint16_t)ErrorCode::PROTOCOL_ERROR: + case ErrorCode::PROTOCOL_ERROR: return FindErrorIndex(ERR_CONNECT_COMMUNICATION_ERROR); - case (uint16_t)ErrorCode::FILAMENT_ALREADY_LOADED: + case ErrorCode::FILAMENT_ALREADY_LOADED: return FindErrorIndex(ERR_SYSTEM_FILAMENT_ALREADY_LOADED); - case (uint16_t)ErrorCode::INVALID_TOOL: + case ErrorCode::INVALID_TOOL: return FindErrorIndex(ERR_SYSTEM_INVALID_TOOL); - case (uint16_t)ErrorCode::QUEUE_FULL: + case ErrorCode::QUEUE_FULL: return FindErrorIndex(ERR_SYSTEM_QUEUE_FULL); - case (uint16_t)ErrorCode::VERSION_MISMATCH: + case ErrorCode::VERSION_MISMATCH: return FindErrorIndex(ERR_SYSTEM_FW_UPDATE_NEEDED); - case (uint16_t)ErrorCode::INTERNAL: + case ErrorCode::INTERNAL: return FindErrorIndex(ERR_SYSTEM_FW_RUNTIME_ERROR); - case (uint16_t)ErrorCode::FINDA_VS_EEPROM_DISREPANCY: + case ErrorCode::FINDA_VS_EEPROM_DISREPANCY: return FindErrorIndex(ERR_SYSTEM_UNLOAD_MANUALLY); - case (uint16_t)ErrorCode::MCU_UNDERVOLTAGE_VCC: + case ErrorCode::MCU_UNDERVOLTAGE_VCC: return FindErrorIndex(ERR_ELECTRICAL_MMU_MCU_ERROR); + default: break; } // Electrical issues which can be detected somehow. // Need to be placed before TMC-related errors in order to process couples of error bits between single ones // and to keep the code size down. - if (ec & (uint16_t)ErrorCode::TMC_PULLEY_BIT) { - if ((ec & (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) == (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) + if (ContainsBit(ec, ErrorCode::TMC_PULLEY_BIT)) { + if ((ec & ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) == ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) return FindErrorIndex(ERR_ELECTRICAL_MMU_PULLEY_SELFTEST_FAILED); - } else if (ec & (uint16_t)ErrorCode::TMC_SELECTOR_BIT) { - if ((ec & (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) == (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) + } else if (ContainsBit(ec, ErrorCode::TMC_SELECTOR_BIT)) { + if ((ec & ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) == ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) return FindErrorIndex(ERR_ELECTRICAL_MMU_SELECTOR_SELFTEST_FAILED); - } else if (ec & (uint16_t)ErrorCode::TMC_IDLER_BIT) { - if ((ec & (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) == (uint16_t)ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) + } else if (ContainsBit(ec, ErrorCode::TMC_IDLER_BIT)) { + if ((ec & ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) == ErrorCode::MMU_SOLDERING_NEEDS_ATTENTION) return FindErrorIndex(ERR_ELECTRICAL_MMU_IDLER_SELFTEST_FAILED); } // TMC-related errors - multiple of these can occur at once // - in such a case we report the first which gets found/converted into Prusa-Error-Codes (usually the fact, that one TMC has an issue is serious enough) // By carefully ordering the checks here we can prioritize the errors being reported to the user. - if (ec & (uint16_t)ErrorCode::TMC_PULLEY_BIT) { - if (ec & (uint16_t)ErrorCode::TMC_IOIN_MISMATCH) + if (ContainsBit(ec, ErrorCode::TMC_PULLEY_BIT)) { + if (ContainsBit(ec, ErrorCode::TMC_IOIN_MISMATCH)) return FindErrorIndex(ERR_ELECTRICAL_TMC_PULLEY_DRIVER_ERROR); - if (ec & (uint16_t)ErrorCode::TMC_RESET) + if (ContainsBit(ec, ErrorCode::TMC_RESET)) return FindErrorIndex(ERR_ELECTRICAL_TMC_PULLEY_DRIVER_RESET); - if (ec & (uint16_t)ErrorCode::TMC_UNDERVOLTAGE_ON_CHARGE_PUMP) + if (ContainsBit(ec, ErrorCode::TMC_UNDERVOLTAGE_ON_CHARGE_PUMP)) return FindErrorIndex(ERR_ELECTRICAL_TMC_PULLEY_UNDERVOLTAGE_ERROR); - if (ec & (uint16_t)ErrorCode::TMC_SHORT_TO_GROUND) + if (ContainsBit(ec, ErrorCode::TMC_SHORT_TO_GROUND)) return FindErrorIndex(ERR_ELECTRICAL_TMC_PULLEY_DRIVER_SHORTED); - if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_WARN) + if (ContainsBit(ec, ErrorCode::TMC_OVER_TEMPERATURE_WARN)) return FindErrorIndex(ERR_TEMPERATURE_WARNING_TMC_PULLEY_TOO_HOT); - if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_ERROR) + if (ContainsBit(ec, ErrorCode::TMC_OVER_TEMPERATURE_ERROR)) return FindErrorIndex(ERR_TEMPERATURE_TMC_PULLEY_OVERHEAT_ERROR); - } else if (ec & (uint16_t)ErrorCode::TMC_SELECTOR_BIT) { - if (ec & (uint16_t)ErrorCode::TMC_IOIN_MISMATCH) + } else if (ContainsBit(ec, ErrorCode::TMC_SELECTOR_BIT)) { + if (ContainsBit(ec, ErrorCode::TMC_IOIN_MISMATCH)) return FindErrorIndex(ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_ERROR); - if (ec & (uint16_t)ErrorCode::TMC_RESET) + if (ContainsBit(ec, ErrorCode::TMC_RESET)) return FindErrorIndex(ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_RESET); - if (ec & (uint16_t)ErrorCode::TMC_UNDERVOLTAGE_ON_CHARGE_PUMP) + if (ContainsBit(ec, ErrorCode::TMC_UNDERVOLTAGE_ON_CHARGE_PUMP)) return FindErrorIndex(ERR_ELECTRICAL_TMC_SELECTOR_UNDERVOLTAGE_ERROR); - if (ec & (uint16_t)ErrorCode::TMC_SHORT_TO_GROUND) + if (ContainsBit(ec, ErrorCode::TMC_SHORT_TO_GROUND)) return FindErrorIndex(ERR_ELECTRICAL_TMC_SELECTOR_DRIVER_SHORTED); - if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_WARN) + if (ContainsBit(ec, ErrorCode::TMC_OVER_TEMPERATURE_WARN)) return FindErrorIndex(ERR_TEMPERATURE_WARNING_TMC_SELECTOR_TOO_HOT); - if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_ERROR) + if (ContainsBit(ec, ErrorCode::TMC_OVER_TEMPERATURE_ERROR)) return FindErrorIndex(ERR_TEMPERATURE_TMC_SELECTOR_OVERHEAT_ERROR); - } else if (ec & (uint16_t)ErrorCode::TMC_IDLER_BIT) { - if (ec & (uint16_t)ErrorCode::TMC_IOIN_MISMATCH) + } else if (ContainsBit(ec, ErrorCode::TMC_IDLER_BIT)) { + if (ContainsBit(ec, ErrorCode::TMC_IOIN_MISMATCH)) return FindErrorIndex(ERR_ELECTRICAL_TMC_IDLER_DRIVER_ERROR); - if (ec & (uint16_t)ErrorCode::TMC_RESET) + if (ContainsBit(ec, ErrorCode::TMC_RESET)) return FindErrorIndex(ERR_ELECTRICAL_TMC_IDLER_DRIVER_RESET); - if (ec & (uint16_t)ErrorCode::TMC_UNDERVOLTAGE_ON_CHARGE_PUMP) + if (ContainsBit(ec, ErrorCode::TMC_UNDERVOLTAGE_ON_CHARGE_PUMP)) return FindErrorIndex(ERR_ELECTRICAL_TMC_IDLER_UNDERVOLTAGE_ERROR); - if (ec & (uint16_t)ErrorCode::TMC_SHORT_TO_GROUND) + if (ContainsBit(ec, ErrorCode::TMC_SHORT_TO_GROUND)) return FindErrorIndex(ERR_ELECTRICAL_TMC_IDLER_DRIVER_SHORTED); - if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_WARN) + if (ContainsBit(ec, ErrorCode::TMC_OVER_TEMPERATURE_WARN)) return FindErrorIndex(ERR_TEMPERATURE_WARNING_TMC_IDLER_TOO_HOT); - if (ec & (uint16_t)ErrorCode::TMC_OVER_TEMPERATURE_ERROR) + if (ContainsBit(ec, ErrorCode::TMC_OVER_TEMPERATURE_ERROR)) return FindErrorIndex(ERR_TEMPERATURE_TMC_IDLER_OVERHEAT_ERROR); } @@ -184,7 +193,7 @@ struct ResetOnExit { } }; -Buttons ButtonPressed(uint16_t ec) { +Buttons ButtonPressed(ErrorCode ec) { if (buttonSelectedOperation == ButtonOperations::NoOperation) { return Buttons::NoButton; // no button } @@ -193,7 +202,7 @@ Buttons ButtonPressed(uint16_t ec) { return ButtonAvailable(ec); } -Buttons ButtonAvailable(uint16_t ec) { +Buttons ButtonAvailable(ErrorCode ec) { uint8_t ei = PrusaErrorCodeIndex(ec); // The list of responses which occur in mmu error dialogs diff --git a/Firmware/mmu2_error_converter.h b/Firmware/mmu2_error_converter.h index 5f24bcb5c..fea2ba2a1 100644 --- a/Firmware/mmu2_error_converter.h +++ b/Firmware/mmu2_error_converter.h @@ -1,13 +1,20 @@ #pragma once #include #include -#include "mmu2/buttons.h" +#ifdef __AVR__ + #include "mmu2/buttons.h" + #include "mmu2/error_codes.h" +#else + #include "buttons.h" + #include "../../../../../../Prusa-Error-Codes/04_MMU/button_operations.h" + #include "../../../../../../Prusa-Firmware-MMU/src/logic/error_codes.h" +#endif namespace MMU2 { /// Translates MMU2::ErrorCode into an index of Prusa-Error-Codes /// Basically this is the way to obtain an index into all other functions in this API -uint8_t PrusaErrorCodeIndex(uint16_t ec); +uint8_t PrusaErrorCodeIndex(ErrorCode ec); /// @returns pointer to a PROGMEM string representing the Title of the Prusa-Error-Codes error /// @param i index of the error - obtained by calling ErrorCodeIndex @@ -38,11 +45,11 @@ void SetButtonResponse(ButtonOperations rsp); /// @returns button index/code based on currently processed error/screen /// Clears the "pressed" button upon exit -Buttons ButtonPressed(uint16_t ec); +Buttons ButtonPressed(ErrorCode ec); /// @returns button index/code based on currently processed error/screen /// Used as a subfunction of ButtonPressed. /// Does not clear the "pressed" button upon exit -Buttons ButtonAvailable(uint16_t ec); +Buttons ButtonAvailable(ErrorCode ec); } // namespace MMU2 diff --git a/Firmware/mmu2_reporting.cpp b/Firmware/mmu2_reporting.cpp index d86f5abb1..f2b0fab45 100644 --- a/Firmware/mmu2_reporting.cpp +++ b/Firmware/mmu2_reporting.cpp @@ -241,7 +241,7 @@ void ReportErrorHook(CommandInProgress /*cip*/, uint16_t ec, uint8_t /*es*/) { ReportErrorHookState = ReportErrorHookStates::DISMISS_ERROR_SCREEN; } - const uint8_t ei = PrusaErrorCodeIndex(ec); + const uint8_t ei = PrusaErrorCodeIndex((ErrorCode)ec); switch ((uint8_t)ReportErrorHookState) { case (uint8_t)ReportErrorHookStates::RENDER_ERROR_SCREEN: