From 134a50f5b32be29bcc2df1d97ad3dab6fc279348 Mon Sep 17 00:00:00 2001
From: PavelSindler <sindlerpa@gmail.com>
Date: Fri, 5 May 2017 01:29:59 +0200
Subject: [PATCH] messages updated, different bowden lengths for SNMM used,
 M600 for SNMM updated, stop print for SNMM updated, load all filaments added

---
 Firmware/Configuration.h  |   2 +-
 Firmware/Marlin_main.cpp  |  39 +++++++++---
 Firmware/language_all.cpp |  19 +++++-
 Firmware/language_all.h   |   2 +
 Firmware/language_cz.h    |   1 +
 Firmware/language_en.h    |   1 +
 Firmware/language_es.h    |   2 +-
 Firmware/language_it.h    |   1 +
 Firmware/language_pl.h    |   1 +
 Firmware/planner.h        |   4 +-
 Firmware/ultralcd.cpp     | 127 +++++++++++++-------------------------
 Firmware/ultralcd.h       |   5 +-
 12 files changed, 102 insertions(+), 102 deletions(-)

diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h
index c2f568a2..483273a0 100644
--- a/Firmware/Configuration.h
+++ b/Firmware/Configuration.h
@@ -5,7 +5,7 @@
 #include "Configuration_prusa.h"
 
 // Firmware version
-#define FW_version "3.0.10-11"
+#define FW_version "3.0.11-RC1"
 
 #define FW_PRUSA3D_MAGIC "PRUSA3DFW"
 #define FW_PRUSA3D_MAGIC_LEN 10
diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp
index 795c1299..ab50a319 100644
--- a/Firmware/Marlin_main.cpp
+++ b/Firmware/Marlin_main.cpp
@@ -1200,6 +1200,7 @@ void setup()
       // Show the message.
       lcd_show_fullscreen_message_and_wait_P(MSG_FOLLOW_CALIBRATION_FLOW);
   }
+  for (int i = 0; i<4; i++) EEPROM_read_B(EEPROM_BOWDEN_LENGTH + i * 2, &bowden_length[i]);
   lcd_update_enable(true);
 
   // Store the currently running firmware into an eeprom,
@@ -5082,7 +5083,7 @@ 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], 50, active_extruder);
 		target[E_AXIS] += (FIL_COOLING*-1);
 		plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 50, active_extruder);
-		target[E_AXIS] += (BOWDEN_LENGTH*-1);
+		target[E_AXIS] += (bowden_length[snmm_extruder] *-1);
 		plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 3000, active_extruder);
 		st_synchronize();
 
@@ -5109,6 +5110,13 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 		  cnt++;
           manage_heater();
           manage_inactivity(true);
+
+/*#ifdef SNMM
+		  target[E_AXIS] += 0.002;
+		  plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 500, active_extruder);
+
+#endif // SNMM*/
+
           if(cnt==0)
           {
           #if BEEPER > 0
@@ -5131,14 +5139,21 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 			   #endif
           #endif
           }
-#ifdef SNMM
-		  if (millis() - load_filament_time > 2) {
-			  load_filament_time = millis();
-			  target[E_AXIS] += 0.001;
-			  plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 1000, active_extruder);
-		  }		  
-#endif
+
         }
+#ifdef SNMM
+		display_loading();
+		do {
+			target[E_AXIS] += 0.002;
+			plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 500, active_extruder);
+			delay_keep_alive(2);
+		} while (!lcd_clicked());		
+		/*if (millis() - load_filament_time > 2) {
+			load_filament_time = millis();
+			target[E_AXIS] += 0.001;
+			plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 1000, active_extruder);
+		}*/
+#endif
         //Filament inserted
         
         WRITE(BEEPER,LOW);
@@ -5147,7 +5162,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 #ifdef SNMM
 		
 		st_synchronize();
-		target[E_AXIS] += BOWDEN_LENGTH;
+		target[E_AXIS] += bowden_length[snmm_extruder];
 		plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 3000, active_extruder);
 		target[E_AXIS] += FIL_LOAD_LENGTH - 60;
 		plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 1400, active_extruder);
@@ -5196,6 +5211,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
              // Everything good             
              default:
                      lcd_change_success();
+					 lcd_update_enable(true);
                      break;
           }
           
@@ -5350,6 +5366,9 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 	break;
 	case 702:
 	{
+#ifdef SNMM
+		extr_unload_all();
+#else
 		custom_message = true;
 		custom_message_type = 2;
 		lcd_setstatuspgm(MSG_UNLOADING_FILAMENT); 
@@ -5361,7 +5380,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 		lcd_setstatuspgm(WELCOME_MSG);
 		custom_message = false;
 		custom_message_type = 0;
-		
+#endif	
 	}
 	break;
 
diff --git a/Firmware/language_all.cpp b/Firmware/language_all.cpp
index c5abd2fa..7c2cf494 100644
--- a/Firmware/language_all.cpp
+++ b/Firmware/language_all.cpp
@@ -968,13 +968,15 @@ const char * const MSG_FIL_ADJUSTING_LANG_TABLE[LANG_NUM] PROGMEM = {
 
 const char MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_EN[] PROGMEM = "Iteration ";
 const char MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_CZ[] PROGMEM = "Iterace ";
-const char MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_ES[] PROGMEM = "Iteracion ";
+const char MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_IT[] PROGMEM = "Reiterazione ";
+const char MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_ES[] PROGMEM = "Reiteracion ";
+const char MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_PL[] PROGMEM = "Iteracja ";
 const char * const MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_EN,
 	MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_CZ,
-	MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_EN,
+	MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_IT,
 	MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_ES,
-	MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_EN,
+	MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_PL,
 	MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION_EN
 };
 
@@ -1280,6 +1282,17 @@ const char * const MSG_LOADING_FILAMENT_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_LOADING_FILAMENT_DE
 };
 
+const char MSG_LOAD_ALL_EN[] PROGMEM = "Load all";
+const char MSG_LOAD_ALL_CZ[] PROGMEM = "Zavest vse";
+const char * const MSG_LOAD_ALL_LANG_TABLE[LANG_NUM] PROGMEM = {
+	MSG_LOAD_ALL_EN,
+	MSG_LOAD_ALL_CZ,
+	MSG_LOAD_ALL_EN,
+	MSG_LOAD_ALL_EN,
+	MSG_LOAD_ALL_EN,
+	MSG_LOAD_ALL_EN
+};
+
 const char MSG_LOAD_EPROM_EN[] PROGMEM = "Load memory";
 const char * const MSG_LOAD_EPROM_LANG_TABLE[1] PROGMEM = {
 	MSG_LOAD_EPROM_EN
diff --git a/Firmware/language_all.h b/Firmware/language_all.h
index 575b8af6..f04a0727 100644
--- a/Firmware/language_all.h
+++ b/Firmware/language_all.h
@@ -255,6 +255,8 @@ extern const char* const MSG_LOADING_COLOR_LANG_TABLE[LANG_NUM];
 #define MSG_LOADING_COLOR LANG_TABLE_SELECT(MSG_LOADING_COLOR_LANG_TABLE)
 extern const char* const MSG_LOADING_FILAMENT_LANG_TABLE[LANG_NUM];
 #define MSG_LOADING_FILAMENT LANG_TABLE_SELECT(MSG_LOADING_FILAMENT_LANG_TABLE)
+extern const char* const MSG_LOAD_ALL_LANG_TABLE[LANG_NUM];
+#define MSG_LOAD_ALL LANG_TABLE_SELECT(MSG_LOAD_ALL_LANG_TABLE)
 extern const char* const MSG_LOAD_EPROM_LANG_TABLE[1];
 #define MSG_LOAD_EPROM LANG_TABLE_SELECT_EXPLICIT(MSG_LOAD_EPROM_LANG_TABLE, 0)
 extern const char* const MSG_LOAD_FILAMENT_LANG_TABLE[LANG_NUM];
diff --git a/Firmware/language_cz.h b/Firmware/language_cz.h
index cadba987..9712ab37 100644
--- a/Firmware/language_cz.h
+++ b/Firmware/language_cz.h
@@ -83,6 +83,7 @@
 #define MSG_UNLOAD_FILAMENT_3				"Vyjmout filament 3"
 #define MSG_UNLOAD_FILAMENT_4				"Vyjmout filament 4"
 #define MSG_UNLOAD_ALL						"Vyjmout vse"
+#define MSG_LOAD_ALL						"Zavest vse"
 
 #define MSG_RECTRACT                        "Rectract"
 #define MSG_ERROR                       "CHYBA:"
diff --git a/Firmware/language_en.h b/Firmware/language_en.h
index 245ad732..ec3ea211 100644
--- a/Firmware/language_en.h
+++ b/Firmware/language_en.h
@@ -80,6 +80,7 @@
 #define MSG_UNLOAD_FILAMENT_3				"Unload filament 3"
 #define MSG_UNLOAD_FILAMENT_4				"Unload filament 4"
 #define MSG_UNLOAD_ALL						"Unload all"
+#define MSG_LOAD_ALL						"Load all"
 
 
 #define MSG_RECTRACT                        "Rectract"
diff --git a/Firmware/language_es.h b/Firmware/language_es.h
index 7a43092f..066412cf 100644
--- a/Firmware/language_es.h
+++ b/Firmware/language_es.h
@@ -206,7 +206,7 @@
 #define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1	"Medir la altura del punto de la calibracion"
 #define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2	" de 9"
 
-#define MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION	"Iteracion "
+#define MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION	"Reiteracion "
 #define MSG_BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND           "Calibracion XYZ fallada. Puntos de calibracion en la cama no encontrados."
 #define MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED            "Calibracion XYZ fallada. Consultar el manual por favor."
 #define MSG_BED_SKEW_OFFSET_DETECTION_PERFECT               "Calibracion XYZ ok. Ejes X/Y perpendiculares. Felicitaciones!"
diff --git a/Firmware/language_it.h b/Firmware/language_it.h
index 26f5ae48..1075d9a7 100644
--- a/Firmware/language_it.h
+++ b/Firmware/language_it.h
@@ -196,6 +196,7 @@
 #define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2		" su 9"
 #define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1		"Misurare l'altezza di riferimento del punto di calibrazione"
 #define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2		" su 9"
+#define MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION	"Reiterazione "
 
 #define MSG_BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND		"Calibrazione XYZ fallita. Il punto di calibrazione sul letto non e' stato trovato."
 #define MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED		"Calibrazione XYZ fallita. Si prega di consultare il manuale."
diff --git a/Firmware/language_pl.h b/Firmware/language_pl.h
index 83fbfa8b..d8cae5c1 100644
--- a/Firmware/language_pl.h
+++ b/Firmware/language_pl.h
@@ -211,6 +211,7 @@
 #define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2   	" z 9"
 #define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1		"Okreslam wysokosc odniesienia punktu kalibracyjnego"
 #define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2		" z 9"
+#define MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION	"Iteracja "
 
 #define MSG_BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND           "Kalibr. XYZ nieudana. Kalibracyjny punkt podkladki nieznaleziony."
 #define MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED            "Kalibracja XYZ niepowiedziona. Sprawdzic w instrukcji."
diff --git a/Firmware/planner.h b/Firmware/planner.h
index a13aa1bd..30194952 100644
--- a/Firmware/planner.h
+++ b/Firmware/planner.h
@@ -171,7 +171,9 @@ FORCE_INLINE block_t *plan_get_current_block()
 }
 
 // Returns true if the buffer has a queued block, false otherwise
-FORCE_INLINE bool blocks_queued() { return (block_buffer_head != block_buffer_tail); }
+FORCE_INLINE bool blocks_queued() { 
+	return (block_buffer_head != block_buffer_tail); 
+}
 
 //return the nr of buffered moves
 FORCE_INLINE uint8_t moves_planned() {
diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp
index 4c907c7b..a933d4bc 100644
--- a/Firmware/ultralcd.cpp
+++ b/Firmware/ultralcd.cpp
@@ -515,43 +515,6 @@ static void lcd_status_screen()
 
 #ifdef ULTIPANEL
 
-void unload_fil() {
-	char cmd1[10];
-	float unload_l = ((BOWDEN_LENGTH + 60 + FIL_LOAD_LENGTH) / 2);
-
-	sprintf_P(cmd1, PSTR("M106 S%d"), fanSpeedBckp);
-	enquecommand(cmd1);
-	strcpy(cmd1, "G1 Z");
-	strcat(cmd1, ftostr32(pause_lastpos[Z_AXIS]));
-	enquecommand(cmd1);
-
-	enquecommand_P(PSTR("M907 E700")); //set extruder current higher
-	enquecommand_P(PSTR("M203 E50")); //set max. feedrate
-	st_synchronize();
-	if (current_temperature[0] < 230) {
-		// PLA
-		enquecommand_P(PSTR("G1 E5.4 F2800.000000"));
-		enquecommand_P(PSTR("G1 E3.2 F3000.000000"));
-		enquecommand_P(PSTR("G1 E3 F3400.000000"));
-		st_synchronize();
-	}
-	else {
-		// ABS
-		enquecommand_P(PSTR("G1 E3.1 F2000.000000"));
-		enquecommand_P(PSTR("G1 E3.1 F2500.000000"));
-		enquecommand_P(PSTR("G1 E4 F3000.000000"));
-		st_synchronize();
-	}
-	enquecommand_P(PSTR("M203 E80")); //set max. feedrate
-	enquecommand_P(PSTR("M907 E550")); //set extruder current
-	st_synchronize();
-	strcpy(cmd1, "G1 E-");
-	strcat(cmd1, ftostr32(unload_l));
-	enquecommand(cmd1);
-	enquecommand(cmd1);
-	st_synchronize();
-}
-
 void lcd_commands()
 {	
 	char cmd1[25];
@@ -650,9 +613,8 @@ void lcd_commands()
 		if (lcd_commands_step == 2 && !blocks_queued())
 		{
 			setTargetBed(0);
-			setTargetHotend(0, 0);
-			setTargetHotend(0, 1);
-			setTargetHotend(0, 2);
+			enquecommand_P(PSTR("M104 S0")); //set hotend temp to 0
+
 			manage_heater();
 			lcd_setstatuspgm(WELCOME_MSG);
 			cancel_heatup = false;
@@ -710,41 +672,7 @@ void lcd_commands()
 			lcd_commands_step = 5;
 		}
 		if (lcd_commands_step == 7 && !blocks_queued()) {
-			MYSERIAL.print("7");
-			stopped_extruder = snmm_extruder;
-			unload_fil();
-			lcd_commands_step = 8;
-		}
-		if (lcd_commands_step == 8 && !blocks_queued()) {
-			MYSERIAL.print("8");
-			if (stopped_extruder != 0) {
-				change_extr(0);
-				unload_fil();
-			}
-			lcd_commands_step = 9;
-		}
-		if (lcd_commands_step == 9 && !blocks_queued()) {
-			MYSERIAL.print("9");
-			if (stopped_extruder != 1) {
-				change_extr(1);
-				unload_fil();
-			}
-			lcd_commands_step = 10;
-		}
-		if (lcd_commands_step == 10 && !blocks_queued()) {
-			MYSERIAL.print("10");
-			if (stopped_extruder != 2) {
-				change_extr(2);
-				unload_fil();
-			}
-			lcd_commands_step = 11;
-		}
-		if (lcd_commands_step == 11 && !blocks_queued()) {
-			MYSERIAL.print("11");
-			if (stopped_extruder != 3) {
-				change_extr(3);
-				unload_fil();
-			}
+			enquecommand_P(PSTR("M702"));
 			lcd_commands_step = 3;
 		}
 	}
@@ -2851,10 +2779,19 @@ void bowden_menu() {
 		lcd.print(i);
 		lcd.print(": ");
 		EEPROM_read_B(EEPROM_BOWDEN_LENGTH + i * 2, &bowden_length[i]);
-		lcd.print(bowden_length[i]);
+		lcd.print(bowden_length[i] - 48);
 
 	}
 	enc_dif = encoderDiff;
+	/*while (1) {
+		if (lcd_clicked()) {
+			while (lcd_clicked());
+			delay(10);
+			while (lcd_clicked());
+			break;
+		}
+	}*/
+
 	while (1) {
 		
 		manage_heater();
@@ -2878,14 +2815,14 @@ void bowden_menu() {
 						if (enc_dif > encoderDiff) {
 							bowden_length[cursor_pos]--;
 							lcd.setCursor(13, cursor_pos);
-							lcd.print(bowden_length[cursor_pos]);
+							lcd.print(bowden_length[cursor_pos] -48);
 							enc_dif = encoderDiff;
 						}
 
 						if (enc_dif < encoderDiff) {
 							bowden_length[cursor_pos]++;
 							lcd.setCursor(13, cursor_pos);
-							lcd.print(bowden_length[cursor_pos]);
+							lcd.print(bowden_length[cursor_pos] -48);
 							enc_dif = encoderDiff;
 						}
 					}
@@ -3082,6 +3019,15 @@ static int get_ext_nr() { //reads multiplexer input pins and return current extr
 }
 
 
+void display_loading() {
+	switch (snmm_extruder) {
+	case 1: (MSG_FILAMENT_LOADING_T1); break;
+	case 2: lcd_display_message_fullscreen_P(MSG_FILAMENT_LOADING_T2); break;
+	case 3: lcd_display_message_fullscreen_P(MSG_FILAMENT_LOADING_T3); break;
+	default: lcd_display_message_fullscreen_P(MSG_FILAMENT_LOADING_T0); break;
+	}
+}
+
 static void extr_adj(int extruder) //loading filament for SNMM
 {
 	bool correct;
@@ -3108,7 +3054,7 @@ static void extr_adj(int extruder) //loading filament for SNMM
 	//if (!correct) goto	START;
 	//extr_mov(BOWDEN_LENGTH/2.f, 500); //dividing by 2 is there because of max. extrusion length limitation (x_max + y_max)
 	//extr_mov(BOWDEN_LENGTH/2.f, 500);
-	extr_mov(BOWDEN_LENGTH, 500);
+	extr_mov(bowden_length[extruder], 500);
 	lcd_implementation_clear();
 	lcd.setCursor(0, 1); lcd_printPGM(MSG_PLEASE_WAIT);
 	st_synchronize();
@@ -3129,9 +3075,10 @@ static void extr_unload() { //unloads filament
 		lcd_display_message_fullscreen_P(PSTR(""));
 		max_feedrate[E_AXIS] = 50;
 		lcd.setCursor(0, 1); lcd_printPGM(MSG_PLEASE_WAIT);
-		current_position[Z_AXIS] += 15; //lifting in Z direction to make space for extrusion
-		plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 25, active_extruder);
-
+		if (current_position[Z_AXIS] < 15) {
+			current_position[Z_AXIS] += 15; //lifting in Z direction to make space for extrusion
+			plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 25, active_extruder);
+		}
 		
 		current_position[E_AXIS] += 10; //extrusion
 		plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 10, active_extruder);
@@ -3159,9 +3106,9 @@ static void extr_unload() { //unloads filament
 		}
 	
 		max_feedrate[E_AXIS] = 80;
-		current_position[E_AXIS] -= (BOWDEN_LENGTH + 60 + FIL_LOAD_LENGTH) / 2;   
+		current_position[E_AXIS] -= (bowden_length[snmm_extruder] + 60 + FIL_LOAD_LENGTH) / 2;
 		plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 500, active_extruder);
-		current_position[E_AXIS] -= (BOWDEN_LENGTH + 60 + FIL_LOAD_LENGTH) / 2;
+		current_position[E_AXIS] -= (bowden_length[snmm_extruder] + 60 + FIL_LOAD_LENGTH) / 2;
 		plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 500, active_extruder);
 		st_synchronize();
 		//digipot_init();
@@ -3208,6 +3155,13 @@ static void extr_adj_3() {
 	extr_adj(3);
 }
 
+static void load_all() {
+	for (int i = 0; i < 4; i++) {
+		change_extr(i);
+		extr_adj(i);
+	}
+}
+
 //wrapper functions for changing extruders
 static void extr_change_0() {
 	change_extr(0);
@@ -3227,7 +3181,7 @@ static void extr_change_3() {
 }
 
 //wrapper functions for unloading filament
-static void extr_unload_all() {
+void extr_unload_all() {
 	if (degHotend0() > EXTRUDE_MINTEMP) {
 		for (int i = 0; i < 4; i++) {
 			change_extr(i);
@@ -3246,6 +3200,8 @@ static void extr_unload_all() {
 	}
 }
 
+
+
 static void extr_unload_0() {
 	change_extr(0);
 	extr_unload();
@@ -3268,6 +3224,7 @@ static void fil_load_menu()
 {
 	START_MENU();
 	MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
+	MENU_ITEM(function, MSG_LOAD_ALL, load_all);
 	MENU_ITEM(function, MSG_LOAD_FILAMENT_1, extr_adj_0);
 	MENU_ITEM(function, MSG_LOAD_FILAMENT_2, extr_adj_1);
 	MENU_ITEM(function, MSG_LOAD_FILAMENT_3, extr_adj_2);
diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h
index 1d2edc47..8da77829 100644
--- a/Firmware/ultralcd.h
+++ b/Firmware/ultralcd.h
@@ -221,7 +221,8 @@ static void extr_unload_1();
 static void extr_unload_2();
 static void extr_unload_3();
 static void lcd_disable_farm_mode();
-static void extr_unload_all();
+void extr_unload_all();
+static void extr_unload();
 
 void stack_error();
 static void lcd_ping_allert();
@@ -249,4 +250,6 @@ void lcd_pinda_calibration_menu();
 void lcd_calibrate_pinda();
 void lcd_temp_calibration_set();
 
+void display_loading();
+
 #endif //ULTRALCD_H
\ No newline at end of file