Skip to content

Commit

Permalink
Merge branch 'mk3-mmu' into PFW-1375
Browse files Browse the repository at this point in the history
  • Loading branch information
DRracer authored Jul 20, 2022
2 parents b9f79ec + 7bf003d commit 70cb3c8
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 23 deletions.
1 change: 1 addition & 0 deletions Firmware/Marlin.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ extern void print_physical_coordinates();
extern void print_mesh_bed_leveling_table();

extern void stop_and_save_print_to_ram(float z_move, float e_move);
void restore_extruder_temperature_from_ram();
extern void restore_print_from_ram_and_continue(float e_move);
extern void cancel_saved_printing();

Expand Down
18 changes: 11 additions & 7 deletions Firmware/Marlin_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11307,6 +11307,16 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
}
}

void restore_extruder_temperature_from_ram() {
if (degTargetHotend(saved_active_extruder) != saved_extruder_temperature)
{
setTargetHotendSafe(saved_extruder_temperature, saved_active_extruder);
heating_status = HeatingStatus::EXTRUDER_HEATING;
wait_for_heater(_millis(), saved_active_extruder);
heating_status = HeatingStatus::EXTRUDER_HEATING_COMPLETE;
}
}

//! @brief Restore print from ram
//!
//! Restore print saved by stop_and_save_print_to_ram(). Is blocking, restores
Expand All @@ -11330,13 +11340,7 @@ void restore_print_from_ram_and_continue(float e_move)
// current_position[axis] = st_get_position_mm(axis);
active_extruder = saved_active_extruder; //restore active_extruder
fanSpeed = saved_fanSpeed;
if (degTargetHotend(saved_active_extruder) != saved_extruder_temperature)
{
setTargetHotendSafe(saved_extruder_temperature, saved_active_extruder);
heating_status = HeatingStatus::EXTRUDER_HEATING;
wait_for_heater(_millis(), saved_active_extruder);
heating_status = HeatingStatus::EXTRUDER_HEATING_COMPLETE;
}
restore_extruder_temperature_from_ram();
axis_relative_modes ^= (-saved_extruder_relative_mode ^ axis_relative_modes) & E_AXIS_MASK;
float e = saved_pos[E_AXIS] - e_move;
plan_set_e_position(e);
Expand Down
46 changes: 44 additions & 2 deletions Firmware/mmu2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ MMU2::MMU2()
, loadFilamentStarted(false)
, unloadFilamentStarted(false)
, loadingToNozzle(false)
, inAutoRetry(false)
{
ResetRetryAttempts();
}

void MMU2::Start() {
Expand Down Expand Up @@ -223,6 +225,36 @@ bool MMU2::WaitForMMUReady(){
}
}

bool MMU2::RetryIfPossible(uint16_t ec){
if( retryAttempts ){
SERIAL_ECHOPGM("retryAttempts=");SERIAL_ECHOLN((uint16_t)retryAttempts);
SetButtonResponse(ButtonOperations::Retry);
// check, that Retry is actually allowed on that operation
if( ButtonAvailable(ec) != NoButton ){
inAutoRetry = true;
SERIAL_ECHOLNPGM("RetryButtonPressed");
// We don't decrement until the button is acknowledged by the MMU.
//--retryAttempts; // "used" one retry attempt
return true;
}
}
inAutoRetry = false;
return false;
}

void MMU2::ResetRetryAttempts(){
SERIAL_ECHOLNPGM("ResetRetryAttempts");
retryAttempts = MAX_RETRIES;
}

void MMU2::DecrementRetryAttempts(){
if (inAutoRetry && retryAttempts)
{
SERIAL_ECHOLNPGM("DecrementRetryAttempts");
retryAttempts--;
}
}

bool MMU2::tool_change(uint8_t index) {
if( ! WaitForMMUReady())
return false;
Expand Down Expand Up @@ -484,6 +516,7 @@ bool MMU2::eject_filament(uint8_t index, bool recover) {
}

void MMU2::Button(uint8_t index){
SERIAL_ECHOLNPGM("Button");
logic.Button(index);
}

Expand Down Expand Up @@ -586,6 +619,8 @@ void MMU2::CheckUserInput(){
case Left:
case Middle:
case Right:
SERIAL_ECHOPGM("CheckUserInput-btnLMR ");
SERIAL_ECHOLN(btn);
ResumeHotendTemp(); // Recover the hotend temp before we attempt to do anything else...
Button(btn);
break;
Expand Down Expand Up @@ -633,7 +668,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
if (!nozzleTimeout.running())
{
nozzleTimeout.start();
LogEchoEvent(" Cooling Timeout started");
LogEchoEvent("Cooling Timeout started");
}
else if (nozzleTimeout.expired(DEFAULT_SAFETYTIMER_TIME_MINS*60*1000ul)) // mins->msec. TODO: do we use the global or have our own independent timeout
{
Expand All @@ -654,13 +689,20 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
// command/operation completed, let Marlin continue its work
// the E may have some more moves to finish - wait for them
ResumeUnpark(); // We can now travel back to the tower or wherever we were when we saved.
ResetRetryAttempts(); // Reset the retry counter.
st_synchronize();
return;
case VersionMismatch: // this basically means the MMU will be disabled until reconnected
CheckUserInput();
return;
case CommunicationTimeout:
case CommandError:
// Don't proceed to the park/save if we are doing an autoretry.
if (inAutoRetry)
{
continue;
}
/* FALLTHRU */
case CommunicationTimeout:
case ProtocolError:
SaveAndPark(move_axes, turn_off_nozzle); // and wait for the user to resolve the problem
CheckUserInput();
Expand Down
19 changes: 16 additions & 3 deletions Firmware/mmu2.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ struct E_Step;

namespace MMU2 {

static constexpr uint8_t MAX_RETRIES = 3U;

/// @@TODO hmmm, 12 bytes... may be we can reduce that
struct xyz_pos_t {
float xyz[3];
Expand Down Expand Up @@ -165,7 +167,16 @@ class MMU2 {
/// Method to read-only mmu_print_saved
bool MMU_PRINT_SAVED() const { return mmu_print_saved != SavedState::None; }

/// Automagically "press" a Retry button if we have any retry attempts left
bool RetryIfPossible(uint16_t ec);

/// Decrement the retry attempts, if in a retry.
// Called by the MMU protocol when a sent button is acknowledged.
void DecrementRetryAttempts();

private:
/// Reset the retryAttempts back to the default value
void ResetRetryAttempts();
/// Perform software self-reset of the MMU (sends an X0 command)
void ResetX0();

Expand Down Expand Up @@ -222,13 +233,13 @@ class MMU2 {

/// Check for any button/user input coming from the printer's UI
void CheckUserInput();

/// Entry check of all external commands.
/// It can wait until the MMU becomes ready.
/// Optionally, it can also emit/display an error screen and the user can decide what to do next.
/// @returns false if the MMU is not ready to perform the command (for whatever reason)
bool WaitForMMUReady();

ProtocolLogic logic; ///< implementation of the protocol logic layer
int extruder; ///< currently active slot in the MMU ... somewhat... not sure where to get it from yet
uint8_t previous_extruder; ///< last active slot in the MMU, useful for M600
Expand All @@ -254,7 +265,9 @@ class MMU2 {
/// unlike the mid-print ToolChange commands, which only load the first ~30mm and then the G-code takes over.
bool loadingToNozzle;


uint8_t retryAttempts;

bool inAutoRetry;
};

/// following Marlin's way of doing stuff - one and only instance of MMU implementation in the code base
Expand Down
5 changes: 4 additions & 1 deletion Firmware/mmu2_error_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,10 @@ Buttons ButtonPressed(uint16_t ec) {
}

ResetOnExit ros; // clear buttonSelectedOperation on exit from this call

return ButtonAvailable(ec);
}

Buttons ButtonAvailable(uint16_t ec) {
uint8_t ei = PrusaErrorCodeIndex(ec);

// The list of responses which occur in mmu error dialogs
Expand Down
6 changes: 6 additions & 0 deletions Firmware/mmu2_error_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ const char * const PrusaErrorButtonMore();
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);

/// @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);

} // namespace MMU2
13 changes: 9 additions & 4 deletions Firmware/mmu2_protocol_logic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,15 @@ StepStatus Command::Step() {
return ProcessFINDAReqSent(Processing, State::Wait);
case State::ButtonSent:{
// button is never confirmed ... may be it should be
// auto expmsg = logic->ExpectingMessage(linkLayerTimeout);
// if (expmsg != MessageReady)
// return expmsg;
SendQuery();
auto expmsg = logic->ExpectingMessage(linkLayerTimeout);
if (expmsg != MessageReady)
return expmsg;
if (logic->rsp.paramCode == ResponseMsgParamCodes::Accepted)
{
// Button was accepted, decrement the retry.
mmu2.DecrementRetryAttempts();
}
SendAndUpdateFilamentSensor();
} break;
default:
return ProtocolError;
Expand Down
4 changes: 2 additions & 2 deletions Firmware/mmu2_protocol_logic.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ class ProtocolLogic {
return mmuFwVersionMinor;
}

inline uint16_t MmuFwVersionBuild() const {
inline uint8_t MmuFwVersionBuild() const {
return mmuFwVersionBuild;
}
#ifndef UNITTEST
Expand Down Expand Up @@ -320,7 +320,7 @@ class ProtocolLogic {
bool findaPressed;

uint8_t mmuFwVersionMajor, mmuFwVersionMinor;
uint16_t mmuFwVersionBuild;
uint8_t mmuFwVersionBuild;

friend class ProtocolLogicPartBase;
friend class Stopped;
Expand Down
13 changes: 11 additions & 2 deletions Firmware/mmu2_reporting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,22 @@ enum class ReportErrorHookStates : uint8_t {

enum ReportErrorHookStates ReportErrorHookState = ReportErrorHookStates::RENDER_ERROR_SCREEN;

/// @brief Render MMU error screen on the LCD. This must be non-blocking
/// and allow the MMU and printer to communicate with each other.
/// @param[in] ec Error code
void ReportErrorHook(uint16_t ec, uint8_t res) {
if (mmu2.MMUCurrentErrorCode() == ErrorCode::OK && res == MMU2::ErrorSourceMMU)
{
if (mmu2.MMUCurrentErrorCode() == ErrorCode::OK && res == MMU2::ErrorSourceMMU) {
// If the error code suddenly changes to OK, that means
// a button was pushed on the MMU and the LCD should
// dismiss the error screen until MMU raises a new error
ReportErrorHookState = ReportErrorHookStates::DISMISS_ERROR_SCREEN;
} else {
// attempt an automatic Retry button
if( ReportErrorHookState == ReportErrorHookStates::MONITOR_SELECTION ){
if( mmu2.RetryIfPossible(ec) ){
ReportErrorHookState = ReportErrorHookStates::DISMISS_ERROR_SCREEN;
}
}
}

const uint8_t ei = PrusaErrorCodeIndex(ec);
Expand Down
14 changes: 12 additions & 2 deletions Firmware/ultralcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6296,7 +6296,7 @@ void lcd_print_stop()
lcd_commands_step = 0;
lcd_commands_type = LcdCommands::Idle;

lcd_cooldown(); //turns off heaters and fan; goes to status screen.
lcd_return_to_status();

current_position[Z_AXIS] += 10; //lift Z.
plan_buffer_line_curposXYZE(manual_feedrate[Z_AXIS] / 60);
Expand All @@ -6309,7 +6309,17 @@ void lcd_print_stop()
}
st_synchronize();

if (MMU2::mmu2.Enabled()) MMU2::mmu2.unload(); //M702 C
if (MMU2::mmu2.Enabled())
{
if (isPrintPaused)
{
// Restore temperature saved in ram after pausing print
restore_extruder_temperature_from_ram();
}
MMU2::mmu2.unload(); //M702 C
}

lcd_cooldown(); //turns off heaters and fan; goes to status screen.

finishAndDisableSteppers(); //M84

Expand Down

0 comments on commit 70cb3c8

Please sign in to comment.