| 
					
				 | 
			
			
				@@ -1466,74 +1466,109 @@ static void load_more() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     st_synchronize(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void increment_load_fail() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint8_t mmu_load_fail = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint16_t mmu_load_fail_tot = eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(mmu_load_fail < 255) eeprom_update_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL, mmu_load_fail + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(mmu_load_fail_tot < 65535) eeprom_update_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT, mmu_load_fail_tot + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! @brief continue loading filament 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //! @par blocking 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//!  * true blocking 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//!  * false non-blocking 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//!  * true blocking - do not return until successful load 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//!  * false non-blocking - pause print and return on load failure 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! @startuml 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! [*] --> [*] : !ir_sensor_detected /\n send MmuCmd::C0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! [*] --> LoadMore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! LoadMore --> [*] : filament \ndetected 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! LoadMore --> Retry : !filament detected /\n increment load fail 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! Retry --> [*] : filament \ndetected 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! Retry --> Unload : !filament \ndetected 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! Unload --> [*] : non-blocking 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! Unload --> Retry : button \nclicked 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! Retry : Cut filament if enabled 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! Retry : repeat last T-code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! Unload : unload filament 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! Unload : pause print 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! Unload : show error message 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//! @enduml 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void mmu_continue_loading(bool blocking) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (ir_sensor_detected) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!ir_sensor_detected) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	    load_more(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	    mmu_command(MmuCmd::C0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (PIN_GET(IR_SENSOR_PIN) != 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			uint8_t mmu_load_fail = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			uint16_t mmu_load_fail_tot = eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if(mmu_load_fail < 255) eeprom_update_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL, mmu_load_fail + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if(mmu_load_fail_tot < 65535) eeprom_update_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT, mmu_load_fail_tot + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    load_more(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    enum class Ls : uint_least8_t 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        enter, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        retry, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        unload, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Ls state = Ls::enter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while (PIN_GET(IR_SENSOR_PIN) != 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        switch (state) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case Ls::enter: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            increment_load_fail(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // no break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case Ls::retry: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef MMU_HAS_CUTTER 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (1 == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			    mmu_command(MmuCmd::K0 + tmp_extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			    manage_response(true, true, MMU_UNLOAD_MOVE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (1 == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                mmu_command(MmuCmd::K0 + tmp_extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                manage_response(true, true, MMU_UNLOAD_MOVE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif //MMU_HAS_CUTTER 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             mmu_command(MmuCmd::T0 + tmp_extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             manage_response(true, true, MMU_TCODE_MOVE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             load_more(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (PIN_GET(IR_SENSOR_PIN) != 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            state = Ls::unload; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case Ls::unload: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            stop_and_save_print_to_ram(0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //lift z 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            current_position[Z_AXIS] += Z_PAUSE_LIFT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 15, active_extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            st_synchronize(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //Move XY to side 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            current_position[X_AXIS] = X_PAUSE_POS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            current_position[Y_AXIS] = Y_PAUSE_POS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 50, active_extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            st_synchronize(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mmu_command(MmuCmd::U0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            manage_response(false, true, MMU_UNLOAD_MOVE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            setAllTargetHotends(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            lcd_setstatuspgm(_i("MMU load failed     "));////c=20 r=1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (blocking) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //pause print, show error message and then repeat last T-code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                stop_and_save_print_to_ram(0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //lift z 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                current_position[Z_AXIS] += Z_PAUSE_LIFT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 15, active_extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                st_synchronize(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //Move XY to side 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                current_position[X_AXIS] = X_PAUSE_POS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                current_position[Y_AXIS] = Y_PAUSE_POS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 50, active_extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                st_synchronize(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                mmu_command(MmuCmd::U0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                manage_response(false, true, MMU_UNLOAD_MOVE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                setAllTargetHotends(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                lcd_setstatuspgm(_i("MMU load failed     "));////MSG_RECOVERING_PRINT c=20 r=1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (blocking) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    marlin_wait_for_click(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    restore_print_from_ram_and_continue(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    mmu_command(MmuCmd::T0 + tmp_extruder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    manage_response(true, true, MMU_TCODE_MOVE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    load_more(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    mmu_fil_loaded = false; //so we can retry same T-code again 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    isPrintPaused = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    mmu_command(MmuCmd::W0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                marlin_wait_for_click(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                restore_print_from_ram_and_continue(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                state = Ls::retry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	else { //mmu_ir_sensor_detected == false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		mmu_command(MmuCmd::C0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                mmu_fil_loaded = false; //so we can retry same T-code again 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                isPrintPaused = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                mmu_command(MmuCmd::W0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |