diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 46a7ef20..b067521f 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -591,27 +591,30 @@ void crashdet_restore_print_and_continue() // babystep_apply(); } +void crashdet_fmt_error(char* buf, uint8_t mask) +{ + if(mask & X_AXIS_MASK) *buf++ = axis_codes[X_AXIS]; + if(mask & Y_AXIS_MASK) *buf++ = axis_codes[Y_AXIS]; + *buf++ = ' '; + strcpy_P(buf, _T(MSG_CRASH_DETECTED)); +} + void crashdet_detected(uint8_t mask) { st_synchronize(); static uint8_t crashDet_counter = 0; + static uint8_t crashDet_axes = 0; bool automatic_recovery_after_crash = true; + char msg[LCD_WIDTH+1] = ""; - if (crashDet_counter++ == 0) { - crashDetTimer.start(); - } - else if (crashDetTimer.expired(CRASHDET_TIMER * 1000ul)){ - crashDetTimer.stop(); - crashDet_counter = 0; - } - else if(crashDet_counter == CRASHDET_COUNTER_MAX){ - automatic_recovery_after_crash = false; - crashDetTimer.stop(); - crashDet_counter = 0; - } - else { - crashDetTimer.start(); - } + if (crashDetTimer.expired(CRASHDET_TIMER * 1000ul)) { + crashDet_counter = 0; + } + if(++crashDet_counter >= CRASHDET_COUNTER_MAX) { + automatic_recovery_after_crash = false; + } + crashDetTimer.start(); + crashDet_axes |= mask; lcd_update_enable(true); lcd_clear(); @@ -627,12 +630,14 @@ void crashdet_detected(uint8_t mask) eeprom_update_byte((uint8_t*)EEPROM_CRASH_COUNT_Y, eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_Y) + 1); eeprom_update_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT, eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT) + 1); } - - lcd_update_enable(true); lcd_update(2); - lcd_setstatuspgm(_T(MSG_CRASH_DETECTED)); + + // prepare the status message with the _current_ axes status + crashdet_fmt_error(msg, mask); + lcd_setstatus(msg); + gcode_G28(true, true, false); //home X and Y st_synchronize(); @@ -640,7 +645,19 @@ void crashdet_detected(uint8_t mask) enquecommand_P(PSTR("CRASH_RECOVER")); }else{ setTargetHotend(0, active_extruder); - bool yesno = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Crash detected. Resume print?"), false);////MSG_CRASH_RESUME c=20 r=3 + + // notify the user of *all* the axes previously affected, not just the last one + lcd_update_enable(false); + lcd_clear(); + crashdet_fmt_error(msg, crashDet_axes); + crashDet_axes = 0; + lcd_print(msg); + + // ask whether to resume printing + lcd_set_cursor(0, 1); + lcd_puts_P(MSG_RESUME_PRINT); + lcd_putc('?'); + bool yesno = lcd_show_yes_no_and_wait(false); lcd_update_enable(true); if (yesno) { diff --git a/Firmware/messages.cpp b/Firmware/messages.cpp index 5b155e85..88e7855c 100644 --- a/Firmware/messages.cpp +++ b/Firmware/messages.cpp @@ -24,7 +24,7 @@ const char MSG_COMMUNITY_MADE[] PROGMEM_I1 = ISTR("Community made"); ////c=18 const char MSG_CONFIRM_NOZZLE_CLEAN[] PROGMEM_I1 = ISTR("Please clean the nozzle for calibration. Click when done."); ////c=20 r=8 const char MSG_COOLDOWN[] PROGMEM_I1 = ISTR("Cooldown"); ////c=18 const char MSG_CRASH[] PROGMEM_I1 = ISTR("Crash"); ////c=7 -const char MSG_CRASH_DETECTED[] PROGMEM_I1 = ISTR("Crash detected."); ////c=20 +const char MSG_CRASH_DETECTED[] PROGMEM_I1 = ISTR("Crash detected."); ////c=17 r=1 const char MSG_CRASHDETECT[] PROGMEM_I1 = ISTR("Crash det."); ////c=13 const char MSG_ERROR[] PROGMEM_I1 = ISTR("ERROR:"); ////c=10 const char MSG_EXTRUDER[] PROGMEM_I1 = ISTR("Extruder"); ////c=17 diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index a0866e01..c6229284 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -3278,18 +3278,14 @@ int8_t lcd_show_multiscreen_message_two_choices_and_wait_P(const char *msg, bool } } -//! @brief Show single screen message with yes and no possible choices and wait with possible timeout -//! @param msg Message to show +//! @brief Display and wait for a Yes/No choice using the last two lines of the LCD //! @param allow_timeouting if true, allows time outing of the screen //! @param default_yes if true, yes choice is selected by default, otherwise no choice is preselected //! @retval 1 yes choice selected by user //! @retval 0 no choice selected by user //! @retval -1 screen timed out -int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow_timeouting, bool default_yes) +int8_t lcd_show_yes_no_and_wait(bool allow_timeouting, bool default_yes) { - - lcd_display_message_fullscreen_P(msg); - if (default_yes) { lcd_putc_at(0, 2, '>'); lcd_puts_P(_T(MSG_YES)); @@ -3342,6 +3338,20 @@ int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow return retval; } +//! @brief Show single screen message with yes and no possible choices and wait with possible timeout +//! @param msg Message to show +//! @param allow_timeouting if true, allows time outing of the screen +//! @param default_yes if true, yes choice is selected by default, otherwise no choice is preselected +//! @retval 1 yes choice selected by user +//! @retval 0 no choice selected by user +//! @retval -1 screen timed out +//! @relates lcd_show_yes_no_and_wait +int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow_timeouting, bool default_yes) +{ + lcd_display_message_fullscreen_P(msg); + return lcd_show_yes_no_and_wait(allow_timeouting, default_yes); +} + void lcd_bed_calibration_show_result(BedSkewOffsetDetectionResultType result, uint8_t point_too_far_mask) { const char *msg = NULL; diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 2ee9fedf..41181554 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -72,6 +72,8 @@ extern void lcd_wait_for_click(); extern bool lcd_wait_for_click_delay(uint16_t nDelay); extern void lcd_show_fullscreen_message_and_wait_P(const char *msg); // 0: no, 1: yes, -1: timeouted +extern int8_t lcd_show_yes_no_and_wait(bool allow_timeouting = true, bool default_yes = false); +// 0: no, 1: yes, -1: timeouted extern int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow_timeouting = true, bool default_yes = false); extern int8_t lcd_show_multiscreen_message_two_choices_and_wait_P(const char *msg, bool allow_timeouting, bool default_yes, const char *first_choice, const char *second_choice);