Merge pull request #3845 from 3d-gussner/MK3_3.12_tm_partial_lock

MK3_3_12: TM: Prevent lockout on invalid model values
This commit is contained in:
3d-gussner 2022-12-20 14:37:24 +01:00 committed by GitHub
commit e511996cd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 75 additions and 52 deletions

View File

@ -678,7 +678,7 @@ void crashdet_cancel()
saved_printing = false;
tmc2130_sg_stop_on_crash = true;
if (saved_printing_type == PRINTING_TYPE_SD) {
lcd_print_stop();
print_stop();
}else if(saved_printing_type == PRINTING_TYPE_USB){
SERIAL_ECHOLNRPGM(MSG_OCTOPRINT_CANCEL); //for Octoprint: works the same as clicking "Abort" button in Octoprint GUI
cmdqueue_reset();
@ -7913,7 +7913,7 @@ Sigma_Exit:
### M603 - Stop print <a href="https://reprap.org/wiki/G-code#M603:_Stop_print">M603: Stop print</a>
*/
case 603: {
lcd_print_stop();
print_stop();
}
break;
@ -9717,14 +9717,14 @@ void UnconditionalStop()
// WARNING: This function is called *continuously* during a thermal failure.
//
// This either pauses (for thermal model errors) or stops *without recovery* depending on
// "allow_pause". If pause is allowed, this forces a printer-initiated instantanenous pause (just
// like an LCD pause) that bypasses the host pausing functionality. In this state the printer is
// kept in busy state and *must* be recovered from the LCD.
void ThermalStop(bool allow_pause)
// "allow_recovery". If recovery is allowed, this forces a printer-initiated instantanenous pause
// (just like an LCD pause) that bypasses the host pausing functionality. In this state the printer
// is kept in busy state and *must* be recovered from the LCD.
void ThermalStop(bool allow_recovery)
{
if(Stopped == false) {
Stopped = true;
if(allow_pause && (IS_SD_PRINTING || usb_timer.running())) {
if(allow_recovery && (IS_SD_PRINTING || usb_timer.running())) {
if (!isPrintPaused) {
lcd_setalertstatuspgm(_T(MSG_PAUSED_THERMAL_ERROR), LCD_STATUS_CRITICAL);
@ -9743,10 +9743,7 @@ void ThermalStop(bool allow_pause)
}
} else {
// We got a hard thermal error and/or there is no print going on. Just stop.
lcd_print_stop();
// Also prevent further menu entry
menu_set_block(MENU_BLOCK_THERMAL_ERROR);
print_stop();
}
// Report the status on the serial, switch to a busy state
@ -9760,13 +9757,15 @@ void ThermalStop(bool allow_pause)
// Make a warning sound! We cannot use Sound_MakeCustom as this would stop further moves.
// Turn on the speaker here (if not already), and turn it off when back in the main loop.
WRITE(BEEPER, HIGH);
}
// Return to the status screen to stop any pending menu action which could have been
// started by the user while stuck in the Stopped state. This also ensures the NEW
// error is immediately shown.
if (menu_menu != lcd_status_screen)
// Always return to the status screen to ensure the NEW error is immediately shown.
lcd_return_to_status();
if(!allow_recovery) {
// prevent menu access for all fatal errors
menu_set_block(MENU_BLOCK_THERMAL_ERROR);
}
}
}
bool IsStopped() { return Stopped; };

View File

@ -366,22 +366,24 @@ void get_command()
comment_mode = false; //for new command
return;
}
cmdbuffer[bufindw+serial_count+CMDHDRSIZE] = 0; //terminate string
if(!comment_mode){
cmdbuffer[bufindw+serial_count+CMDHDRSIZE] = 0; // terminate string
char* cmd_head = cmdbuffer+bufindw+CMDHDRSIZE; // current command pointer
char* cmd_start = cmd_head; // pointer past the line number (if any)
long gcode_N = -1;
if(!comment_mode){
long gcode_N = -1; // seen line number
// Line numbers must be first in buffer
if ((strstr_P(cmdbuffer+bufindw+CMDHDRSIZE, PSTR("PRUSA")) == NULL) &&
(cmdbuffer[bufindw+CMDHDRSIZE] == 'N')) {
(*cmd_head == 'N')) {
// Line number met. When sending a G-code over a serial line, each line may be stamped with its index,
// and Marlin tests, whether the successive lines are stamped with an increasing line number ID
gcode_N = (strtol(cmdbuffer+bufindw+CMDHDRSIZE+1, NULL, 10));
if(gcode_N != gcode_LastN+1 && (strstr_P(cmdbuffer+bufindw+CMDHDRSIZE, PSTR("M110")) == NULL) ) {
// M110 - set current line number.
// Line numbers not sent in succession.
// Line number met: decode the number, then move cmd_start past all spaces.
gcode_N = (strtol(cmd_head+1, &cmd_start, 10));
while (*cmd_start == ' ') ++cmd_start;
// Test whether the successive lines are stamped with an increasing line number ID.
if(gcode_N != gcode_LastN+1 && strncmp_P(cmd_start, PSTR("M110"), 4)) {
// Line numbers not sent in succession and M110 not seen.
SERIAL_ERROR_START;
SERIAL_ERRORRPGM(_n("Line Number is not Last Line Number+1, Last Line: "));////MSG_ERR_LINE_NO
SERIAL_ERRORLN(gcode_LastN);
@ -391,10 +393,10 @@ void get_command()
return;
}
if((strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, '*')) != NULL)
if((strchr_pointer = strchr(cmd_start, '*')) != NULL)
{
byte checksum = 0;
char *p = cmdbuffer+bufindw+CMDHDRSIZE;
char *p = cmd_head;
while (p != strchr_pointer)
checksum = checksum^(*p++);
if (code_value_short() != (int16_t)checksum) {
@ -419,12 +421,11 @@ void get_command()
}
// Don't parse N again with code_seen('N')
cmdbuffer[bufindw + CMDHDRSIZE] = '$';
*cmd_head = '$';
}
// if we don't receive 'N' but still see '*'
if ((cmdbuffer[bufindw + CMDHDRSIZE] != 'N') && (cmdbuffer[bufindw + CMDHDRSIZE] != '$') && (strchr(cmdbuffer+bufindw+CMDHDRSIZE, '*') != NULL))
if ((*cmd_head != 'N') && (*cmd_head != '$') && (strchr(cmd_start, '*') != NULL))
{
SERIAL_ERROR_START;
SERIAL_ERRORRPGM(_n("No Line Number with checksum, Last Line: "));////MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM
SERIAL_ERRORLN(gcode_LastN);
@ -432,16 +433,21 @@ void get_command()
serial_count = 0;
return;
}
// Handle KILL early, even when Stopped
if(strcmp(cmdbuffer+bufindw+CMDHDRSIZE, "M112") == 0)
if(strcmp_P(cmd_start, PSTR("M112")) == 0)
kill(MSG_M112_KILL, 2);
// Bypass Stopped for some commands
bool allow_when_stopped = false;
if(strncmp_P(cmd_start, PSTR("M310"), 4) == 0)
allow_when_stopped = true;
// Handle the USB timer
if ((strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, 'G')) != NULL) {
if (!IS_SD_PRINTING) {
if ((*cmd_start == 'G') && !(IS_SD_PRINTING))
usb_timer.start();
}
}
if (Stopped == true) {
if (allow_when_stopped == false && Stopped == true) {
// Stopped can be set either during error states (thermal error: cannot continue), or
// when a printer-initiated action is processed. In such case the printer will send to
// the host an action, but cannot know if the action has been processed while new

View File

@ -165,6 +165,7 @@ extern const char MSG_PAUSED_THERMAL_ERROR[] PROGMEM_I1 = ISTR("PAUSED THERMAL E
#ifdef TEMP_MODEL
extern const char MSG_THERMAL_ANOMALY[] PROGMEM_I1 = ISTR("THERMAL ANOMALY");////MSG_THERMAL_ANOMALY c=20
extern const char MSG_TM_NOT_CAL[] PROGMEM_I1 = ISTR("Temp model not calibrated yet.");////MSG_TM_NOT_CAL c=20 r=4
extern const char MSG_TM_ACK_ERROR[] PROGMEM_I1 = ISTR("Clear TM error");////MSG_TM_ACK_ERROR c=18
#endif
extern const char MSG_NOZZLE_CNG_MENU [] PROGMEM_I1 = ISTR("Nozzle change");////MSG_NOZZLE_CNG_MENU c=18
extern const char MSG_NOZZLE_CNG_READ_HELP [] PROGMEM_I1 = ISTR("For a Nozzle change please read\nprusa.io/nozzle-mk3s");////MSG_NOZZLE_CNG_READ_HELP c=20 r=4

View File

@ -169,6 +169,7 @@ extern const char MSG_PAUSED_THERMAL_ERROR[];
#ifdef TEMP_MODEL
extern const char MSG_THERMAL_ANOMALY[];
extern const char MSG_TM_NOT_CAL[];
extern const char MSG_TM_ACK_ERROR[];
#endif
extern const char MSG_NOZZLE_CNG_MENU [];
extern const char MSG_NOZZLE_CNG_READ_HELP [];

View File

@ -1766,7 +1766,6 @@ void handle_temp_error()
} else {
temp_error_state.v = 0;
WRITE(BEEPER, LOW);
menu_unset_block(MENU_BLOCK_THERMAL_ERROR);
// hotend error was transitory and disappeared, re-enable bed
if (!target_temperature_bed)
@ -2442,6 +2441,7 @@ void handle_warning()
lcd_setalertstatuspgm(_T(MSG_THERMAL_ANOMALY), LCD_STATUS_INFO);
WRITE(BEEPER, HIGH);
}
first = false;
} else {
if(warn_beep) TOGGLE(BEEPER);
}

View File

@ -835,7 +835,7 @@ void lcd_status_screen() // NOT static due to using ins
}
}
void print_stop();
void lcd_print_stop_finish();
void lcd_commands()
{
@ -853,7 +853,7 @@ void lcd_commands()
lcd_setstatuspgm(_T(MSG_PRINT_ABORTED));
lcd_commands_type = LcdCommands::Idle;
lcd_commands_step = 0;
print_stop();
lcd_print_stop_finish();
}
}
@ -5623,7 +5623,7 @@ static void lcd_main_menu()
if ( moves_planned() || printer_active() ) {
MENU_ITEM_SUBMENU_P(_i("Tune"), lcd_tune_menu);////MSG_TUNE c=18
} else {
} else if (!Stopped) {
MENU_ITEM_SUBMENU_P(_i("Preheat"), lcd_preheat_menu);////MSG_PREHEAT c=18
}
@ -5652,6 +5652,11 @@ static void lcd_main_menu()
if((IS_SD_PRINTING || usb_timer.running() || isPrintPaused) && (custom_message_type != CustomMsg::MeshBedLeveling)) {
MENU_ITEM_SUBMENU_P(_T(MSG_STOP_PRINT), lcd_sdcard_stop);
}
#ifdef TEMP_MODEL
else if(Stopped) {
MENU_ITEM_SUBMENU_P(_T(MSG_TM_ACK_ERROR), lcd_print_stop);
}
#endif
#ifdef SDSUPPORT //!@todo SDSUPPORT undefined creates several issues in source code
if (card.cardOK || lcd_commands_type == LcdCommands::Layer1Cal) {
if (!card.isFileOpen()) {
@ -5682,7 +5687,7 @@ static void lcd_main_menu()
}
}
if ( ! ( IS_SD_PRINTING || usb_timer.running() || (lcd_commands_type == LcdCommands::Layer1Cal) ) ) {
if ( ! ( IS_SD_PRINTING || usb_timer.running() || (lcd_commands_type == LcdCommands::Layer1Cal || Stopped) ) ) {
if (mmu_enabled) {
MENU_ITEM_SUBMENU_P(_T(MSG_LOAD_FILAMENT), mmu_load_filament_menu);
MENU_ITEM_SUBMENU_P(_i("Load to nozzle"), mmu_load_to_nozzle_menu);////MSG_LOAD_TO_NOZZLE c=18
@ -6050,7 +6055,7 @@ static void lcd_sd_updir()
}
// continue stopping the print from the main loop after lcd_print_stop() is called
void print_stop()
void lcd_print_stop_finish()
{
// save printing time
stoptime = _millis();
@ -6082,11 +6087,11 @@ void print_stop()
axis_relative_modes = E_AXIS_MASK; //XYZ absolute, E relative
}
void lcd_print_stop()
void print_stop(bool interactive)
{
// UnconditionalStop() will internally cause planner_abort_hard(), meaning we _cannot_ plan
// any more move in this call! Any further move must happen inside print_stop(), which is called
// by the main loop one iteration later.
// UnconditionalStop() will internally cause planner_abort_hard(), meaning we _cannot_ plan any
// more move in this call! Any further move must happen inside lcd_print_stop_finish(), which is
// called by the main loop one iteration later.
UnconditionalStop();
if (!card.sdprinting) {
@ -6101,11 +6106,21 @@ void lcd_print_stop()
pause_time = 0;
isPrintPaused = false;
if (interactive) {
// acknowledged by the user from the LCD: resume processing USB commands again
Stopped = false;
}
// return to status is required to continue processing in the main loop!
lcd_commands_type = LcdCommands::StopPrint;
lcd_return_to_status();
}
void lcd_print_stop()
{
print_stop(true);
}
#ifdef TEMP_MODEL
void lcd_temp_model_cal()
{
@ -7707,13 +7722,13 @@ void lcd_setalertstatus_(const char* message, uint8_t severity, bool progmem)
bool same = !(progmem?
strcmp_P(lcd_status_message, message):
strcmp(lcd_status_message, message));
lcd_updatestatus(message, progmem);
lcd_status_message_timeout.start();
lcd_status_message_level = severity;
custom_message_type = CustomMsg::Status;
custom_message_state = 0;
if (!same) {
// do not kick the user out of the menus if the message is unchanged
lcd_updatestatus(message, progmem);
lcd_return_to_status();
}
}
@ -7745,7 +7760,7 @@ void menu_lcd_longpress_func(void)
// start LCD inactivity timer
lcd_timeoutToStatus.start();
backlight_wake();
if (homing_flag || mesh_bed_leveling_flag || menu_menu == lcd_babystep_z || menu_menu == lcd_move_z || menu_block_mask != MENU_BLOCK_NONE)
if (homing_flag || mesh_bed_leveling_flag || menu_menu == lcd_babystep_z || menu_menu == lcd_move_z || menu_block_mask != MENU_BLOCK_NONE || Stopped)
{
// disable longpress during re-entry, while homing, calibration or if a serious error
lcd_quick_feedback();

View File

@ -47,7 +47,8 @@ void lcd_sdcard_stop();
void lcd_pause_print();
void lcd_pause_usb_print();
void lcd_resume_print();
void lcd_print_stop();
void lcd_print_stop(); // interactive print stop
void print_stop(bool interactive=false);
#ifdef TEMP_MODEL
void lcd_temp_model_cal();
#endif //TEMP_MODEL