ソースを参照

Merge remote-tracking branch 'remotes/upstream/MK3' into MK3_stepper_lowres

bubnikv 7 年 前
コミット
5deee8f42c

+ 3 - 2
Firmware/Configuration.h

@@ -8,11 +8,12 @@
 #define STR(x) STR_HELPER(x)
 
 // Firmware version
-#define FW_VERSION "3.1.1-RC4"
-#define FW_COMMIT_NR   145
+#define FW_VERSION "3.1.1-RC5"
+#define FW_COMMIT_NR   150
 #define FW_DEV_VERSION FW_VERSION_RC
 #define FW_VERSION_FULL FW_VERSION "-" STR(FW_COMMIT_NR)
 
+#define FW_VERSION_DEBUG 5
 #define FW_VERSION_UNKNOWN 4
 #define FW_VERSION_ALPHA 3
 #define FW_VERSION_BETA 2

+ 2 - 0
Firmware/ConfigurationStore.cpp

@@ -311,6 +311,8 @@ void Config_RetrieveSettings(uint16_t offset, uint8_t level)
         EEPROM_READ_VAR(i,max_jerk[Y_AXIS]);
 		EEPROM_READ_VAR(i,max_jerk[Z_AXIS]);
 		EEPROM_READ_VAR(i,max_jerk[E_AXIS]);
+		if (max_jerk[X_AXIS] > DEFAULT_XJERK) max_jerk[X_AXIS] = DEFAULT_XJERK;
+		if (max_jerk[Y_AXIS] > DEFAULT_YJERK) max_jerk[Y_AXIS] = DEFAULT_YJERK;
         EEPROM_READ_VAR(i,add_homing);
         #ifndef ULTIPANEL
         int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed;

+ 13 - 6
Firmware/Configuration_prusa.h

@@ -75,12 +75,17 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 #define MANUAL_FEEDRATE {2700, 2700, 1000, 100}   // set the speeds for manual moves (mm/min)
 
 //Silent mode limits
-#define SILENT_MAX_ACCEL_X  960 // X-axis max acceleration in silent mode in mm/s^2
-#define SILENT_MAX_ACCEL_Y  960 // Y-axis max axxeleration in silent mode in mm/s^2
-#define SILENT_MAX_ACCEL_X_ST (100*SILENT_MAX_ACCEL_X) // X max accel in steps/s^2
-#define SILENT_MAX_ACCEL_Y_ST (100*SILENT_MAX_ACCEL_Y) // Y max accel in steps/s^2
+#define SILENT_MAX_ACCEL  960 // max axxeleration in silent mode in mm/s^2
+#define SILENT_MAX_ACCEL_ST (100*SILENT_MAX_ACCEL) // max accel in steps/s^2
 #define SILENT_MAX_FEEDRATE 172  //max feedrate in mm/s, because mode switched to normal for homming , this value limits also homing, it should be greater (172mm/s=9600mm/min>2700mm/min)
 
+//Normal mode limits
+#define NORMAL_MAX_ACCEL 2500 // Y-axis max axxeleration in normal mode in mm/s^2
+#define NORMAL_MAX_ACCEL_ST (100*NORMAL_MAX_ACCEL) // max accel in steps/s^2
+#define NORMAL_MAX_FEEDRATE 200  //max feedrate in mm/s, because mode switched to normal for homming , this value limits also homing, it should be greater (172mm/s=9600mm/min>2700mm/min)
+
+//#define SIMPLE_ACCEL_LIMIT          //new limitation method for normal/silent
+
 //number of bytes from end of the file to start check
 #define END_FILE_SECTION 10000
 
@@ -96,8 +101,8 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 // this value is litlebit higher that real limit, because ambient termistor is on the board and is temperated from it,
 // temperature inside the case is around 31C for ambient temperature 25C, when the printer is powered on long time and idle
 // the real limit is 15C (same as MINTEMP limit), this is because 15C is end of scale for both used thermistors (bed, heater)
-#define MINTEMP_MINAMBIENT      18
-#define MINTEMP_MINAMBIENT_RAW  991
+#define MINTEMP_MINAMBIENT      25
+#define MINTEMP_MINAMBIENT_RAW  978
 
 
 //DEBUG
@@ -547,6 +552,8 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 
 #define HEATBED_V2
 
+#define M600_TIMEOUT 600  //seconds
+
 //#define SUPPORT_VERBOSITY
 
 #endif //__CONFIGURATION_PRUSA_H

+ 0 - 4
Firmware/MarlinSerial.cpp

@@ -196,10 +196,6 @@ int MarlinSerial::read(void)
 
 void MarlinSerial::flush()
 {
-  // don't reverse this or there may be problems if the RX interrupt
-  // occurs after reading the value of rx_buffer_head but before writing
-  // the value to rx_buffer_tail; the previous value of rx_buffer_head
-  // may be written to rx_buffer_tail, making it appear as if the buffer
   // don't reverse this or there may be problems if the RX interrupt
   // occurs after reading the value of rx_buffer_head but before writing
   // the value to rx_buffer_tail; the previous value of rx_buffer_head

+ 112 - 14
Firmware/Marlin_main.cpp

@@ -887,11 +887,12 @@ void factory_reset()
 }
 
 void show_fw_version_warnings() {
-	if (FW_DEV_VERSION == FW_VERSION_GOLD) return;
+	if (FW_DEV_VERSION == FW_VERSION_GOLD || FW_DEV_VERSION == FW_VERSION_RC) return;
 	switch (FW_DEV_VERSION) {
 	case(FW_VERSION_ALPHA): lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_ALPHA); break;
 	case(FW_VERSION_BETA): lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_BETA); break;
 	case(FW_VERSION_RC): lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_RC); break;
+	case(FW_VERSION_DEBUG): lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_DEBUG); break;
 	default: lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_UNKNOWN); break;
 	}
 	lcd_update_enable(true);
@@ -1069,6 +1070,7 @@ void setup()
 		// EEPROM_LANG to number lower than 0x0ff.
 		// 1) Set a high power mode.
 		eeprom_write_byte((uint8_t*)EEPROM_SILENT, 0);
+		tmc2130_mode = TMC2130_MODE_NORMAL;
 		eeprom_write_byte((uint8_t*)EEPROM_WIZARD_ACTIVE, 1); //run wizard
 
 	}
@@ -2019,6 +2021,12 @@ bool gcode_M45(bool onlyZ)
 	lcd_display_message_fullscreen_P(MSG_AUTO_HOME);
 	home_xy();
 
+	enable_endstops(false);
+	current_position[X_AXIS] += 5;
+	current_position[Y_AXIS] += 5;
+	plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[Z_AXIS] / 40, active_extruder);
+	st_synchronize();
+
 	// Let the user move the Z axes up to the end stoppers.
 #ifdef TMC2130
 	if (calibrate_z_auto())
@@ -2092,7 +2100,7 @@ bool gcode_M45(bool onlyZ)
 			else
 			{
 				// Reset the baby step value and the baby step applied flag.
-				calibration_status_store(CALIBRATION_STATUS_ASSEMBLED);
+				calibration_status_store(CALIBRATION_STATUS_XYZ_CALIBRATION);
 				eeprom_update_word((uint16_t*)EEPROM_BABYSTEP_Z, 0);
 				// Complete XYZ calibration.
 				uint8_t point_too_far_mask = 0;
@@ -4941,6 +4949,8 @@ Sigma_Exit:
       if(code_seen('Y')) max_jerk[Y_AXIS] = code_value();
       if(code_seen('Z')) max_jerk[Z_AXIS] = code_value();
       if(code_seen('E')) max_jerk[E_AXIS] = code_value();
+		if (max_jerk[X_AXIS] > DEFAULT_XJERK) max_jerk[X_AXIS] = DEFAULT_XJERK;
+		if (max_jerk[Y_AXIS] > DEFAULT_YJERK) max_jerk[Y_AXIS] = DEFAULT_YJERK;
     }
     break;
     case 206: // M206 additional homing offset
@@ -5459,6 +5469,8 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
         feedmultiplyBckp=feedmultiply;
         int8_t TooLowZ = 0;
 
+		float HotendTempBckp = degTargetHotend(active_extruder);
+		int fanSpeedBckp = fanSpeed;
         target[X_AXIS]=current_position[X_AXIS];
         target[Y_AXIS]=current_position[Y_AXIS];
         target[Z_AXIS]=current_position[Z_AXIS];
@@ -5528,11 +5540,14 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 		KEEPALIVE_STATE(PAUSED_FOR_USER);
 
 		uint8_t cnt = 0;
-		int counterBeep = 0;
+		int counterBeep = 0;	
+		fanSpeed = 0;
+		unsigned long waiting_start_time = millis();
+		uint8_t wait_for_user_state = 0;
 		lcd_display_message_fullscreen_P(MSG_PRESS_TO_UNLOAD);
-		while (!lcd_clicked()) {
+		while (!(wait_for_user_state == 0 && lcd_clicked())){
 
-			cnt++;
+			//cnt++;
 			manage_heater();
 			manage_inactivity(true);
 
@@ -5542,7 +5557,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 
 			#endif // SNMM*/
 
-			if (cnt == 0)
+			//if (cnt == 0)
 			{
 #if BEEPER > 0
 				if (counterBeep == 500) {
@@ -5555,6 +5570,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 				if (counterBeep == 20) {
 					WRITE(BEEPER, LOW);
 				}
+				
 				counterBeep++;
 #else
 #if !defined(LCD_FEEDBACK_FREQUENCY_HZ) || !defined(LCD_FEEDBACK_FREQUENCY_DURATION_MS)
@@ -5564,18 +5580,61 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 #endif
 #endif
 			}
+			
+			switch (wait_for_user_state) {
+			case 0: 
+				delay_keep_alive(4);
+
+				if (millis() > waiting_start_time + (unsigned long)M600_TIMEOUT * 1000) {
+					lcd_display_message_fullscreen_P(MSG_PRESS_TO_PREHEAT);
+					wait_for_user_state = 1;
+					setTargetHotend(0, 0);
+					setTargetHotend(0, 1);
+					setTargetHotend(0, 2);
+					st_synchronize();
+					disable_e0();
+					disable_e1();
+					disable_e2();
+				}
+				break;
+			case 1:
+				delay_keep_alive(4);
+		
+				if (lcd_clicked()) {
+					setTargetHotend(HotendTempBckp, active_extruder);
+					lcd_wait_for_heater();
+
+					wait_for_user_state = 2;
+				}
+				break;
+			case 2:
+
+				if (abs(degTargetHotend(active_extruder) - degHotend(active_extruder)) < 1) {
+					lcd_display_message_fullscreen_P(MSG_PRESS_TO_UNLOAD);
+					waiting_start_time = millis();
+					wait_for_user_state = 0;
+				}
+				else {
+					counterBeep = 20; //beeper will be inactive during waiting for nozzle preheat
+					lcd.setCursor(1, 4);
+					lcd.print(ftostr3(degHotend(active_extruder)));
+				}
+				break;
+
+			}
 
 		}
 		WRITE(BEEPER, LOW);
 		
 		lcd_change_fil_state = 0;
-		while (lcd_change_fil_state == 0) {
+		
+
+		// Unload filament
 			lcd_display_message_fullscreen_P(MSG_UNLOADING_FILAMENT);
 			KEEPALIVE_STATE(IN_HANDLER);
 			custom_message = true;
 			lcd_setstatuspgm(MSG_UNLOADING_FILAMENT);
 
-			// Unload filament
 			if (code_seen('L'))
 			{
 				target[E_AXIS] += code_value();
@@ -5616,10 +5675,10 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
             plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 5200 / 60, active_extruder);
             st_synchronize();
             target[E_AXIS] -= 15;
-            plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 160 / 60, active_extruder);
+            plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 1000 / 60, active_extruder);
             st_synchronize();
             target[E_AXIS] -= 20;
-            plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 5000 / 60, active_extruder);
+            plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 1000 / 60, active_extruder);
             st_synchronize();
             
 #endif // SNMM
@@ -5627,16 +5686,31 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 
 			//finish moves
 			st_synchronize();
+
+			lcd_display_message_fullscreen_P(MSG_PULL_OUT_FILAMENT);
+			
 			//disable extruder steppers so filament can be removed
 			disable_e0();
 			disable_e1();
 			disable_e2();
 			delay(100);
+			 
+			
+			WRITE(BEEPER, HIGH);
+			counterBeep = 0;
+			while(!lcd_clicked() && (counterBeep < 50)) {
+				if(counterBeep > 5) WRITE(BEEPER, LOW);
+				delay_keep_alive(100);
+				counterBeep++;
+			}
+			WRITE(BEEPER, LOW);
+
 			KEEPALIVE_STATE(PAUSED_FOR_USER);
-			lcd_change_fil_state = !lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_UNLOAD_SUCCESSFULL, false, false);
+			lcd_change_fil_state = lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_UNLOAD_SUCCESSFULL, false, true);
+			if (lcd_change_fil_state == 0) lcd_show_fullscreen_message_and_wait_P(MSG_CHECK_IDLER);
 			//lcd_return_to_status();
 			lcd_update_enable(true);
-		}
+		
         //Wait for user to insert filament
         lcd_wait_interact();
 		//load_filament_time = millis();
@@ -5770,6 +5844,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
         
 
       //Not let's go back to print
+		fanSpeed = fanSpeedBckp;
 
       //Feed a little of filament to stabilize pressure
       target[E_AXIS]+= FILAMENTCHANGE_RECFEED;
@@ -6018,11 +6093,34 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 		plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 5200 / 60, active_extruder);
         st_synchronize();
         current_position[E_AXIS] -= 15;
-        plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 160 / 60, active_extruder);
+        plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 1000 / 60, active_extruder);
         st_synchronize();
         current_position[E_AXIS] -= 20;
-        plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 5000 / 60, active_extruder);
+        plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 1000 / 60, active_extruder);
 		st_synchronize();
+
+		lcd_display_message_fullscreen_P(MSG_PULL_OUT_FILAMENT);
+
+		//disable extruder steppers so filament can be removed
+		disable_e0();
+		disable_e1();
+		disable_e2();
+		delay(100);
+
+
+		WRITE(BEEPER, HIGH);
+		uint8_t counterBeep = 0;
+		while (!lcd_clicked() && (counterBeep < 50)) {
+			if (counterBeep > 5) WRITE(BEEPER, LOW);
+			delay_keep_alive(100);
+			counterBeep++;
+		}
+		WRITE(BEEPER, LOW);
+		st_synchronize();	
+		while (lcd_clicked()) delay_keep_alive(100);
+
+		lcd_update_enable(true);
+	
 		lcd_setstatuspgm(WELCOME_MSG);
 		custom_message = false;
 		custom_message_type = 0;

+ 10 - 6
Firmware/cmdqueue.cpp

@@ -368,11 +368,15 @@ void get_command()
     
     bool rx_buffer_full = false; //flag that serial rx buffer is full
 
+	if (MYSERIAL.available() == RX_BUFFER_SIZE - 1) { //compare number of chars buffered in rx buffer with rx buffer size
+		MYSERIAL.flush();
+		SERIAL_ECHOLNPGM("Full RX Buffer");   //if buffer was full, there is danger that reading of last gcode will not be completed
+
+		rx_buffer_full = true;                //sets flag that buffer was full    
+	}
+
   while (MYSERIAL.available() > 0) {
-      if (MYSERIAL.available() == RX_BUFFER_SIZE - 1) { //compare number of chars buffered in rx buffer with rx buffer size
-          SERIAL_ECHOLNPGM("Full RX Buffer");   //if buffer was full, there is danger that reading of last gcode will not be completed
-          rx_buffer_full = true;                //sets flag that buffer was full    
-      }
+
     char serial_char = MYSERIAL.read();
 /*    if (selectedSerialPort == 1)
     {
@@ -529,11 +533,11 @@ void get_command()
     }
 
     //add comment
-    if (rx_buffer_full == true && serial_count > 0) {   //if rx buffer was full and string was not properly terminated
+   /*if (rx_buffer_full == true && serial_count > 0) {   //if rx buffer was full and string was not properly terminated
         rx_buffer_full = false;
         bufindw = bufindw - serial_count;               //adjust tail of the buffer to prepare buffer for writing new command
         serial_count = 0;
-    }
+    }*/
 
   #ifdef SDSUPPORT
   if(!card.sdprinting || serial_count!=0){

+ 6 - 3
Firmware/fsensor.cpp

@@ -153,11 +153,13 @@ bool fsensor_check_autoload(void)
 
 ISR(PCINT2_vect)
 {
-//	return;
-	if (!((fsensor_int_pin_old ^ PINK) & FSENSOR_INT_PIN_MSK)) return;
 //	puts("PCINT2\n");
+	if (!((fsensor_int_pin_old ^ PINK) & FSENSOR_INT_PIN_MSK)) return;
+	fsensor_int_pin_old = PINK;
+	static bool _lock = false;
+	if (_lock) return;
+	_lock = true;
 //	return;
-
 	int st_cnt = fsensor_st_cnt;
 	fsensor_st_cnt = 0;
 	sei();
@@ -218,6 +220,7 @@ ISR(PCINT2_vect)
 		}
 	}
 	pat9125_y = 0;
+	_lock = false;
 	return;
 }
 

+ 30 - 2
Firmware/language_all.cpp

@@ -341,6 +341,13 @@ const char * const MSG_CHANGING_FILAMENT_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_CHANGING_FILAMENT_CZ
 };
 
+const char MSG_CHECK_IDLER_EN[] PROGMEM = "Please open idler and remove filament manually.";
+const char MSG_CHECK_IDLER_CZ[] PROGMEM = "Prosim otevrete idler a manualne odstrante filament.";
+const char * const MSG_CHECK_IDLER_LANG_TABLE[LANG_NUM] PROGMEM = {
+	MSG_CHECK_IDLER_EN,
+	MSG_CHECK_IDLER_CZ
+};
+
 const char MSG_CHOOSE_EXTRUDER_EN[] PROGMEM = "Choose extruder:";
 const char MSG_CHOOSE_EXTRUDER_CZ[] PROGMEM = "Vyberte extruder:";
 const char * const MSG_CHOOSE_EXTRUDER_LANG_TABLE[LANG_NUM] PROGMEM = {
@@ -838,6 +845,13 @@ const char * const MSG_FW_VERSION_BETA_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_FW_VERSION_BETA_CZ
 };
 
+const char MSG_FW_VERSION_DEBUG_EN[] PROGMEM = "This is development firmware version which contains additional debugging features. Using this version may cause printer damage.";
+const char MSG_FW_VERSION_DEBUG_CZ[] PROGMEM = "Toto je vyvojova verze firmwaru obsahujici funkce pro debugging. Pouziti teto verze muze poskodit Vasi tiskarnu.";
+const char * const MSG_FW_VERSION_DEBUG_LANG_TABLE[LANG_NUM] PROGMEM = {
+	MSG_FW_VERSION_DEBUG_EN,
+	MSG_FW_VERSION_DEBUG_CZ
+};
+
 const char MSG_FW_VERSION_RC_EN[] PROGMEM = "This firmware version is release candidate. Some of the features may not work properly.";
 const char MSG_FW_VERSION_RC_CZ[] PROGMEM = "Tato verze firmware je release candidate. Nektere z funkci nemusi pracovat spolehlive.";
 const char * const MSG_FW_VERSION_RC_LANG_TABLE[LANG_NUM] PROGMEM = {
@@ -1444,6 +1458,13 @@ const char * const MSG_PRESS_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_PRESS_CZ
 };
 
+const char MSG_PRESS_TO_PREHEAT_EN[] PROGMEM = "Press knob to preheat nozzle and continue.";
+const char MSG_PRESS_TO_PREHEAT_CZ[] PROGMEM = "Pro nahrati trysky a pokracovani stisknete tlacitko.";
+const char * const MSG_PRESS_TO_PREHEAT_LANG_TABLE[LANG_NUM] PROGMEM = {
+	MSG_PRESS_TO_PREHEAT_EN,
+	MSG_PRESS_TO_PREHEAT_CZ
+};
+
 const char MSG_PRESS_TO_UNLOAD_EN[] PROGMEM = "Please press the knob to unload filament";
 const char MSG_PRESS_TO_UNLOAD_CZ[] PROGMEM = "Pro vysunuti filamentu stisknete prosim tlacitko";
 const char * const MSG_PRESS_TO_UNLOAD_LANG_TABLE[LANG_NUM] PROGMEM = {
@@ -1491,6 +1512,13 @@ const char * const MSG_PRUSA3D_HOWTO_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_PRUSA3D_HOWTO_CZ
 };
 
+const char MSG_PULL_OUT_FILAMENT_EN[] PROGMEM = "Please pull out filament immediately";
+const char MSG_PULL_OUT_FILAMENT_CZ[] PROGMEM = "Prosim vyjmete urychlene filament";
+const char * const MSG_PULL_OUT_FILAMENT_LANG_TABLE[LANG_NUM] PROGMEM = {
+	MSG_PULL_OUT_FILAMENT_EN,
+	MSG_PULL_OUT_FILAMENT_CZ
+};
+
 const char MSG_REBOOT_EN[] PROGMEM = "Reboot the printer";
 const char MSG_REBOOT_CZ[] PROGMEM = "Restartujte tiskarnu";
 const char * const MSG_REBOOT_LANG_TABLE[LANG_NUM] PROGMEM = {
@@ -2207,8 +2235,8 @@ const char * const MSG_UNLOAD_FILAMENT_4_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_UNLOAD_FILAMENT_4_CZ
 };
 
-const char MSG_UNLOAD_SUCCESSFULL_EN[] PROGMEM = "Repeat unloading filament?";
-const char MSG_UNLOAD_SUCCESSFULL_CZ[] PROGMEM = "Opakovat vysunuti filamentu?";
+const char MSG_UNLOAD_SUCCESSFULL_EN[] PROGMEM = "Was filament unload successfull?";
+const char MSG_UNLOAD_SUCCESSFULL_CZ[] PROGMEM = "Bylo vysunuti filamentu uspesne?";
 const char * const MSG_UNLOAD_SUCCESSFULL_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_UNLOAD_SUCCESSFULL_EN,
 	MSG_UNLOAD_SUCCESSFULL_CZ

+ 8 - 0
Firmware/language_all.h

@@ -126,6 +126,8 @@ extern const char* const MSG_CHANGE_SUCCESS_LANG_TABLE[LANG_NUM];
 #define MSG_CHANGE_SUCCESS LANG_TABLE_SELECT(MSG_CHANGE_SUCCESS_LANG_TABLE)
 extern const char* const MSG_CHANGING_FILAMENT_LANG_TABLE[LANG_NUM];
 #define MSG_CHANGING_FILAMENT LANG_TABLE_SELECT(MSG_CHANGING_FILAMENT_LANG_TABLE)
+extern const char* const MSG_CHECK_IDLER_LANG_TABLE[LANG_NUM];
+#define MSG_CHECK_IDLER LANG_TABLE_SELECT(MSG_CHECK_IDLER_LANG_TABLE)
 extern const char* const MSG_CHOOSE_EXTRUDER_LANG_TABLE[LANG_NUM];
 #define MSG_CHOOSE_EXTRUDER LANG_TABLE_SELECT(MSG_CHOOSE_EXTRUDER_LANG_TABLE)
 extern const char* const MSG_CLEAN_NOZZLE_E_LANG_TABLE[LANG_NUM];
@@ -288,6 +290,8 @@ extern const char* const MSG_FW_VERSION_ALPHA_LANG_TABLE[LANG_NUM];
 #define MSG_FW_VERSION_ALPHA LANG_TABLE_SELECT(MSG_FW_VERSION_ALPHA_LANG_TABLE)
 extern const char* const MSG_FW_VERSION_BETA_LANG_TABLE[LANG_NUM];
 #define MSG_FW_VERSION_BETA LANG_TABLE_SELECT(MSG_FW_VERSION_BETA_LANG_TABLE)
+extern const char* const MSG_FW_VERSION_DEBUG_LANG_TABLE[LANG_NUM];
+#define MSG_FW_VERSION_DEBUG LANG_TABLE_SELECT(MSG_FW_VERSION_DEBUG_LANG_TABLE)
 extern const char* const MSG_FW_VERSION_RC_LANG_TABLE[LANG_NUM];
 #define MSG_FW_VERSION_RC LANG_TABLE_SELECT(MSG_FW_VERSION_RC_LANG_TABLE)
 extern const char* const MSG_FW_VERSION_UNKNOWN_LANG_TABLE[LANG_NUM];
@@ -482,6 +486,8 @@ extern const char* const MSG_PREPARE_FILAMENT_LANG_TABLE[LANG_NUM];
 #define MSG_PREPARE_FILAMENT LANG_TABLE_SELECT(MSG_PREPARE_FILAMENT_LANG_TABLE)
 extern const char* const MSG_PRESS_LANG_TABLE[LANG_NUM];
 #define MSG_PRESS LANG_TABLE_SELECT(MSG_PRESS_LANG_TABLE)
+extern const char* const MSG_PRESS_TO_PREHEAT_LANG_TABLE[LANG_NUM];
+#define MSG_PRESS_TO_PREHEAT LANG_TABLE_SELECT(MSG_PRESS_TO_PREHEAT_LANG_TABLE)
 extern const char* const MSG_PRESS_TO_UNLOAD_LANG_TABLE[LANG_NUM];
 #define MSG_PRESS_TO_UNLOAD LANG_TABLE_SELECT(MSG_PRESS_TO_UNLOAD_LANG_TABLE)
 extern const char* const MSG_PRINTER_DISCONNECTED_LANG_TABLE[1];
@@ -496,6 +502,8 @@ extern const char* const MSG_PRUSA3D_FORUM_LANG_TABLE[LANG_NUM];
 #define MSG_PRUSA3D_FORUM LANG_TABLE_SELECT(MSG_PRUSA3D_FORUM_LANG_TABLE)
 extern const char* const MSG_PRUSA3D_HOWTO_LANG_TABLE[LANG_NUM];
 #define MSG_PRUSA3D_HOWTO LANG_TABLE_SELECT(MSG_PRUSA3D_HOWTO_LANG_TABLE)
+extern const char* const MSG_PULL_OUT_FILAMENT_LANG_TABLE[LANG_NUM];
+#define MSG_PULL_OUT_FILAMENT LANG_TABLE_SELECT(MSG_PULL_OUT_FILAMENT_LANG_TABLE)
 extern const char* const MSG_REBOOT_LANG_TABLE[LANG_NUM];
 #define MSG_REBOOT LANG_TABLE_SELECT(MSG_REBOOT_LANG_TABLE)
 extern const char* const MSG_RECOVERING_PRINT_LANG_TABLE[LANG_NUM];

+ 31 - 28
Firmware/language_cz.h

@@ -74,7 +74,7 @@
 #define MSG_PREHEAT                         "Predehrev"
 #define MSG_UNLOAD_FILAMENT                 "Vyjmout filament"
 #define MSG_LOAD_FILAMENT					"Zavest filament"
-#define(length=17) MSG_AUTOLOAD_FILAMENT    "AutoZavedeni fil."
+#define MSG_AUTOLOAD_FILAMENT				"AutoZavedeni fil."
 #define MSG_LOAD_FILAMENT_1					"Zavest filament 1"
 #define MSG_LOAD_FILAMENT_2					"Zavest filament 2"
 #define MSG_LOAD_FILAMENT_3					"Zavest filament 3"
@@ -265,7 +265,7 @@
 #define MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF					"SD card  [normal]"
 #define MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON					"SD card [FlshAir]"
 
-#define(length=20, lines=4) MSG_STACK_ERROR                     "Chyba - Doslo k prepisu staticke pameti!"
+#define MSG_STACK_ERROR                     "Chyba - Doslo k prepisu staticke pameti!"
 
 #define MSG_LOOSE_PULLEY								"Uvolnena remenicka"
 #define MSG_FILAMENT_LOADING_T0							"Vlozte filament do extruderu 1. Potvrdte tlacitkem."
@@ -345,7 +345,7 @@
 #define MSG_MEASURED_SKEW					"Merene zkoseni:"
 #define MSG_SLIGHT_SKEW						"Lehke zkoseni:"
 #define MSG_SEVERE_SKEW						"Tezke zkoseni:"
-ve
+
 #define MSG_CALIBRATE_Z_AUTO				"Kalibruji Z"
 #define MSG_FSENSOR_OFF						"Fil. senzor [vyp]"
 #define MSG_FSENSOR_NA						"Fil. senzor [N/A]"
@@ -355,12 +355,12 @@ ve
 #define MSG_CRASHDETECT_OFF					"Crash det.  [vyp]"
 #define MSG_FANS_CHECK_ON					"Kontr. vent.[zap]"
 #define MSG_FANS_CHECK_OFF					        "Kontr. vent.[vyp]"
-#define(length=17, lines=1) MSG_FSENS_AUTOLOAD_ON   "F. autozav. [zap]"
-#define(length=17, lines=1) MSG_FSENS_AUTOLOAD_OFF  "F. autozav. [vyp]"
-#define(length=17, lines=1) MSG_FSENS_AUTOLOAD_NA  "F. autozav. [N/A]"
+#define MSG_FSENS_AUTOLOAD_ON   "F. autozav. [zap]"
+#define MSG_FSENS_AUTOLOAD_OFF  "F. autozav. [vyp]"
+#define MSG_FSENS_AUTOLOAD_NA  "F. autozav. [N/A]"
 #define MSG_RECOVERING_PRINT				"Obnovovani tisku    "
-#define(length=20, lines=1) MSG_CRASH_DETECTED   "Detekovan naraz."
-#define(length=20, lines=2) MSG_CRASH_DETECTED2   "Naraz detekovan, pokracovat v tisku?"
+#define MSG_CRASH_DETECTED   "Detekovan naraz."
+#define MSG_CRASH_DETECTED2   "Naraz detekovan, pokracovat v tisku?"
 
 #define MSG_SELFTEST_AXIS					"Osa"
 #define MSG_SELFTEST_AXIS_LENGTH			"Delka osy"
@@ -369,37 +369,40 @@ ve
 #define MSG_PLACE_STEEL_SHEET				"Umistete prosim tiskovy plat na heatbed"
 #define MSG_RECOVER_PRINT					"Detekovan vypadek proudu.Obnovit tisk?"
 #define MSG_PRESS_TO_UNLOAD					"Pro vysunuti filamentu stisknete prosim tlacitko"	
-#define MSG_UNLOAD_SUCCESSFULL				"Opakovat vysunuti filamentu?"
+#define MSG_UNLOAD_SUCCESSFULL				"Bylo vysunuti filamentu uspesne?"
+#define MSG_PRESS_TO_PREHEAT				"Pro nahrati trysky a pokracovani stisknete tlacitko."
+#define MSG_PULL_OUT_FILAMENT				"Prosim vyjmete urychlene filament"
+#define MSG_CHECK_IDLER						"Prosim otevrete idler a manualne odstrante filament."
 #define MSG_FILE_INCOMPLETE					"Soubor nekompletni. Pokracovat?"
 #define MSG_FILE_CNT						"Nektere soubory nebudou setrideny. Maximalni pocet souboru pro setrideni je 100."
 #define MSG_SORT_TIME						"Trideni     [Cas]"
 #define MSG_SORT_ALPHA						"Trideni [Abeceda]"
 #define MSG_SORT_NONE						"Trideni   [Zadne]"
-#define(length=20, lines=1) MSG_SORTING                            "Trideni souboru"
-
+#define MSG_SORTING                            "Trideni souboru"
 
-#define(length=12, lines=1) MSG_INFO_NOZZLE_FAN                 "Trysk. vent:"
-#define(length=12, lines=1) MSG_INFO_PRINT_FAN                  "Tisk. vent:"
 
+#define MSG_INFO_NOZZLE_FAN                 "Trysk. vent:"
+#define MSG_INFO_PRINT_FAN                  "Tisk. vent:"
 
-#define(length=17, lines=1) MSG_SECOND_SERIAL_ON                 "RPi port    [zap]"
-#define(length=17, lines=1) MSG_SECOND_SERIAL_OFF                "RPi port    [vyp]"
 
-#define(length=15, lines=1) MSG_INFO_EXTRUDER                "Extruder info"
-#define(length=15, lines=1) MSG_MENU_VOLTAGES               "Napeti"
-#define(length=15, lines=1) MSG_MENU_TEMPERATURES           "Teploty"
-#define(length=15, lines=1) MSG_MENU_BELT_STATUS            "Stav remenu"
+#define MSG_SECOND_SERIAL_ON                 "RPi port    [zap]"
+#define MSG_SECOND_SERIAL_OFF                "RPi port    [vyp]"
 
-#define(length=20, lines=4) MSG_CRASH_DET_ONLY_IN_NORMAL        "\x1b[2JCrash detekce muze\x1b[1;0Hbyt zapnuta pouze v\x1b[2;0HNormal modu"
-#define(length=20, lines=4) MSG_CRASH_DET_STEALTH_FORCE_OFF     "\x1b[2JPOZOR:\x1b[1;0HCrash detekce\x1b[2;0Hdeaktivovana ve\x1b[3;0HStealth modu"
+#define MSG_INFO_EXTRUDER                "Extruder info"
+#define MSG_MENU_VOLTAGES               "Napeti"
+#define MSG_MENU_TEMPERATURES           "Teploty"
+#define MSG_MENU_BELT_STATUS            "Stav remenu"
 
-#define(length=20, lines=4) MSG_AUTOLOADING_ENABLED             "Automaticke zavadeni filamentu aktivni, stisknete tlacitko a vlozte filament..."
-#define(length=20, lines=4) MSG_AUTOLOADING_ONLY_IF_FSENS_ON    "Automaticke zavadeni filamentu dostupne pouze pri zapnutem filament senzoru..."
+#define MSG_CRASH_DET_ONLY_IN_NORMAL        "\x1b[2JCrash detekce muze\x1b[1;0Hbyt zapnuta pouze v\x1b[2;0HNormal modu"
+#define MSG_CRASH_DET_STEALTH_FORCE_OFF     "\x1b[2JPOZOR:\x1b[1;0HCrash detekce\x1b[2;0Hdeaktivovana ve\x1b[3;0HStealth modu"
 
-#define(length=20, lines=4) MSG_FSENS_NOT_RESPONDING     "CHYBA: Filament senzor nereaguje, zkontrolujte zapojeni."
+#define MSG_AUTOLOADING_ENABLED             "Automaticke zavadeni filamentu aktivni, stisknete tlacitko a vlozte filament..."
+#define MSG_AUTOLOADING_ONLY_IF_FSENS_ON    "Automaticke zavadeni filamentu dostupne pouze pri zapnutem filament senzoru..."
 
-#define(length=20, lines=8) MSG_FW_VERSION_UNKNOWN		 "VAROVANI: Neznama verze firmware"
-#define(length=20, lines=8) MSG_FW_VERSION_ALPHA		 "Pouzivate alpha verzi firmwaru. Jedna se o vyvojovou verzi. Pouzivani teto verze firmware neni doporuceno a muze zpusobit poskozeni tiskarny." 
-#define(length=20, lines=8) MSG_FW_VERSION_BETA			 "Pouzivate beta verzi firmwaru. Jedna se o vyvojovou verzi. Pouzivani teto verze firmware neni doporuceno a muze zpusobit poskozeni tiskarny."
-#define(length=20, lines=8) MSG_FW_VERSION_RC			 "Tato verze firmware je release candidate. Nektere z funkci nemusi pracovat spolehlive."
+#define MSG_FSENS_NOT_RESPONDING     "CHYBA: Filament senzor nereaguje, zkontrolujte zapojeni."
 
+#define MSG_FW_VERSION_UNKNOWN		 "VAROVANI: Neznama verze firmware"
+#define MSG_FW_VERSION_ALPHA		 "Pouzivate alpha verzi firmwaru. Jedna se o vyvojovou verzi. Pouzivani teto verze firmware neni doporuceno a muze zpusobit poskozeni tiskarny." 
+#define MSG_FW_VERSION_BETA			 "Pouzivate beta verzi firmwaru. Jedna se o vyvojovou verzi. Pouzivani teto verze firmware neni doporuceno a muze zpusobit poskozeni tiskarny."
+#define MSG_FW_VERSION_RC			 "Tato verze firmware je release candidate. Nektere z funkci nemusi pracovat spolehlive."
+#define MSG_FW_VERSION_DEBUG		 "Toto je vyvojova verze firmwaru obsahujici funkce pro debugging. Pouziti teto verze muze poskodit Vasi tiskarnu."

+ 5 - 1
Firmware/language_en.h

@@ -385,7 +385,10 @@
 #define(length=17, lines=1) MSG_FSENS_AUTOLOAD_OFF				"F. autoload [off]"
 #define(length=17, lines=1) MSG_FSENS_AUTOLOAD_NA                "F. autoload [N/A]"
 #define(length=20, lines=4) MSG_PRESS_TO_UNLOAD					"Please press the knob to unload filament"
-#define(length=20, lines=2) MSG_UNLOAD_SUCCESSFULL				"Repeat unloading filament?"
+#define(length=20, lines=4) MSG_PRESS_TO_PREHEAT				"Press knob to preheat nozzle and continue."
+#define(length=20, lines=2) MSG_UNLOAD_SUCCESSFULL				"Was filament unload successfull?"
+#define(length=20, lines=4) MSG_CHECK_IDLER						"Please open idler and remove filament manually."
+#define(length=20, lines=4) MSG_PULL_OUT_FILAMENT				"Please pull out filament immediately"
 #define(length=20, lines=2) MSG_FILE_INCOMPLETE					"File incomplete. Continue anyway?"
 
 #define(length=20, lines=4) MSG_DEFAULT_SETTINGS_LOADED			"Default settings loaded"
@@ -408,3 +411,4 @@
 #define(length=20, lines=8) MSG_FW_VERSION_ALPHA		 "You are using firmware alpha version. This is development version. Using this version is not recommended and may cause printer damage." 
 #define(length=20, lines=8) MSG_FW_VERSION_BETA			 "You are using firmware beta version. This is development version. Using this version is not recommended and may cause printer damage."
 #define(length=20, lines=8) MSG_FW_VERSION_RC			 "This firmware version is release candidate. Some of the features may not work properly."
+#define(length=20, lines=8) MSG_FW_VERSION_DEBUG		 "This is development firmware version which contains additional debugging features. Using this version may cause printer damage."

+ 45 - 14
Firmware/planner.cpp

@@ -999,8 +999,19 @@ Having the real displacement of the head, we can calculate the total movement le
     current_speed[i] = delta_mm[i] * inverse_second;
 #ifdef TMC2130
 	float max_fr = max_feedrate[i];
-	if ((tmc2130_mode == TMC2130_MODE_SILENT) && (i < 2))
-		max_fr = SILENT_MAX_FEEDRATE;
+	if (i < 2) // X, Y
+	{
+		if (tmc2130_mode == TMC2130_MODE_SILENT)
+		{
+			if (max_fr > SILENT_MAX_FEEDRATE)
+				max_fr = SILENT_MAX_FEEDRATE;
+		}
+		else
+		{
+			if (max_fr > NORMAL_MAX_FEEDRATE)
+				max_fr = NORMAL_MAX_FEEDRATE;
+		}
+	}
     if(fabs(current_speed[i]) > max_fr)
       speed_factor = min(speed_factor, max_fr / fabs(current_speed[i]));
 #else //TMC2130
@@ -1032,21 +1043,41 @@ Having the real displacement of the head, we can calculate the total movement le
   {
     block->acceleration_st = ceil(acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
 #ifdef TMC2130
+#ifdef SIMPLE_ACCEL_LIMIT // in some cases can be acceleration limited inproperly
+	if (tmc2130_mode == TMC2130_MODE_SILENT)
+	{
+		if (block->steps_x.wide || block->steps_y.wide)
+			if (block->acceleration_st > SILENT_MAX_ACCEL_ST) block->acceleration_st = SILENT_MAX_ACCEL_ST;
+	}
+	else
+	{
+		if (block->steps_x.wide || block->steps_y.wide)
+			if (block->acceleration_st > NORMAL_MAX_ACCEL_ST) block->acceleration_st = NORMAL_MAX_ACCEL_ST;
+	}
+	if (block->steps_x.wide && (block->acceleration_st > axis_steps_per_sqr_second[X_AXIS])) block->acceleration_st = axis_steps_per_sqr_second[X_AXIS];
+	if (block->steps_y.wide && (block->acceleration_st > axis_steps_per_sqr_second[Y_AXIS])) block->acceleration_st = axis_steps_per_sqr_second[Y_AXIS];
+	if (block->steps_z.wide && (block->acceleration_st > axis_steps_per_sqr_second[Z_AXIS])) block->acceleration_st = axis_steps_per_sqr_second[Z_AXIS];
+	if (block->steps_e.wide && (block->acceleration_st > axis_steps_per_sqr_second[E_AXIS])) block->acceleration_st = axis_steps_per_sqr_second[E_AXIS];
+#else // SIMPLE_ACCEL_LIMIT
 	if (tmc2130_mode == TMC2130_MODE_SILENT)
 	{
-		if(((float)block->acceleration_st * (float)block->steps_x.wide / (float)block->step_event_count.wide) > SILENT_MAX_ACCEL_X_ST)
-		  block->acceleration_st = SILENT_MAX_ACCEL_X_ST;
-		if(((float)block->acceleration_st * (float)block->steps_y.wide / (float)block->step_event_count.wide) > SILENT_MAX_ACCEL_Y_ST)
-		  block->acceleration_st = SILENT_MAX_ACCEL_Y_ST;
+		if ((block->steps_x.wide > block->step_event_count.wide / 2) || (block->steps_y.wide > block->step_event_count.wide / 2))
+			if (block->acceleration_st > SILENT_MAX_ACCEL_ST) block->acceleration_st = SILENT_MAX_ACCEL_ST;
+	}
+	else
+	{
+		if ((block->steps_x.wide > block->step_event_count.wide / 2) || (block->steps_y.wide > block->step_event_count.wide / 2))
+			if (block->acceleration_st > NORMAL_MAX_ACCEL_ST) block->acceleration_st = NORMAL_MAX_ACCEL_ST;
 	}
-	if(((float)block->acceleration_st * (float)block->steps_x.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[X_AXIS])
-	  block->acceleration_st = axis_steps_per_sqr_second[X_AXIS];
-	if(((float)block->acceleration_st * (float)block->steps_y.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[Y_AXIS])
-	  block->acceleration_st = axis_steps_per_sqr_second[Y_AXIS];
-	if(((float)block->acceleration_st * (float)block->steps_e.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[E_AXIS])
-	  block->acceleration_st = axis_steps_per_sqr_second[E_AXIS];
-	if(((float)block->acceleration_st * (float)block->steps_z.wide / (float)block->step_event_count.wide ) > axis_steps_per_sqr_second[Z_AXIS])
-	  block->acceleration_st = axis_steps_per_sqr_second[Z_AXIS];
+    if(((float)block->acceleration_st * (float)block->steps_x.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[X_AXIS])
+      block->acceleration_st = axis_steps_per_sqr_second[X_AXIS];
+    if(((float)block->acceleration_st * (float)block->steps_y.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[Y_AXIS])
+      block->acceleration_st = axis_steps_per_sqr_second[Y_AXIS];
+    if(((float)block->acceleration_st * (float)block->steps_z.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[Z_AXIS])
+      block->acceleration_st = axis_steps_per_sqr_second[Z_AXIS];
+    if(((float)block->acceleration_st * (float)block->steps_e.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[E_AXIS])
+      block->acceleration_st = axis_steps_per_sqr_second[E_AXIS];
+#endif // SIMPLE_ACCEL_LIMIT
 #else //TMC2130
     // Limit acceleration per axis
     //FIXME Vojtech: One shall rather limit a projection of the acceleration vector instead of using the limit.

+ 4 - 0
Firmware/temperature.cpp

@@ -1879,14 +1879,18 @@ ISR(TIMER0_COMPB_vect)
    
     if(curTodo>0)
     {
+		asm("cli");
       babystep(axis,/*fwd*/true);
       babystepsTodo[axis]--; //less to do next time
+		asm("sei");
     }
     else
     if(curTodo<0)
     {
+		asm("cli");
       babystep(axis,/*fwd*/false);
       babystepsTodo[axis]++; //less to do next time
+		asm("sei");
     }
   }
 #endif //BABYSTEPPING

+ 3 - 1
Firmware/tmc2130.cpp

@@ -239,7 +239,9 @@ void tmc2130_st_isr(uint8_t last_step_mask)
 		{
 			tmc2130_sg_cnt[axis] = tmc2130_sg_err[axis];
 			tmc2130_sg_change = true;
-			if (tmc2130_sg_err[axis] >= 32)
+			uint8_t sg_thr = 48;
+			if (axis == Y_AXIS) sg_thr = 64;
+			if (tmc2130_sg_err[axis] >= sg_thr)
 			{
 				tmc2130_sg_err[axis] = 0;
 				crash = true;

+ 38 - 15
Firmware/ultralcd.cpp

@@ -335,22 +335,28 @@ uint8_t lcdDrawUpdate = 2;                  /* Set to none-zero when the LCD nee
 // float raw_Ki, raw_Kd;
 #endif
 
-static void lcd_goto_menu(menuFunc_t menu, const uint32_t encoder = 0, const bool feedback = true, bool reset_menu_state = true) {
-  if (currentMenu != menu) {
-    currentMenu = menu;
-    encoderPosition = encoder;
-    if (reset_menu_state) {
-        // Resets the global shared C union.
-        // This ensures, that the menu entered will find out, that it shall initialize itself.
-        memset(&menuData, 0, sizeof(menuData));
-    }
-    if (feedback) lcd_quick_feedback();
-
-    // For LCD_PROGRESS_BAR re-initialize the custom characters
+static void lcd_goto_menu(menuFunc_t menu, const uint32_t encoder = 0, const bool feedback = true, bool reset_menu_state = true)
+{
+	asm("cli");
+	if (currentMenu != menu)
+	{
+		currentMenu = menu;
+		encoderPosition = encoder;
+		asm("sei");
+		if (reset_menu_state)
+		{
+			// Resets the global shared C union.
+			// This ensures, that the menu entered will find out, that it shall initialize itself.
+			memset(&menuData, 0, sizeof(menuData));
+		}
+		if (feedback) lcd_quick_feedback();
+		// For LCD_PROGRESS_BAR re-initialize the custom characters
 #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)
-    lcd_set_custom_characters(menu == lcd_status_screen);
+		lcd_set_custom_characters(menu == lcd_status_screen);
 #endif
-  }
+	}
+	else
+		asm("sei");
 }
 
 /* Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependent */
@@ -2458,6 +2464,17 @@ void lcd_adjust_z() {
 
 }
 
+void lcd_wait_for_heater() {
+	lcd_display_message_fullscreen_P(MSG_WIZARD_HEATING);
+
+		lcd.setCursor(0, 4);
+		lcd.print(LCD_STR_THERMOMETER[0]);
+		lcd.print(ftostr3(degHotend(active_extruder)));
+		lcd.print("/");
+		lcd.print(ftostr3(degTargetHotend(active_extruder)));
+		lcd.print(LCD_STR_DEGREE);
+}
+
 void lcd_wait_for_cool_down() {
 	lcd_set_custom_characters_degree();
 	setTargetHotend(0,0);
@@ -5495,8 +5512,10 @@ void lcd_sdcard_menu()
   } \
   static void menu_action_setting_edit_ ## _name (const char* pstr, _type* ptr, _type minValue, _type maxValue) \
   { \
-    menuData.editMenuParentState.prevMenu = currentMenu; \
+    asm("cli"); \
+	menuData.editMenuParentState.prevMenu = currentMenu; \
     menuData.editMenuParentState.prevEncoderPosition = encoderPosition; \
+    asm("sei"); \
     \
     lcdDrawUpdate = 2; \
     menuData.editMenuParentState.editLabel = pstr; \
@@ -6910,6 +6929,9 @@ void lcd_setcontrast(uint8_t value)
 /* Warning: This function is called from interrupt context */
 void lcd_buttons_update()
 {
+	static bool _lock = false;
+	if (_lock) return;
+	_lock = true;
 #ifdef NEWPANEL
   uint8_t newbutton = 0;
   if (READ(BTN_EN1) == 0)  newbutton |= EN_A;
@@ -7034,6 +7056,7 @@ void lcd_buttons_update()
     }
   }
   lastEncoderBits = enc;
+  _lock = false;
 }
 
 bool lcd_detected(void)

+ 1 - 0
Firmware/ultralcd.h

@@ -258,6 +258,7 @@ void lcd_farm_sdcard_menu();
 void lcd_farm_sdcard_menu_w();
 //void get_description();
 
+void lcd_wait_for_heater();
 void lcd_wait_for_cool_down();
 void adjust_bed_reset();
 void lcd_extr_cal_reset();