From ae08788c99ea77ad5a08e22fc156430b537322ac Mon Sep 17 00:00:00 2001
From: Marek Bel <marek.bel@posta.cz>
Date: Wed, 18 Apr 2018 23:30:01 +0200
Subject: [PATCH 1/7] Split lcd_service_mode_show_result screens to separate
 functions. Make them non blocking. Remove global array distance_from_min,
 pass it as function return value. Make Support submenus returning to Support
 menu.

---
 Firmware/Marlin.h                 |   1 -
 Firmware/Marlin_main.cpp          |   2 -
 Firmware/mesh_bed_calibration.cpp |  11 +--
 Firmware/mesh_bed_calibration.h   |   3 +-
 Firmware/ultralcd.cpp             | 112 +++++++++++++++---------------
 Firmware/ultralcd.h               |   2 -
 6 files changed, 65 insertions(+), 66 deletions(-)

diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h
index c540b13b..5767b8b2 100644
--- a/Firmware/Marlin.h
+++ b/Firmware/Marlin.h
@@ -343,7 +343,6 @@ extern unsigned long t_fan_rising_edge;
 extern bool mesh_bed_leveling_flag;
 extern bool mesh_bed_run_from_menu;
 
-extern float distance_from_min[2];
 extern bool sortAlpha;
 
 extern char dir_names[3][9];
diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp
index 1102e111..833cea94 100644
--- a/Firmware/Marlin_main.cpp
+++ b/Firmware/Marlin_main.cpp
@@ -324,8 +324,6 @@ unsigned int custom_message_type;
 unsigned int custom_message_state;
 char snmm_filaments_used = 0;
 
-float distance_from_min[2];
-
 bool fan_state[2];
 int fan_edge_counter[2];
 int fan_speed[2];
diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp
index 266733c8..907136b6 100644
--- a/Firmware/mesh_bed_calibration.cpp
+++ b/Firmware/mesh_bed_calibration.cpp
@@ -2960,8 +2960,8 @@ void babystep_reset()
       babystepLoadZ = 0;    
 }
 
-void count_xyz_details() {
-	float a1, a2;
+DistanceMin count_xyz_details() {
+    DistanceMin distanceMin;
 	float cntr[2] = {
 		eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER + 0)),
 		eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER + 4))
@@ -2974,12 +2974,15 @@ void count_xyz_details() {
 		eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y + 0)),
 		eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y + 4))
 	};
+#if 0
 	a2 = -1 * asin(vec_y[0] / MACHINE_AXIS_SCALE_Y);
 	a1 = asin(vec_x[1] / MACHINE_AXIS_SCALE_X);
-	//angleDiff = fabs(a2 - a1);
+	angleDiff = fabs(a2 - a1);
+#endif
 	for (uint8_t mesh_point = 0; mesh_point < 2; ++mesh_point) {
 		float y = vec_x[1] * pgm_read_float(bed_ref_points_4 + mesh_point * 2) + vec_y[1] * pgm_read_float(bed_ref_points_4 + mesh_point * 2 + 1) + cntr[1];
-		distance_from_min[mesh_point] = (y - Y_MIN_POS_CALIBRATION_POINT_OUT_OF_REACH);
+		distanceMin.d[mesh_point] = (y - Y_MIN_POS_CALIBRATION_POINT_OUT_OF_REACH);
 	}
+	return distanceMin;
 }
 
diff --git a/Firmware/mesh_bed_calibration.h b/Firmware/mesh_bed_calibration.h
index ced77cf6..34def34a 100644
--- a/Firmware/mesh_bed_calibration.h
+++ b/Firmware/mesh_bed_calibration.h
@@ -181,7 +181,8 @@ extern void babystep_undo();
 
 // Reset the current babystep counter without moving the axes.
 extern void babystep_reset();
-extern void count_xyz_details();
+typedef struct{ float d[2];} DistanceMin;
+extern DistanceMin count_xyz_details();
 extern bool sample_z();
 
 #endif /* MESH_BED_CALIBRATION_H */
diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp
index a9518158..ac5d3bcf 100644
--- a/Firmware/ultralcd.cpp
+++ b/Firmware/ultralcd.cpp
@@ -222,6 +222,8 @@ static void prusa_stat_temperatures();
 static void prusa_stat_printinfo();
 static void lcd_farm_no();
 static void lcd_menu_extruder_info();
+static void lcd_menu_xyz_y_min();
+static void lcd_menu_xyz_skew();
 #if defined(TMC2130) || defined(PAT9125)
 static void lcd_menu_fails_stats();
 #endif //TMC2130 or PAT9125
@@ -1582,7 +1584,7 @@ static void lcd_menu_extruder_info()
     if (lcd_clicked())
     {
         lcd_quick_feedback();
-        lcd_return_to_status();
+        menu_action_back();
     }
 }
 
@@ -1686,7 +1688,7 @@ static void lcd_menu_debug()
 	if (lcd_clicked())
     {
         lcd_quick_feedback();
-        lcd_return_to_status();
+        menu_action_back();
     }
 }
 #endif /* DEBUG_BUILD */
@@ -1703,7 +1705,7 @@ static void lcd_menu_temperatures()
 	if (lcd_clicked())
     {
         lcd_quick_feedback();
-        lcd_return_to_status();
+        menu_action_back();
     }
 }
 
@@ -1721,7 +1723,7 @@ static void lcd_menu_voltages()
     if (lcd_clicked())
     {
         lcd_quick_feedback();
-        lcd_return_to_status();
+        menu_action_back();
     }
 }
 #endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN
@@ -1733,7 +1735,7 @@ static void lcd_menu_belt_status()
     if (lcd_clicked())
     {
         lcd_quick_feedback();
-        lcd_return_to_status();
+        menu_action_back();
     }
 }
 #endif //TMC2130
@@ -1831,7 +1833,7 @@ static void lcd_support_menu()
   }
   #ifndef MK1BP
   MENU_ITEM(back, PSTR("------------"), 0);
-  if (!IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL)) MENU_ITEM(function, MSG_XYZ_DETAILS, lcd_service_mode_show_result);
+  if (!IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL)) MENU_ITEM(submenu, MSG_XYZ_DETAILS, lcd_menu_xyz_y_min);
   MENU_ITEM(submenu, MSG_INFO_EXTRUDER, lcd_menu_extruder_info);
 
 #ifdef TMC2130
@@ -2285,62 +2287,60 @@ static void lcd_move_e()
 	}
 }
 
-void lcd_service_mode_show_result() {
-	float angleDiff;
-	lcd_set_custom_characters_degree();
-	count_xyz_details();
-	angleDiff = eeprom_read_float((float*)(EEPROM_XYZ_CAL_SKEW));
-	lcd_update_enable(false);
-	lcd_implementation_clear();
-	lcd_printPGM(MSG_Y_DISTANCE_FROM_MIN);
-	lcd_print_at_PGM(0, 1, MSG_LEFT);
-	lcd_print_at_PGM(0, 2, MSG_RIGHT);
+static void lcd_menu_xyz_y_min()
+{
+    lcd.setCursor(0,0);
+    lcd_printPGM(MSG_Y_DISTANCE_FROM_MIN);
+    lcd_print_at_PGM(0, 1, PSTR("--------------------"));
+    lcd_print_at_PGM(0, 2, MSG_LEFT);
+    lcd_print_at_PGM(0, 3, MSG_RIGHT);
 
-	for (int i = 0; i < 2; i++) {
-		if(distance_from_min[i] < 200) {
-			lcd_print_at_PGM(11, i + 1, PSTR(""));
-			lcd.print(distance_from_min[i]);
-			lcd_print_at_PGM((distance_from_min[i] < 0) ? 17 : 16, i + 1, PSTR("mm"));		
-		} else lcd_print_at_PGM(11, i + 1, PSTR("N/A"));
-	}
-	delay_keep_alive(500);
-	KEEPALIVE_STATE(PAUSED_FOR_USER);
-	while (!lcd_clicked()) {
-		delay_keep_alive(100);
-	}
-	delay_keep_alive(500);
-	lcd_implementation_clear();
-	
+    DistanceMin distanceMin = count_xyz_details();
 
-	lcd_printPGM(MSG_MEASURED_SKEW);
-	if (angleDiff < 100) {
-		lcd.setCursor(15, 0);
-		lcd.print(angleDiff * 180 / M_PI);
-		lcd.print(LCD_STR_DEGREE);
-	}else lcd_print_at_PGM(16, 0, PSTR("N/A"));
-	lcd_print_at_PGM(0, 1, PSTR("--------------------"));
-	lcd_print_at_PGM(0, 2, MSG_SLIGHT_SKEW);
-	lcd_print_at_PGM(15, 2, PSTR(""));
-	lcd.print(bed_skew_angle_mild * 180 / M_PI);
-	lcd.print(LCD_STR_DEGREE);
-	lcd_print_at_PGM(0, 3, MSG_SEVERE_SKEW);
-	lcd_print_at_PGM(15, 3, PSTR(""));
-	lcd.print(bed_skew_angle_extreme * 180 / M_PI);
-	lcd.print(LCD_STR_DEGREE);
-	delay_keep_alive(500);
-	while (!lcd_clicked()) {
-		delay_keep_alive(100);
-	}
-	KEEPALIVE_STATE(NOT_BUSY);
-	delay_keep_alive(500);
-	lcd_set_custom_characters_arrows();
-	lcd_return_to_status();
-	lcd_update_enable(true);
-	lcd_update(2);
+    for (int i = 0; i < 2; i++) {
+        if(distanceMin.d[i] < 200) {
+            lcd_print_at_PGM(11, i + 2, PSTR(""));
+            lcd.print(distanceMin.d[i]);
+            lcd_print_at_PGM((distanceMin.d[i] < 0) ? 17 : 16, i + 2, PSTR("mm"));
+        } else lcd_print_at_PGM(11, i + 2, PSTR("N/A"));
+    }
+    if (lcd_clicked())
+    {
+        lcd_quick_feedback();
+        lcd_set_custom_characters_degree();
+        lcd_goto_menu(lcd_menu_xyz_skew);
+    }
 }
 
+static void lcd_menu_xyz_skew()
+{
+    float angleDiff;
+    angleDiff = eeprom_read_float((float*)(EEPROM_XYZ_CAL_SKEW));
 
+    lcd.setCursor(0,0);
+    lcd_printPGM(MSG_MEASURED_SKEW);
+    if (angleDiff < 100) {
+        lcd.setCursor(15, 0);
+        lcd.print(angleDiff * 180 / M_PI);
+        lcd.print(LCD_STR_DEGREE);
+    }else lcd_print_at_PGM(16, 0, PSTR("N/A"));
+    lcd_print_at_PGM(0, 1, PSTR("--------------------"));
+    lcd_print_at_PGM(0, 2, MSG_SLIGHT_SKEW);
+    lcd_print_at_PGM(15, 2, PSTR(""));
+    lcd.print(bed_skew_angle_mild * 180 / M_PI);
+    lcd.print(LCD_STR_DEGREE);
+    lcd_print_at_PGM(0, 3, MSG_SEVERE_SKEW);
+    lcd_print_at_PGM(15, 3, PSTR(""));
+    lcd.print(bed_skew_angle_extreme * 180 / M_PI);
+    lcd.print(LCD_STR_DEGREE);
 
+    if (lcd_clicked())
+    {
+        lcd_set_custom_characters_arrows();
+        lcd_quick_feedback();
+        menu_action_back();
+    }
+}
 
 // Save a single axis babystep value.
 void EEPROM_save_B(int pos, int* value)
diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h
index 740dd738..4107bc72 100644
--- a/Firmware/ultralcd.h
+++ b/Firmware/ultralcd.h
@@ -296,8 +296,6 @@ void lcd_temp_calibration_set();
 
 void display_loading();
 
-void lcd_service_mode_show_result();
-
 #if !SDSORT_USES_RAM
  void lcd_set_degree();
  void lcd_set_progress();

From d6aa149cfa37de60b8d5a50d2cee15cb1fd9a6ee Mon Sep 17 00:00:00 2001
From: Marek Bel <marek.bel@posta.cz>
Date: Thu, 19 Apr 2018 00:15:08 +0200
Subject: [PATCH 2/7] Conserve 58 bytes of flash by returning by reference.

---
 Firmware/mesh_bed_calibration.cpp | 6 ++----
 Firmware/mesh_bed_calibration.h   | 4 ++--
 Firmware/ultralcd.cpp             | 9 +++++----
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp
index 907136b6..b8296662 100644
--- a/Firmware/mesh_bed_calibration.cpp
+++ b/Firmware/mesh_bed_calibration.cpp
@@ -2960,8 +2960,7 @@ void babystep_reset()
       babystepLoadZ = 0;    
 }
 
-DistanceMin count_xyz_details() {
-    DistanceMin distanceMin;
+void count_xyz_details(float (&distanceMin)[2]) {
 	float cntr[2] = {
 		eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER + 0)),
 		eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER + 4))
@@ -2981,8 +2980,7 @@ DistanceMin count_xyz_details() {
 #endif
 	for (uint8_t mesh_point = 0; mesh_point < 2; ++mesh_point) {
 		float y = vec_x[1] * pgm_read_float(bed_ref_points_4 + mesh_point * 2) + vec_y[1] * pgm_read_float(bed_ref_points_4 + mesh_point * 2 + 1) + cntr[1];
-		distanceMin.d[mesh_point] = (y - Y_MIN_POS_CALIBRATION_POINT_OUT_OF_REACH);
+		distanceMin[mesh_point] = (y - Y_MIN_POS_CALIBRATION_POINT_OUT_OF_REACH);
 	}
-	return distanceMin;
 }
 
diff --git a/Firmware/mesh_bed_calibration.h b/Firmware/mesh_bed_calibration.h
index 34def34a..d1fa6523 100644
--- a/Firmware/mesh_bed_calibration.h
+++ b/Firmware/mesh_bed_calibration.h
@@ -181,8 +181,8 @@ extern void babystep_undo();
 
 // Reset the current babystep counter without moving the axes.
 extern void babystep_reset();
-typedef struct{ float d[2];} DistanceMin;
-extern DistanceMin count_xyz_details();
+
+extern void count_xyz_details(float (&distanceMin)[2]);
 extern bool sample_z();
 
 #endif /* MESH_BED_CALIBRATION_H */
diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp
index ac5d3bcf..32f03f80 100644
--- a/Firmware/ultralcd.cpp
+++ b/Firmware/ultralcd.cpp
@@ -2295,13 +2295,14 @@ static void lcd_menu_xyz_y_min()
     lcd_print_at_PGM(0, 2, MSG_LEFT);
     lcd_print_at_PGM(0, 3, MSG_RIGHT);
 
-    DistanceMin distanceMin = count_xyz_details();
+    float distanceMin[2];
+    count_xyz_details(distanceMin);
 
     for (int i = 0; i < 2; i++) {
-        if(distanceMin.d[i] < 200) {
+        if(distanceMin[i] < 200) {
             lcd_print_at_PGM(11, i + 2, PSTR(""));
-            lcd.print(distanceMin.d[i]);
-            lcd_print_at_PGM((distanceMin.d[i] < 0) ? 17 : 16, i + 2, PSTR("mm"));
+            lcd.print(distanceMin[i]);
+            lcd_print_at_PGM((distanceMin[i] < 0) ? 17 : 16, i + 2, PSTR("mm"));
         } else lcd_print_at_PGM(11, i + 2, PSTR("N/A"));
     }
     if (lcd_clicked())

From c1dd269a9278674c50ec42e53060488a9751631b Mon Sep 17 00:00:00 2001
From: Marek Bel <marek.bel@posta.cz>
Date: Thu, 19 Apr 2018 00:22:21 +0200
Subject: [PATCH 3/7] Fix missing degree symbol after returning to status
 screen. Those lcd_set_custom_characters* calls were redundant.

---
 Firmware/ultralcd.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp
index 32f03f80..71134c30 100644
--- a/Firmware/ultralcd.cpp
+++ b/Firmware/ultralcd.cpp
@@ -2308,7 +2308,6 @@ static void lcd_menu_xyz_y_min()
     if (lcd_clicked())
     {
         lcd_quick_feedback();
-        lcd_set_custom_characters_degree();
         lcd_goto_menu(lcd_menu_xyz_skew);
     }
 }
@@ -2337,7 +2336,6 @@ static void lcd_menu_xyz_skew()
 
     if (lcd_clicked())
     {
-        lcd_set_custom_characters_arrows();
         lcd_quick_feedback();
         menu_action_back();
     }

From b6888470cfa80451e34755474b6a5b8edc02700d Mon Sep 17 00:00:00 2001
From: Marek Bel <marek.bel@posta.cz>
Date: Thu, 19 Apr 2018 00:49:42 +0200
Subject: [PATCH 4/7] Save 42 bytes of flash by removing duplicate string
 "--------------------".

---
 Firmware/ultralcd.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp
index 71134c30..08ba18ca 100644
--- a/Firmware/ultralcd.cpp
+++ b/Firmware/ultralcd.cpp
@@ -192,6 +192,8 @@ unsigned char firstrun = 1;
 
 #include "ultralcd_implementation_hitachi_HD44780.h"
 
+static const char separator[] PROGMEM = "--------------------";
+
 /** forward declarations **/
 
 static const char* lcd_display_message_fullscreen_nonBlocking_P(const char *msg, uint8_t &nlines);
@@ -2291,7 +2293,7 @@ static void lcd_menu_xyz_y_min()
 {
     lcd.setCursor(0,0);
     lcd_printPGM(MSG_Y_DISTANCE_FROM_MIN);
-    lcd_print_at_PGM(0, 1, PSTR("--------------------"));
+    lcd_print_at_PGM(0, 1, separator);
     lcd_print_at_PGM(0, 2, MSG_LEFT);
     lcd_print_at_PGM(0, 3, MSG_RIGHT);
 
@@ -2324,7 +2326,7 @@ static void lcd_menu_xyz_skew()
         lcd.print(angleDiff * 180 / M_PI);
         lcd.print(LCD_STR_DEGREE);
     }else lcd_print_at_PGM(16, 0, PSTR("N/A"));
-    lcd_print_at_PGM(0, 1, PSTR("--------------------"));
+    lcd_print_at_PGM(0, 1, separator);
     lcd_print_at_PGM(0, 2, MSG_SLIGHT_SKEW);
     lcd_print_at_PGM(15, 2, PSTR(""));
     lcd.print(bed_skew_angle_mild * 180 / M_PI);
@@ -7138,7 +7140,7 @@ static int lcd_selftest_screen(int _step, int _progress, int _progress_scale, bo
 	if (_step == 13) lcd_printPGM(PSTR("Calibrating home"));
 
 	lcd.setCursor(0, 1);
-	lcd.print("--------------------");
+	lcd_printPGM(separator);
 	if ((_step >= -1) && (_step <= 1))
 	{
 		//SERIAL_ECHOLNPGM("Fan test");

From 1a80fc28e8779315a2653fb206eef07729396ea5 Mon Sep 17 00:00:00 2001
From: Marek Bel <marek.bel@posta.cz>
Date: Thu, 19 Apr 2018 14:17:46 +0200
Subject: [PATCH 5/7] Add zero point offset information support menu.

Note: XYZ menu is shown only if not printing and printer must me homed to show non-zero value.
---
 Firmware/language_all.cpp |  5 +++++
 Firmware/language_all.h   |  2 ++
 Firmware/language_en.h    |  1 +
 Firmware/ultralcd.cpp     | 22 ++++++++++++++++++++++
 4 files changed, 30 insertions(+)

diff --git a/Firmware/language_all.cpp b/Firmware/language_all.cpp
index 2be14ede..510d2e68 100644
--- a/Firmware/language_all.cpp
+++ b/Firmware/language_all.cpp
@@ -1161,6 +1161,11 @@ const char * const MSG_MAX_LANG_TABLE[1] PROGMEM = {
 	MSG_MAX_EN
 };
 
+const char MSG_MEASURED_OFFSET_EN[] PROGMEM = "[0;0] point offset";
+const char * const MSG_MEASURED_OFFSET_LANG_TABLE[1] PROGMEM = {
+	MSG_MEASURED_OFFSET_EN
+};
+
 const char MSG_MEASURED_SKEW_EN[] PROGMEM = "Measured skew:";
 const char MSG_MEASURED_SKEW_CZ[] PROGMEM = "Merene zkoseni:";
 const char * const MSG_MEASURED_SKEW_LANG_TABLE[LANG_NUM] PROGMEM = {
diff --git a/Firmware/language_all.h b/Firmware/language_all.h
index 992d602c..c7353d96 100644
--- a/Firmware/language_all.h
+++ b/Firmware/language_all.h
@@ -392,6 +392,8 @@ extern const char* const MSG_MARK_FIL_LANG_TABLE[LANG_NUM];
 #define MSG_MARK_FIL LANG_TABLE_SELECT(MSG_MARK_FIL_LANG_TABLE)
 extern const char* const MSG_MAX_LANG_TABLE[1];
 #define MSG_MAX LANG_TABLE_SELECT_EXPLICIT(MSG_MAX_LANG_TABLE, 0)
+extern const char* const MSG_MEASURED_OFFSET_LANG_TABLE[1];
+#define MSG_MEASURED_OFFSET LANG_TABLE_SELECT_EXPLICIT(MSG_MEASURED_OFFSET_LANG_TABLE, 0)
 extern const char* const MSG_MEASURED_SKEW_LANG_TABLE[LANG_NUM];
 #define MSG_MEASURED_SKEW LANG_TABLE_SELECT(MSG_MEASURED_SKEW_LANG_TABLE)
 extern const char* const MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_LANG_TABLE[LANG_NUM];
diff --git a/Firmware/language_en.h b/Firmware/language_en.h
index 695546a8..9b1e86e5 100644
--- a/Firmware/language_en.h
+++ b/Firmware/language_en.h
@@ -218,6 +218,7 @@
 #define(length=17,lines=1) MSG_SHOW_END_STOPS					"Show end stops"
 #define MSG_CALIBRATE_BED					"Calibrate XYZ"
 #define MSG_CALIBRATE_BED_RESET				"Reset XYZ calibr."
+#define MSG_MEASURED_OFFSET                 "[0;0] point offset"
 
 #define(length=20,lines=8) MSG_MOVE_CARRIAGE_TO_THE_TOP 	"Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
 #define(length=20,lines=8) MSG_MOVE_CARRIAGE_TO_THE_TOP_Z 	"Calibrating Z. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp
index 08ba18ca..ec9252ab 100644
--- a/Firmware/ultralcd.cpp
+++ b/Firmware/ultralcd.cpp
@@ -226,6 +226,7 @@ static void lcd_farm_no();
 static void lcd_menu_extruder_info();
 static void lcd_menu_xyz_y_min();
 static void lcd_menu_xyz_skew();
+static void lcd_menu_xyz_offset();
 #if defined(TMC2130) || defined(PAT9125)
 static void lcd_menu_fails_stats();
 #endif //TMC2130 or PAT9125
@@ -2336,6 +2337,27 @@ static void lcd_menu_xyz_skew()
     lcd.print(bed_skew_angle_extreme * 180 / M_PI);
     lcd.print(LCD_STR_DEGREE);
 
+    if (lcd_clicked())
+    {
+        lcd_quick_feedback();
+        lcd_goto_menu(lcd_menu_xyz_offset);
+    }
+}
+
+static void lcd_menu_xyz_offset()
+{
+    lcd.setCursor(0,0);
+    lcd_printPGM(MSG_MEASURED_OFFSET);
+    lcd_print_at_PGM(0, 1, separator);
+    lcd_print_at_PGM(0, 2, PSTR("X"));
+    lcd_print_at_PGM(0, 3, PSTR("Y"));
+
+    for (int i = 0; i < 2; i++)
+    {
+        lcd_print_at_PGM(11, i + 2, PSTR(""));
+        lcd.print(world2machine_shift[i]);
+        lcd_print_at_PGM((world2machine_shift[i] < 0) ? 17 : 16, i + 2, PSTR("mm"));
+    }
     if (lcd_clicked())
     {
         lcd_quick_feedback();

From ab68221976c3a6ac95215ac407defe4d218e328e Mon Sep 17 00:00:00 2001
From: Marek Bel <marek.bel@posta.cz>
Date: Mon, 23 Apr 2018 21:23:36 +0200
Subject: [PATCH 6/7] Always show XYZ cal. details menu.

---
 Firmware/ultralcd.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp
index ec9252ab..ef392677 100644
--- a/Firmware/ultralcd.cpp
+++ b/Firmware/ultralcd.cpp
@@ -1836,7 +1836,7 @@ static void lcd_support_menu()
   }
   #ifndef MK1BP
   MENU_ITEM(back, PSTR("------------"), 0);
-  if (!IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL)) MENU_ITEM(submenu, MSG_XYZ_DETAILS, lcd_menu_xyz_y_min);
+  MENU_ITEM(submenu, MSG_XYZ_DETAILS, lcd_menu_xyz_y_min);
   MENU_ITEM(submenu, MSG_INFO_EXTRUDER, lcd_menu_extruder_info);
 
 #ifdef TMC2130

From 329ea199ec58a15acb828580928eabab2123eab2 Mon Sep 17 00:00:00 2001
From: Marek Bel <marek.bel@posta.cz>
Date: Thu, 10 May 2018 18:24:49 +0200
Subject: [PATCH 7/7] Show measured bed offset from expected position even if
 not homed. Remove redundant lcd_quick_feedback() calls.

---
 Firmware/mesh_bed_calibration.cpp | 153 ++++++++++++++++++------------
 Firmware/mesh_bed_calibration.h   |   8 +-
 Firmware/ultralcd.cpp             |  31 +++---
 3 files changed, 113 insertions(+), 79 deletions(-)

diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp
index b8296662..c8e839c4 100644
--- a/Firmware/mesh_bed_calibration.cpp
+++ b/Firmware/mesh_bed_calibration.cpp
@@ -732,19 +732,24 @@ void world2machine_reset()
 }
 
 /**
- * @brief Set calibration matrix to default value
+ * @brief Get calibration matrix default value
  *
  * This is used if no valid calibration data can be read from EEPROM.
+ * @param [out] vec_x axis x vector
+ * @param [out] vec_y axis y vector
+ * @param [out] cntr offset vector
  */
-static void world2machine_default()
+static void world2machine_default(float vec_x[2], float vec_y[2], float cntr[2])
 {
+    vec_x[0] = 1.f;
+    vec_x[1] = 0.f;
+    vec_y[0] = 0.f;
+    vec_y[1] = 1.f;
+    cntr[0] =  0.f;
 #ifdef DEFAULT_Y_OFFSET
-    const float vx[] = { 1.f, 0.f };
-    const float vy[] = { 0.f, 1.f };
-    const float cntr[] = { 0.f, DEFAULT_Y_OFFSET };
-    world2machine_update(vx, vy, cntr);
+    cntr[1] = DEFAULT_Y_OFFSET;
 #else
-    world2machine_reset();
+    cntr[1] = 0.f;
 #endif
 }
 /**
@@ -768,93 +773,121 @@ static inline bool vec_undef(const float v[2])
     return vx[0] == 0x0FFFFFFFF || vx[1] == 0x0FFFFFFFF;
 }
 
+
 /**
- * @brief Read and apply calibration data from EEPROM
+ * @brief Read calibration data from EEPROM
  *
  * If no calibration data has been stored in EEPROM or invalid,
  * world2machine_default() is used.
  *
  * If stored calibration data is invalid, EEPROM storage is cleared.
- *
+ * @param [out] vec_x axis x vector
+ * @param [out] vec_y axis y vector
+ * @param [out] cntr offset vector
  */
-void world2machine_initialize()
+void world2machine_read_valid(float vec_x[2], float vec_y[2], float cntr[2])
 {
-    //SERIAL_ECHOLNPGM("world2machine_initialize");
-    float cntr[2] = {
-        eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+0)),
-        eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+4))
-    };
-    float vec_x[2] = {
-        eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +0)),
-        eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +4))
-    };
-    float vec_y[2] = {
-        eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +0)),
-        eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +4))
-    };
+    vec_x[0] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +0));
+    vec_x[1] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +4));
+    vec_y[0] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +0));
+    vec_y[1] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +4));
+    cntr[0] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+0));
+    cntr[1] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+4));
 
     bool reset = false;
-    if (vec_undef(cntr) || vec_undef(vec_x) || vec_undef(vec_y)) {
-//        SERIAL_ECHOLNPGM("Undefined bed correction matrix.");
+    if (vec_undef(cntr) || vec_undef(vec_x) || vec_undef(vec_y))
+    {
+#if 0
+        SERIAL_ECHOLNPGM("Undefined bed correction matrix.");
+#endif
         reset = true;
     }
-    else {
+    else
+    {
         // Length of the vec_x shall be close to unity.
         float l = sqrt(vec_x[0] * vec_x[0] + vec_x[1] * vec_x[1]);
-        if (l < 0.9 || l > 1.1) {
-//			SERIAL_ECHOLNPGM("X vector length:");
-//			MYSERIAL.println(l);
-//            SERIAL_ECHOLNPGM("Invalid bed correction matrix. Length of the X vector out of range.");
+        if (l < 0.9 || l > 1.1)
+        {
+#if 0
+            SERIAL_ECHOLNPGM("X vector length:");
+            MYSERIAL.println(l);
+            SERIAL_ECHOLNPGM("Invalid bed correction matrix. Length of the X vector out of range.");
+#endif
             reset = true;
         }
         // Length of the vec_y shall be close to unity.
         l = sqrt(vec_y[0] * vec_y[0] + vec_y[1] * vec_y[1]);
-        if (l < 0.9 || l > 1.1) {
-//			SERIAL_ECHOLNPGM("Y vector length:");
-//			MYSERIAL.println(l);
-//            SERIAL_ECHOLNPGM("Invalid bed correction matrix. Length of the Y vector out of range.");
+        if (l < 0.9 || l > 1.1)
+        {
+#if 0
+            SERIAL_ECHOLNPGM("Y vector length:");
+            MYSERIAL.println(l);
+            SERIAL_ECHOLNPGM("Invalid bed correction matrix. Length of the Y vector out of range.");
+#endif
             reset = true;
         }
         // Correction of the zero point shall be reasonably small.
         l = sqrt(cntr[0] * cntr[0] + cntr[1] * cntr[1]);
-        if (l > 15.f) {
-//			SERIAL_ECHOLNPGM("Zero point correction:");
-//			MYSERIAL.println(l);
-//            SERIAL_ECHOLNPGM("Invalid bed correction matrix. Shift out of range.");
+        if (l > 15.f)
+        {
+#if 0
+            SERIAL_ECHOLNPGM("Zero point correction:");
+            MYSERIAL.println(l);
+            SERIAL_ECHOLNPGM("Invalid bed correction matrix. Shift out of range.");
+#endif
             reset = true;
         }
         // vec_x and vec_y shall be nearly perpendicular.
         l = vec_x[0] * vec_y[0] + vec_x[1] * vec_y[1];
-        if (fabs(l) > 0.1f) {
-//            SERIAL_ECHOLNPGM("Invalid bed correction matrix. X/Y axes are far from being perpendicular.");
+        if (fabs(l) > 0.1f)
+        {
+#if 0
+            SERIAL_ECHOLNPGM("Invalid bed correction matrix. X/Y axes are far from being perpendicular.");
+#endif
             reset = true;
         }
     }
 
-    if (reset) {
-//        SERIAL_ECHOLNPGM("Invalid bed correction matrix. Resetting to identity.");
+    if (reset)
+    {
+#if 0
+        SERIAL_ECHOLNPGM("Invalid bed correction matrix. Resetting to identity.");
+#endif
         reset_bed_offset_and_skew();
-        world2machine_default();
-    } else {
-        world2machine_update(vec_x, vec_y, cntr);
-        /*
-        SERIAL_ECHOPGM("world2machine_initialize() loaded: ");
-        MYSERIAL.print(world2machine_rotation_and_skew[0][0], 5);
-        SERIAL_ECHOPGM(", ");
-        MYSERIAL.print(world2machine_rotation_and_skew[0][1], 5);
-        SERIAL_ECHOPGM(", ");
-        MYSERIAL.print(world2machine_rotation_and_skew[1][0], 5);
-        SERIAL_ECHOPGM(", ");
-        MYSERIAL.print(world2machine_rotation_and_skew[1][1], 5);
-        SERIAL_ECHOPGM(", offset ");
-        MYSERIAL.print(world2machine_shift[0], 5);
-        SERIAL_ECHOPGM(", ");
-        MYSERIAL.print(world2machine_shift[1], 5);
-        SERIAL_ECHOLNPGM("");
-        */
+        world2machine_default(vec_x, vec_y, cntr);
     }
 }
 
+/**
+ * @brief Read and apply validated calibration data from EEPROM
+ */
+void world2machine_initialize()
+{
+#if 0
+    SERIAL_ECHOLNPGM("world2machine_initialize");
+#endif
+    float vec_x[2];
+    float vec_y[2];
+    float cntr[2];
+    world2machine_read_valid(vec_x, vec_y, cntr);
+    world2machine_update(vec_x, vec_y, cntr);
+#if 0
+    SERIAL_ECHOPGM("world2machine_initialize() loaded: ");
+    MYSERIAL.print(world2machine_rotation_and_skew[0][0], 5);
+    SERIAL_ECHOPGM(", ");
+    MYSERIAL.print(world2machine_rotation_and_skew[0][1], 5);
+    SERIAL_ECHOPGM(", ");
+    MYSERIAL.print(world2machine_rotation_and_skew[1][0], 5);
+    SERIAL_ECHOPGM(", ");
+    MYSERIAL.print(world2machine_rotation_and_skew[1][1], 5);
+    SERIAL_ECHOPGM(", offset ");
+    MYSERIAL.print(world2machine_shift[0], 5);
+    SERIAL_ECHOPGM(", ");
+    MYSERIAL.print(world2machine_shift[1], 5);
+    SERIAL_ECHOLNPGM("");
+#endif
+}
+
 /**
  * @brief Update current position after switching to corrected coordinates
  *
diff --git a/Firmware/mesh_bed_calibration.h b/Firmware/mesh_bed_calibration.h
index d1fa6523..6d020f8c 100644
--- a/Firmware/mesh_bed_calibration.h
+++ b/Firmware/mesh_bed_calibration.h
@@ -26,16 +26,10 @@ extern float world2machine_rotation_and_skew_inv[2][2];
 // Shift of the machine zero point, in the machine coordinates.
 extern float world2machine_shift[2];
 
-// Resets the transformation to identity.
 extern void world2machine_reset();
-// Resets the transformation to identity and update current_position[X,Y] from the servos.
 extern void world2machine_revert_to_uncorrected();
-// Loads the transformation from the EEPROM, if available.
 extern void world2machine_initialize();
-
-// When switching from absolute to corrected coordinates,
-// this will apply an inverse world2machine transformation
-// to current_position[x,y].
+extern void world2machine_read_valid(float vec_x[2], float vec_y[2], float cntr[2]);
 extern void world2machine_update_current();
 
 inline void world2machine(float &x, float &y)
diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp
index ef392677..96b0ff83 100644
--- a/Firmware/ultralcd.cpp
+++ b/Firmware/ultralcd.cpp
@@ -1586,7 +1586,6 @@ static void lcd_menu_extruder_info()
     
     if (lcd_clicked())
     {
-        lcd_quick_feedback();
         menu_action_back();
     }
 }
@@ -1707,7 +1706,6 @@ static void lcd_menu_temperatures()
 
 	if (lcd_clicked())
     {
-        lcd_quick_feedback();
         menu_action_back();
     }
 }
@@ -1725,7 +1723,6 @@ static void lcd_menu_voltages()
     fprintf_P(lcdout, PSTR( ESC_H(1,1)"PWR:      %d.%01dV"), (int)volt_pwr, (int)(10*fabs(volt_pwr - (int)volt_pwr))) ;
     if (lcd_clicked())
     {
-        lcd_quick_feedback();
         menu_action_back();
     }
 }
@@ -1737,7 +1734,6 @@ static void lcd_menu_belt_status()
     fprintf_P(lcdout, PSTR(ESC_H(1,0) "Belt status" ESC_H(2,1) "X %d" ESC_H(2,2) "Y %d" ), eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_X)), eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_Y)));
     if (lcd_clicked())
     {
-        lcd_quick_feedback();
         menu_action_back();
     }
 }
@@ -2289,7 +2285,12 @@ static void lcd_move_e()
 		lcd_return_to_status();
 	}
 }
-
+/**
+ * @brief Show measured Y distance of front calibration points from Y_MIN_POS
+ *
+ * If those points are detected too close to edge of reachable area, their confidence is lowered.
+ * This functionality is applied more often for MK2 printers.
+ */
 static void lcd_menu_xyz_y_min()
 {
     lcd.setCursor(0,0);
@@ -2310,11 +2311,12 @@ static void lcd_menu_xyz_y_min()
     }
     if (lcd_clicked())
     {
-        lcd_quick_feedback();
         lcd_goto_menu(lcd_menu_xyz_skew);
     }
 }
-
+/**
+ * @brief Show measured axis skewness
+ */
 static void lcd_menu_xyz_skew()
 {
     float angleDiff;
@@ -2339,11 +2341,12 @@ static void lcd_menu_xyz_skew()
 
     if (lcd_clicked())
     {
-        lcd_quick_feedback();
         lcd_goto_menu(lcd_menu_xyz_offset);
     }
 }
-
+/**
+ * @brief Show measured bed offset from expected position
+ */
 static void lcd_menu_xyz_offset()
 {
     lcd.setCursor(0,0);
@@ -2352,15 +2355,19 @@ static void lcd_menu_xyz_offset()
     lcd_print_at_PGM(0, 2, PSTR("X"));
     lcd_print_at_PGM(0, 3, PSTR("Y"));
 
+    float vec_x[2];
+    float vec_y[2];
+    float cntr[2];
+    world2machine_read_valid(vec_x, vec_y, cntr);
+
     for (int i = 0; i < 2; i++)
     {
         lcd_print_at_PGM(11, i + 2, PSTR(""));
-        lcd.print(world2machine_shift[i]);
-        lcd_print_at_PGM((world2machine_shift[i] < 0) ? 17 : 16, i + 2, PSTR("mm"));
+        lcd.print(cntr[i]);
+        lcd_print_at_PGM((cntr[i] < 0) ? 17 : 16, i + 2, PSTR("mm"));
     }
     if (lcd_clicked())
     {
-        lcd_quick_feedback();
         menu_action_back();
     }
 }