Jelajahi Sumber

Hack around old MMU FW's msgs

D.R.racer 2 tahun lalu
induk
melakukan
b6b265e371
2 mengubah file dengan 80 tambahan dan 43 penghapusan
  1. 41 41
      Firmware/mmu2/errors_list.h
  2. 39 2
      Firmware/mmu2_protocol_logic.cpp

+ 41 - 41
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::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::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::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::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::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]));

+ 39 - 2
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: