diff --git a/Firmware/mmu2.cpp b/Firmware/mmu2.cpp index 4965a71b0..fe558225b 100644 --- a/Firmware/mmu2.cpp +++ b/Firmware/mmu2.cpp @@ -230,31 +230,26 @@ void MMU2::mmu_loop() { avoidRecursion = false; } -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 - if (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((uint16_t)lastErrorCode); } } -void MMU2::CheckFINDARunout() -{ +void MMU2::CheckFINDARunout() { // Check for FINDA filament runout if (!FindaDetectsFilament() && CHECK_FSENSOR) { SERIAL_ECHOLNPGM("FINDA filament runout!"); stop_and_save_print_to_ram(0, 0); restore_print_from_ram_and_continue(0); - if (SpoolJoin::spooljoin.isSpoolJoinEnabled() && get_current_tool() != (uint8_t)FILAMENT_UNKNOWN) // Can't auto if F=? - { - enquecommand_front_P(PSTR("M600 AUTO")); //save print and run M600 command - } - else - { - enquecommand_front_P(PSTR("M600")); //save print and run M600 command + if (SpoolJoin::spooljoin.isSpoolJoinEnabled() && get_current_tool() != (uint8_t)FILAMENT_UNKNOWN){ // Can't auto if F=? + enquecommand_front_P(PSTR("M600 AUTO")); // save print and run M600 command + } else { + enquecommand_front_P(PSTR("M600")); // save print and run M600 command } } } @@ -303,28 +298,48 @@ void MMU2::ResetRetryAttempts(){ retryAttempts = MAX_RETRIES; } -void MMU2::DecrementRetryAttempts(){ - if (inAutoRetry && retryAttempts) - { +void MMU2::DecrementRetryAttempts() { + if (inAutoRetry && retryAttempts) { SERIAL_ECHOLNPGM("DecrementRetryAttempts"); retryAttempts--; } } -void MMU2::update_tool_change_counter_eeprom() -{ - uint32_t toolchanges = eeprom_read_dword((uint32_t*)EEPROM_TOTAL_TOOLCHANGE_COUNT); +void MMU2::update_tool_change_counter_eeprom() { + uint32_t toolchanges = eeprom_read_dword((uint32_t *)EEPROM_TOTAL_TOOLCHANGE_COUNT); eeprom_update_dword((uint32_t *)EEPROM_TOTAL_TOOLCHANGE_COUNT, toolchanges + (uint32_t)read_toolchange_counter()); reset_toolchange_counter(); } +void MMU2::MMU2::ToolChangeCommon(uint8_t index){ + tool_change_extruder = index; + do { + for(;;) { + logic.ToolChange(index); // let the MMU pull the filament out and push a new one in + if( manage_response(true, true) ) + break; + // otherwise: failed to perform the command - unload first and then let it run again + unload(); + } + // reset current position to whatever the planner thinks it is + plan_set_e_position(current_position[E_AXIS]); + } while (0); // while not successfully fed into etruder's PTFE tube + + extruder = index; //filament change is finished + SpoolJoin::spooljoin.setSlot(index); + + // @@TODO really report onto the serial? May be for the Octoprint? Not important now + // SERIAL_ECHO_START(); + // SERIAL_ECHOLNPAIR(MSG_ACTIVE_EXTRUDER, int(extruder)); + increment_tool_change_counter(); +} + bool MMU2::tool_change(uint8_t index) { if( ! WaitForMMUReady()) return false; if (index != extruder) { - if (!IS_SD_PRINTING && !usb_timer.running()) - { + if (!IS_SD_PRINTING && !usb_timer.running()) { // If Tcodes are used manually through the serial // we need to unload manually as well unload(); @@ -332,25 +347,8 @@ bool MMU2::tool_change(uint8_t index) { ReportingRAII rep(CommandInProgress::ToolChange); FSensorBlockRunout blockRunout; - st_synchronize(); - - tool_change_extruder = index; - logic.ToolChange(index); // let the MMU pull the filament out and push a new one in - if( ! manage_response(true, true) ){ - // @@TODO failed to perform the command - retry - ; - } - // reset current position to whatever the planner thinks it is - plan_set_e_position(current_position[E_AXIS]); - - extruder = index; //filament change is finished - SpoolJoin::spooljoin.setSlot(index); - - // @@TODO really report onto the serial? May be for the Octoprint? Not important now - // SERIAL_ECHO_START(); - // SERIAL_ECHOLNPAIR(MSG_ACTIVE_EXTRUDER, int(extruder)); - increment_tool_change_counter(); + ToolChangeCommon(index); } return true; } @@ -437,11 +435,12 @@ bool MMU2::unload() { ReportingRAII rep(CommandInProgress::UnloadFilament); filament_ramming(); - logic.UnloadFilament(); - if( ! manage_response(false, true) ){ - // @@TODO failed to perform the command - retry - ; - } + // we assume the printer managed to relieve filament tip from the gears, + // so repeating that part in case of an MMU restart is not necessary + do { + logic.UnloadFilament(); + } while( ! manage_response(false, true) ); + Sound_MakeSound(e_SOUND_TYPE_StandardConfirm); // no active tool @@ -489,11 +488,10 @@ bool MMU2::load_filament(uint8_t index) { FullScreenMsg(_T(MSG_LOADING_FILAMENT), index); ReportingRAII rep(CommandInProgress::LoadFilament); - logic.LoadFilament(index); - if( ! manage_response(false, false) ){ - // @@TODO failed to perform the command - retry - ; - } + do { + logic.LoadFilament(index); + } while( ! manage_response(false, false) ); + Sound_MakeSound(e_SOUND_TYPE_StandardConfirm); lcd_update_enable(true); @@ -529,28 +527,11 @@ bool MMU2::load_filament_to_nozzle(uint8_t index) { filament_ramming(); } - tool_change_extruder = index; - logic.ToolChange(index); - if( ! manage_response(true, true) ){ - // @@TODO failed to perform the command - retry - ; - } - - // The MMU's idler is disengaged at this point - // That means the MK3/S now has fully control - - // reset current position to whatever the planner thinks it is - st_synchronize(); - plan_set_e_position(current_position[E_AXIS]); + ToolChangeCommon(index); // Finish loading to the nozzle with finely tuned steps. execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, sizeof(load_to_nozzle_sequence) / sizeof (load_to_nozzle_sequence[0])); - - extruder = index; - SpoolJoin::spooljoin.setSlot(index); - Sound_MakeSound(e_SOUND_TYPE_StandardConfirm); - increment_tool_change_counter(); } lcd_update_enable(true); return true; diff --git a/Firmware/mmu2.h b/Firmware/mmu2.h index e52f7db5e..beaa257fa 100644 --- a/Firmware/mmu2.h +++ b/Firmware/mmu2.h @@ -284,6 +284,9 @@ private: /// @returns false if the MMU is not ready to perform the command (for whatever reason) bool WaitForMMUReady(); + /// Common processing of pushing filament into the extruder - shared by tool_change, load_to_nozzle and probably others + void ToolChangeCommon(uint8_t index); + ProtocolLogic logic; ///< implementation of the protocol logic layer uint8_t extruder; ///< currently active slot in the MMU ... somewhat... not sure where to get it from yet uint8_t tool_change_extruder; ///< only used for UI purposes