diff --git a/Firmware/mmu2/errors_list.h b/Firmware/mmu2/errors_list.h index 921b034d6..827fd8385 100644 --- a/Firmware/mmu2/errors_list.h +++ b/Firmware/mmu2/errors_list.h @@ -148,7 +148,7 @@ static const char titleCOMMUNICATION_ERROR[] PROGMEM_I1 = ISTR("COMMUNICATION ER static const char titleFILAMENT_ALREADY_LOADED[] PROGMEM_I1 = ISTR("FILAMENT ALREADY LOA"); static const char titleINVALID_TOOL[] PROGMEM_I1 = ISTR("INVALID TOOL"); static const char titleQUEUE_FULL[] PROGMEM_I1 = ISTR("QUEUE FULL"); -static const char titleFW_UPDATE_NEEDED[] PROGMEM_I1 = ISTR("FW UPDATE NEEDED"); +static const char titleFW_UPDATE_NEEDED[] PROGMEM_I1 = ISTR("MMU FW UPDATE NEEDED"); static const char titleFW_RUNTIME_ERROR[] PROGMEM_I1 = ISTR("FW RUNTIME ERROR"); static const char titleUNLOAD_MANUALLY[] PROGMEM_I1 = ISTR("UNLOAD MANUALLY"); @@ -301,46 +301,46 @@ uint8_t constexpr Btns(ButtonOperations bMiddle, ButtonOperations bRight){ } static const uint8_t errorButtons[] PROGMEM = { - Btns(ButtonOperations::Retry, ButtonOperations::Continue), - Btns(ButtonOperations::Retry, ButtonOperations::Continue), - Btns(ButtonOperations::Retry, ButtonOperations::Continue), - Btns(ButtonOperations::Retry, ButtonOperations::Continue), - - Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), - Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), - Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), - Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), - Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), - Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), + Btns(ButtonOperations::Retry, ButtonOperations::Continue),//FINDA_DIDNT_TRIGGER + Btns(ButtonOperations::Retry, ButtonOperations::Continue),//FINDA_DIDNT_GO_OFF + Btns(ButtonOperations::Retry, ButtonOperations::Continue),//FSENSOR_DIDNT_TRIGGER + Btns(ButtonOperations::Retry, ButtonOperations::Continue),//FSENSOR_DIDNT_GO_OFF - Btns(ButtonOperations::Continue, ButtonOperations::RestartMMU), - Btns(ButtonOperations::Continue, ButtonOperations::RestartMMU), - Btns(ButtonOperations::Continue, ButtonOperations::RestartMMU), - - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), + Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//PULLEY_STALLED + Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//FSENSOR_TOO_EARLY + Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//SELECTOR_CANNOT_HOME + Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//SELECTOR_CANNOT_MOVE + Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//IDLER_CANNOT_HOME + Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//IDLER_CANNOT_MOVE - Btns(ButtonOperations::Unload, ButtonOperations::Continue), - Btns(ButtonOperations::StopPrint, ButtonOperations::RestartMMU), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::DisableMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation), - Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), + Btns(ButtonOperations::Continue, ButtonOperations::RestartMMU),//PULLEY_WARNING_TMC_TOO_HOT + Btns(ButtonOperations::Continue, ButtonOperations::RestartMMU),//SELECTOR_WARNING_TMC_TOO_HOT + Btns(ButtonOperations::Continue, ButtonOperations::RestartMMU),//IDLER_WARNING_TMC_TOO_HOT + + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_TMC_OVERHEAT_ERROR + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_TMC_OVERHEAT_ERROR + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_TMC_OVERHEAT_ERROR + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_TMC_DRIVER_ERROR + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_TMC_DRIVER_ERROR + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_TMC_DRIVER_ERROR + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_TMC_DRIVER_RESET + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_TMC_DRIVER_RESET + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_TMC_DRIVER_RESET + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_TMC_UNDERVOLTAGE_ERROR + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_TMC_UNDERVOLTAGE_ERROR + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_TMC_UNDERVOLTAGE_ERROR + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_TMC_DRIVER_SHORTED + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_TMC_DRIVER_SHORTED + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_TMC_DRIVER_SHORTED + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//MMU_NOT_RESPONDING + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//COMMUNICATION_ERROR + + Btns(ButtonOperations::Unload, ButtonOperations::Continue),//FILAMENT_ALREADY_LOADED + Btns(ButtonOperations::StopPrint, ButtonOperations::RestartMMU),//INVALID_TOOL + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//QUEUE_FULL + Btns(ButtonOperations::DisableMMU, ButtonOperations::NoOperation),//FW_UPDATE_NEEDED + Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//FW_RUNTIME_ERROR + Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//UNLOAD_MANUALLY }; static_assert( sizeof(errorCodes) / sizeof(errorCodes[0]) == sizeof(errorDescs) / sizeof (errorDescs[0])); diff --git a/Firmware/mmu2_protocol_logic.cpp b/Firmware/mmu2_protocol_logic.cpp index 1492b9058..35c65b1b6 100644 --- a/Firmware/mmu2_protocol_logic.cpp +++ b/Firmware/mmu2_protocol_logic.cpp @@ -56,10 +56,35 @@ StepStatus ProtocolLogic::ProcessUARTByte(uint8_t c) { } } +// searches for "ok\n" in the incoming serial data (that's the usual response of the old MMU FW) +struct OldMMUFWDetector { + uint8_t ok; + inline constexpr OldMMUFWDetector():ok(0) { } + + enum class State : uint8_t { MatchingPart, SomethingElse, Matched }; + + /// @returns true when "ok\n" gets detected + State Detect(uint8_t c){ + // consume old MMU FW's data if any -> avoid confusion of protocol decoder + if(ok == 0 && c == 'o'){ + ++ok; + return State::MatchingPart; + } else if(ok == 1 && c == 'k'){ + ++ok; + return State::MatchingPart; + } else if(ok == 2 && c == '\n'){ + return State::Matched; + } + return State::SomethingElse; + } +}; + StepStatus ProtocolLogic::ExpectingMessage(uint32_t timeout) { int bytesConsumed = 0; int c = -1; + OldMMUFWDetector oldMMUh4x0r; // old MMU FW hacker ;) + // try to consume as many rx bytes as possible (until a message has been completed) while((c = uart->read()) >= 0){ ++bytesConsumed; @@ -72,7 +97,19 @@ StepStatus ProtocolLogic::ExpectingMessage(uint32_t timeout) { return MessageReady; case DecodeStatus::NeedMoreData: break; - case DecodeStatus::Error: + case DecodeStatus::Error:{ + // consume old MMU FW's data if any -> avoid confusion of protocol decoder + auto old = oldMMUh4x0r.Detect(c); + if( old == OldMMUFWDetector::State::Matched ){ + // hack bad FW version - BEWARE - we silently assume that the first query is an "S0" + // The old MMU FW responds with "ok\n" and we fake the response to a bad FW version at this spot + rsp = ResponseMsg(RequestMsg(RequestMsgCodes::Version, 0), ResponseMsgParamCodes::Accepted, 0); + return MessageReady; + } else if( old == OldMMUFWDetector::State::MatchingPart ){ + break; + } + } + // otherwise [[fallthrough]] default: RecordUARTActivity(); // something has happened on the UART, update the timeout record return ProtocolError; @@ -394,7 +431,7 @@ void ProtocolLogic::RecordReceivedByte(uint8_t c){ lrb = (lrb+1) % lastReceivedBytes.size(); } -char NibbleToChar(uint8_t c){ +constexpr char NibbleToChar(uint8_t c){ switch (c) { case 0: case 1: