Browse Source

Merge branch 'MK3' into use_Timer

Marek Bel 7 years ago
parent
commit
fc657bc31e

+ 2 - 2
Firmware/Configuration.h

@@ -7,8 +7,8 @@
 #define STR(x) STR_HELPER(x)
 #define STR(x) STR_HELPER(x)
 
 
 // Firmware version
 // Firmware version
-#define FW_VERSION "3.2.1"
-#define FW_COMMIT_NR   576
+#define FW_VERSION "3.3.0"
+#define FW_COMMIT_NR   830
 // FW_VERSION_UNKNOWN means this is an unofficial build.
 // FW_VERSION_UNKNOWN means this is an unofficial build.
 // The firmware should only be checked into github with this symbol.
 // The firmware should only be checked into github with this symbol.
 #define FW_DEV_VERSION FW_VERSION_UNKNOWN
 #define FW_DEV_VERSION FW_VERSION_UNKNOWN

+ 7 - 2
Firmware/Marlin.h

@@ -229,13 +229,18 @@ bool IsStopped();
 
 
 //put an ASCII command at the end of the current buffer.
 //put an ASCII command at the end of the current buffer.
 void enquecommand(const char *cmd, bool from_progmem = false);
 void enquecommand(const char *cmd, bool from_progmem = false);
+
 //put an ASCII command at the end of the current buffer, read from flash
 //put an ASCII command at the end of the current buffer, read from flash
 #define enquecommand_P(cmd) enquecommand(cmd, true)
 #define enquecommand_P(cmd) enquecommand(cmd, true)
+
+//put an ASCII command at the begin of the current buffer
 void enquecommand_front(const char *cmd, bool from_progmem = false);
 void enquecommand_front(const char *cmd, bool from_progmem = false);
-//put an ASCII command at the end of the current buffer, read from flash
-#define enquecommand_P(cmd) enquecommand(cmd, true)
+
+//put an ASCII command at the begin of the current buffer, read from flash
 #define enquecommand_front_P(cmd) enquecommand_front(cmd, true)
 #define enquecommand_front_P(cmd) enquecommand_front(cmd, true)
+
 void repeatcommand_front();
 void repeatcommand_front();
+
 // Remove all lines from the command queue.
 // Remove all lines from the command queue.
 void cmdqueue_reset();
 void cmdqueue_reset();
 
 

+ 175 - 29
Firmware/Marlin_main.cpp

@@ -71,6 +71,7 @@
 #include "math.h"
 #include "math.h"
 #include "util.h"
 #include "util.h"
 #include "Timer.h"
 #include "Timer.h"
+#include "uart2.h"
 
 
 #include <avr/wdt.h>
 #include <avr/wdt.h>
 #include <avr/pgmspace.h>
 #include <avr/pgmspace.h>
@@ -528,6 +529,7 @@ static float saved_pos[4] = { 0, 0, 0, 0 };
 static float saved_feedrate2 = 0;
 static float saved_feedrate2 = 0;
 static uint8_t saved_active_extruder = 0;
 static uint8_t saved_active_extruder = 0;
 static bool saved_extruder_under_pressure = false;
 static bool saved_extruder_under_pressure = false;
+static bool saved_extruder_relative_mode = false;
 
 
 //===========================================================================
 //===========================================================================
 //=============================Routines======================================
 //=============================Routines======================================
@@ -663,12 +665,12 @@ void crashdet_disable()
 
 
 void crashdet_stop_and_save_print()
 void crashdet_stop_and_save_print()
 {
 {
-	stop_and_save_print_to_ram(10, -2); //XY - no change, Z 10mm up, E -2mm retract
+	stop_and_save_print_to_ram(10, -DEFAULT_RETRACTION); //XY - no change, Z 10mm up, E -1mm retract
 }
 }
 
 
 void crashdet_restore_print_and_continue()
 void crashdet_restore_print_and_continue()
 {
 {
-	restore_print_from_ram_and_continue(2); //XYZ = orig, E +2mm unretract
+	restore_print_from_ram_and_continue(DEFAULT_RETRACTION); //XYZ = orig, E +1mm unretract
 //	babystep_apply();
 //	babystep_apply();
 }
 }
 
 
@@ -847,6 +849,15 @@ void factory_reset(char level, bool quiet)
 			farm_mode = false;
 			farm_mode = false;
 			eeprom_update_byte((uint8_t*)EEPROM_FARM_MODE, farm_mode);
 			eeprom_update_byte((uint8_t*)EEPROM_FARM_MODE, farm_mode);
             EEPROM_save_B(EEPROM_FARM_NUMBER, &farm_no);
             EEPROM_save_B(EEPROM_FARM_NUMBER, &farm_no);
+
+            eeprom_update_dword((uint32_t *)EEPROM_TOTALTIME, 0);
+            eeprom_update_dword((uint32_t *)EEPROM_FILAMENTUSED, 0);
+            eeprom_update_word((uint16_t *)EEPROM_CRASH_COUNT_X_TOT, 0);
+            eeprom_update_word((uint16_t *)EEPROM_CRASH_COUNT_Y_TOT, 0);
+            eeprom_update_word((uint16_t *)EEPROM_FERROR_COUNT_TOT, 0);
+            eeprom_update_word((uint16_t *)EEPROM_POWER_COUNT_TOT, 0);
+
+            fsensor_enable();
                        
                        
             WRITE(BEEPER, HIGH);
             WRITE(BEEPER, HIGH);
             _delay_ms(100);
             _delay_ms(100);
@@ -1113,7 +1124,7 @@ uint8_t lang_xflash_enum_codes(uint16_t* codes)
 		printf_P(_n(" _lt_count        = 0x%04x (%d)\n"), header.count, header.count);
 		printf_P(_n(" _lt_count        = 0x%04x (%d)\n"), header.count, header.count);
 		printf_P(_n(" _lt_chsum        = 0x%04x\n"), header.checksum);
 		printf_P(_n(" _lt_chsum        = 0x%04x\n"), header.checksum);
 		printf_P(_n(" _lt_code         = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff);
 		printf_P(_n(" _lt_code         = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff);
-		printf_P(_n(" _lt_resv1        = 0x%08lx\n"), header.reserved1);
+		printf_P(_n(" _lt_sign         = 0x%08lx\n"), header.signature);
 
 
 		addr += header.size;
 		addr += header.size;
 		codes[count] = header.code;
 		codes[count] = header.code;
@@ -1173,11 +1184,19 @@ void setup()
 	selectedSerialPort = eeprom_read_byte((uint8_t*)EEPROM_SECOND_SERIAL_ACTIVE);
 	selectedSerialPort = eeprom_read_byte((uint8_t*)EEPROM_SECOND_SERIAL_ACTIVE);
 	if (selectedSerialPort == 0xFF) selectedSerialPort = 0;
 	if (selectedSerialPort == 0xFF) selectedSerialPort = 0;
 	if (farm_mode)
 	if (farm_mode)
-	{ 
+	{
 		no_response = true; //we need confirmation by recieving PRUSA thx
 		no_response = true; //we need confirmation by recieving PRUSA thx
 		important_status = 8;
 		important_status = 8;
 		prusa_statistics(8);
 		prusa_statistics(8);
 		selectedSerialPort = 1;
 		selectedSerialPort = 1;
+#ifdef TMC2130
+		//increased extruder current (PFW363)
+		tmc2130_current_h[E_AXIS] = 36;
+		tmc2130_current_r[E_AXIS] = 36;
+#endif //TMC2130
+		//disabled filament autoload (PFW360)
+		filament_autoload_enabled = false;
+		eeprom_update_byte((uint8_t*)EEPROM_FSENS_AUTOLOAD_ENABLED, 0);
 	}
 	}
 	MYSERIAL.begin(BAUDRATE);
 	MYSERIAL.begin(BAUDRATE);
 	fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream
 	fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream
@@ -1186,11 +1205,13 @@ void setup()
 	SERIAL_ECHO_START;
 	SERIAL_ECHO_START;
 	printf_P(PSTR(" " FW_VERSION_FULL "\n"));
 	printf_P(PSTR(" " FW_VERSION_FULL "\n"));
 
 
+	uart2_init();
+
 
 
 #ifdef DEBUG_SEC_LANG
 #ifdef DEBUG_SEC_LANG
 	lang_table_header_t header;
 	lang_table_header_t header;
 	uint32_t src_addr = 0x00000;
 	uint32_t src_addr = 0x00000;
-	if (lang_get_header(3, &header, &src_addr))
+	if (lang_get_header(1, &header, &src_addr))
 	{
 	{
 //this is comparsion of some printing-methods regarding to flash space usage and code size/readability
 //this is comparsion of some printing-methods regarding to flash space usage and code size/readability
 #define LT_PRINT_TEST 2
 #define LT_PRINT_TEST 2
@@ -1207,7 +1228,7 @@ void setup()
 		printf_P(_n(" _lt_count = 0x%04x (%d)\n"), header.count, header.count);
 		printf_P(_n(" _lt_count = 0x%04x (%d)\n"), header.count, header.count);
 		printf_P(_n(" _lt_chsum = 0x%04x\n"), header.checksum);
 		printf_P(_n(" _lt_chsum = 0x%04x\n"), header.checksum);
 		printf_P(_n(" _lt_code  = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff);
 		printf_P(_n(" _lt_code  = 0x%04x (%c%c)\n"), header.code, header.code >> 8, header.code & 0xff);
-		printf_P(_n(" _lt_resv1 = 0x%08lx\n"), header.reserved1);
+		printf_P(_n(" _lt_sign = 0x%08lx\n"), header.signature);
 #elif (LT_PRINT_TEST==2) //optimized printf
 #elif (LT_PRINT_TEST==2) //optimized printf
 		printf_P(
 		printf_P(
 		 _n(
 		 _n(
@@ -1225,7 +1246,7 @@ void setup()
 		 header.count, header.count,
 		 header.count, header.count,
 		 header.checksum,
 		 header.checksum,
 		 header.code, header.code >> 8, header.code & 0xff,
 		 header.code, header.code >> 8, header.code & 0xff,
-		 header.reserved1
+		 header.signature
 		);
 		);
 #elif (LT_PRINT_TEST==3) //arduino print/println (leading zeros not solved)
 #elif (LT_PRINT_TEST==3) //arduino print/println (leading zeros not solved)
 		MYSERIAL.print(" _src_addr = 0x");
 		MYSERIAL.print(" _src_addr = 0x");
@@ -1252,7 +1273,7 @@ void setup()
 		MYSERIAL.print((char)(header.code & 0xff), 0);
 		MYSERIAL.print((char)(header.code & 0xff), 0);
 		MYSERIAL.println(")");
 		MYSERIAL.println(")");
 		MYSERIAL.print(" _lt_resv1 = 0x");
 		MYSERIAL.print(" _lt_resv1 = 0x");
-		MYSERIAL.println(header.reserved1, 16);
+		MYSERIAL.println(header.signature, 16);
 #endif //(LT_PRINT_TEST==)
 #endif //(LT_PRINT_TEST==)
 #undef LT_PRINT_TEST
 #undef LT_PRINT_TEST
 
 
@@ -1265,7 +1286,22 @@ void setup()
 			if ((i % 16) == 15) putchar('\n');
 			if ((i % 16) == 15) putchar('\n');
 		}
 		}
 #endif
 #endif
-#if 1
+		uint16_t sum = 0;
+		for (uint16_t i = 0; i < header.size; i++)
+			sum += (uint16_t)pgm_read_byte((uint8_t*)(_SEC_LANG_TABLE + i)) << ((i & 1)?0:8);
+		printf_P(_n("_SEC_LANG_TABLE checksum = %04x\n"), sum);
+		sum -= header.checksum; //subtract checksum
+		printf_P(_n("_SEC_LANG_TABLE checksum = %04x\n"), sum);
+		sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes
+		if (sum == header.checksum)
+			printf_P(_n("Checksum OK\n"), sum);
+		else
+			printf_P(_n("Checksum NG\n"), sum);
+	}
+	else
+		printf_P(_n("lang_get_header failed!\n"));
+
+#if 0
 		for (uint16_t i = 0; i < 1024*10; i++)
 		for (uint16_t i = 0; i < 1024*10; i++)
 		{
 		{
 			if ((i % 16) == 0) printf_P(_n("%04x:"), _SEC_LANG_TABLE+i);
 			if ((i % 16) == 0) printf_P(_n("%04x:"), _SEC_LANG_TABLE+i);
@@ -1273,10 +1309,6 @@ void setup()
 			if ((i % 16) == 15) putchar('\n');
 			if ((i % 16) == 15) putchar('\n');
 		}
 		}
 #endif
 #endif
-	}
-	else
-		printf_P(_n("lang_get_header failed!\n"));
-
 
 
 #if 0
 #if 0
 	SERIAL_ECHOLN("Reading eeprom from 0 to 100: start");
 	SERIAL_ECHOLN("Reading eeprom from 0 to 100: start");
@@ -3222,16 +3254,59 @@ void process_commands()
 	}
 	}
 	else if (strncmp_P(CMDBUFFER_CURRENT_STRING, PSTR("TMC_"), 4) == 0)
 	else if (strncmp_P(CMDBUFFER_CURRENT_STRING, PSTR("TMC_"), 4) == 0)
 	{
 	{
-		if (strncmp_P(CMDBUFFER_CURRENT_STRING + 4, PSTR("SET_WAVE_E"), 10) == 0)
+		if (strncmp_P(CMDBUFFER_CURRENT_STRING + 4, PSTR("SET_WAVE_"), 9) == 0)
+		{
+			uint8_t axis = *(CMDBUFFER_CURRENT_STRING + 13);
+			axis = (axis == 'E')?3:(axis - 'X');
+			if (axis < 4)
+			{
+				uint8_t fac = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 14, NULL, 10);
+				tmc2130_set_wave(axis, 247, fac);
+			}
+		}
+		else if (strncmp_P(CMDBUFFER_CURRENT_STRING + 4, PSTR("SET_STEP_"), 9) == 0)
 		{
 		{
-			uint8_t fac = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 14, NULL, 10);
-			tmc2130_set_wave(E_AXIS, 247, fac);
+			uint8_t axis = *(CMDBUFFER_CURRENT_STRING + 13);
+			axis = (axis == 'E')?3:(axis - 'X');
+			if (axis < 4)
+			{
+				uint8_t step = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 14, NULL, 10);
+				uint16_t res = tmc2130_get_res(axis);
+				tmc2130_goto_step(axis, step & (4*res - 1), 2, 1000, res);
+			}
 		}
 		}
-		else if (strncmp_P(CMDBUFFER_CURRENT_STRING + 4, PSTR("SET_STEP_E"), 10) == 0)
+		else if (strncmp_P(CMDBUFFER_CURRENT_STRING + 4, PSTR("SET_CHOP_"), 9) == 0)
 		{
 		{
-			uint8_t step = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 14, NULL, 10);
-			uint16_t res = tmc2130_get_res(E_AXIS);
-			tmc2130_goto_step(E_AXIS, step & (4*res - 1), 2, 1000, res);
+			uint8_t axis = *(CMDBUFFER_CURRENT_STRING + 13);
+			axis = (axis == 'E')?3:(axis - 'X');
+			if (axis < 4)
+			{
+				uint8_t chop0 = tmc2130_chopper_config[axis].toff;
+				uint8_t chop1 = tmc2130_chopper_config[axis].hstr;
+				uint8_t chop2 = tmc2130_chopper_config[axis].hend;
+				uint8_t chop3 = tmc2130_chopper_config[axis].tbl;
+				char* str_end = 0;
+				if (CMDBUFFER_CURRENT_STRING[14])
+				{
+					chop0 = (uint8_t)strtol(CMDBUFFER_CURRENT_STRING + 14, &str_end, 10) & 15;
+					if (str_end && *str_end)
+					{
+						chop1 = (uint8_t)strtol(str_end, &str_end, 10) & 7;
+						if (str_end && *str_end)
+						{
+							chop2 = (uint8_t)strtol(str_end, &str_end, 10) & 15;
+							if (str_end && *str_end)
+								chop3 = (uint8_t)strtol(str_end, &str_end, 10) & 3;
+						}
+					}
+				}
+				tmc2130_chopper_config[axis].toff = chop0;
+				tmc2130_chopper_config[axis].hstr = chop1 & 7;
+				tmc2130_chopper_config[axis].hend = chop2 & 15;
+				tmc2130_chopper_config[axis].tbl = chop3 & 3;
+				tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
+				//printf_P(_N("TMC_SET_CHOP_%c %hhd %hhd %hhd %hhd\n"), "xyze"[axis], chop0, chop1, chop2, chop3);
+			}
 		}
 		}
 	}
 	}
 #endif //TMC2130
 #endif //TMC2130
@@ -3259,6 +3334,20 @@ void process_commands()
 		}
 		}
 		else if (code_seen("thx")) {
 		else if (code_seen("thx")) {
 			no_response = false;
 			no_response = false;
+        } else if (code_seen("RESET")) {
+            // careful!
+            if (farm_mode) {
+#ifdef WATCHDOG
+				wdt_enable(WDTO_15MS);
+				cli();
+				while(1);
+#else //WATCHDOG
+                asm volatile("jmp 0x3E000");
+#endif //WATCHDOG
+            }
+            else {
+                MYSERIAL.println("Not in farm mode.");
+            }
 		}else if (code_seen("fv")) {
 		}else if (code_seen("fv")) {
         // get file version
         // get file version
         #ifdef SDSUPPORT
         #ifdef SDSUPPORT
@@ -4377,6 +4466,7 @@ void process_commands()
 		}
 		}
 		KEEPALIVE_STATE(NOT_BUSY);
 		KEEPALIVE_STATE(NOT_BUSY);
 		// Restore custom message state
 		// Restore custom message state
+		lcd_setstatuspgm(_T(WELCOME_MSG));
 		custom_message = custom_message_old;
 		custom_message = custom_message_old;
 		custom_message_type = custom_message_type_old;
 		custom_message_type = custom_message_type_old;
 		custom_message_state = custom_message_state_old;
 		custom_message_state = custom_message_state_old;
@@ -6986,6 +7076,45 @@ Sigma_Exit:
 			  tmp_extruder = code_value();
 			  tmp_extruder = code_value();
 		  }
 		  }
 		  snmm_filaments_used |= (1 << tmp_extruder); //for stop print
 		  snmm_filaments_used |= (1 << tmp_extruder); //for stop print
+
+#ifdef SNMM_V2
+		  printf_P(PSTR("T code: %d \n"), tmp_extruder);
+          switch (tmp_extruder) 
+          {
+          case 1:
+              
+              fprintf_P(uart2io, PSTR("T1\n"));
+              break;
+          case 2:
+              
+              fprintf_P(uart2io, PSTR("T2\n"));
+              break;
+          case 3:
+              
+              fprintf_P(uart2io, PSTR("T3\n"));
+              break;
+          case 4:
+              
+              fprintf_P(uart2io, PSTR("T4\n"));
+              break;
+          default:
+              
+              fprintf_P(uart2io, PSTR("T0\n"));
+              break;
+          }
+
+          
+
+          
+              // get response
+            uart2_rx_clr();
+              while (!uart2_rx_ok())
+              {
+                  //printf_P(PSTR("waiting..\n"));
+                  delay_keep_alive(100);
+              }
+#endif
+
 #ifdef SNMM
 #ifdef SNMM
           
           
     #ifdef LIN_ADVANCE
     #ifdef LIN_ADVANCE
@@ -7148,8 +7277,8 @@ void FlushSerialRequestResend()
 void ClearToSend()
 void ClearToSend()
 {
 {
     previous_millis_cmd = millis();
     previous_millis_cmd = millis();
-    if ((CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_USB) || (CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_USB_WITH_LINENR))
-        SERIAL_PROTOCOLLNRPGM(_T(MSG_OK));
+	if ((CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_USB) || (CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_USB_WITH_LINENR)) 
+		SERIAL_PROTOCOLLNRPGM(_T(MSG_OK));
 }
 }
 
 
 #if MOTHERBOARD == BOARD_RAMBO_MINI_1_0 || MOTHERBOARD == BOARD_RAMBO_MINI_1_3
 #if MOTHERBOARD == BOARD_RAMBO_MINI_1_0 || MOTHERBOARD == BOARD_RAMBO_MINI_1_3
@@ -7297,6 +7426,7 @@ void clamp_to_software_endstops(float target[3])
             float de = e - current_position[E_AXIS];
             float de = e - current_position[E_AXIS];
             for (int i = 1; i < n_segments; ++ i) {
             for (int i = 1; i < n_segments; ++ i) {
                 float t = float(i) / float(n_segments);
                 float t = float(i) / float(n_segments);
+                if (saved_printing || (mbl.active == false)) return;
                 plan_buffer_line(
                 plan_buffer_line(
                                  current_position[X_AXIS] + t * dx,
                                  current_position[X_AXIS] + t * dx,
                                  current_position[Y_AXIS] + t * dy,
                                  current_position[Y_AXIS] + t * dy,
@@ -8792,11 +8922,11 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
         uint16_t value;
         uint16_t value;
     } sdlen_single;
     } sdlen_single;
     int _bufindr = bufindr;
     int _bufindr = bufindr;
-    for (int _buflen  = buflen; _buflen > 0; ++ iline) {
+	for (int _buflen  = buflen; _buflen > 0; ++ iline) {
         if (cmdbuffer[_bufindr] == CMDBUFFER_CURRENT_TYPE_SDCARD) {
         if (cmdbuffer[_bufindr] == CMDBUFFER_CURRENT_TYPE_SDCARD) {
             sdlen_single.lohi.lo = cmdbuffer[_bufindr + 1];
             sdlen_single.lohi.lo = cmdbuffer[_bufindr + 1];
             sdlen_single.lohi.hi = cmdbuffer[_bufindr + 2];
             sdlen_single.lohi.hi = cmdbuffer[_bufindr + 2];
-        }
+        }		 
         SERIAL_ECHOPGM("Buffer line (from buffer): ");
         SERIAL_ECHOPGM("Buffer line (from buffer): ");
         MYSERIAL.print(int(iline), DEC);
         MYSERIAL.print(int(iline), DEC);
         SERIAL_ECHOPGM(", type: ");
         SERIAL_ECHOPGM(", type: ");
@@ -8807,7 +8937,6 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
         MYSERIAL.println(cmdbuffer + _bufindr + CMDHDRSIZE);
         MYSERIAL.println(cmdbuffer + _bufindr + CMDHDRSIZE);
 
 
         SERIAL_ECHOPGM("Buffer line (from file): ");
         SERIAL_ECHOPGM("Buffer line (from file): ");
-        MYSERIAL.print(int(iline), DEC);
         MYSERIAL.println(int(iline), DEC);
         MYSERIAL.println(int(iline), DEC);
         for (; sdlen_single.value > 0; -- sdlen_single.value)
         for (; sdlen_single.value > 0; -- sdlen_single.value)
           MYSERIAL.print(char(card.get()));
           MYSERIAL.print(char(card.get()));
@@ -8840,7 +8969,7 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
 	saved_active_extruder = active_extruder; //save active_extruder
 	saved_active_extruder = active_extruder; //save active_extruder
 
 
 	saved_extruder_under_pressure = extruder_under_pressure; //extruder under pressure flag - currently unused
 	saved_extruder_under_pressure = extruder_under_pressure; //extruder under pressure flag - currently unused
-
+	saved_extruder_relative_mode = axis_relative_modes[E_AXIS];
 	cmdqueue_reset(); //empty cmdqueue
 	cmdqueue_reset(); //empty cmdqueue
 	card.sdprinting = false;
 	card.sdprinting = false;
 //	card.closefile();
 //	card.closefile();
@@ -8854,10 +8983,16 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
     char buf[48];
     char buf[48];
 
 
 	// First unretract (relative extrusion)
 	// First unretract (relative extrusion)
+	if(!saved_extruder_relative_mode){
+	  strcpy_P(buf, PSTR("M83"));
+	  enquecommand(buf, false);
+	}
+	
+	//retract 45mm/s
 	strcpy_P(buf, PSTR("G1 E"));
 	strcpy_P(buf, PSTR("G1 E"));
 	dtostrf(e_move, 6, 3, buf + strlen(buf));
 	dtostrf(e_move, 6, 3, buf + strlen(buf));
 	strcat_P(buf, PSTR(" F"));
 	strcat_P(buf, PSTR(" F"));
-	dtostrf(retract_feedrate*60, 8, 3, buf + strlen(buf));
+	dtostrf(2700, 8, 3, buf + strlen(buf));
 	enquecommand(buf, false);
 	enquecommand(buf, false);
 
 
 	// Then lift Z axis
 	// Then lift Z axis
@@ -8886,26 +9021,37 @@ void restore_print_from_ram_and_continue(float e_move)
 //	    current_position[axis] = st_get_position_mm(axis);
 //	    current_position[axis] = st_get_position_mm(axis);
 	active_extruder = saved_active_extruder; //restore active_extruder
 	active_extruder = saved_active_extruder; //restore active_extruder
 	feedrate = saved_feedrate2; //restore feedrate
 	feedrate = saved_feedrate2; //restore feedrate
+	axis_relative_modes[E_AXIS] = saved_extruder_relative_mode;
 	float e = saved_pos[E_AXIS] - e_move;
 	float e = saved_pos[E_AXIS] - e_move;
 	plan_set_e_position(e);
 	plan_set_e_position(e);
-	plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], saved_pos[Z_AXIS], saved_pos[E_AXIS], homing_feedrate[Z_AXIS]/13, active_extruder);
+	//first move print head in XY to the saved position:
+	plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], current_position[Z_AXIS], saved_pos[E_AXIS] - e_move, homing_feedrate[Z_AXIS]/13, active_extruder);
+	st_synchronize();
+	//then move Z
+	plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], saved_pos[Z_AXIS], saved_pos[E_AXIS] - e_move, homing_feedrate[Z_AXIS]/13, active_extruder);
 	st_synchronize();
 	st_synchronize();
+	//and finaly unretract (35mm/s)
+	plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], saved_pos[Z_AXIS], saved_pos[E_AXIS], 35, active_extruder);
+	st_synchronize();
+
 	memcpy(current_position, saved_pos, sizeof(saved_pos));
 	memcpy(current_position, saved_pos, sizeof(saved_pos));
 	memcpy(destination, current_position, sizeof(destination));
 	memcpy(destination, current_position, sizeof(destination));
 	if (saved_printing_type == PRINTING_TYPE_SD) { //was sd printing
 	if (saved_printing_type == PRINTING_TYPE_SD) { //was sd printing
 		card.setIndex(saved_sdpos);
 		card.setIndex(saved_sdpos);
 		sdpos_atomic = saved_sdpos;
 		sdpos_atomic = saved_sdpos;
 		card.sdprinting = true;
 		card.sdprinting = true;
+		printf_P(PSTR("ok\n")); //dummy response because of octoprint is waiting for this
 	}
 	}
 	else if (saved_printing_type == PRINTING_TYPE_USB) { //was usb printing
 	else if (saved_printing_type == PRINTING_TYPE_USB) { //was usb printing
 		gcode_LastN = saved_sdpos; //saved_sdpos was reused for storing line number when usb printing
 		gcode_LastN = saved_sdpos; //saved_sdpos was reused for storing line number when usb printing
+		serial_count = 0; 
 		FlushSerialRequestResend();
 		FlushSerialRequestResend();
 	}
 	}
 	else {
 	else {
 		//not sd printing nor usb printing
 		//not sd printing nor usb printing
 	}
 	}
+	lcd_setstatuspgm(_T(WELCOME_MSG));
 	saved_printing = false;
 	saved_printing = false;
-	
 }
 }
 
 
 void print_world_coordinates()
 void print_world_coordinates()

+ 2 - 1
Firmware/cmdqueue.cpp

@@ -385,7 +385,8 @@ void get_command()
 		rx_buffer_full = true;                //sets flag that buffer was full    
 		rx_buffer_full = true;                //sets flag that buffer was full    
 	}
 	}
 
 
-  while (MYSERIAL.available() > 0) {
+  // start of serial line processing loop
+  while (MYSERIAL.available() > 0 && !saved_printing) {  //is print is saved (crash detection or filament detection), dont process data from serial line
 	
 	
     char serial_char = MYSERIAL.read();
     char serial_char = MYSERIAL.read();
 /*    if (selectedSerialPort == 1)
 /*    if (selectedSerialPort == 1)

+ 3 - 3
Firmware/config.h

@@ -27,9 +27,9 @@
 #define W25X20CL_SPSR          SPI_SPSR(W25X20CL_SPI_RATE)
 #define W25X20CL_SPSR          SPI_SPSR(W25X20CL_SPI_RATE)
 
 
 //LANG - Multi-language support
 //LANG - Multi-language support
-//#define LANG_MODE               0 // primary language only
-#define LANG_MODE               1 // sec. language support
-#define LANG_SIZE_RESERVED 0x2700 // reserved space for secondary language (~10kb)
+//#define LANG_MODE                      0 // primary language only
+#define LANG_MODE                        1 // sec. language support
+#define LANG_SIZE_RESERVED          0x2400 // reserved space for secondary language (~12kb)
 //#define LANG_SIZE_RESERVED 0x1ef8 // reserved space for secondary language (~10kb)
 //#define LANG_SIZE_RESERVED 0x1ef8 // reserved space for secondary language (~10kb)
 
 
 
 

+ 62 - 12
Firmware/language.c

@@ -5,6 +5,7 @@
 #include "bootapp.h"
 #include "bootapp.h"
 
 
 #include "Configuration.h"
 #include "Configuration.h"
+#include "pins.h"
 
 
 #ifdef W25X20CL
 #ifdef W25X20CL
 #include "w25x20cl.h"
 #include "w25x20cl.h"
@@ -28,6 +29,9 @@ uint8_t lang_is_selected(void) { return 1; }
 //reserved xx kbytes for secondary language table
 //reserved xx kbytes for secondary language table
 const char _SEC_LANG[LANG_SIZE_RESERVED] PROGMEM_I2 = "_SEC_LANG";
 const char _SEC_LANG[LANG_SIZE_RESERVED] PROGMEM_I2 = "_SEC_LANG";
 
 
+//primary language signature
+const uint32_t _PRI_LANG_SIGNATURE[1] __attribute__((section(".progmem0"))) = {0xffffffff};
+
 //lang_table pointer
 //lang_table pointer
 lang_table_t* lang_table = 0;
 lang_table_t* lang_table = 0;
 
 
@@ -56,11 +60,28 @@ uint8_t lang_select(uint8_t lang)
 	{
 	{
 		if (pgm_read_dword(((uint32_t*)_SEC_LANG_TABLE)) == LANG_MAGIC) //magic valid
 		if (pgm_read_dword(((uint32_t*)_SEC_LANG_TABLE)) == LANG_MAGIC) //magic valid
 		{
 		{
-			lang_table = _SEC_LANG_TABLE; // set table pointer
-			lang_selected = lang; // set language id
+			if (lang_check(_SEC_LANG_TABLE))
+				if (pgm_read_dword(((uint32_t*)(_SEC_LANG_TABLE + 12))) == pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE)))) //signature valid
+				{
+					lang_table = _SEC_LANG_TABLE; // set table pointer
+					lang_selected = lang; // set language id
+				}
 		}
 		}
 	}
 	}
 #else //W25X20CL
 #else //W25X20CL
+	if (lang == LANG_ID_SEC)
+	{
+		uint16_t table = _SEC_LANG_TABLE;
+		if (pgm_read_dword(((uint32_t*)table)) == LANG_MAGIC) //magic valid
+		{
+			if (lang_check(table))
+				if (pgm_read_dword(((uint32_t*)(table + 12))) == pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE)))) //signature valid
+				{
+					lang_table = table; // set table pointer
+					lang_selected = lang; // set language id
+				}
+		}
+	}
 #endif //W25X20CL
 #endif //W25X20CL
 	if (lang_selected == lang)
 	if (lang_selected == lang)
 	{
 	{
@@ -70,8 +91,22 @@ uint8_t lang_select(uint8_t lang)
 	return 0;
 	return 0;
 }
 }
 
 
+uint8_t lang_check(uint16_t addr)
+{
+	uint16_t sum = 0;
+	uint16_t size = pgm_read_word((uint16_t*)(addr + 4));
+	uint16_t lt_sum = pgm_read_word((uint16_t*)(addr + 8));
+	uint16_t i; for (i = 0; i < size; i++)
+		sum += (uint16_t)pgm_read_byte((uint8_t*)(addr + i)) << ((i & 1)?0:8);
+	sum -= lt_sum; //subtract checksum
+	sum = (sum >> 8) | ((sum & 0xff) << 8); //swap bytes
+	return (sum == lt_sum);
+}
+
 uint8_t lang_get_count()
 uint8_t lang_get_count()
 {
 {
+	if (pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE))) == 0xffffffff)
+		return 1; //signature not set - only primary language will be available
 #ifdef W25X20CL
 #ifdef W25X20CL
 	W25X20CL_SPI_ENTER();
 	W25X20CL_SPI_ENTER();
 	uint8_t count = 2; //count = 1+n (primary + secondary + all in xflash)
 	uint8_t count = 2; //count = 1+n (primary + secondary + all in xflash)
@@ -84,9 +119,16 @@ uint8_t lang_get_count()
 		addr += header.size; //calc address of next table
 		addr += header.size; //calc address of next table
 		count++; //inc counter
 		count++; //inc counter
 	}
 	}
-	return count;
 #else //W25X20CL
 #else //W25X20CL
+	uint16_t table = _SEC_LANG_TABLE;
+	uint8_t count = 1; //count = 1 (primary)
+	while (pgm_read_dword(((uint32_t*)table)) == LANG_MAGIC) //magic valid
+	{
+		table += pgm_read_word((uint16_t*)(table + 4));
+		count++;
+	}
 #endif //W25X20CL
 #endif //W25X20CL
+	return count;
 }
 }
 
 
 uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* offset)
 uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* offset)
@@ -98,7 +140,7 @@ uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* off
 		uint16_t ui = _SEC_LANG_TABLE; //table pointer
 		uint16_t ui = _SEC_LANG_TABLE; //table pointer
 		memcpy_P(header, ui, sizeof(lang_table_header_t)); //read table header from progmem
 		memcpy_P(header, ui, sizeof(lang_table_header_t)); //read table header from progmem
 		if (offset) *offset = ui;
 		if (offset) *offset = ui;
-		return (header == LANG_MAGIC)?1:0; //return 1 if magic valid
+		return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid
 	}
 	}
 	W25X20CL_SPI_ENTER();
 	W25X20CL_SPI_ENTER();
 	uint32_t addr = 0x00000; //start of xflash
 	uint32_t addr = 0x00000; //start of xflash
@@ -111,9 +153,16 @@ uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* off
 		if (--lang == 0) return 1;
 		if (--lang == 0) return 1;
 		addr += header->size; //calc address of next table
 		addr += header->size; //calc address of next table
 	}
 	}
-	return 0;
 #else //W25X20CL
 #else //W25X20CL
+	if (lang == LANG_ID_SEC)
+	{
+		uint16_t ui = _SEC_LANG_TABLE; //table pointer
+		memcpy_P(header, ui, sizeof(lang_table_header_t)); //read table header from progmem
+		if (offset) *offset = ui;
+		return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid
+	}
 #endif //W25X20CL
 #endif //W25X20CL
+	return 0;
 }
 }
 
 
 uint16_t lang_get_code(uint8_t lang)
 uint16_t lang_get_code(uint8_t lang)
@@ -138,14 +187,15 @@ uint16_t lang_get_code(uint8_t lang)
 		addr += header.size; //calc address of next table
 		addr += header.size; //calc address of next table
 	}
 	}
 #else //W25X20CL
 #else //W25X20CL
+	uint16_t table = _SEC_LANG_TABLE;
+	uint8_t count = 1; //count = 1 (primary)
+	while (pgm_read_dword((uint32_t*)table) == LANG_MAGIC) //magic valid
+	{
+		if (count == lang) return pgm_read_word(((uint16_t*)(table + 10))); //read language code
+		table += pgm_read_word((uint16_t*)(table + 4));
+		count++;
+	}
 #endif //W25X20CL
 #endif //W25X20CL
-
-//	if (lang == LANG_ID_SEC)
-//	{
-//		uint16_t ui = _SEC_LANG_TABLE; //table pointer
-//		if (pgm_read_dword(((uint32_t*)(ui + 0))) == LANG_MAGIC) //magic num is OK
-//			return pgm_read_word(((uint16_t*)(ui + 10))); //read language code
-//	}
 	return LANG_CODE_XX;
 	return LANG_CODE_XX;
 }
 }
 
 

+ 4 - 2
Firmware/language.h

@@ -2,7 +2,6 @@
 #ifndef LANGUAGE_H
 #ifndef LANGUAGE_H
 #define LANGUAGE_H
 #define LANGUAGE_H
 
 
-#define W25X20CL
 
 
 #include "config.h"
 #include "config.h"
 #include <inttypes.h>
 #include <inttypes.h>
@@ -52,7 +51,7 @@ typedef struct
 	uint16_t count;      //+6
 	uint16_t count;      //+6
 	uint16_t checksum;   //+8
 	uint16_t checksum;   //+8
 	uint16_t code;       //+10
 	uint16_t code;       //+10
-	uint32_t reserved1;  //+12
+	uint32_t signature;  //+12
 } lang_table_header_t;
 } lang_table_header_t;
 
 
 //lang_table_t structure - (size= 16byte + 2*count)
 //lang_table_t structure - (size= 16byte + 2*count)
@@ -98,10 +97,13 @@ extern uint8_t lang_selected;
 extern const char _SEC_LANG[LANG_SIZE_RESERVED];
 extern const char _SEC_LANG[LANG_SIZE_RESERVED];
 extern const char* lang_get_translation(const char* s);
 extern const char* lang_get_translation(const char* s);
 #define _SEC_LANG_TABLE ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00)
 #define _SEC_LANG_TABLE ((((uint16_t)&_SEC_LANG) + 0x00ff) & 0xff00)
+//extern const uint32_t _PRI_LANG_SIGNATURE;
 #endif //(LANG_MODE != 0)
 #endif //(LANG_MODE != 0)
 
 
 //selects language, eeprom is updated in case of success
 //selects language, eeprom is updated in case of success
 extern uint8_t lang_select(uint8_t lang);
 extern uint8_t lang_select(uint8_t lang);
+//performs checksum test of secondary language data
+extern uint8_t lang_check(uint16_t addr);
 //returns total number of languages (primary + all in xflash)
 //returns total number of languages (primary + all in xflash)
 extern uint8_t lang_get_count(void);
 extern uint8_t lang_get_count(void);
 //reads lang table header and offset in xflash or progmem
 //reads lang table header and offset in xflash or progmem

+ 2 - 2
Firmware/mesh_bed_calibration.cpp

@@ -2845,11 +2845,11 @@ bool sample_mesh_and_store_reference()
     {
     {
         // Verify the span of the Z values.
         // Verify the span of the Z values.
         float zmin = mbl.z_values[0][0];
         float zmin = mbl.z_values[0][0];
-        float zmax = zmax;
+        float zmax = zmin;
         for (int8_t j = 0; j < 3; ++ j)
         for (int8_t j = 0; j < 3; ++ j)
            for (int8_t i = 0; i < 3; ++ i) {
            for (int8_t i = 0; i < 3; ++ i) {
                 zmin = min(zmin, mbl.z_values[j][i]);
                 zmin = min(zmin, mbl.z_values[j][i]);
-                zmax = min(zmax, mbl.z_values[j][i]);
+                zmax = max(zmax, mbl.z_values[j][i]);
            }
            }
         if (zmax - zmin > 3.f) {
         if (zmax - zmin > 3.f) {
             // The span of the Z offsets is extreme. Give up.
             // The span of the Z offsets is extreme. Give up.

+ 2 - 0
Firmware/optiboot_w25x20cl.cpp

@@ -5,6 +5,7 @@
 #include "Marlin.h"
 #include "Marlin.h"
 #include "w25x20cl.h"
 #include "w25x20cl.h"
 #include "stk500.h"
 #include "stk500.h"
+#include "bootapp.h"
 
 
 #define OPTIBOOT_MAJVER 6
 #define OPTIBOOT_MAJVER 6
 #define OPTIBOOT_CUSTOMVER 0
 #define OPTIBOOT_CUSTOMVER 0
@@ -98,6 +99,7 @@ extern struct block_t *block_buffer;
 
 
 void optiboot_w25x20cl_enter()
 void optiboot_w25x20cl_enter()
 {
 {
+  if (boot_app_flags & BOOT_APP_FLG_USER0) return;
   uint8_t ch;
   uint8_t ch;
   uint8_t rampz = 0;
   uint8_t rampz = 0;
   register uint16_t address = 0;
   register uint16_t address = 0;

+ 1 - 1
Firmware/pins_Rambo_1_0.h

@@ -16,7 +16,7 @@
 
 
 #define PAT9125_SWI2C
 #define PAT9125_SWI2C
 #define PAT9125_SWI2C_SDA      20 //SDA on P3
 #define PAT9125_SWI2C_SDA      20 //SDA on P3
-#define PAT9125_SWI2C_SCL      21 //SCL on P3
+#define PAT9125_SWI2C_SCL      84 //PH2 on P3, sensor cable must be rewired
 #define PAT9125_SWI2C_CFG    0xb1 //2us clock delay, 2048 cycles timeout
 #define PAT9125_SWI2C_CFG    0xb1 //2us clock delay, 2048 cycles timeout
 
 
 //#define PAT9125_HWI2C
 //#define PAT9125_HWI2C

+ 65 - 0
Firmware/rbuf.c

@@ -0,0 +1,65 @@
+//rbuf.c
+#include "rbuf.h"
+//#include <avr/interrupt.h>
+
+
+void rbuf_ini(uint8_t* ptr, uint8_t l)
+{
+	ptr[0] = l;
+	ptr[1] = 0;
+	ptr[2] = 0;
+}
+
+//lock/unlock macros
+//#define _lock() uint8_t _sreg = SREG; cli();
+//#define _unlock() SREG = _sreg;
+#define _lock()
+#define _unlock()
+
+//put single byte to buffer
+int rbuf_put(uint8_t* ptr, uint8_t b)
+{
+//#ifdef _NO_ASM
+	_lock();                         //lock
+	uint8_t buf_w = ptr[1];          //get write index
+	uint8_t buf_r = ptr[2];          //get read index
+	_unlock();                       //unlock
+	ptr[4 + buf_w] = b;              //store byte to buffer
+	buf_w++;                         //incerment write index
+	uint8_t buf_l = ptr[0];          //get length
+	if (buf_w >= buf_l) buf_w = 0;   //rotate write index
+	if (buf_w == buf_r) return -1;   //return -1 to signal buffer full
+	ptr[1] = buf_w;                  //store write index
+	return 0;                        //return 0 to signal success
+//#else //_NO_ASM
+// TODO - optimized assembler version
+//	asm("movw r26, r24");
+//	asm("ld r18, X+");
+//	asm("cli");
+//	asm("ld r19, X+");
+//	asm("ld r20, X");
+//	asm("cp r19, r18");
+//	asm("brne .-6");*/
+//#endif //_NO_ASM
+}
+
+//get single byte from buffer
+int rbuf_get(uint8_t* ptr)
+{
+//#ifdef _NO_ASM
+	_lock();                         //lock
+	uint8_t buf_w = ptr[1];          //get write index
+	uint8_t buf_r = ptr[2];          //get read index
+	_unlock();                       //unlock
+	if (buf_r == buf_w) return -1;   //return -1 to signal buffer empty
+	int ret = ptr[4 + buf_r];        //get byte from buffer
+	buf_r++;                         //increment read index
+	uint8_t buf_l = ptr[0];          //get length
+	if (buf_r >= buf_l) buf_r = 0;   //rotate read index
+	ptr[2] = buf_r;                  //store read index
+	return ret;                      //return byte (0-255)
+//	return 0;                        //return 0 to signal success
+//#else //_NO_ASM
+// TODO - optimized assembler version
+//#endif //_NO_ASM
+}

+ 27 - 0
Firmware/rbuf.h

@@ -0,0 +1,27 @@
+//rbuf.h
+#ifndef _RBUF_H
+#define _RBUF_H
+
+#include <inttypes.h>
+
+
+#define rbuf_l(ptr) (ptr[0])
+#define rbuf_w(ptr) (ptr[1])
+#define rbuf_r(ptr) (ptr[2])
+#define rbuf_empty(ptr) (ptr[1] == ptr[2])
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif //defined(__cplusplus)
+
+
+extern void rbuf_ini(uint8_t* ptr, uint8_t len);
+extern int rbuf_put(uint8_t* ptr, uint8_t val);
+extern int rbuf_get(uint8_t* ptr);
+
+
+#if defined(__cplusplus)
+}
+#endif //defined(__cplusplus)
+#endif //_RBUF_H

+ 16 - 13
Firmware/tmc2130.cpp

@@ -62,6 +62,13 @@ uint8_t tmc2130_home_fsteps[2] = {48, 48};
 
 
 uint8_t tmc2130_wave_fac[4] = {0, 0, 0, 0};
 uint8_t tmc2130_wave_fac[4] = {0, 0, 0, 0};
 
 
+tmc2130_chopper_config_t tmc2130_chopper_config[4] = {
+	{TMC2130_TOFF_XYZ, 5, 1, 2, 0},
+	{TMC2130_TOFF_XYZ, 5, 1, 2, 0},
+	{TMC2130_TOFF_XYZ, 5, 1, 2, 0},
+	{TMC2130_TOFF_E, 5, 1, 2, 0}
+};
+
 bool tmc2130_sg_stop_on_crash = true;
 bool tmc2130_sg_stop_on_crash = true;
 uint8_t tmc2130_sg_diag_mask = 0x00;
 uint8_t tmc2130_sg_diag_mask = 0x00;
 uint8_t tmc2130_sg_crash = 0;
 uint8_t tmc2130_sg_crash = 0;
@@ -418,13 +425,13 @@ void tmc2130_check_overtemp()
 void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r)
 void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r)
 {
 {
 	uint8_t intpol = 1;
 	uint8_t intpol = 1;
-	uint8_t toff = TMC2130_TOFF_XYZ; // toff = 3 (fchop = 27.778kHz)
-	uint8_t hstrt = 5; //initial 4, modified to 5
-	uint8_t hend = 1;
+	uint8_t toff = tmc2130_chopper_config[axis].toff; // toff = 3 (fchop = 27.778kHz)
+	uint8_t hstrt = tmc2130_chopper_config[axis].hstr; //initial 4, modified to 5
+	uint8_t hend = tmc2130_chopper_config[axis].hend; //original value = 1
 	uint8_t fd3 = 0;
 	uint8_t fd3 = 0;
 	uint8_t rndtf = 0; //random off time
 	uint8_t rndtf = 0; //random off time
 	uint8_t chm = 0; //spreadCycle
 	uint8_t chm = 0; //spreadCycle
-	uint8_t tbl = 2; //blanking time
+	uint8_t tbl = tmc2130_chopper_config[axis].tbl; //blanking time, original value = 2
 	if (axis == E_AXIS)
 	if (axis == E_AXIS)
 	{
 	{
 #ifdef TMC2130_CNSTOFF_E
 #ifdef TMC2130_CNSTOFF_E
@@ -434,9 +441,11 @@ void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_
 		hend = 0; //sine wave offset
 		hend = 0; //sine wave offset
 		chm = 1; // constant off time mod
 		chm = 1; // constant off time mod
 #endif //TMC2130_CNSTOFF_E
 #endif //TMC2130_CNSTOFF_E
-		toff = TMC2130_TOFF_E; // toff = 3-5
+//		toff = TMC2130_TOFF_E; // toff = 3-5
 //		rndtf = 1;
 //		rndtf = 1;
 	}
 	}
+	DBG(_n("tmc2130_setup_chopper(axis=%hhd, mres=%hhd, curh=%hhd, curr=%hhd\n"), axis, mres, current_h, current_r);
+	DBG(_n(" toff=%hhd, hstr=%hhd, hend=%hhd, tbl=%hhd\n"), toff, hstrt, hend, tbl);
 	if (current_r <= 31)
 	if (current_r <= 31)
 	{
 	{
 		tmc2130_wr_CHOPCONF(axis, toff, hstrt, hend, fd3, 0, rndtf, chm, tbl, 1, 0, 0, 0, mres, intpol, 0, 0);
 		tmc2130_wr_CHOPCONF(axis, toff, hstrt, hend, fd3, 0, rndtf, chm, tbl, 1, 0, 0, 0, mres, intpol, 0, 0);
@@ -475,10 +484,7 @@ void tmc2130_print_currents()
 
 
 void tmc2130_set_pwm_ampl(uint8_t axis, uint8_t pwm_ampl)
 void tmc2130_set_pwm_ampl(uint8_t axis, uint8_t pwm_ampl)
 {
 {
-	MYSERIAL.print("tmc2130_set_pwm_ampl ");
-	MYSERIAL.print((int)axis);
-	MYSERIAL.print(" ");
-	MYSERIAL.println((int)pwm_ampl);
+	DBG(_n("tmc2130_set_pwm_ampl(axis=%hhd, pwm_ampl=%hhd\n"), axis, pwm_ampl);
 	tmc2130_pwm_ampl[axis] = pwm_ampl;
 	tmc2130_pwm_ampl[axis] = pwm_ampl;
 	if (((axis == 0) || (axis == 1)) && (tmc2130_mode == TMC2130_MODE_SILENT))
 	if (((axis == 0) || (axis == 1)) && (tmc2130_mode == TMC2130_MODE_SILENT))
 		tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
 		tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
@@ -486,10 +492,7 @@ void tmc2130_set_pwm_ampl(uint8_t axis, uint8_t pwm_ampl)
 
 
 void tmc2130_set_pwm_grad(uint8_t axis, uint8_t pwm_grad)
 void tmc2130_set_pwm_grad(uint8_t axis, uint8_t pwm_grad)
 {
 {
-	MYSERIAL.print("tmc2130_set_pwm_grad ");
-	MYSERIAL.print((int)axis);
-	MYSERIAL.print(" ");
-	MYSERIAL.println((int)pwm_grad);
+	DBG(_n("tmc2130_set_pwm_grad(axis=%hhd, pwm_grad=%hhd\n"), axis, pwm_grad);
 	tmc2130_pwm_grad[axis] = pwm_grad;
 	tmc2130_pwm_grad[axis] = pwm_grad;
 	if (((axis == 0) || (axis == 1)) && (tmc2130_mode == TMC2130_MODE_SILENT))
 	if (((axis == 0) || (axis == 1)) && (tmc2130_mode == TMC2130_MODE_SILENT))
 		tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
 		tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);

+ 15 - 0
Firmware/tmc2130.h

@@ -36,6 +36,19 @@ extern uint8_t tmc2130_home_fsteps[2];
 
 
 extern uint8_t tmc2130_wave_fac[4];
 extern uint8_t tmc2130_wave_fac[4];
 
 
+#pragma pack(push)
+#pragma pack(1)
+typedef struct
+{
+	uint8_t toff:4;
+	uint8_t hstr:3;
+	uint8_t hend:4;
+	uint8_t tbl:2;
+	uint8_t res:3;
+} tmc2130_chopper_config_t;
+#pragma pack(pop)
+
+extern tmc2130_chopper_config_t tmc2130_chopper_config[4];
 
 
 //initialize tmc2130
 //initialize tmc2130
 extern void tmc2130_init();
 extern void tmc2130_init();
@@ -55,6 +68,7 @@ extern void tmc2130_sg_meassure_start(uint8_t axis);
 //stop current stallguard meassuring and report result
 //stop current stallguard meassuring and report result
 extern uint16_t tmc2130_sg_meassure_stop();
 extern uint16_t tmc2130_sg_meassure_stop();
 
 
+extern void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r);
 
 
 //set holding current for any axis (M911)
 //set holding current for any axis (M911)
 extern void tmc2130_set_current_h(uint8_t axis, uint8_t current);
 extern void tmc2130_set_current_h(uint8_t axis, uint8_t current);
@@ -80,6 +94,7 @@ extern bool tmc2130_wait_standstill_xy(int timeout);
 extern void tmc2130_eeprom_load_config();
 extern void tmc2130_eeprom_load_config();
 extern void tmc2130_eeprom_save_config();
 extern void tmc2130_eeprom_save_config();
 
 
+
 #pragma pack(push)
 #pragma pack(push)
 #pragma pack(1)
 #pragma pack(1)
 struct
 struct

+ 79 - 0
Firmware/uart2.c

@@ -0,0 +1,79 @@
+//uart2.c
+#include "uart2.h"
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+#include "rbuf.h"
+
+#define UART2_BAUD 115200
+#define UART_BAUD_SELECT(baudRate,xtalCpu) (((float)(xtalCpu))/(((float)(baudRate))*8.0)-1.0+0.5)
+#define uart2_rxcomplete (UCSR2A & (1 << RXC2))
+#define uart2_txcomplete (UCSR2A & (1 << TXC2))
+#define uart2_txready    (UCSR2A & (1 << UDRE2))
+
+uint8_t uart2_ibuf[10] = {0, 0};
+
+FILE _uart2io = {0};
+
+
+int uart2_putchar(char c, FILE *stream)
+{
+	while (!uart2_txready);
+	UDR2 = c; // transmit byte
+//	while (!uart2_txcomplete); // wait until byte sent
+//	UCSR2A |= (1 << TXC2); // delete TXCflag
+	return 0;
+}
+
+int uart2_getchar(FILE *stream)
+{
+	if (rbuf_empty(uart2_ibuf)) return -1;
+	return rbuf_get(uart2_ibuf);
+}
+
+void uart2_init(void)
+{
+	rbuf_ini(uart2_ibuf, 6);
+	UCSR2A |= (1 << U2X2); // baudrate multiplier
+	UBRR2L = UART_BAUD_SELECT(UART2_BAUD, F_CPU); // select baudrate
+	UCSR2B = (1 << RXEN2) | (1 << TXEN2); // enable receiver and transmitter
+	UCSR2B |= (1 << RXCIE2); // enable rx interrupt
+	fdev_setup_stream(uart2io, uart2_putchar, uart2_getchar, _FDEV_SETUP_WRITE | _FDEV_SETUP_READ); //setup uart2 i/o stream
+}
+
+uint8_t uart2_rx_clr(void)
+{
+	rbuf_w(uart2_ibuf) = 0;
+	rbuf_r(uart2_ibuf) = 0;
+}
+
+uint8_t uart2_rx_ok(void)
+{
+	//printf_P(PSTR("uart2_rx_ok %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu\n"), uart2_ibuf[0], uart2_ibuf[1], uart2_ibuf[2], uart2_ibuf[3], uart2_ibuf[4], uart2_ibuf[5], uart2_ibuf[6], uart2_ibuf[7], uart2_ibuf[8], uart2_ibuf[9]);
+//	return 0;
+//	_lock();                                   //lock
+	uint8_t i = rbuf_w(uart2_ibuf);            //get write index
+//	_unlock();                                 //unlock
+	uint8_t e = rbuf_l(uart2_ibuf) - 1;        //get end index
+//	printf_P(PSTR("%d %d \n"), i, e);
+//	return 0;
+	if ((i--) == 255) i = e;                   //decrement index
+	if ((uart2_ibuf[4 + i] != '\n') &&
+		(uart2_ibuf[4 + i] != '\r')) return 0; //no match - exit
+	if ((i--) == 255) i = e;                   //decrement index
+	if (uart2_ibuf[4 + i] != 'k') return 0;    //no match - exit
+	if ((i--) == 255) i = e;                   //decrement index
+	if (uart2_ibuf[4 + i] != 'o') return 0;    //no match - exit
+	uart2_ibuf[4 + i] = 0;                     //discard char
+	return 1;                                  //match "ok\n"
+}
+
+ISR(USART2_RX_vect)
+{
+	//printf_P(PSTR("USART2_RX_vect \n") );
+	if (rbuf_put(uart2_ibuf, UDR2) < 0) // put received byte to buffer
+	{
+		//rx buffer full
+	}
+}
+

+ 29 - 0
Firmware/uart2.h

@@ -0,0 +1,29 @@
+//uart2.h
+#ifndef _UART2_H
+#define _UART2_H
+
+#include <inttypes.h>
+#include <stdio.h>
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif //defined(__cplusplus)
+
+
+extern FILE _uart2io;
+#define uart2io (&_uart2io)
+
+//extern uint8_t uart2_ibuf[10];
+
+extern void uart2_init(void);
+
+extern uint8_t uart2_rx_clr(void);
+
+extern uint8_t uart2_rx_ok(void);
+
+
+#if defined(__cplusplus)
+}
+#endif //defined(__cplusplus)
+#endif //_UART2_H

+ 613 - 400
Firmware/ultralcd.cpp

@@ -26,23 +26,6 @@
 #endif //TMC2130
 #endif //TMC2130
 
 
 
 
-#include <stdarg.h>
-
-int lcd_puts_P(const char* str)
-{
-	return fputs_P(str, lcdout);
-}
-
-int lcd_printf_P(const char* format, ...)
-{
-	va_list args;
-	va_start(args, format);
-	int ret = vfprintf_P(lcdout, format, args);
-	va_end(args);
-	return ret;
-}
-
-
 int8_t encoderDiff; /* encoderDiff is updated from interrupt context and added to encoderPosition every LCD update */
 int8_t encoderDiff; /* encoderDiff is updated from interrupt context and added to encoderPosition every LCD update */
 
 
 extern int lcd_change_fil_state;
 extern int lcd_change_fil_state;
@@ -133,6 +116,10 @@ union MenuData
         bool initialized;
         bool initialized;
         bool endstopsEnabledPrevious;
         bool endstopsEnabledPrevious;
     } _lcd_moveMenu;
     } _lcd_moveMenu;
+	struct sdcard_menu_t
+	{
+		uint8_t viewState;
+	} sdcard_menu;
 };
 };
 
 
 // State of the currently active menu.
 // State of the currently active menu.
@@ -264,12 +251,6 @@ static void lcd_delta_calibrate_menu();
 static void lcd_quick_feedback();//Cause an LCD refresh, and give the user visual or audible feedback that something has happened
 static void lcd_quick_feedback();//Cause an LCD refresh, and give the user visual or audible feedback that something has happened
 
 
 /* Different types of actions that can be used in menu items. */
 /* Different types of actions that can be used in menu items. */
-static void menu_action_back(menuFunc_t data = 0);
-#define menu_action_back_RAM menu_action_back
-static void menu_action_submenu(menuFunc_t data);
-static void menu_action_gcode(const char* pgcode);
-static void menu_action_function(menuFunc_t data);
-static void menu_action_setlang(unsigned char lang);
 static void menu_action_sdfile(const char* filename, char* longFilename);
 static void menu_action_sdfile(const char* filename, char* longFilename);
 static void menu_action_sddirectory(const char* filename, char* longFilename);
 static void menu_action_sddirectory(const char* filename, char* longFilename);
 static void menu_action_setting_edit_bool(const char* pstr, bool* ptr);
 static void menu_action_setting_edit_bool(const char* pstr, bool* ptr);
@@ -315,15 +296,11 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l
 #endif
 #endif
 #endif
 #endif
 
 
+uint8_t _lineNr = 0;
+uint8_t _menuItemNr = 0;
+uint8_t _drawLineNr = 0;
 
 
-/* Helper macros for menus */
-#define START_MENU() do { \
-    if (encoderPosition > 0x8000) encoderPosition = 0; \
-    if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM < currentMenuViewOffset) currentMenuViewOffset = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM;\
-    uint8_t _lineNr = currentMenuViewOffset, _menuItemNr; \
-    bool wasClicked = LCD_CLICKED;\
-    for(uint8_t _drawLineNr = 0; _drawLineNr < LCD_HEIGHT; _drawLineNr++, _lineNr++) { \
-      _menuItemNr = 0;
+bool wasClicked = false;
 
 
 #define MENU_ITEM(type, label, args...) do { \
 #define MENU_ITEM(type, label, args...) do { \
     if (_menuItemNr == _lineNr) { \
     if (_menuItemNr == _lineNr) { \
@@ -344,13 +321,9 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l
     _menuItemNr++;\
     _menuItemNr++;\
   } while(0)
   } while(0)
 
 
-#define MENU_ITEM_DUMMY() do { _menuItemNr++; } while(0)
+//#define MENU_ITEM_DUMMY() do { _menuItemNr++; } while(0)
 #define MENU_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, (label) , ## args )
 #define MENU_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, (label) , ## args )
 #define MENU_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, (label) , ## args )
 #define MENU_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, (label) , ## args )
-#define END_MENU() \
-  if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM >= _menuItemNr) encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; \
-  if ((uint8_t)(encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) - LCD_HEIGHT + 1; lcdDrawUpdate = 1; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \
-  } } while(0)
 
 
 /** Used variables to keep track of the menu */
 /** Used variables to keep track of the menu */
 #ifndef REPRAPWORLD_KEYPAD
 #ifndef REPRAPWORLD_KEYPAD
@@ -385,8 +358,8 @@ uint8_t lcdDrawUpdate = 2;                  /* Set to none-zero when the LCD nee
 /**
 /**
  * @brief Go to menu
  * @brief Go to menu
  *
  *
- * In MENU_ITEM(submenu,... ) use MENU_ITEM(back,...) or
- * menu_action_back() and menu_action_submenu() instead, otherwise menuStack will be broken.
+ * In MENU_ITEM_SUBMENU_P(str, func) use MENU_ITEM_BACK_P(str) or
+ * menu_back() and menu_submenu() instead, otherwise menuStack will be broken.
  *
  *
  * It is acceptable to call lcd_goto_menu(menu) directly from MENU_ITEM(function,...), if destination menu
  * It is acceptable to call lcd_goto_menu(menu) directly from MENU_ITEM(function,...), if destination menu
  * is the same, from which function was called.
  * is the same, from which function was called.
@@ -424,8 +397,282 @@ static void lcd_goto_menu(menuFunc_t menu, const uint32_t encoder = 0, const boo
 		asm("sei");
 		asm("sei");
 }
 }
 
 
-/* Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependent */
 
 
+////////////////////////////////////////////////////////////////////////////////
+// New Menu implementation
+
+#include <stdarg.h>
+
+int lcd_puts_P(const char* str)
+{
+	return fputs_P(str, lcdout);
+}
+
+int lcd_putc(int c)
+{
+	return fputc(c, lcdout);
+}
+
+int lcd_printf_P(const char* format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	int ret = vfprintf_P(lcdout, format, args);
+	va_end(args);
+	return ret;
+}
+
+#define MENU_BEGIN() menu_start(); for(_drawLineNr = 0; _drawLineNr < LCD_HEIGHT; _drawLineNr++, _lineNr++) { _menuItemNr = 0;
+void menu_start(void)
+{
+    if (encoderPosition > 0x8000) encoderPosition = 0;
+    if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM < currentMenuViewOffset)
+		currentMenuViewOffset = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM;
+    _lineNr = currentMenuViewOffset;
+    wasClicked = LCD_CLICKED;
+}
+
+#define MENU_END() menu_end(); }
+void menu_end(void)
+{
+	if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM >= _menuItemNr)
+		encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1;
+	if ((uint8_t)(encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) >= currentMenuViewOffset + LCD_HEIGHT)
+	{
+		currentMenuViewOffset = (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) - LCD_HEIGHT + 1;
+		lcdDrawUpdate = 1;
+		_lineNr = currentMenuViewOffset - 1;
+		_drawLineNr = -1;
+	}
+}
+
+void menu_back(void)
+{
+	MenuStack::Record record = menuStack.pop();
+	lcd_goto_menu(record.menu);
+	encoderPosition = record.position;
+}
+
+void menu_back_if_clicked(void)
+{
+	if (lcd_clicked())
+		menu_back();
+}
+
+void menu_back_if_clicked_fb(void)
+{
+	if (lcd_clicked())
+	{
+        lcd_quick_feedback();
+		menu_back();
+	}
+}
+
+void menu_submenu(menuFunc_t submenu)
+{
+	menuStack.push(currentMenu, encoderPosition);
+	lcd_goto_menu(submenu);
+}
+
+uint8_t menu_item_ret(void)
+{
+	lcd_implementation_quick_feedback();
+	lcdDrawUpdate = 2;
+	button_pressed = false;
+	return 1;
+}
+
+uint8_t menu_enc_is_at_item(void)
+{
+	return ((encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr);
+}
+
+/*
+int menu_item_printf_P(char type_char, const char* format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	int ret = 0;
+    lcd.setCursor(0, _drawLineNr);
+	if ((encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr)
+		lcd.print('>');
+	else
+		lcd.print(' ');
+	int cnt = vfprintf_P(lcdout, format, args);
+	for (int i = cnt; i < 18; i++)
+		lcd.print(' ');
+	lcd.print(type_char);
+	va_end(args);
+	return ret;
+}
+*/
+int menu_draw_item_puts_P(char type_char, const char* str)
+{
+    lcd.setCursor(0, _drawLineNr);
+	int cnt = lcd_printf_P(_N("%c%-18S%c"), menu_enc_is_at_item()?'>':' ', str, type_char);
+	return cnt;
+}
+
+#define MENU_ITEM_DUMMY() menu_item_dummy()
+inline void menu_item_dummy(void)
+{
+	_menuItemNr++;
+}
+
+#define MENU_ITEM_TEXT_P(str) do { if (menu_item_text_P(str)) return; } while (0)
+uint8_t menu_item_text_P(const char* str)
+{
+	if (_menuItemNr == _lineNr)
+	{
+		if (lcdDrawUpdate) menu_draw_item_puts_P(' ', str);
+		if (wasClicked && menu_enc_is_at_item())
+			return menu_item_ret();
+	}
+	_menuItemNr++;
+	return 0;
+}
+
+#define MENU_ITEM_SUBMENU_P(str, submenu) do { if (menu_item_submenu_P(str, submenu)) return; } while (0)
+uint8_t menu_item_submenu_P(const char* str, menuFunc_t submenu)
+{
+	if (_menuItemNr == _lineNr)
+	{
+		if (lcdDrawUpdate) menu_draw_item_puts_P(LCD_STR_ARROW_RIGHT[0], str);
+		if (wasClicked && menu_enc_is_at_item())
+		{
+			menuStack.push(currentMenu, encoderPosition);
+			lcd_goto_menu(submenu, 0, false, true);
+			return menu_item_ret();
+		}
+	}
+	_menuItemNr++;
+	return 0;
+}
+
+#define MENU_ITEM_BACK_P(str) do { if (menu_item_back_P(str)) return; } while (0)
+uint8_t menu_item_back_P(const char* str)
+{
+	if (_menuItemNr == _lineNr)
+	{
+		if (lcdDrawUpdate) menu_draw_item_puts_P(LCD_STR_UPLEVEL[0], str);
+		if (wasClicked && menu_enc_is_at_item())
+		{
+			MenuStack::Record record = menuStack.pop();
+			lcd_goto_menu(record.menu, false, true);
+			encoderPosition = record.position;
+			return menu_item_ret();
+		}
+	}
+	_menuItemNr++;
+	return 0;
+}
+
+#define MENU_ITEM_FUNCTION_P(str, func) do { if (menu_item_function_P(str, func)) return; } while (0)
+uint8_t menu_item_function_P(const char* str, menuFunc_t func)
+{
+	if (_menuItemNr == _lineNr)
+	{
+		if (lcdDrawUpdate) menu_draw_item_puts_P(' ', str);
+		if (wasClicked && menu_enc_is_at_item())
+		{
+			if (func) func();
+			return menu_item_ret();
+		}
+	}
+	_menuItemNr++;
+	return 0;
+}
+
+#define MENU_ITEM_GCODE_P(str, str_gcode) do { if (menu_item_gcode_P(str, str_gcode)) return; } while (0)
+uint8_t menu_item_gcode_P(const char* str, const char* str_gcode)
+{
+	if (_menuItemNr == _lineNr)
+	{
+		if (lcdDrawUpdate) menu_draw_item_puts_P(' ', str);
+		if (wasClicked && menu_enc_is_at_item())
+		{
+			if (str_gcode) enquecommand_P(str_gcode);
+			return menu_item_ret();
+		}
+	}
+	_menuItemNr++;
+	return 0;
+}
+
+//#define MENU_ITEM_SDDIR(str, str_fn, str_fnl) do { if (menu_item_sddir(str, str_fn, str_fnl)) return; } while (0)
+#define MENU_ITEM_SDDIR(str, str_fn, str_fnl) MENU_ITEM(sddirectory, str, str_fn, str_fnl)
+uint8_t menu_item_sddir(const char* str, const char* str_fn, char* str_fnl)
+{
+//	str_fnl[18] = 0;
+//	printf_P(_N("menu dir %d '%s' '%s'\n"), _drawLineNr, str_fn, str_fnl);
+	if (_menuItemNr == _lineNr)
+	{
+		if (lcdDrawUpdate)
+		{
+			lcd.setCursor(0, _drawLineNr);
+			int cnt = lcd_printf_P(_N("%c%c%-18s"), menu_enc_is_at_item()?'>':' ', LCD_STR_FOLDER[0], str_fnl[0]?str_fnl:str_fn);
+//			int cnt = lcd_printf_P(_N("%c%c%-18s"), menu_enc_is_at_item()?'>':' ', LCD_STR_FOLDER[0], str_fn);
+		}
+		if (wasClicked && menu_enc_is_at_item())
+		{
+			uint8_t depth = (uint8_t)card.getWorkDirDepth();
+			strcpy(dir_names[depth], str_fn);
+//			printf_P(PSTR("%s\n"), dir_names[depth]);
+			card.chdir(str_fn);
+			encoderPosition = 0;
+			return menu_item_ret();
+		}
+	}
+	_menuItemNr++;
+	return 0;
+}
+
+//#define MENU_ITEM_SDFILE(str, str_fn, str_fnl) do { if (menu_item_sdfile(str, str_fn, str_fnl)) return; } while (0)
+#define MENU_ITEM_SDFILE(str, str_fn, str_fnl) MENU_ITEM(sdfile, str, str_fn, str_fnl)
+uint8_t menu_item_sdfile(const char* str, const char* str_fn, char* str_fnl)
+{
+//	printf_P(_N("menu sdfile\n"));
+//	str_fnl[19] = 0;
+//	printf_P(_N("menu file %d '%s' '%s'\n"), _drawLineNr, str_fn, str_fnl);
+	if (_menuItemNr == _lineNr)
+	{
+		if (lcdDrawUpdate)
+		{
+//			printf_P(_N("menu file %d %d '%s'\n"), _drawLineNr, menuData.sdcard_menu.viewState, str_fnl[0]?str_fnl:str_fn);
+			lcd.setCursor(0, _drawLineNr);
+/*			if (menu_enc_is_at_item())
+			{
+				lcd_printf_P(_N("%c%-19s"), menu_enc_is_at_item()?'>':' ', (str_fnl[0]?str_fnl:str_fn) + 1);
+				if (menuData.sdcard_menu.viewState == 0)
+				{
+					menuData.sdcard_menu.viewState++;
+					lcd_printf_P(_N("%c%-19s"), menu_enc_is_at_item()?'>':' ', (str_fnl[0]?str_fnl:str_fn) + 1);
+				}
+				else if (menuData.sdcard_menu.viewState == 1)
+				{
+					lcd_printf_P(_N("%c%-19s"), menu_enc_is_at_item()?'>':' ', (str_fnl[0]?str_fnl:str_fn) + 2);
+				}
+			}
+			else*/
+			{
+				str_fnl[19] = 0;
+				lcd_printf_P(_N("%c%-19s"), menu_enc_is_at_item()?'>':' ', str_fnl[0]?str_fnl:str_fn);
+			}
+
+//			int cnt = lcd_printf_P(_N("%c%-19s"), menu_enc_is_at_item()?'>':' ', str_fnl);
+//			int cnt = lcd_printf_P(_N("%cTESTIK.gcode"), menu_enc_is_at_item()?'>':' ');
+		}
+		if (wasClicked && menu_enc_is_at_item())
+		{
+			return menu_item_ret();
+		}
+	}
+	_menuItemNr++;
+	return 0;
+}
+
+
+/* Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependent */
 
 
 static void lcd_status_screen()
 static void lcd_status_screen()
 {
 {
@@ -538,7 +785,7 @@ static void lcd_status_screen()
   if (current_click && (lcd_commands_type != LCD_COMMAND_STOP_PRINT)) //click is aborted unless stop print finishes
   if (current_click && (lcd_commands_type != LCD_COMMAND_STOP_PRINT)) //click is aborted unless stop print finishes
   {
   {
     menuStack.reset(); //redundant, as already done in lcd_return_to_status(), just to be sure
     menuStack.reset(); //redundant, as already done in lcd_return_to_status(), just to be sure
-    menu_action_submenu(lcd_main_menu);
+    menu_submenu(lcd_main_menu);
     lcd_implementation_init( // to maybe revive the LCD if static electricity killed it.
     lcd_implementation_init( // to maybe revive the LCD if static electricity killed it.
 #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)
 #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)
       currentMenu == lcd_status_screen
       currentMenu == lcd_status_screen
@@ -982,7 +1229,7 @@ void lcd_commands()
 
 
 			lcd_implementation_clear();
 			lcd_implementation_clear();
 			menuStack.reset();
 			menuStack.reset();
-			menu_action_submenu(lcd_babystep_z);
+			menu_submenu(lcd_babystep_z);
 			enquecommand_P(PSTR("G1 X60.0 E9.0 F1000.0")); //intro line
 			enquecommand_P(PSTR("G1 X60.0 E9.0 F1000.0")); //intro line
 			enquecommand_P(PSTR("G1 X100.0 E12.5 F1000.0")); //intro line			
 			enquecommand_P(PSTR("G1 X100.0 E12.5 F1000.0")); //intro line			
 			enquecommand_P(PSTR("G92 E0.0"));
 			enquecommand_P(PSTR("G92 E0.0"));
@@ -1545,10 +1792,7 @@ static void lcd_menu_extruder_info()
 	);
 	);
 #endif //PAT9125
 #endif //PAT9125
     
     
-    if (lcd_clicked())
-    {
-        menu_action_back();
-    }
+    menu_back_if_clicked();
 }
 }
 
 
 #if defined(TMC2130) && defined(PAT9125)
 #if defined(TMC2130) && defined(PAT9125)
@@ -1565,11 +1809,7 @@ static void lcd_menu_fails_stats_total()
     uint16_t crashX = eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT);
     uint16_t crashX = eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT);
     uint16_t crashY = eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT);
     uint16_t crashY = eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT);
 	lcd_printf_P(PSTR(ESC_H(0,0) "Total failures" ESC_H(1,1) "Power failures  %-3d" ESC_H(1,2) "Filam. runouts  %-3d" ESC_H(1,3) "Crash  X %-3d  Y %-3d"), power, filam, crashX, crashY);
 	lcd_printf_P(PSTR(ESC_H(0,0) "Total failures" ESC_H(1,1) "Power failures  %-3d" ESC_H(1,2) "Filam. runouts  %-3d" ESC_H(1,3) "Crash  X %-3d  Y %-3d"), power, filam, crashX, crashY);
-	if (lcd_clicked())
-    {
-        lcd_quick_feedback();
-        menu_action_back();
-    }
+	menu_back_if_clicked_fb();
 }
 }
 
 
 static void lcd_menu_fails_stats_print()
 static void lcd_menu_fails_stats_print()
@@ -1585,11 +1825,7 @@ static void lcd_menu_fails_stats_print()
     uint8_t crashX = eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_X);
     uint8_t crashX = eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_X);
     uint8_t crashY = eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_Y);
     uint8_t crashY = eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_Y);
 	lcd_printf_P(PSTR(ESC_H(0,0) "Last print failures" ESC_H(1,1) "Power failures  %-3d" ESC_H(1,2) "Filam. runouts  %-3d" ESC_H(1,3) "Crash  X %-3d  Y %-3d"), power, filam, crashX, crashY);
 	lcd_printf_P(PSTR(ESC_H(0,0) "Last print failures" ESC_H(1,1) "Power failures  %-3d" ESC_H(1,2) "Filam. runouts  %-3d" ESC_H(1,3) "Crash  X %-3d  Y %-3d"), power, filam, crashX, crashY);
-	if (lcd_clicked())
-    {
-        lcd_quick_feedback();
-		menu_action_back();
-    }    
+	menu_back_if_clicked_fb();
 }
 }
 /**
 /**
  * @brief Open fail statistics menu
  * @brief Open fail statistics menu
@@ -1600,11 +1836,11 @@ static void lcd_menu_fails_stats_print()
  */
  */
 static void lcd_menu_fails_stats()
 static void lcd_menu_fails_stats()
 {
 {
-	START_MENU();
-	MENU_ITEM(back, _T(MSG_MAIN), 0);
-	MENU_ITEM(submenu, PSTR("Last print"), lcd_menu_fails_stats_print);
-	MENU_ITEM(submenu, PSTR("Total"), lcd_menu_fails_stats_total);
-	END_MENU();
+	MENU_BEGIN();
+	MENU_ITEM_BACK_P(_T(MSG_MAIN));
+	MENU_ITEM_SUBMENU_P(PSTR("Last print"), lcd_menu_fails_stats_print);
+	MENU_ITEM_SUBMENU_P(PSTR("Total"), lcd_menu_fails_stats_total);
+	MENU_END();
 }
 }
 #elif defined(PAT9125)
 #elif defined(PAT9125)
 /**
 /**
@@ -1627,10 +1863,7 @@ static void lcd_menu_fails_stats()
     uint8_t filamentLast = eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT);
     uint8_t filamentLast = eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT);
     uint16_t filamentTotal = eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT);
     uint16_t filamentTotal = eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT);
     lcd_printf_P(PSTR(ESC_H(0,0) "Last print failures" ESC_H(1,1) "Filam. runouts  %-3d" ESC_H(0,2) "Total failures" ESC_H(1,3) "Filam. runouts  %-3d"), filamentLast, filamentTotal);
     lcd_printf_P(PSTR(ESC_H(0,0) "Last print failures" ESC_H(1,1) "Filam. runouts  %-3d" ESC_H(0,2) "Total failures" ESC_H(1,3) "Filam. runouts  %-3d"), filamentLast, filamentTotal);
-    if (lcd_clicked())
-    {
-        menu_action_back();
-    }
+    menu_back_if_clicked();
 }
 }
 #endif //TMC2130
 #endif //TMC2130
 
 
@@ -1648,11 +1881,7 @@ static void lcd_menu_debug()
 	lcd_printf_P(PSTR(ESC_H(1,1) "RAM statistics" ESC_H(5,1) "SP_min: 0x%04x" ESC_H(1,2) "heap_start: 0x%04x" ESC_H(3,3) "heap_end: 0x%04x"), SP_min, __malloc_heap_start, __malloc_heap_end);
 	lcd_printf_P(PSTR(ESC_H(1,1) "RAM statistics" ESC_H(5,1) "SP_min: 0x%04x" ESC_H(1,2) "heap_start: 0x%04x" ESC_H(3,3) "heap_end: 0x%04x"), SP_min, __malloc_heap_start, __malloc_heap_end);
 #endif //DEBUG_STACK_MONITOR
 #endif //DEBUG_STACK_MONITOR
 
 
-	if (lcd_clicked())
-    {
-        lcd_quick_feedback();
-        menu_action_back();
-    }
+	menu_back_if_clicked_fb();
 }
 }
 #endif /* DEBUG_BUILD */
 #endif /* DEBUG_BUILD */
 
 
@@ -1665,10 +1894,7 @@ static void lcd_menu_temperatures()
 	lcd_printf_P(PSTR(ESC_H(1,2) "PINDA:    %d%c"), (int)current_temperature_pinda, '\x01');
 	lcd_printf_P(PSTR(ESC_H(1,2) "PINDA:    %d%c"), (int)current_temperature_pinda, '\x01');
 #endif //AMBIENT_THERMISTOR
 #endif //AMBIENT_THERMISTOR
 
 
-	if (lcd_clicked())
-    {
-        menu_action_back();
-    }
+    menu_back_if_clicked();
 }
 }
 
 
 #if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN)
 #if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN)
@@ -1682,10 +1908,7 @@ static void lcd_menu_voltages()
 //	float volt_bed = VOLT_DIV_REF * ((float)current_voltage_raw_bed / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
 //	float volt_bed = VOLT_DIV_REF * ((float)current_voltage_raw_bed / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
 //	lcd_printf_P(PSTR(ESC_H(1,1)"PWR:      %d.%01dV" ESC_H(1,2)"BED:      %d.%01dV"), (int)volt_pwr, (int)(10*fabs(volt_pwr - (int)volt_pwr)), (int)volt_bed, (int)(10*fabs(volt_bed - (int)volt_bed)));
 //	lcd_printf_P(PSTR(ESC_H(1,1)"PWR:      %d.%01dV" ESC_H(1,2)"BED:      %d.%01dV"), (int)volt_pwr, (int)(10*fabs(volt_pwr - (int)volt_pwr)), (int)volt_bed, (int)(10*fabs(volt_bed - (int)volt_bed)));
     lcd_printf_P(PSTR( ESC_H(1,1)"PWR:      %d.%01dV"), (int)volt_pwr, (int)(10*fabs(volt_pwr - (int)volt_pwr))) ;
     lcd_printf_P(PSTR( ESC_H(1,1)"PWR:      %d.%01dV"), (int)volt_pwr, (int)(10*fabs(volt_pwr - (int)volt_pwr))) ;
-    if (lcd_clicked())
-    {
-        menu_action_back();
-    }
+    menu_back_if_clicked();
 }
 }
 #endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN
 #endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN
 
 
@@ -1693,10 +1916,7 @@ static void lcd_menu_voltages()
 static void lcd_menu_belt_status()
 static void lcd_menu_belt_status()
 {
 {
     lcd_printf_P(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)));
     lcd_printf_P(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())
-    {
-        menu_action_back();
-    }
+    menu_back_if_clicked();
 }
 }
 #endif //TMC2130
 #endif //TMC2130
 
 
@@ -1715,27 +1935,27 @@ static void lcd_menu_test_restore()
 
 
 static void lcd_preheat_menu()
 static void lcd_preheat_menu()
 {
 {
-  START_MENU();
+  MENU_BEGIN();
 
 
-  MENU_ITEM(back, _T(MSG_MAIN), 0);
+  MENU_ITEM_BACK_P(_T(MSG_MAIN));
 
 
   if (farm_mode) {
   if (farm_mode) {
-	  MENU_ITEM(function, PSTR("farm   -  " STRINGIFY(FARM_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(FARM_PREHEAT_HPB_TEMP)), lcd_preheat_farm);
-	  MENU_ITEM(function, PSTR("nozzle -  " STRINGIFY(FARM_PREHEAT_HOTEND_TEMP) "/0"), lcd_preheat_farm_nozzle);
-	  MENU_ITEM(function, _T(MSG_COOLDOWN), lcd_cooldown);
-	  MENU_ITEM(function, PSTR("ABS    -  " STRINGIFY(ABS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(ABS_PREHEAT_HPB_TEMP)), lcd_preheat_abs);
+	  MENU_ITEM_FUNCTION_P(PSTR("farm   -  " STRINGIFY(FARM_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(FARM_PREHEAT_HPB_TEMP)), lcd_preheat_farm);
+	  MENU_ITEM_FUNCTION_P(PSTR("nozzle -  " STRINGIFY(FARM_PREHEAT_HOTEND_TEMP) "/0"), lcd_preheat_farm_nozzle);
+	  MENU_ITEM_FUNCTION_P(_T(MSG_COOLDOWN), lcd_cooldown);
+	  MENU_ITEM_FUNCTION_P(PSTR("ABS    -  " STRINGIFY(ABS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(ABS_PREHEAT_HPB_TEMP)), lcd_preheat_abs);
   } else {
   } else {
-	  MENU_ITEM(function, PSTR("PLA  -  " STRINGIFY(PLA_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PLA_PREHEAT_HPB_TEMP)), lcd_preheat_pla);
-	  MENU_ITEM(function, PSTR("PET  -  " STRINGIFY(PET_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PET_PREHEAT_HPB_TEMP)), lcd_preheat_pet);
-	  MENU_ITEM(function, PSTR("ABS  -  " STRINGIFY(ABS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(ABS_PREHEAT_HPB_TEMP)), lcd_preheat_abs);
-	  MENU_ITEM(function, PSTR("HIPS -  " STRINGIFY(HIPS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(HIPS_PREHEAT_HPB_TEMP)), lcd_preheat_hips);
-	  MENU_ITEM(function, PSTR("PP   -  " STRINGIFY(PP_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PP_PREHEAT_HPB_TEMP)), lcd_preheat_pp);
-	  MENU_ITEM(function, PSTR("FLEX -  " STRINGIFY(FLEX_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(FLEX_PREHEAT_HPB_TEMP)), lcd_preheat_flex);
-	  MENU_ITEM(function, _T(MSG_COOLDOWN), lcd_cooldown);
+	  MENU_ITEM_FUNCTION_P(PSTR("PLA  -  " STRINGIFY(PLA_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PLA_PREHEAT_HPB_TEMP)), lcd_preheat_pla);
+	  MENU_ITEM_FUNCTION_P(PSTR("PET  -  " STRINGIFY(PET_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PET_PREHEAT_HPB_TEMP)), lcd_preheat_pet);
+	  MENU_ITEM_FUNCTION_P(PSTR("ABS  -  " STRINGIFY(ABS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(ABS_PREHEAT_HPB_TEMP)), lcd_preheat_abs);
+	  MENU_ITEM_FUNCTION_P(PSTR("HIPS -  " STRINGIFY(HIPS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(HIPS_PREHEAT_HPB_TEMP)), lcd_preheat_hips);
+	  MENU_ITEM_FUNCTION_P(PSTR("PP   -  " STRINGIFY(PP_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PP_PREHEAT_HPB_TEMP)), lcd_preheat_pp);
+	  MENU_ITEM_FUNCTION_P(PSTR("FLEX -  " STRINGIFY(FLEX_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(FLEX_PREHEAT_HPB_TEMP)), lcd_preheat_flex);
+	  MENU_ITEM_FUNCTION_P(_T(MSG_COOLDOWN), lcd_cooldown);
   }
   }
   
   
 
 
-  END_MENU();
+  MENU_END();
 }
 }
 
 
 static void lcd_support_menu()
 static void lcd_support_menu()
@@ -1757,61 +1977,62 @@ static void lcd_support_menu()
         menuData.supportMenu.status = 0;
         menuData.supportMenu.status = 0;
     }
     }
 
 
-  START_MENU();
+  MENU_BEGIN();
 
 
-  MENU_ITEM(back, _T(MSG_MAIN), 0);
+  MENU_ITEM_BACK_P(_T(MSG_MAIN));
 
 
-  MENU_ITEM(back, PSTR("Firmware:"), 0);
-  MENU_ITEM(back, PSTR(" " FW_VERSION_FULL), 0);
+  MENU_ITEM_BACK_P(PSTR("Firmware:"));
+  MENU_ITEM_BACK_P(PSTR(" " FW_VERSION_FULL));
 #if (FW_DEV_VERSION != FW_VERSION_GOLD) && (FW_DEV_VERSION != FW_VERSION_RC)
 #if (FW_DEV_VERSION != FW_VERSION_GOLD) && (FW_DEV_VERSION != FW_VERSION_RC)
-  MENU_ITEM(back, PSTR(" repo " FW_REPOSITORY), 0);
+  MENU_ITEM_BACK_P(PSTR(" repo " FW_REPOSITORY));
 #endif
 #endif
   // Ideally this block would be optimized out by the compiler.
   // Ideally this block would be optimized out by the compiler.
 /*  const uint8_t fw_string_len = strlen_P(FW_VERSION_STR_P());
 /*  const uint8_t fw_string_len = strlen_P(FW_VERSION_STR_P());
   if (fw_string_len < 6) {
   if (fw_string_len < 6) {
-      MENU_ITEM(back, PSTR(MSG_FW_VERSION " - " FW_version), 0);
+      MENU_ITEM_BACK_P(PSTR(MSG_FW_VERSION " - " FW_version));
   } else {
   } else {
-      MENU_ITEM(back, PSTR("FW - " FW_version), 0);
+      MENU_ITEM_BACK_P(PSTR("FW - " FW_version));
   }*/
   }*/
       
       
-  MENU_ITEM(back, _i("prusa3d.com"), 0);////MSG_PRUSA3D c=0 r=0
-  MENU_ITEM(back, _i("forum.prusa3d.com"), 0);////MSG_PRUSA3D_FORUM c=0 r=0
-  MENU_ITEM(back, _i("howto.prusa3d.com"), 0);////MSG_PRUSA3D_HOWTO c=0 r=0
-  MENU_ITEM(back, PSTR("------------"), 0);
-  MENU_ITEM(back, PSTR(FILAMENT_SIZE), 0);
-  MENU_ITEM(back, PSTR(ELECTRONICS),0);
-  MENU_ITEM(back, PSTR(NOZZLE_TYPE),0);
-  MENU_ITEM(back, PSTR("------------"), 0);
-  MENU_ITEM(back, _i("Date:"), 0);////MSG_DATE c=17 r=1
-  MENU_ITEM(back, PSTR(__DATE__), 0);
+  MENU_ITEM_BACK_P(_i("prusa3d.com"));////MSG_PRUSA3D c=0 r=0
+  MENU_ITEM_BACK_P(_i("forum.prusa3d.com"));////MSG_PRUSA3D_FORUM c=0 r=0
+  MENU_ITEM_BACK_P(_i("howto.prusa3d.com"));////MSG_PRUSA3D_HOWTO c=0 r=0
+  MENU_ITEM_BACK_P(PSTR("------------"));
+  MENU_ITEM_BACK_P(PSTR(FILAMENT_SIZE));
+  MENU_ITEM_BACK_P(PSTR(ELECTRONICS));
+  MENU_ITEM_BACK_P(PSTR(NOZZLE_TYPE));
+  MENU_ITEM_BACK_P(PSTR("------------"));
+  MENU_ITEM_BACK_P(_i("Date:"));////MSG_DATE c=17 r=1
+  MENU_ITEM_BACK_P(PSTR(__DATE__));
 
 
   // Show the FlashAir IP address, if the card is available.
   // Show the FlashAir IP address, if the card is available.
   if (menuData.supportMenu.is_flash_air) {
   if (menuData.supportMenu.is_flash_air) {
-      MENU_ITEM(back, PSTR("------------"), 0);
-      MENU_ITEM(back, PSTR("FlashAir IP Addr:"), 0);
-      MENU_ITEM(back_RAM, menuData.supportMenu.ip_str, 0);
+      MENU_ITEM_BACK_P(PSTR("------------"));
+      MENU_ITEM_BACK_P(PSTR("FlashAir IP Addr:"));
+///!      MENU_ITEM(back_RAM, menuData.supportMenu.ip_str, 0);
   }
   }
   #ifndef MK1BP
   #ifndef MK1BP
-  MENU_ITEM(back, PSTR("------------"), 0);
-  MENU_ITEM(submenu, _i("XYZ cal. details"), lcd_menu_xyz_y_min);////MSG_XYZ_DETAILS c=19 r=1
-  MENU_ITEM(submenu, _i("Extruder info"), lcd_menu_extruder_info);////MSG_INFO_EXTRUDER c=15 r=1
+  MENU_ITEM_BACK_P(PSTR("------------"));
+  MENU_ITEM_SUBMENU_P(_i("XYZ cal. details"), lcd_menu_xyz_y_min);////MSG_XYZ_DETAILS c=19 r=1
+  MENU_ITEM_SUBMENU_P(_i("Extruder info"), lcd_menu_extruder_info);////MSG_INFO_EXTRUDER c=15 r=1
 
 
 #ifdef TMC2130
 #ifdef TMC2130
-  MENU_ITEM(submenu, _i("Belt status"), lcd_menu_belt_status);////MSG_MENU_BELT_STATUS c=15 r=1
+  MENU_ITEM_SUBMENU_P(_i("Belt status"), lcd_menu_belt_status);////MSG_MENU_BELT_STATUS c=15 r=1
 #endif //TMC2130
 #endif //TMC2130
     
     
-  MENU_ITEM(submenu, _i("Temperatures"), lcd_menu_temperatures);////MSG_MENU_TEMPERATURES c=15 r=1
+  MENU_ITEM_SUBMENU_P(_i("Temperatures"), lcd_menu_temperatures);////MSG_MENU_TEMPERATURES c=15 r=1
 
 
 #if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN)
 #if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN)
-  MENU_ITEM(submenu, _i("Voltages"), lcd_menu_voltages);////MSG_MENU_VOLTAGES c=15 r=1
+  MENU_ITEM_SUBMENU_P(_i("Voltages"), lcd_menu_voltages);////MSG_MENU_VOLTAGES c=15 r=1
 #endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN
 #endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN
 
 
 #ifdef DEBUG_BUILD
 #ifdef DEBUG_BUILD
-  MENU_ITEM(submenu, PSTR("Debug"), lcd_menu_debug);
+  MENU_ITEM_SUBMENU_P(PSTR("Debug"), lcd_menu_debug);
 #endif /* DEBUG_BUILD */
 #endif /* DEBUG_BUILD */
 
 
   #endif //MK1BP
   #endif //MK1BP
-  END_MENU();
+
+  MENU_END();
 }
 }
 
 
 void lcd_set_fan_check() {
 void lcd_set_fan_check() {
@@ -1844,7 +2065,7 @@ void lcd_unLoadFilament()
     lcd_implementation_clear();
     lcd_implementation_clear();
   }
   }
 
 
-  menu_action_back();
+  menu_back();
 }
 }
 
 
 void lcd_change_filament() {
 void lcd_change_filament() {
@@ -2053,9 +2274,9 @@ static void lcd_menu_AutoLoadFilament()
         lcd_printPGM(_T(MSG_ERROR));
         lcd_printPGM(_T(MSG_ERROR));
         lcd.setCursor(0, 2);
         lcd.setCursor(0, 2);
         lcd_printPGM(_T(MSG_PREHEAT_NOZZLE));
         lcd_printPGM(_T(MSG_PREHEAT_NOZZLE));
-        if (ptimer->expired(2000ul)) menu_action_back();
+        if (ptimer->expired(2000ul)) menu_back();
     }
     }
-    if (lcd_clicked()) menu_action_back();
+    menu_back_if_clicked();
 }
 }
 #endif //PAT9125
 #endif //PAT9125
 
 
@@ -2110,11 +2331,7 @@ void lcd_menu_statistics()
 		 _i("Print time"),
 		 _i("Print time"),
 		 _h, _m, _s
 		 _h, _m, _s
 		);
 		);
-		if (lcd_clicked())
-		{
-			lcd_quick_feedback();
-			menu_action_back();
-		}
+		menu_back_if_clicked_fb();
 	}
 	}
 	else
 	else
 	{
 	{
@@ -2155,7 +2372,7 @@ void lcd_menu_statistics()
 		}
 		}
 		KEEPALIVE_STATE(NOT_BUSY);
 		KEEPALIVE_STATE(NOT_BUSY);
 		lcd_quick_feedback();
 		lcd_quick_feedback();
-		menu_action_back();
+		menu_back();
 	}
 	}
 }
 }
 
 
@@ -2181,7 +2398,7 @@ static void _lcd_move(const char *name, int axis, int min, int max) {
   }
   }
   if (lcdDrawUpdate) lcd_implementation_drawedit(name, ftostr31(current_position[axis]));
   if (lcdDrawUpdate) lcd_implementation_drawedit(name, ftostr31(current_position[axis]));
   if (menuExiting || LCD_CLICKED) (void)enable_endstops(menuData._lcd_moveMenu.endstopsEnabledPrevious);
   if (menuExiting || LCD_CLICKED) (void)enable_endstops(menuData._lcd_moveMenu.endstopsEnabledPrevious);
-  if (LCD_CLICKED) menu_action_back();
+  if (LCD_CLICKED) menu_back();
 }
 }
 
 
 
 
@@ -2202,7 +2419,7 @@ static void lcd_move_e()
   {
   {
     lcd_implementation_drawedit(PSTR("Extruder"), ftostr31(current_position[E_AXIS]));
     lcd_implementation_drawedit(PSTR("Extruder"), ftostr31(current_position[E_AXIS]));
   }
   }
-  if (LCD_CLICKED) menu_action_back();
+  if (LCD_CLICKED) menu_back();
 }
 }
 	else {
 	else {
 		lcd_implementation_clear();
 		lcd_implementation_clear();
@@ -2250,9 +2467,7 @@ static void lcd_menu_xyz_y_min()
 		else lcd_printf_P(_N("%6.2fmm"), distanceMin[i]);
 		else lcd_printf_P(_N("%6.2fmm"), distanceMin[i]);
 	}
 	}
     if (lcd_clicked())
     if (lcd_clicked())
-    {
         lcd_goto_menu(lcd_menu_xyz_skew);
         lcd_goto_menu(lcd_menu_xyz_skew);
-    }
 }
 }
 /**
 /**
  * @brief Show measured axis skewness
  * @brief Show measured axis skewness
@@ -2267,13 +2482,13 @@ static void lcd_menu_xyz_skew()
 //|01234567890123456789|
 //|01234567890123456789|
 //|Measured skew:  N/A |
 //|Measured skew:  N/A |
 //|--------------------|
 //|--------------------|
-//|Slight skew:   0.12°|
-//|Severe skew:   0.25°|
+//|Slight skew:   0.12�|
+//|Severe skew:   0.25�|
 //----------------------
 //----------------------
     float angleDiff = eeprom_read_float((float*)(EEPROM_XYZ_CAL_SKEW));
     float angleDiff = eeprom_read_float((float*)(EEPROM_XYZ_CAL_SKEW));
 	lcd_printf_P(_N(
 	lcd_printf_P(_N(
 	  ESC_H(0,0)
 	  ESC_H(0,0)
-	  "%S:  N/A\n"
+	  "%S:\n"
 	  "%S\n"
 	  "%S\n"
 	  "%S:  %5.2f\x01\n"
 	  "%S:  %5.2f\x01\n"
 	  "%S:  %5.2f\x01"
 	  "%S:  %5.2f\x01"
@@ -2283,11 +2498,12 @@ static void lcd_menu_xyz_skew()
 	 _i("Slight skew"), _deg(bed_skew_angle_mild),
 	 _i("Slight skew"), _deg(bed_skew_angle_mild),
 	 _i("Severe skew"), _deg(bed_skew_angle_extreme)
 	 _i("Severe skew"), _deg(bed_skew_angle_extreme)
 	);
 	);
-	if (angleDiff < 100) lcd_printf_P(_N(ESC_H(15,0)"%4.2f\x01"), _deg(angleDiff));
+	if (angleDiff < 100)
+		lcd_printf_P(_N(ESC_H(15,0)"%4.2f\x01"), _deg(angleDiff));
+	else
+		lcd_puts_P(_N(ESC_H(15,0)"N/A"));
     if (lcd_clicked())
     if (lcd_clicked())
-    {
         lcd_goto_menu(lcd_menu_xyz_offset);
         lcd_goto_menu(lcd_menu_xyz_offset);
-    }
 }
 }
 /**
 /**
  * @brief Show measured bed offset from expected position
  * @brief Show measured bed offset from expected position
@@ -2311,10 +2527,7 @@ static void lcd_menu_xyz_offset()
         lcd.print(cntr[i]);
         lcd.print(cntr[i]);
         lcd_print_at_PGM((cntr[i] < 0) ? 17 : 16, i + 2, PSTR("mm"));
         lcd_print_at_PGM((cntr[i] < 0) ? 17 : 16, i + 2, PSTR("mm"));
     }
     }
-    if (lcd_clicked())
-    {
-        menu_action_back();
-    }
+    menu_back_if_clicked();
 }
 }
 
 
 // Save a single axis babystep value.
 // Save a single axis babystep value.
@@ -2410,7 +2623,7 @@ static void _lcd_babystep(int axis, const char *msg)
 
 
     if(Z_AXIS == axis) calibration_status_store(CALIBRATION_STATUS_CALIBRATED);
     if(Z_AXIS == axis) calibration_status_store(CALIBRATION_STATUS_CALIBRATED);
   }
   }
-  if (LCD_CLICKED) menu_action_back();
+  if (LCD_CLICKED) menu_back();
 }
 }
 
 
 static void lcd_babystep_x() {
 static void lcd_babystep_x() {
@@ -2494,14 +2707,14 @@ static void lcd_adjust_bed()
     if (menuData.adjustBed.rear  != menuData.adjustBed.rear2)
     if (menuData.adjustBed.rear  != menuData.adjustBed.rear2)
         eeprom_update_int8((unsigned char*)EEPROM_BED_CORRECTION_REAR,  menuData.adjustBed.rear  = menuData.adjustBed.rear2);
         eeprom_update_int8((unsigned char*)EEPROM_BED_CORRECTION_REAR,  menuData.adjustBed.rear  = menuData.adjustBed.rear2);
 
 
-    START_MENU();
-    MENU_ITEM(back, _T(MSG_SETTINGS), 0);
+    MENU_BEGIN();
+    MENU_ITEM_BACK_P(_T(MSG_SETTINGS));
     MENU_ITEM_EDIT(int3, _i("Left side [um]"),  &menuData.adjustBed.left2,  -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX);////MSG_BED_CORRECTION_LEFT c=14 r=1
     MENU_ITEM_EDIT(int3, _i("Left side [um]"),  &menuData.adjustBed.left2,  -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX);////MSG_BED_CORRECTION_LEFT c=14 r=1
     MENU_ITEM_EDIT(int3, _i("Right side[um]"), &menuData.adjustBed.right2, -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX);////MSG_BED_CORRECTION_RIGHT c=14 r=1
     MENU_ITEM_EDIT(int3, _i("Right side[um]"), &menuData.adjustBed.right2, -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX);////MSG_BED_CORRECTION_RIGHT c=14 r=1
     MENU_ITEM_EDIT(int3, _i("Front side[um]"), &menuData.adjustBed.front2, -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX);////MSG_BED_CORRECTION_FRONT c=14 r=1
     MENU_ITEM_EDIT(int3, _i("Front side[um]"), &menuData.adjustBed.front2, -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX);////MSG_BED_CORRECTION_FRONT c=14 r=1
     MENU_ITEM_EDIT(int3, _i("Rear side [um]"),  &menuData.adjustBed.rear2,  -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX);////MSG_BED_CORRECTION_REAR c=14 r=1
     MENU_ITEM_EDIT(int3, _i("Rear side [um]"),  &menuData.adjustBed.rear2,  -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX);////MSG_BED_CORRECTION_REAR c=14 r=1
-    MENU_ITEM(function, _i("Reset"), lcd_adjust_bed_reset);////MSG_BED_CORRECTION_RESET c=0 r=0
-    END_MENU();
+    MENU_ITEM_FUNCTION_P(_i("Reset"), lcd_adjust_bed_reset);////MSG_BED_CORRECTION_RESET c=0 r=0
+    MENU_END();
 }
 }
 
 
 void pid_extruder() {
 void pid_extruder() {
@@ -3143,7 +3356,7 @@ static void lcd_show_end_stops() {
 
 
 static void menu_show_end_stops() {
 static void menu_show_end_stops() {
     lcd_show_end_stops();
     lcd_show_end_stops();
-    if (LCD_CLICKED) menu_action_back();
+    if (LCD_CLICKED) menu_back();
 }
 }
 
 
 // Lets the user move the Z carriage up to the end stoppers.
 // Lets the user move the Z carriage up to the end stoppers.
@@ -3488,13 +3701,13 @@ void lcd_pick_babystep(){
 */
 */
 void lcd_move_menu_axis()
 void lcd_move_menu_axis()
 {
 {
-	START_MENU();
-	MENU_ITEM(back, _T(MSG_SETTINGS), 0);
-	MENU_ITEM(submenu, _i("Move X"), lcd_move_x);////MSG_MOVE_X c=0 r=0
-	MENU_ITEM(submenu, _i("Move Y"), lcd_move_y);////MSG_MOVE_Y c=0 r=0
-	MENU_ITEM(submenu, _i("Move Z"), lcd_move_z);////MSG_MOVE_Z c=0 r=0
-	MENU_ITEM(submenu, _i("Extruder"), lcd_move_e);////MSG_MOVE_E c=0 r=0
-	END_MENU();
+	MENU_BEGIN();
+	MENU_ITEM_BACK_P(_T(MSG_SETTINGS));
+	MENU_ITEM_SUBMENU_P(_i("Move X"), lcd_move_x);////MSG_MOVE_X c=0 r=0
+	MENU_ITEM_SUBMENU_P(_i("Move Y"), lcd_move_y);////MSG_MOVE_Y c=0 r=0
+	MENU_ITEM_SUBMENU_P(_i("Move Z"), lcd_move_z);////MSG_MOVE_Z c=0 r=0
+	MENU_ITEM_SUBMENU_P(_i("Extruder"), lcd_move_e);////MSG_MOVE_E c=0 r=0
+	MENU_END();
 }
 }
 
 
 static void lcd_move_menu_1mm()
 static void lcd_move_menu_1mm()
@@ -3549,8 +3762,7 @@ static void lcd_crash_mode_info()
 		fputs_P(_i("\x1b[2JCrash detection can\x1b[1;0Hbe turned on only in\x1b[2;0HNormal mode"), lcdout);////MSG_CRASH_DET_ONLY_IN_NORMAL c=20 r=4
 		fputs_P(_i("\x1b[2JCrash detection can\x1b[1;0Hbe turned on only in\x1b[2;0HNormal mode"), lcdout);////MSG_CRASH_DET_ONLY_IN_NORMAL c=20 r=4
 		tim = millis();
 		tim = millis();
 	}
 	}
-	if (lcd_clicked())
-          menu_action_back();
+    menu_back_if_clicked();
 }
 }
 
 
 static void lcd_crash_mode_info2()
 static void lcd_crash_mode_info2()
@@ -3562,8 +3774,7 @@ static void lcd_crash_mode_info2()
 		fputs_P(_i("\x1b[2JWARNING:\x1b[1;0HCrash detection\x1b[2;0Hdisabled in\x1b[3;0HStealth mode"), lcdout);////MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
 		fputs_P(_i("\x1b[2JWARNING:\x1b[1;0HCrash detection\x1b[2;0Hdisabled in\x1b[3;0HStealth mode"), lcdout);////MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
 		tim = millis();
 		tim = millis();
 	}
 	}
-	if (lcd_clicked())
-          menu_action_back();
+    menu_back_if_clicked();
 }
 }
 #endif //TMC2130
 #endif //TMC2130
 
 
@@ -3578,8 +3789,7 @@ uint8_t nlines;
           lcd_display_message_fullscreen_nonBlocking_P(_i("Autoloading filament available only when filament sensor is turned on..."), nlines); ////MSG_AUTOLOADING_ONLY_IF_FSENS_ON c=20 r=4
           lcd_display_message_fullscreen_nonBlocking_P(_i("Autoloading filament available only when filament sensor is turned on..."), nlines); ////MSG_AUTOLOADING_ONLY_IF_FSENS_ON c=20 r=4
 		tim = millis();
 		tim = millis();
 	}
 	}
-	if (lcd_clicked())
-          menu_action_back();
+    menu_back_if_clicked();
 }
 }
 
 
 static void lcd_fsensor_fail()
 static void lcd_fsensor_fail()
@@ -3592,8 +3802,7 @@ uint8_t nlines;
           lcd_display_message_fullscreen_nonBlocking_P(_i("ERROR: Filament sensor is not responding, please check connection."), nlines);////MSG_FSENS_NOT_RESPONDING c=20 r=4
           lcd_display_message_fullscreen_nonBlocking_P(_i("ERROR: Filament sensor is not responding, please check connection."), nlines);////MSG_FSENS_NOT_RESPONDING c=20 r=4
 		tim = millis();
 		tim = millis();
 	}
 	}
-	if (lcd_clicked())
-          menu_action_back();
+    menu_back_if_clicked();
 }
 }
 #endif //PAT9125
 #endif //PAT9125
 
 
@@ -3631,7 +3840,7 @@ static void lcd_silent_mode_set() {
   st_current_init();
   st_current_init();
 #ifdef TMC2130
 #ifdef TMC2130
   if (CrashDetectMenu && (SilentModeMenu != SILENT_MODE_NORMAL))
   if (CrashDetectMenu && (SilentModeMenu != SILENT_MODE_NORMAL))
-	  menu_action_submenu(lcd_crash_mode_info2);
+	  menu_submenu(lcd_crash_mode_info2);
 #endif //TMC2130
 #endif //TMC2130
 }
 }
 
 
@@ -3658,11 +3867,11 @@ static void lcd_fsensor_state_set()
     if (!FSensorStateMenu) {
     if (!FSensorStateMenu) {
         fsensor_disable();
         fsensor_disable();
         if (filament_autoload_enabled)
         if (filament_autoload_enabled)
-            menu_action_submenu(lcd_filament_autoload_info);
+            menu_submenu(lcd_filament_autoload_info);
     }else{
     }else{
         fsensor_enable();
         fsensor_enable();
         if (fsensor_not_responding)
         if (fsensor_not_responding)
-            menu_action_submenu(lcd_fsensor_fail);
+            menu_submenu(lcd_fsensor_fail);
     }
     }
 }
 }
 #endif //PAT9125
 #endif //PAT9125
@@ -3679,15 +3888,51 @@ void lcd_set_progress() {
 #endif
 #endif
 
 
 #if (LANG_MODE != 0)
 #if (LANG_MODE != 0)
+
+void menu_setlang(unsigned char lang)
+{
+	if (!lang_select(lang))
+	{
+		if (lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Copy selected language from XFLASH?"), false, true))
+			lang_boot_update_start(lang);
+		lcd_update_enable(true);
+		lcd_implementation_clear();
+		lcd_goto_menu(lcd_language_menu);
+		lcd_timeoutToStatus.stop(); //infinite timeout
+		lcdDrawUpdate = 2;
+	}
+}
+
 static void lcd_language_menu()
 static void lcd_language_menu()
 {
 {
-	START_MENU();
-	if (lang_is_selected()) MENU_ITEM(back, _T(MSG_SETTINGS), 0);
-	MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(0)), 0);
-//	MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(1)), 1);
-	for (int i = 2; i < lang_get_count(); i++) //skip seconday language - solved in lang_select
-		MENU_ITEM(setlang, lang_get_name_by_code(lang_get_code(i)), i);
-	END_MENU();
+	MENU_BEGIN();
+	if (lang_is_selected()) MENU_ITEM_BACK_P(_T(MSG_SETTINGS)); //
+	if (menu_item_text_P(lang_get_name_by_code(lang_get_code(0)))) //primary language
+	{
+		menu_setlang(0);
+		return;
+	}
+	uint8_t cnt = lang_get_count();
+#ifdef W25X20CL
+	if (cnt == 2) //display secondary language in case of clear xflash 
+	{
+		if (menu_item_text_P(lang_get_name_by_code(lang_get_code(1))))
+		{
+			menu_setlang(1);
+			return;
+		}
+	}
+	else
+		for (int i = 2; i < cnt; i++) //skip seconday language - solved in lang_select (MK3)
+#else //W25X20CL
+		for (int i = 1; i < cnt; i++) //all seconday languages (MK2/25)
+#endif //W25X20CL
+			if (menu_item_text_P(lang_get_name_by_code(lang_get_code(i))))
+			{
+				menu_setlang(i);
+				return;
+			}
+	MENU_END();
 }
 }
 #endif //(LANG_MODE != 0)
 #endif //(LANG_MODE != 0)
 
 
@@ -3713,10 +3958,10 @@ void lcd_mesh_calibration_z()
 
 
 void lcd_pinda_calibration_menu()
 void lcd_pinda_calibration_menu()
 {
 {
-	START_MENU();
-		MENU_ITEM(back, _T(MSG_MENU_CALIBRATION), 0);
-		MENU_ITEM(submenu, _i("Calibrate"), lcd_calibrate_pinda);////MSG_CALIBRATE_PINDA c=17 r=1
-	END_MENU();
+	MENU_BEGIN();
+		MENU_ITEM_BACK_P(_T(MSG_MENU_CALIBRATION));
+		MENU_ITEM_SUBMENU_P(_i("Calibrate"), lcd_calibrate_pinda);////MSG_CALIBRATE_PINDA c=17 r=1
+	MENU_END();
 }
 }
 
 
 void lcd_temp_calibration_set() {
 void lcd_temp_calibration_set() {
@@ -4075,26 +4320,30 @@ void lcd_wizard(int state) {
 static void lcd_settings_menu()
 static void lcd_settings_menu()
 {
 {
   EEPROM_read(EEPROM_SILENT, (uint8_t*)&SilentModeMenu, sizeof(SilentModeMenu));
   EEPROM_read(EEPROM_SILENT, (uint8_t*)&SilentModeMenu, sizeof(SilentModeMenu));
-  START_MENU();
+  MENU_BEGIN();
 
 
-  MENU_ITEM(back, _T(MSG_MAIN), lcd_settings_menu_back);
+  if (menu_item_back_P(_T(MSG_MAIN)))
+  {
+	  lcd_settings_menu_back();
+	  return;
+  }
 
 
-  MENU_ITEM(submenu, _i("Temperature"), lcd_control_temperature_menu);////MSG_TEMPERATURE c=0 r=0
+  MENU_ITEM_SUBMENU_P(_i("Temperature"), lcd_control_temperature_menu);////MSG_TEMPERATURE c=0 r=0
   if (!homing_flag)
   if (!homing_flag)
   {
   {
-	  MENU_ITEM(submenu, _i("Move axis"), lcd_move_menu_1mm);////MSG_MOVE_AXIS c=0 r=0
+	  MENU_ITEM_SUBMENU_P(_i("Move axis"), lcd_move_menu_1mm);////MSG_MOVE_AXIS c=0 r=0
   }
   }
   if (!isPrintPaused)
   if (!isPrintPaused)
   {
   {
-	  MENU_ITEM(gcode, _i("Disable steppers"), PSTR("M84"));////MSG_DISABLE_STEPPERS c=0 r=0
+	  MENU_ITEM_GCODE_P(_i("Disable steppers"), PSTR("M84"));////MSG_DISABLE_STEPPERS c=0 r=0
   }
   }
 #ifndef TMC2130
 #ifndef TMC2130
   if (!farm_mode) { //dont show in menu if we are in farm mode
   if (!farm_mode) { //dont show in menu if we are in farm mode
 	  switch (SilentModeMenu) {
 	  switch (SilentModeMenu) {
-	  case SILENT_MODE_POWER: MENU_ITEM(function, _T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break;
-	  case SILENT_MODE_SILENT: MENU_ITEM(function, _T(MSG_SILENT_MODE_ON), lcd_silent_mode_set); break;
-	  case SILENT_MODE_AUTO: MENU_ITEM(function, _T(MSG_AUTO_MODE_ON), lcd_silent_mode_set); break;
-	  default: MENU_ITEM(function, _T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break; // (probably) not needed
+	  case SILENT_MODE_POWER: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break;
+	  case SILENT_MODE_SILENT: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_ON), lcd_silent_mode_set); break;
+	  case SILENT_MODE_AUTO: MENU_ITEM_FUNCTION_P(_T(MSG_AUTO_MODE_ON), lcd_silent_mode_set); break;
+	  default: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break; // (probably) not needed
 	  }
 	  }
   }
   }
 #endif //TMC2130
 #endif //TMC2130
@@ -4104,24 +4353,24 @@ static void lcd_settings_menu()
   if (FSensorStateMenu == 0) {
   if (FSensorStateMenu == 0) {
       if (fsensor_not_responding){
       if (fsensor_not_responding){
           // Filament sensor not working
           // Filament sensor not working
-          MENU_ITEM(function, _i("Fil. sensor [N/A]"), lcd_fsensor_state_set);////MSG_FSENSOR_NA c=0 r=0
-          MENU_ITEM(submenu, _T(MSG_FSENS_AUTOLOAD_NA), lcd_fsensor_fail);
+          MENU_ITEM_FUNCTION_P(_i("Fil. sensor [N/A]"), lcd_fsensor_state_set);////MSG_FSENSOR_NA c=0 r=0
+          MENU_ITEM_SUBMENU_P(_T(MSG_FSENS_AUTOLOAD_NA), lcd_fsensor_fail);
       }
       }
       else{
       else{
           // Filament sensor turned off, working, no problems
           // Filament sensor turned off, working, no problems
-          MENU_ITEM(function, _T(MSG_FSENSOR_OFF), lcd_fsensor_state_set);
-          MENU_ITEM(submenu,_T(MSG_FSENS_AUTOLOAD_NA), lcd_filament_autoload_info);
+          MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_OFF), lcd_fsensor_state_set);
+          MENU_ITEM_SUBMENU_P(_T(MSG_FSENS_AUTOLOAD_NA), lcd_filament_autoload_info);
       }
       }
   } else {
   } else {
       // Filament sensor turned on, working, no problems
       // Filament sensor turned on, working, no problems
-      MENU_ITEM(function, _T(MSG_FSENSOR_ON), lcd_fsensor_state_set);
+      MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_ON), lcd_fsensor_state_set);
      
      
 
 
       if (filament_autoload_enabled) {
       if (filament_autoload_enabled) {
-          MENU_ITEM(function, _i("F. autoload  [on]"), lcd_set_filament_autoload);////MSG_FSENS_AUTOLOAD_ON c=17 r=1
+          MENU_ITEM_FUNCTION_P(_i("F. autoload  [on]"), lcd_set_filament_autoload);////MSG_FSENS_AUTOLOAD_ON c=17 r=1
       }
       }
       else {
       else {
-          MENU_ITEM(function, _i("F. autoload [off]"), lcd_set_filament_autoload);////MSG_FSENS_AUTOLOAD_OFF c=17 r=1
+          MENU_ITEM_FUNCTION_P(_i("F. autoload [off]"), lcd_set_filament_autoload);////MSG_FSENS_AUTOLOAD_OFF c=17 r=1
       }
       }
       
       
   }
   }
@@ -4129,23 +4378,23 @@ static void lcd_settings_menu()
 #endif //PAT9125
 #endif //PAT9125
 
 
   if (fans_check_enabled == true) {
   if (fans_check_enabled == true) {
-	  MENU_ITEM(function, _i("Fans check   [on]"), lcd_set_fan_check);////MSG_FANS_CHECK_ON c=17 r=1
+	  MENU_ITEM_FUNCTION_P(_i("Fans check   [on]"), lcd_set_fan_check);////MSG_FANS_CHECK_ON c=17 r=1
   }
   }
   else {
   else {
-	  MENU_ITEM(function, _i("Fans check  [off]"), lcd_set_fan_check);////MSG_FANS_CHECK_OFF c=17 r=1
+	  MENU_ITEM_FUNCTION_P(_i("Fans check  [off]"), lcd_set_fan_check);////MSG_FANS_CHECK_OFF c=17 r=1
   }
   }
 
 
 #ifdef TMC2130
 #ifdef TMC2130
   if(!farm_mode)
   if(!farm_mode)
   {
   {
-    if (SilentModeMenu == SILENT_MODE_NORMAL) MENU_ITEM(function, _T(MSG_STEALTH_MODE_OFF), lcd_silent_mode_set);
-    else MENU_ITEM(function, _T(MSG_STEALTH_MODE_ON), lcd_silent_mode_set);
+	if (SilentModeMenu == SILENT_MODE_NORMAL) { MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_OFF), lcd_silent_mode_set); }
+    else MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_ON), lcd_silent_mode_set);
     if (SilentModeMenu == SILENT_MODE_NORMAL)
     if (SilentModeMenu == SILENT_MODE_NORMAL)
     {
     {
-      if (CrashDetectMenu == 0) MENU_ITEM(function, _T(MSG_CRASHDETECT_OFF), lcd_crash_mode_set);
-      else MENU_ITEM(function, _T(MSG_CRASHDETECT_ON), lcd_crash_mode_set);
+	  if (CrashDetectMenu == 0) { MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_OFF), lcd_crash_mode_set); }
+      else MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_ON), lcd_crash_mode_set);
     }
     }
-    else MENU_ITEM(submenu, _T(MSG_CRASHDETECT_NA), lcd_crash_mode_info);
+    else MENU_ITEM_SUBMENU_P(_T(MSG_CRASHDETECT_NA), lcd_crash_mode_info);
   }
   }
 
 
 #ifdef TMC2130_LINEARITY_CORRECTION_XYZ
 #ifdef TMC2130_LINEARITY_CORRECTION_XYZ
@@ -4157,33 +4406,33 @@ static void lcd_settings_menu()
 #endif //TMC2130
 #endif //TMC2130
 
 
   if (temp_cal_active == false) {
   if (temp_cal_active == false) {
-	  MENU_ITEM(function, _i("Temp. cal.  [off]"), lcd_temp_calibration_set);////MSG_TEMP_CALIBRATION_OFF c=20 r=1
+	  MENU_ITEM_FUNCTION_P(_i("Temp. cal.  [off]"), lcd_temp_calibration_set);////MSG_TEMP_CALIBRATION_OFF c=20 r=1
   }
   }
   else {
   else {
-	  MENU_ITEM(function, _i("Temp. cal.   [on]"), lcd_temp_calibration_set);////MSG_TEMP_CALIBRATION_ON c=20 r=1
+	  MENU_ITEM_FUNCTION_P(_i("Temp. cal.   [on]"), lcd_temp_calibration_set);////MSG_TEMP_CALIBRATION_ON c=20 r=1
   }
   }
 #ifdef HAS_SECOND_SERIAL_PORT
 #ifdef HAS_SECOND_SERIAL_PORT
   if (selectedSerialPort == 0) {
   if (selectedSerialPort == 0) {
-	  MENU_ITEM(function, _i("RPi port    [off]"), lcd_second_serial_set);////MSG_SECOND_SERIAL_OFF c=17 r=1
+	  MENU_ITEM_FUNCTION_P(_i("RPi port    [off]"), lcd_second_serial_set);////MSG_SECOND_SERIAL_OFF c=17 r=1
   }
   }
   else {
   else {
-	  MENU_ITEM(function, _i("RPi port     [on]"), lcd_second_serial_set);////MSG_SECOND_SERIAL_ON c=17 r=1
+	  MENU_ITEM_FUNCTION_P(_i("RPi port     [on]"), lcd_second_serial_set);////MSG_SECOND_SERIAL_ON c=17 r=1
   }
   }
 #endif //HAS_SECOND_SERIAL
 #endif //HAS_SECOND_SERIAL
 
 
   if (!isPrintPaused && !homing_flag)
   if (!isPrintPaused && !homing_flag)
 	{
 	{
-		MENU_ITEM(submenu, _T(MSG_BABYSTEP_Z), lcd_babystep_z);
+		MENU_ITEM_SUBMENU_P(_T(MSG_BABYSTEP_Z), lcd_babystep_z);
 	}
 	}
 
 
 #if (LANG_MODE != 0)
 #if (LANG_MODE != 0)
-	MENU_ITEM(submenu, _i("Select language"), lcd_language_menu);////MSG_LANGUAGE_SELECT c=0 r=0
+	MENU_ITEM_SUBMENU_P(_i("Select language"), lcd_language_menu);////MSG_LANGUAGE_SELECT c=0 r=0
 #endif //(LANG_MODE != 0)
 #endif //(LANG_MODE != 0)
 
 
   if (card.ToshibaFlashAir_isEnabled()) {
   if (card.ToshibaFlashAir_isEnabled()) {
-    MENU_ITEM(function, _i("SD card [FlshAir]"), lcd_toshiba_flash_air_compatibility_toggle);////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
+    MENU_ITEM_FUNCTION_P(_i("SD card [FlshAir]"), lcd_toshiba_flash_air_compatibility_toggle);////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
   } else {
   } else {
-    MENU_ITEM(function, _i("SD card  [normal]"), lcd_toshiba_flash_air_compatibility_toggle);////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1
+    MENU_ITEM_FUNCTION_P(_i("SD card  [normal]"), lcd_toshiba_flash_air_compatibility_toggle);////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1
   }
   }
 
 
   #ifdef SDCARD_SORT_ALPHA
   #ifdef SDCARD_SORT_ALPHA
@@ -4191,20 +4440,20 @@ static void lcd_settings_menu()
 	  uint8_t sdSort;
 	  uint8_t sdSort;
 	  EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));
 	  EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));
 	  switch (sdSort) {
 	  switch (sdSort) {
-		  case SD_SORT_TIME: MENU_ITEM(function, _i("Sort:      [Time]"), lcd_sort_type_set); break;////MSG_SORT_TIME c=17 r=1
-		  case SD_SORT_ALPHA: MENU_ITEM(function, _i("Sort:  [Alphabet]"), lcd_sort_type_set); break;////MSG_SORT_ALPHA c=17 r=1
-		  default: MENU_ITEM(function, _i("Sort:      [None]"), lcd_sort_type_set);////MSG_SORT_NONE c=17 r=1
+		  case SD_SORT_TIME: MENU_ITEM_FUNCTION_P(_i("Sort:      [Time]"), lcd_sort_type_set); break;////MSG_SORT_TIME c=17 r=1
+		  case SD_SORT_ALPHA: MENU_ITEM_FUNCTION_P(_i("Sort:  [Alphabet]"), lcd_sort_type_set); break;////MSG_SORT_ALPHA c=17 r=1
+		  default: MENU_ITEM_FUNCTION_P(_i("Sort:      [None]"), lcd_sort_type_set);////MSG_SORT_NONE c=17 r=1
 	  }
 	  }
   }
   }
   #endif // SDCARD_SORT_ALPHA
   #endif // SDCARD_SORT_ALPHA
     
     
     if (farm_mode)
     if (farm_mode)
     {
     {
-        MENU_ITEM(submenu, PSTR("Farm number"), lcd_farm_no);
-		MENU_ITEM(function, PSTR("Disable farm mode"), lcd_disable_farm_mode);
+        MENU_ITEM_SUBMENU_P(PSTR("Farm number"), lcd_farm_no);
+		MENU_ITEM_FUNCTION_P(PSTR("Disable farm mode"), lcd_disable_farm_mode);
     }
     }
 
 
-	END_MENU();
+	MENU_END();
 }
 }
 
 
 static void lcd_selftest_()
 static void lcd_selftest_()
@@ -4238,7 +4487,7 @@ static void lcd_settings_menu_back()
     if (changed) tmc2130_init();
     if (changed) tmc2130_init();
 #endif //TMC2130
 #endif //TMC2130
     currentMenu = lcd_main_menu;
     currentMenu = lcd_main_menu;
-    lcd_main_menu();
+//    lcd_main_menu();
 }
 }
 #ifdef EXPERIMENTAL_FEATURES
 #ifdef EXPERIMENTAL_FEATURES
 
 
@@ -4279,27 +4528,27 @@ static void lcd_homing_accuracy_menu_advanced_back()
 static void lcd_homing_accuracy_menu_advanced()
 static void lcd_homing_accuracy_menu_advanced()
 {
 {
 	lcd_timeoutToStatus.start();
 	lcd_timeoutToStatus.start();
-	START_MENU();
-	MENU_ITEM(back, PSTR("Homing accuracy"), lcd_homing_accuracy_menu_advanced_back);
-	MENU_ITEM(function, PSTR("Reset def. steps"), lcd_homing_accuracy_menu_advanced_reset);
+	MENU_BEGIN();
+///!	MENU_ITEM_BACK_P(PSTR("Homing accuracy"), lcd_homing_accuracy_menu_advanced_back);
+	MENU_ITEM_FUNCTION_P(PSTR("Reset def. steps"), lcd_homing_accuracy_menu_advanced_reset);
 	MENU_ITEM_EDIT(byte3, PSTR("X-origin"),  &tmc2130_home_origin[X_AXIS],  0, 63);
 	MENU_ITEM_EDIT(byte3, PSTR("X-origin"),  &tmc2130_home_origin[X_AXIS],  0, 63);
 	MENU_ITEM_EDIT(byte3, PSTR("Y-origin"),  &tmc2130_home_origin[Y_AXIS],  0, 63);
 	MENU_ITEM_EDIT(byte3, PSTR("Y-origin"),  &tmc2130_home_origin[Y_AXIS],  0, 63);
 	MENU_ITEM_EDIT(byte3, PSTR("X-bsteps"),  &tmc2130_home_bsteps[X_AXIS],  0, 128);
 	MENU_ITEM_EDIT(byte3, PSTR("X-bsteps"),  &tmc2130_home_bsteps[X_AXIS],  0, 128);
 	MENU_ITEM_EDIT(byte3, PSTR("Y-bsteps"),  &tmc2130_home_bsteps[Y_AXIS],  0, 128);
 	MENU_ITEM_EDIT(byte3, PSTR("Y-bsteps"),  &tmc2130_home_bsteps[Y_AXIS],  0, 128);
 	MENU_ITEM_EDIT(byte3, PSTR("X-fsteps"),  &tmc2130_home_fsteps[X_AXIS],  0, 128);
 	MENU_ITEM_EDIT(byte3, PSTR("X-fsteps"),  &tmc2130_home_fsteps[X_AXIS],  0, 128);
 	MENU_ITEM_EDIT(byte3, PSTR("Y-fsteps"),  &tmc2130_home_fsteps[Y_AXIS],  0, 128);
 	MENU_ITEM_EDIT(byte3, PSTR("Y-fsteps"),  &tmc2130_home_fsteps[Y_AXIS],  0, 128);
-	END_MENU();
+	MENU_END();
 }
 }
 
 
 static void lcd_homing_accuracy_menu()
 static void lcd_homing_accuracy_menu()
 {
 {
-	START_MENU();
-	MENU_ITEM(back, PSTR("Experimental"), 0);
-	MENU_ITEM(function, tmc2130_home_enabled?PSTR("Accur. homing  On"):PSTR("Accur. homing Off"), lcd_accurate_home_set);
-    MENU_ITEM(gcode, PSTR("Calibrate X"), PSTR("G28XC"));
-    MENU_ITEM(gcode, PSTR("Calibrate Y"), PSTR("G28YC"));
-	MENU_ITEM(submenu, PSTR("Advanced"), lcd_homing_accuracy_menu_advanced);
-	END_MENU();
+	MENU_BEGIN();
+	MENU_ITEM_BACK_P(PSTR("Experimental"));
+	MENU_ITEM_FUNCTION_P(tmc2130_home_enabled?PSTR("Accur. homing  On"):PSTR("Accur. homing Off"), lcd_accurate_home_set);
+    MENU_ITEM_GCODE_P(PSTR("Calibrate X"), PSTR("G28XC"));
+    MENU_ITEM_GCODE_P(PSTR("Calibrate Y"), PSTR("G28YC"));
+	MENU_ITEM_SUBMENU_P(PSTR("Advanced"), lcd_homing_accuracy_menu_advanced);
+	MENU_END();
 }
 }
 
 
 static void lcd_ustep_resolution_menu_save()
 static void lcd_ustep_resolution_menu_save()
@@ -4360,14 +4609,14 @@ static void lcd_ustep_resolution_reset_def_xyze()
 static void lcd_ustep_resolution_menu()
 static void lcd_ustep_resolution_menu()
 {
 {
 	lcd_timeoutToStatus.start();
 	lcd_timeoutToStatus.start();
-	START_MENU();
-	MENU_ITEM(back, PSTR("Experimental"), lcd_ustep_resolution_menu_back);
-	MENU_ITEM(function, PSTR("Reset defaults"),  lcd_ustep_resolution_reset_def_xyze);
+	MENU_BEGIN();
+///!	MENU_ITEM_BACK_P(PSTR("Experimental"), lcd_ustep_resolution_menu_back);
+	MENU_ITEM_FUNCTION_P(PSTR("Reset defaults"),  lcd_ustep_resolution_reset_def_xyze);
 	MENU_ITEM_EDIT(mres, PSTR("X-resolution"),  &tmc2130_mres[X_AXIS],  4, 4);
 	MENU_ITEM_EDIT(mres, PSTR("X-resolution"),  &tmc2130_mres[X_AXIS],  4, 4);
 	MENU_ITEM_EDIT(mres, PSTR("Y-resolution"),  &tmc2130_mres[Y_AXIS],  4, 4);
 	MENU_ITEM_EDIT(mres, PSTR("Y-resolution"),  &tmc2130_mres[Y_AXIS],  4, 4);
 	MENU_ITEM_EDIT(mres, PSTR("Z-resolution"),  &tmc2130_mres[Z_AXIS],  4, 4);
 	MENU_ITEM_EDIT(mres, PSTR("Z-resolution"),  &tmc2130_mres[Z_AXIS],  4, 4);
 	MENU_ITEM_EDIT(mres, PSTR("E-resolution"),  &tmc2130_mres[E_AXIS],  2, 5);
 	MENU_ITEM_EDIT(mres, PSTR("E-resolution"),  &tmc2130_mres[E_AXIS],  2, 5);
-	END_MENU();
+	MENU_END();
 }
 }
 
 
 
 
@@ -4408,15 +4657,15 @@ static void lcd_ustep_linearity_menu_reset()
 static void lcd_ustep_linearity_menu()
 static void lcd_ustep_linearity_menu()
 {
 {
 	lcd_timeoutToStatus.start();
 	lcd_timeoutToStatus.start();
-	START_MENU();
-	MENU_ITEM(back, PSTR("Experimental"), lcd_ustep_linearity_menu_back);
-	MENU_ITEM(function, PSTR("Reset correction"), lcd_ustep_linearity_menu_reset);
-	MENU_ITEM(function, PSTR("Recomended config"), lcd_ustep_linearity_menu_recomended);
+	MENU_BEGIN();
+///!	MENU_ITEM_BACK_P(PSTR("Experimental"), lcd_ustep_linearity_menu_back);
+	MENU_ITEM_FUNCTION_P(PSTR("Reset correction"), lcd_ustep_linearity_menu_reset);
+	MENU_ITEM_FUNCTION_P(PSTR("Recomended config"), lcd_ustep_linearity_menu_recomended);
 	MENU_ITEM_EDIT(wfac, PSTR("X-correction"),  &tmc2130_wave_fac[X_AXIS],  TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);
 	MENU_ITEM_EDIT(wfac, PSTR("X-correction"),  &tmc2130_wave_fac[X_AXIS],  TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);
 	MENU_ITEM_EDIT(wfac, PSTR("Y-correction"),  &tmc2130_wave_fac[Y_AXIS],  TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);
 	MENU_ITEM_EDIT(wfac, PSTR("Y-correction"),  &tmc2130_wave_fac[Y_AXIS],  TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);
 	MENU_ITEM_EDIT(wfac, PSTR("Z-correction"),  &tmc2130_wave_fac[Z_AXIS],  TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);
 	MENU_ITEM_EDIT(wfac, PSTR("Z-correction"),  &tmc2130_wave_fac[Z_AXIS],  TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);
 	MENU_ITEM_EDIT(wfac, PSTR("E-correction"),  &tmc2130_wave_fac[E_AXIS],  TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);
 	MENU_ITEM_EDIT(wfac, PSTR("E-correction"),  &tmc2130_wave_fac[E_AXIS],  TMC2130_WAVE_FAC1000_MIN-TMC2130_WAVE_FAC1000_STP, TMC2130_WAVE_FAC1000_MAX);
-	END_MENU();
+	MENU_END();
 }
 }
 
 
 static void lcd_experimantal_menu_save_all()
 static void lcd_experimantal_menu_save_all()
@@ -4438,61 +4687,61 @@ static void lcd_experimantal_menu_disable_all()
 
 
 static void lcd_experimantal_menu()
 static void lcd_experimantal_menu()
 {
 {
-	START_MENU();
-	MENU_ITEM(back, _T(MSG_MAIN), 0);
-	MENU_ITEM(function, PSTR("All Xfeatures off"), lcd_experimantal_menu_disable_all);
-	MENU_ITEM(submenu, PSTR("Homing accuracy"), lcd_homing_accuracy_menu);
-	MENU_ITEM(submenu, PSTR("uStep resolution"), lcd_ustep_resolution_menu);
-	MENU_ITEM(submenu, PSTR("uStep linearity"), lcd_ustep_linearity_menu);
-	END_MENU();
+	MENU_BEGIN();
+	MENU_ITEM_BACK_P(_T(MSG_MAIN));
+	MENU_ITEM_FUNCTION_P(PSTR("All Xfeatures off"), lcd_experimantal_menu_disable_all);
+	MENU_ITEM_SUBMENU_P(PSTR("Homing accuracy"), lcd_homing_accuracy_menu);
+	MENU_ITEM_SUBMENU_P(PSTR("uStep resolution"), lcd_ustep_resolution_menu);
+	MENU_ITEM_SUBMENU_P(PSTR("uStep linearity"), lcd_ustep_linearity_menu);
+	MENU_END();
 }
 }
 #endif //EXPERIMENTAL_FEATURES
 #endif //EXPERIMENTAL_FEATURES
 
 
 
 
 static void lcd_calibration_menu()
 static void lcd_calibration_menu()
 {
 {
-  START_MENU();
-  MENU_ITEM(back, _T(MSG_MAIN), 0);
+  MENU_BEGIN();
+  MENU_ITEM_BACK_P(_T(MSG_MAIN));
   if (!isPrintPaused)
   if (!isPrintPaused)
   {
   {
-	MENU_ITEM(function, _i("Wizard"), lcd_wizard);////MSG_WIZARD c=17 r=1
-	MENU_ITEM(submenu, _i("First layer cal."), lcd_v2_calibration);////MSG_V2_CALIBRATION c=17 r=1
-	MENU_ITEM(gcode, _T(MSG_AUTO_HOME), PSTR("G28 W"));
-	MENU_ITEM(function, _i("Selftest         "), lcd_selftest_v);////MSG_SELFTEST c=0 r=0
+	MENU_ITEM_FUNCTION_P(_i("Wizard"), lcd_wizard);////MSG_WIZARD c=17 r=1
+	MENU_ITEM_SUBMENU_P(_i("First layer cal."), lcd_v2_calibration);////MSG_V2_CALIBRATION c=17 r=1
+	MENU_ITEM_GCODE_P(_T(MSG_AUTO_HOME), PSTR("G28 W"));
+	MENU_ITEM_FUNCTION_P(_i("Selftest         "), lcd_selftest_v);////MSG_SELFTEST c=0 r=0
 #ifdef MK1BP
 #ifdef MK1BP
     // MK1
     // MK1
     // "Calibrate Z"
     // "Calibrate Z"
-    MENU_ITEM(gcode, _T(MSG_HOMEYZ), PSTR("G28 Z"));
+    MENU_ITEM_GCODE_P(_T(MSG_HOMEYZ), PSTR("G28 Z"));
 #else //MK1BP
 #else //MK1BP
     // MK2
     // MK2
-    MENU_ITEM(function, _i("Calibrate XYZ"), lcd_mesh_calibration);////MSG_CALIBRATE_BED c=0 r=0
+    MENU_ITEM_FUNCTION_P(_i("Calibrate XYZ"), lcd_mesh_calibration);////MSG_CALIBRATE_BED c=0 r=0
     // "Calibrate Z" with storing the reference values to EEPROM.
     // "Calibrate Z" with storing the reference values to EEPROM.
-    MENU_ITEM(submenu, _T(MSG_HOMEYZ), lcd_mesh_calibration_z);
+    MENU_ITEM_SUBMENU_P(_T(MSG_HOMEYZ), lcd_mesh_calibration_z);
 #ifndef SNMM
 #ifndef SNMM
-	//MENU_ITEM(function, _i("Calibrate E"), lcd_calibrate_extruder);////MSG_CALIBRATE_E c=20 r=1
+	//MENU_ITEM_FUNCTION_P(_i("Calibrate E"), lcd_calibrate_extruder);////MSG_CALIBRATE_E c=20 r=1
 #endif
 #endif
     // "Mesh Bed Leveling"
     // "Mesh Bed Leveling"
-    MENU_ITEM(submenu, _i("Mesh Bed Leveling"), lcd_mesh_bedleveling);////MSG_MESH_BED_LEVELING c=0 r=0
+    MENU_ITEM_SUBMENU_P(_i("Mesh Bed Leveling"), lcd_mesh_bedleveling);////MSG_MESH_BED_LEVELING c=0 r=0
 	
 	
 #endif //MK1BP
 #endif //MK1BP
 
 
-    MENU_ITEM(submenu, _i("Bed level correct"), lcd_adjust_bed);////MSG_BED_CORRECTION_MENU c=0 r=0
-	MENU_ITEM(submenu, _i("PID calibration"), pid_extruder);////MSG_PID_EXTRUDER c=17 r=1
+    MENU_ITEM_SUBMENU_P(_i("Bed level correct"), lcd_adjust_bed);////MSG_BED_CORRECTION_MENU c=0 r=0
+	MENU_ITEM_SUBMENU_P(_i("PID calibration"), pid_extruder);////MSG_PID_EXTRUDER c=17 r=1
 #ifndef TMC2130
 #ifndef TMC2130
-    MENU_ITEM(submenu, _i("Show end stops"), menu_show_end_stops);////MSG_SHOW_END_STOPS c=17 r=1
+    MENU_ITEM_SUBMENU_P(_i("Show end stops"), menu_show_end_stops);////MSG_SHOW_END_STOPS c=17 r=1
 #endif
 #endif
 #ifndef MK1BP
 #ifndef MK1BP
-    MENU_ITEM(gcode, _i("Reset XYZ calibr."), PSTR("M44"));////MSG_CALIBRATE_BED_RESET c=0 r=0
+    MENU_ITEM_GCODE_P(_i("Reset XYZ calibr."), PSTR("M44"));////MSG_CALIBRATE_BED_RESET c=0 r=0
 #endif //MK1BP
 #endif //MK1BP
 #ifndef SNMM
 #ifndef SNMM
-	//MENU_ITEM(function, MSG_RESET_CALIBRATE_E, lcd_extr_cal_reset);
+	//MENU_ITEM_FUNCTION_P(MSG_RESET_CALIBRATE_E, lcd_extr_cal_reset);
 #endif
 #endif
 #ifndef MK1BP
 #ifndef MK1BP
-	MENU_ITEM(submenu, _i("Temp. calibration"), lcd_pinda_calibration_menu);////MSG_CALIBRATION_PINDA_MENU c=17 r=1
+	MENU_ITEM_SUBMENU_P(_i("Temp. calibration"), lcd_pinda_calibration_menu);////MSG_CALIBRATION_PINDA_MENU c=17 r=1
 #endif //MK1BP
 #endif //MK1BP
   }
   }
   
   
-  END_MENU();
+  MENU_END();
 }
 }
 
 
 void bowden_menu() {
 void bowden_menu() {
@@ -5135,39 +5384,39 @@ static void extr_unload_3() {
 
 
 static void fil_load_menu()
 static void fil_load_menu()
 {
 {
-	START_MENU();
-	MENU_ITEM(back, _T(MSG_MAIN), 0);
-	MENU_ITEM(function, _i("Load all"), load_all);////MSG_LOAD_ALL c=0 r=0
-	MENU_ITEM(function, _i("Load filament 1"), extr_adj_0);////MSG_LOAD_FILAMENT_1 c=17 r=0
-	MENU_ITEM(function, _i("Load filament 2"), extr_adj_1);////MSG_LOAD_FILAMENT_2 c=17 r=0
-	MENU_ITEM(function, _i("Load filament 3"), extr_adj_2);////MSG_LOAD_FILAMENT_3 c=17 r=0
-	MENU_ITEM(function, _i("Load filament 4"), extr_adj_3);////MSG_LOAD_FILAMENT_4 c=17 r=0
+	MENU_BEGIN();
+	MENU_ITEM_BACK_P(_T(MSG_MAIN));
+	MENU_ITEM_FUNCTION_P(_i("Load all"), load_all);////MSG_LOAD_ALL c=0 r=0
+	MENU_ITEM_FUNCTION_P(_i("Load filament 1"), extr_adj_0);////MSG_LOAD_FILAMENT_1 c=17 r=0
+	MENU_ITEM_FUNCTION_P(_i("Load filament 2"), extr_adj_1);////MSG_LOAD_FILAMENT_2 c=17 r=0
+	MENU_ITEM_FUNCTION_P(_i("Load filament 3"), extr_adj_2);////MSG_LOAD_FILAMENT_3 c=17 r=0
+	MENU_ITEM_FUNCTION_P(_i("Load filament 4"), extr_adj_3);////MSG_LOAD_FILAMENT_4 c=17 r=0
 	
 	
-	END_MENU();
+	MENU_END();
 }
 }
 
 
 static void fil_unload_menu()
 static void fil_unload_menu()
 {
 {
-	START_MENU();
-	MENU_ITEM(back, _T(MSG_MAIN), 0);
-	MENU_ITEM(function, _i("Unload all"), extr_unload_all);////MSG_UNLOAD_ALL c=0 r=0
-	MENU_ITEM(function, _i("Unload filament 1"), extr_unload_0);////MSG_UNLOAD_FILAMENT_1 c=17 r=0
-	MENU_ITEM(function, _i("Unload filament 2"), extr_unload_1);////MSG_UNLOAD_FILAMENT_2 c=17 r=0
-	MENU_ITEM(function, _i("Unload filament 3"), extr_unload_2);////MSG_UNLOAD_FILAMENT_3 c=17 r=0
-	MENU_ITEM(function, _i("Unload filament 4"), extr_unload_3);////MSG_UNLOAD_FILAMENT_4 c=17 r=0
+	MENU_BEGIN();
+	MENU_ITEM_BACK_P(_T(MSG_MAIN));
+	MENU_ITEM_FUNCTION_P(_i("Unload all"), extr_unload_all);////MSG_UNLOAD_ALL c=0 r=0
+	MENU_ITEM_FUNCTION_P(_i("Unload filament 1"), extr_unload_0);////MSG_UNLOAD_FILAMENT_1 c=17 r=0
+	MENU_ITEM_FUNCTION_P(_i("Unload filament 2"), extr_unload_1);////MSG_UNLOAD_FILAMENT_2 c=17 r=0
+	MENU_ITEM_FUNCTION_P(_i("Unload filament 3"), extr_unload_2);////MSG_UNLOAD_FILAMENT_3 c=17 r=0
+	MENU_ITEM_FUNCTION_P(_i("Unload filament 4"), extr_unload_3);////MSG_UNLOAD_FILAMENT_4 c=17 r=0
 
 
-	END_MENU();
+	MENU_END();
 }
 }
 
 
 static void change_extr_menu(){
 static void change_extr_menu(){
-	START_MENU();
-	MENU_ITEM(back, _T(MSG_MAIN), 0);
-	MENU_ITEM(function, _i("Extruder 1"), extr_change_0);////MSG_EXTRUDER_1 c=17 r=1
-	MENU_ITEM(function, _i("Extruder 2"), extr_change_1);////MSG_EXTRUDER_2 c=17 r=1
-	MENU_ITEM(function, _i("Extruder 3"), extr_change_2);////MSG_EXTRUDER_3 c=17 r=1
-	MENU_ITEM(function, _i("Extruder 4"), extr_change_3);////MSG_EXTRUDER_4 c=17 r=1
+	MENU_BEGIN();
+	MENU_ITEM_BACK_P(_T(MSG_MAIN));
+	MENU_ITEM_FUNCTION_P(_i("Extruder 1"), extr_change_0);////MSG_EXTRUDER_1 c=17 r=1
+	MENU_ITEM_FUNCTION_P(_i("Extruder 2"), extr_change_1);////MSG_EXTRUDER_2 c=17 r=1
+	MENU_ITEM_FUNCTION_P(_i("Extruder 3"), extr_change_2);////MSG_EXTRUDER_3 c=17 r=1
+	MENU_ITEM_FUNCTION_P(_i("Extruder 4"), extr_change_3);////MSG_EXTRUDER_4 c=17 r=1
 
 
-	END_MENU();
+	MENU_END();
 }
 }
 
 
 #endif
 #endif
@@ -5415,23 +5664,23 @@ static void lcd_main_menu()
 {
 {
 
 
   SDscrool = 0;
   SDscrool = 0;
-  START_MENU();
+  MENU_BEGIN();
 
 
   // Majkl superawesome menu
   // Majkl superawesome menu
 
 
 
 
- MENU_ITEM(back, _T(MSG_WATCH), 0);
+ MENU_ITEM_BACK_P(_T(MSG_WATCH));
 
 
 #ifdef RESUME_DEBUG 
 #ifdef RESUME_DEBUG 
  if (!saved_printing) 
  if (!saved_printing) 
-  MENU_ITEM(function, PSTR("tst - Save"), lcd_menu_test_save);
+  MENU_ITEM_FUNCTION_P(PSTR("tst - Save"), lcd_menu_test_save);
  else
  else
-  MENU_ITEM(function, PSTR("tst - Restore"), lcd_menu_test_restore);
+  MENU_ITEM_FUNCTION_P(PSTR("tst - Restore"), lcd_menu_test_restore);
 #endif //RESUME_DEBUG 
 #endif //RESUME_DEBUG 
 
 
 #ifdef TMC2130_DEBUG
 #ifdef TMC2130_DEBUG
- MENU_ITEM(function, PSTR("recover print"), recover_print);
- MENU_ITEM(function, PSTR("power panic"), uvlo_);
+ MENU_ITEM_FUNCTION_P(PSTR("recover print"), recover_print);
+ MENU_ITEM_FUNCTION_P(PSTR("power panic"), uvlo_);
 #endif //TMC2130_DEBUG
 #endif //TMC2130_DEBUG
 
 
  /* if (farm_mode && !IS_SD_PRINTING )
  /* if (farm_mode && !IS_SD_PRINTING )
@@ -5447,10 +5696,10 @@ static void lcd_main_menu()
         if (card.filename[0] == '/')
         if (card.filename[0] == '/')
         {
         {
 #if SDCARDDETECT == -1
 #if SDCARDDETECT == -1
-            MENU_ITEM(function, _T(MSG_REFRESH), lcd_sd_refresh);
+            MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh);
 #endif
 #endif
         } else {
         } else {
-            MENU_ITEM(function, PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir);
+            MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir);
         }
         }
         
         
         for (uint16_t i = 0; i < fileCnt; i++)
         for (uint16_t i = 0; i < fileCnt; i++)
@@ -5464,10 +5713,10 @@ static void lcd_main_menu()
 #endif
 #endif
                 if (card.filenameIsDir)
                 if (card.filenameIsDir)
                 {
                 {
-                    MENU_ITEM(sddirectory, _T(MSG_CARD_MENU), card.filename, card.longFilename);
+                    MENU_ITEM_SDDIR(_T(MSG_CARD_MENU), card.filename, card.longFilename);
                 } else {
                 } else {
                     
                     
-                    MENU_ITEM(sdfile, _T(MSG_CARD_MENU), card.filename, card.longFilename);
+                    MENU_ITEM_SDFILE(_T(MSG_CARD_MENU), card.filename, card.longFilename);
                     
                     
                     
                     
                     
                     
@@ -5478,23 +5727,23 @@ static void lcd_main_menu()
             }
             }
         }
         }
         
         
-        MENU_ITEM(back, PSTR("- - - - - - - - -"), 0);
+        MENU_ITEM_BACK_P(PSTR("- - - - - - - - -"));
     
     
         
         
     }*/
     }*/
     
     
   if ( ( IS_SD_PRINTING || is_usb_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL)) && (current_position[Z_AXIS] < Z_HEIGHT_HIDE_LIVE_ADJUST_MENU) && !homing_flag && !mesh_bed_leveling_flag)
   if ( ( IS_SD_PRINTING || is_usb_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL)) && (current_position[Z_AXIS] < Z_HEIGHT_HIDE_LIVE_ADJUST_MENU) && !homing_flag && !mesh_bed_leveling_flag)
   {
   {
-	MENU_ITEM(submenu, _T(MSG_BABYSTEP_Z), lcd_babystep_z);//8
+	MENU_ITEM_SUBMENU_P(_T(MSG_BABYSTEP_Z), lcd_babystep_z);//8
   }
   }
 
 
 
 
   if ( moves_planned() || IS_SD_PRINTING || is_usb_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL))
   if ( moves_planned() || IS_SD_PRINTING || is_usb_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL))
   {
   {
-    MENU_ITEM(submenu, _i("Tune"), lcd_tune_menu);////MSG_TUNE c=0 r=0
+    MENU_ITEM_SUBMENU_P(_i("Tune"), lcd_tune_menu);////MSG_TUNE c=0 r=0
   } else 
   } else 
   {
   {
-    MENU_ITEM(submenu, _i("Preheat"), lcd_preheat_menu);////MSG_PREHEAT c=0 r=0
+    MENU_ITEM_SUBMENU_P(_i("Preheat"), lcd_preheat_menu);////MSG_PREHEAT c=0 r=0
   }
   }
 
 
 #ifdef SDSUPPORT
 #ifdef SDSUPPORT
@@ -5505,35 +5754,35 @@ static void lcd_main_menu()
 		if (mesh_bed_leveling_flag == false && homing_flag == false) {
 		if (mesh_bed_leveling_flag == false && homing_flag == false) {
 			if (card.sdprinting)
 			if (card.sdprinting)
 			{
 			{
-				MENU_ITEM(function, _i("Pause print"), lcd_sdcard_pause);////MSG_PAUSE_PRINT c=0 r=0
+				MENU_ITEM_FUNCTION_P(_i("Pause print"), lcd_sdcard_pause);////MSG_PAUSE_PRINT c=0 r=0
 			}
 			}
 			else
 			else
 			{
 			{
-				MENU_ITEM(function, _i("Resume print"), lcd_sdcard_resume);////MSG_RESUME_PRINT c=0 r=0
+				MENU_ITEM_FUNCTION_P(_i("Resume print"), lcd_sdcard_resume);////MSG_RESUME_PRINT c=0 r=0
 			}
 			}
-			MENU_ITEM(submenu, _T(MSG_STOP_PRINT), lcd_sdcard_stop);
+			MENU_ITEM_SUBMENU_P(_T(MSG_STOP_PRINT), lcd_sdcard_stop);
 		}
 		}
 	}
 	}
 	else if (lcd_commands_type == LCD_COMMAND_V2_CAL && mesh_bed_leveling_flag == false && homing_flag == false) {
 	else if (lcd_commands_type == LCD_COMMAND_V2_CAL && mesh_bed_leveling_flag == false && homing_flag == false) {
-		//MENU_ITEM(submenu, _T(MSG_STOP_PRINT), lcd_sdcard_stop);
+		//MENU_ITEM_SUBMENU_P(_T(MSG_STOP_PRINT), lcd_sdcard_stop);
 	}
 	}
 	else
 	else
 	{
 	{
 		if (!is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL))
 		if (!is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL))
 		{
 		{
-			//if (farm_mode) MENU_ITEM(submenu, MSG_FARM_CARD_MENU, lcd_farm_sdcard_menu);
-			/*else*/ MENU_ITEM(submenu, _T(MSG_CARD_MENU), lcd_sdcard_menu);
+			//if (farm_mode) MENU_ITEM_SUBMENU_P(MSG_FARM_CARD_MENU, lcd_farm_sdcard_menu);
+			/*else*/ MENU_ITEM_SUBMENU_P(_T(MSG_CARD_MENU), lcd_sdcard_menu);
 		}
 		}
 #if SDCARDDETECT < 1
 #if SDCARDDETECT < 1
-      MENU_ITEM(gcode, _i("Change SD card"), PSTR("M21"));  // SD-card changed by user////MSG_CNG_SDCARD c=0 r=0
+      MENU_ITEM_GCODE_P(_i("Change SD card"), PSTR("M21"));  // SD-card changed by user////MSG_CNG_SDCARD c=0 r=0
 #endif
 #endif
     }
     }
 	
 	
   } else 
   } else 
   {
   {
-    MENU_ITEM(submenu, _i("No SD card"), lcd_sdcard_menu);////MSG_NO_CARD c=0 r=0
+    MENU_ITEM_SUBMENU_P(_i("No SD card"), lcd_sdcard_menu);////MSG_NO_CARD c=0 r=0
 #if SDCARDDETECT < 1
 #if SDCARDDETECT < 1
-    MENU_ITEM(gcode, _i("Init. SD card"), PSTR("M21")); // Manually initialize the SD-card via user interface////MSG_INIT_SDCARD c=0 r=0
+    MENU_ITEM_GCODE_P(_i("Init. SD card"), PSTR("M21")); // Manually initialize the SD-card via user interface////MSG_INIT_SDCARD c=0 r=0
 #endif
 #endif
   }
   }
 #endif
 #endif
@@ -5543,7 +5792,7 @@ static void lcd_main_menu()
   {
   {
 	  if (farm_mode)
 	  if (farm_mode)
 	  {
 	  {
-		  MENU_ITEM(submenu, PSTR("Farm number"), lcd_farm_no);
+		  MENU_ITEM_SUBMENU_P(PSTR("Farm number"), lcd_farm_no);
 	  }
 	  }
   } 
   } 
   else 
   else 
@@ -5551,38 +5800,39 @@ static void lcd_main_menu()
 	#ifndef SNMM
 	#ifndef SNMM
 #ifdef PAT9125
 #ifdef PAT9125
 	if ( ((filament_autoload_enabled == true) && (fsensor_enabled == true)))
 	if ( ((filament_autoload_enabled == true) && (fsensor_enabled == true)))
-        MENU_ITEM(submenu, _i("AutoLoad filament"), lcd_menu_AutoLoadFilament);////MSG_AUTOLOAD_FILAMENT c=17 r=0
+        MENU_ITEM_SUBMENU_P(_i("AutoLoad filament"), lcd_menu_AutoLoadFilament);////MSG_AUTOLOAD_FILAMENT c=17 r=0
 	else
 	else
 #endif //PAT9125
 #endif //PAT9125
-		MENU_ITEM(function, _T(MSG_LOAD_FILAMENT), lcd_LoadFilament);
-	MENU_ITEM(submenu, _T(MSG_UNLOAD_FILAMENT), lcd_unLoadFilament);
+		MENU_ITEM_FUNCTION_P(_T(MSG_LOAD_FILAMENT), lcd_LoadFilament);
+	MENU_ITEM_SUBMENU_P(_T(MSG_UNLOAD_FILAMENT), lcd_unLoadFilament);
 	#endif
 	#endif
 	#ifdef SNMM
 	#ifdef SNMM
-	MENU_ITEM(submenu, _T(MSG_LOAD_FILAMENT), fil_load_menu);
-	MENU_ITEM(submenu, _T(MSG_UNLOAD_FILAMENT), fil_unload_menu);
-	MENU_ITEM(submenu, _i("Change extruder"), change_extr_menu);////MSG_CHANGE_EXTR c=20 r=1
+	MENU_ITEM_SUBMENU_P(_T(MSG_LOAD_FILAMENT), fil_load_menu);
+	MENU_ITEM_SUBMENU_P(_T(MSG_UNLOAD_FILAMENT), fil_unload_menu);
+	MENU_ITEM_SUBMENU_P(_i("Change extruder"), change_extr_menu);////MSG_CHANGE_EXTR c=20 r=1
 	#endif
 	#endif
-	MENU_ITEM(submenu, _T(MSG_SETTINGS), lcd_settings_menu);
-    if(!isPrintPaused) MENU_ITEM(submenu, _T(MSG_MENU_CALIBRATION), lcd_calibration_menu);
+	MENU_ITEM_SUBMENU_P(_T(MSG_SETTINGS), lcd_settings_menu);
+    if(!isPrintPaused) MENU_ITEM_SUBMENU_P(_T(MSG_MENU_CALIBRATION), lcd_calibration_menu);
 
 
 #ifdef EXPERIMENTAL_FEATURES
 #ifdef EXPERIMENTAL_FEATURES
-	MENU_ITEM(submenu, PSTR("Experimantal"), lcd_experimantal_menu);
+	MENU_ITEM_SUBMENU_P(PSTR("Experimantal"), lcd_experimantal_menu);
 #endif //EXPERIMENTAL_FEATURES
 #endif //EXPERIMENTAL_FEATURES
   }
   }
 
 
   if (!is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL))
   if (!is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL))
   {
   {
-	  MENU_ITEM(submenu, _i("Statistics  "), lcd_menu_statistics);////MSG_STATISTICS c=0 r=0
+	  MENU_ITEM_SUBMENU_P(_i("Statistics  "), lcd_menu_statistics);////MSG_STATISTICS c=0 r=0
   }
   }
     
     
 #if defined(TMC2130) || defined(PAT9125)
 #if defined(TMC2130) || defined(PAT9125)
-  MENU_ITEM(submenu, PSTR("Fail stats"), lcd_menu_fails_stats);
+  MENU_ITEM_SUBMENU_P(PSTR("Fail stats"), lcd_menu_fails_stats);
 #endif
 #endif
 
 
-  MENU_ITEM(submenu, _i("Support"), lcd_support_menu);////MSG_SUPPORT c=0 r=0
-  MENU_ITEM(submenu, _i("W25x20XL init"), lcd_test_menu);////MSG_SUPPORT c=0 r=0
+  MENU_ITEM_SUBMENU_P(_i("Support"), lcd_support_menu);////MSG_SUPPORT c=0 r=0
 
 
-  END_MENU();
+  MENU_ITEM_SUBMENU_P(_i("W25x20CL init"), lcd_test_menu);////MSG_SUPPORT c=0 r=0
+
+  MENU_END();
 
 
 }
 }
 
 
@@ -5642,7 +5892,7 @@ static void lcd_silent_mode_set_tune() {
   }
   }
   eeprom_update_byte((unsigned char *)EEPROM_SILENT, SilentModeMenu);
   eeprom_update_byte((unsigned char *)EEPROM_SILENT, SilentModeMenu);
   st_current_init();
   st_current_init();
-  menu_action_back();
+  menu_back();
 }
 }
 
 
 static void lcd_colorprint_change() {
 static void lcd_colorprint_change() {
@@ -5672,8 +5922,8 @@ static void lcd_tune_menu()
 
 
 
 
 
 
-	START_MENU();
-	MENU_ITEM(back, _T(MSG_MAIN), 0); //1
+	MENU_BEGIN();
+	MENU_ITEM_BACK_P(_T(MSG_MAIN)); //1
 	MENU_ITEM_EDIT(int3, _i("Speed"), &feedmultiply, 10, 999);//2////MSG_SPEED c=0 r=0
 	MENU_ITEM_EDIT(int3, _i("Speed"), &feedmultiply, 10, 999);//2////MSG_SPEED c=0 r=0
 
 
 	MENU_ITEM_EDIT(int3, _T(MSG_NOZZLE), &target_temperature[0], 0, HEATER_0_MAXTEMP - 10);//3
 	MENU_ITEM_EDIT(int3, _T(MSG_NOZZLE), &target_temperature[0], 0, HEATER_0_MAXTEMP - 10);//3
@@ -5682,16 +5932,16 @@ static void lcd_tune_menu()
 	MENU_ITEM_EDIT(int3, _T(MSG_FAN_SPEED), &fanSpeed, 0, 255);//5
 	MENU_ITEM_EDIT(int3, _T(MSG_FAN_SPEED), &fanSpeed, 0, 255);//5
 	MENU_ITEM_EDIT(int3, _i("Flow"), &extrudemultiply, 10, 999);//6////MSG_FLOW c=0 r=0
 	MENU_ITEM_EDIT(int3, _i("Flow"), &extrudemultiply, 10, 999);//6////MSG_FLOW c=0 r=0
 #ifdef FILAMENTCHANGEENABLE
 #ifdef FILAMENTCHANGEENABLE
-	MENU_ITEM(function, _T(MSG_FILAMENTCHANGE), lcd_colorprint_change);//7
+	MENU_ITEM_FUNCTION_P(_T(MSG_FILAMENTCHANGE), lcd_colorprint_change);//7
 #endif
 #endif
 
 
 #ifndef DEBUG_DISABLE_FSENSORCHECK
 #ifndef DEBUG_DISABLE_FSENSORCHECK
 #ifdef PAT9125
 #ifdef PAT9125
 	if (FSensorStateMenu == 0) {
 	if (FSensorStateMenu == 0) {
-		MENU_ITEM(function, _T(MSG_FSENSOR_OFF), lcd_fsensor_state_set);
+		MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_OFF), lcd_fsensor_state_set);
 	}
 	}
 	else {
 	else {
-		MENU_ITEM(function, _T(MSG_FSENSOR_ON), lcd_fsensor_state_set);
+		MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_ON), lcd_fsensor_state_set);
 	}
 	}
 #endif //PAT9125
 #endif //PAT9125
 #endif //DEBUG_DISABLE_FSENSORCHECK
 #endif //DEBUG_DISABLE_FSENSORCHECK
@@ -5699,27 +5949,27 @@ static void lcd_tune_menu()
 #ifdef TMC2130
 #ifdef TMC2130
      if(!farm_mode)
      if(!farm_mode)
      {
      {
-          if (SilentModeMenu == SILENT_MODE_NORMAL) MENU_ITEM(function, _T(MSG_STEALTH_MODE_OFF), lcd_silent_mode_set);
-          else MENU_ITEM(function, _T(MSG_STEALTH_MODE_ON), lcd_silent_mode_set);
+          if (SilentModeMenu == SILENT_MODE_NORMAL) MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_OFF), lcd_silent_mode_set);
+          else MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_ON), lcd_silent_mode_set);
 
 
           if (SilentModeMenu == SILENT_MODE_NORMAL)
           if (SilentModeMenu == SILENT_MODE_NORMAL)
           {
           {
-               if (CrashDetectMenu == 0) MENU_ITEM(function, _T(MSG_CRASHDETECT_OFF), lcd_crash_mode_set);
-               else MENU_ITEM(function, _T(MSG_CRASHDETECT_ON), lcd_crash_mode_set);
+               if (CrashDetectMenu == 0) MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_OFF), lcd_crash_mode_set);
+               else MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_ON), lcd_crash_mode_set);
           }
           }
-          else MENU_ITEM(submenu, _T(MSG_CRASHDETECT_NA), lcd_crash_mode_info);
+          else MENU_ITEM_SUBMENU_P(_T(MSG_CRASHDETECT_NA), lcd_crash_mode_info);
      }
      }
 #else //TMC2130
 #else //TMC2130
 	if (!farm_mode) { //dont show in menu if we are in farm mode
 	if (!farm_mode) { //dont show in menu if we are in farm mode
 		switch (SilentModeMenu) {
 		switch (SilentModeMenu) {
-		case SILENT_MODE_POWER: MENU_ITEM(function, _T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break;
-		case SILENT_MODE_SILENT: MENU_ITEM(function, _T(MSG_SILENT_MODE_ON), lcd_silent_mode_set); break;
-		case SILENT_MODE_AUTO: MENU_ITEM(function, _T(MSG_AUTO_MODE_ON), lcd_silent_mode_set); break;
-		default: MENU_ITEM(function, _T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break; // (probably) not needed
+		case SILENT_MODE_POWER: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break;
+		case SILENT_MODE_SILENT: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_ON), lcd_silent_mode_set); break;
+		case SILENT_MODE_AUTO: MENU_ITEM_FUNCTION_P(_T(MSG_AUTO_MODE_ON), lcd_silent_mode_set); break;
+		default: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break; // (probably) not needed
 		}
 		}
 	}
 	}
 #endif //TMC2130
 #endif //TMC2130
-	END_MENU();
+	MENU_END();
 }
 }
 
 
 static void lcd_move_menu_01mm()
 static void lcd_move_menu_01mm()
@@ -5736,8 +5986,8 @@ static void lcd_control_temperature_menu()
 //  raw_Kd = unscalePID_d(Kd);
 //  raw_Kd = unscalePID_d(Kd);
 #endif
 #endif
 
 
-  START_MENU();
-  MENU_ITEM(back, _T(MSG_SETTINGS), 0);
+  MENU_BEGIN();
+  MENU_ITEM_BACK_P(_T(MSG_SETTINGS));
 #if TEMP_SENSOR_0 != 0
 #if TEMP_SENSOR_0 != 0
   MENU_ITEM_EDIT(int3, _T(MSG_NOZZLE), &target_temperature[0], 0, HEATER_0_MAXTEMP - 10);
   MENU_ITEM_EDIT(int3, _T(MSG_NOZZLE), &target_temperature[0], 0, HEATER_0_MAXTEMP - 10);
 #endif
 #endif
@@ -5758,7 +6008,7 @@ static void lcd_control_temperature_menu()
   MENU_ITEM_EDIT(float32, _i(" \002 Fact"), &autotemp_factor, 0.0, 1.0);////MSG_FACTOR c=0 r=0
   MENU_ITEM_EDIT(float32, _i(" \002 Fact"), &autotemp_factor, 0.0, 1.0);////MSG_FACTOR c=0 r=0
 #endif
 #endif
 
 
-  END_MENU();
+  MENU_END();
 }
 }
 
 
 
 
@@ -5874,6 +6124,7 @@ void getFileDescription(char *name, char *description) {
 
 
 void lcd_sdcard_menu()
 void lcd_sdcard_menu()
 {
 {
+  printf_P(_N("menu sd\n"));
   uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT);
   uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT);
   int tempScrool = 0;
   int tempScrool = 0;
   if (presort_flag == true) {
   if (presort_flag == true) {
@@ -5885,16 +6136,17 @@ void lcd_sdcard_menu()
     return; // nothing to do (so don't thrash the SD card)
     return; // nothing to do (so don't thrash the SD card)
   uint16_t fileCnt = card.getnrfilenames();
   uint16_t fileCnt = card.getnrfilenames();
 
 
-  START_MENU();
-  MENU_ITEM(back, _T(MSG_MAIN), 0);
+
+  MENU_BEGIN();
+  MENU_ITEM_BACK_P(_T(MSG_MAIN));
   card.getWorkDirName();
   card.getWorkDirName();
   if (card.filename[0] == '/')
   if (card.filename[0] == '/')
   {
   {
 #if SDCARDDETECT == -1
 #if SDCARDDETECT == -1
-    MENU_ITEM(function, _T(MSG_REFRESH), lcd_sd_refresh);
+    MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh);
 #endif
 #endif
   } else {
   } else {
-    MENU_ITEM(function, PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir);
+    MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir);
   }
   }
 
 
   for (uint16_t i = 0; i < fileCnt; i++)
   for (uint16_t i = 0; i < fileCnt; i++)
@@ -5916,14 +6168,14 @@ void lcd_sdcard_menu()
 		#endif
 		#endif
 			
 			
 		if (card.filenameIsDir)
 		if (card.filenameIsDir)
-			MENU_ITEM(sddirectory, _T(MSG_CARD_MENU), card.filename, card.longFilename);
+			MENU_ITEM_SDDIR(_T(MSG_CARD_MENU), card.filename, card.longFilename);
 		else
 		else
-			MENU_ITEM(sdfile, _T(MSG_CARD_MENU), card.filename, card.longFilename);
+			MENU_ITEM_SDFILE(_T(MSG_CARD_MENU), card.filename, card.longFilename);
     } else {
     } else {
       MENU_ITEM_DUMMY();
       MENU_ITEM_DUMMY();
     }
     }
   }
   }
-  END_MENU();
+  MENU_END();
 }
 }
 
 
 //char description [10] [31];
 //char description [10] [31];
@@ -5952,17 +6204,17 @@ void lcd_sdcard_menu()
 			return; // nothing to do (so don't thrash the SD card)
 			return; // nothing to do (so don't thrash the SD card)
 		uint16_t fileCnt = card.getnrfilenames();
 		uint16_t fileCnt = card.getnrfilenames();
 
 
-		START_MENU();
-		MENU_ITEM(back, _T(MSG_MAIN), 0);
+		MENU_BEGIN();
+		MENU_ITEM_BACK_P(_T(MSG_MAIN));
 		card.getWorkDirName();
 		card.getWorkDirName();
 		if (card.filename[0] == '/')
 		if (card.filename[0] == '/')
 		{
 		{
 #if SDCARDDETECT == -1
 #if SDCARDDETECT == -1
-			MENU_ITEM(function, _T(MSG_REFRESH), lcd_sd_refresh);
+			MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh);
 #endif
 #endif
 		}
 		}
 		else {
 		else {
-			MENU_ITEM(function, PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir);
+			MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir);
 		}
 		}
 
 
 
 
@@ -5978,18 +6230,18 @@ void lcd_sdcard_menu()
 #endif
 #endif
 				if (card.filenameIsDir)
 				if (card.filenameIsDir)
 				{
 				{
-					MENU_ITEM(sddirectory, _T(MSG_CARD_MENU), card.filename, card.longFilename);
+					MENU_ITEM_SDDIR(_T(MSG_CARD_MENU), card.filename, card.longFilename);
 				}
 				}
 				else {
 				else {
 					
 					
-					MENU_ITEM(sdfile, _T(MSG_CARD_MENU), card.filename, description[i]);
+					MENU_ITEM_SDFILE(_T(MSG_CARD_MENU), card.filename, description[i]);
 				}
 				}
 			}
 			}
 			else {
 			else {
 				MENU_ITEM_DUMMY();
 				MENU_ITEM_DUMMY();
 			}
 			}
 		}
 		}
-		END_MENU();
+		MENU_END();
 
 
 }*/
 }*/
 
 
@@ -7063,47 +7315,6 @@ static void lcd_quick_feedback()
 
 
 /** Menu action functions **/
 /** Menu action functions **/
 
 
-/**
- * @brief Go up in menu structure
- * @param data one time action to be done before leaving menu e.g. saving data or 0
- */
-static void menu_action_back(menuFunc_t data)
-{
-    if (data) data();
-    MenuStack::Record record = menuStack.pop();
-    lcd_goto_menu(record.menu);
-    encoderPosition = record.position;
-}
-/**
- * @brief Go deeper into menu structure
- * @param data nested menu
- */
-static void menu_action_submenu(menuFunc_t data) {
-  menuStack.push(currentMenu, encoderPosition);
-  lcd_goto_menu(data);
-}
-static void menu_action_gcode(const char* pgcode) {
-  enquecommand_P(pgcode);
-}
-
-static void menu_action_setlang(unsigned char lang)
-{
-	if (!lang_select(lang))
-	{
-		if (lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Copy selected language from XFLASH?"), false, true))
-			lang_boot_update_start(lang);
-		lcd_update_enable(true);
-		lcd_implementation_clear();
-		lcd_goto_menu(lcd_language_menu);
-		lcd_timeoutToStatus.stop(); //infinite timeout
-		lcdDrawUpdate = 2;
-	}
-}
-
-static void menu_action_function(menuFunc_t data) {
-  (*data)();
-}
-
 static bool check_file(const char* filename) {
 static bool check_file(const char* filename) {
 	if (farm_mode) return true;
 	if (farm_mode) return true;
 	bool result = false;
 	bool result = false;
@@ -7434,7 +7645,9 @@ static void lcd_send_status() {
 		//send important status messages periodicaly
 		//send important status messages periodicaly
 		prusa_statistics(important_status, saved_filament_type);
 		prusa_statistics(important_status, saved_filament_type);
 		NcTime = millis();
 		NcTime = millis();
+#ifdef FARM_CONNECT_MESSAGE
 		lcd_connect_printer();
 		lcd_connect_printer();
+#endif //FARM_CONNECT_MESSAGE
 	}
 	}
 }
 }
 
 
@@ -7576,7 +7789,7 @@ void lcd_buttons_update()
 				  if (longPressTimer.expired(LONG_PRESS_TIME)) {
 				  if (longPressTimer.expired(LONG_PRESS_TIME)) {
 					  long_press_active = true;
 					  long_press_active = true;
 					  move_menu_scale = 1.0;
 					  move_menu_scale = 1.0;
-					  menu_action_submenu(lcd_move_z);
+					  menu_submenu(lcd_move_z);
 				  }
 				  }
 			  }
 			  }
 		  }
 		  }

+ 11 - 16
Firmware/ultralcd_implementation_hitachi_HD44780.h

@@ -699,7 +699,7 @@ static inline void lcd_print_percent_done() {
 	{
 	{
 		lcd_printPGM(PSTR("---"));
 		lcd_printPGM(PSTR("---"));
 	}
 	}
-	lcd.print('%');
+	lcd_printPGM(PSTR("% "));
 }
 }
 
 
 static inline void lcd_print_time() {
 static inline void lcd_print_time() {
@@ -718,8 +718,14 @@ static inline void lcd_print_time() {
 		lcd.print(itostr2(print_t/60));
 		lcd.print(itostr2(print_t/60));
         lcd.print(':');
         lcd.print(':');
         lcd.print(itostr2(print_t%60));	
         lcd.print(itostr2(print_t%60));	
-		(print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) ? lcd.print('R') : lcd.print(' ');
-		(feedmultiply == 100) ? lcd.print(' ') : lcd.print('?');
+		if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT)
+		{
+			lcd.print('R');
+			(feedmultiply == 100) ? lcd.print(' ') : lcd.print('?');
+		}
+		else {
+			lcd_printPGM(PSTR("  "));
+		}
     }else{
     }else{
         lcd_printPGM(PSTR("--:--  "));
         lcd_printPGM(PSTR("--:--  "));
     }
     }
@@ -828,7 +834,7 @@ if (print_sd_status)
 	// Farm number display
 	// Farm number display
 	if (farm_mode)
 	if (farm_mode)
 	{
 	{
-		lcd.setCursor(0, 6);
+		lcd.setCursor(6, 2);
 		lcd_printPGM(PSTR(" F"));
 		lcd_printPGM(PSTR(" F"));
 		lcd.print(farm_no);
 		lcd.print(farm_no);
 		lcd_printPGM(PSTR("  "));
 		lcd_printPGM(PSTR("  "));
@@ -1352,18 +1358,7 @@ static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* pst
     while(n--)
     while(n--)
         lcd.print(' ');
         lcd.print(' ');
 }
 }
-#define lcd_implementation_drawmenu_back_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
-#define lcd_implementation_drawmenu_back(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_UPLEVEL[0])
-#define lcd_implementation_drawmenu_back_RAM_selected(row, str, data) lcd_implementation_drawmenu_generic_RAM(row, str, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
-#define lcd_implementation_drawmenu_back_RAM(row, str, data) lcd_implementation_drawmenu_generic_RAM(row, str, ' ', LCD_STR_UPLEVEL[0])
-#define lcd_implementation_drawmenu_submenu_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
-#define lcd_implementation_drawmenu_submenu(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_ARROW_RIGHT[0])
-#define lcd_implementation_drawmenu_gcode_selected(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')
-#define lcd_implementation_drawmenu_gcode(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')
-#define lcd_implementation_drawmenu_function_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')
-#define lcd_implementation_drawmenu_function(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')
-#define lcd_implementation_drawmenu_setlang_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')
-#define lcd_implementation_drawmenu_setlang(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')
+
 
 
 static void lcd_implementation_quick_feedback()
 static void lcd_implementation_quick_feedback()
 {
 {

+ 3 - 1
Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h

@@ -467,6 +467,8 @@
 // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
 // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
 #endif // PIDTEMPBED
 #endif // PIDTEMPBED
 
 
+//connect message when communication with monitoring broken
+//#define FARM_CONNECT_MESSAGE
 
 
 /*-----------------------------------
 /*-----------------------------------
  PREHEAT SETTINGS
  PREHEAT SETTINGS
@@ -598,7 +600,7 @@
 
 
 #define MIN_PRINT_FAN_SPEED 75
 #define MIN_PRINT_FAN_SPEED 75
 
 
-#ifdef SNMM
+#if defined (SNMM) || defined (SNMM_V2)
 #define DEFAULT_RETRACTION 4 //used for PINDA temp calibration and pause print
 #define DEFAULT_RETRACTION 4 //used for PINDA temp calibration and pause print
 #else
 #else
 #define DEFAULT_RETRACTION 1 //used for PINDA temp calibration and pause print
 #define DEFAULT_RETRACTION 1 //used for PINDA temp calibration and pause print

+ 627 - 0
Firmware/variants/1_75mm_MK3-MMU-EINSy10a-E3Dv6full.h

@@ -0,0 +1,627 @@
+#ifndef CONFIGURATION_PRUSA_H
+#define CONFIGURATION_PRUSA_H
+
+/*------------------------------------
+ GENERAL SETTINGS
+ *------------------------------------*/
+
+// Printer revision
+#define PRINTER_TYPE PRINTER_MK3
+#define FILAMENT_SIZE "1_75mm_MK3"
+#define NOZZLE_TYPE "E3Dv6full"
+
+// Developer flag
+#define DEVELOPER
+
+// Printer name
+#define CUSTOM_MENDEL_NAME "Prusa i3 MK3"
+
+// Electronics
+#define MOTHERBOARD BOARD_EINSY_1_0a
+
+#define STEEL_SHEET
+#define HAS_SECOND_SERIAL_PORT
+#define SNMM_V2
+
+// Uncomment the below for the E3D PT100 temperature sensor (with or without PT100 Amplifier)
+//#define E3D_PT100_EXTRUDER_WITH_AMP
+//#define E3D_PT100_EXTRUDER_NO_AMP
+//#define E3D_PT100_BED_WITH_AMP
+//#define E3D_PT100_BED_NO_AMP
+
+
+/*------------------------------------
+ AXIS SETTINGS
+ *------------------------------------*/
+
+// Steps per unit {X,Y,Z,E}
+//#define DEFAULT_AXIS_STEPS_PER_UNIT   {100,100,3200/8,140}
+#define DEFAULT_AXIS_STEPS_PER_UNIT   {100,100,3200/8,280}
+//#define DEFAULT_AXIS_STEPS_PER_UNIT   {100,100,3200/8,560}
+
+// Endstop inverting
+#define X_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
+#define Y_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
+#define Z_MIN_ENDSTOP_INVERTING 0 // set to 1 to invert the logic of the endstop.
+
+// Direction inverting
+#define INVERT_X_DIR 1    // for Mendel set to 0, for Orca set to 1
+#define INVERT_Y_DIR 0    // for Mendel set to 1, for Orca set to 0
+#define INVERT_Z_DIR 1     // for Mendel set to 0, for Orca set to 1
+#define INVERT_E0_DIR 0   // for direct drive extruder v9 set to 1, for geared extruder set to 0
+#define INVERT_E1_DIR 0    // for direct drive extruder v9 set to 1, for geared extruder set to 0
+#define INVERT_E2_DIR 0   // for direct drive extruder v9 set to 1, for geared extruder set to 0
+
+// Home position
+#define MANUAL_X_HOME_POS 0
+#define MANUAL_Y_HOME_POS -2.2
+#define MANUAL_Z_HOME_POS 0.2
+
+// Travel limits after homing
+#define X_MAX_POS 255
+#define X_MIN_POS 0
+#define Y_MAX_POS 212.5
+#define Y_MIN_POS -4 //orig -4
+#define Z_MAX_POS 210
+#define Z_MIN_POS 0.15
+
+// Canceled home position
+#define X_CANCEL_POS 50
+#define Y_CANCEL_POS 190
+
+//Pause print position
+#define X_PAUSE_POS 50
+#define Y_PAUSE_POS 190
+#define Z_PAUSE_LIFT 20
+
+#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+#define HOMING_FEEDRATE {3000, 3000, 800, 0}  // set the homing speeds (mm/min) // 3000 is also valid for stallGuard homing. Valid range: 2200 - 3000
+
+//#define DEFAULT_Y_OFFSET    4.f // Default distance of Y_MIN_POS point from endstop, when the printer is not calibrated.
+/**
+ * [0,0] steel sheet print area point X coordinate in bed print area coordinates
+ */
+#define SHEET_PRINT_ZERO_REF_X 0.f
+/**
+ * [0,0] steel sheet print area point Y coordinate in bed print area coordinates
+ */
+#define SHEET_PRINT_ZERO_REF_Y -2.f
+
+#define DEFAULT_MAX_FEEDRATE          {200, 200, 12, 120}      // (mm/sec)   max feedrate (M203)
+#define DEFAULT_MAX_ACCELERATION      {1000, 1000, 200, 5000}  // (mm/sec^2) max acceleration (M201)
+
+
+#define DEFAULT_ACCELERATION          1250   // X, Y, Z and E max acceleration in mm/s^2 for printing moves (M204S)
+#define DEFAULT_RETRACT_ACCELERATION  1250   // X, Y, Z and E max acceleration in mm/s^2 for retracts (M204T)
+
+#define MANUAL_FEEDRATE {2700, 2700, 1000, 100}   // set the speeds for manual moves (mm/min)
+
+//Silent mode limits
+#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
+
+#define Z_AXIS_ALWAYS_ON 1
+
+//Crash detection
+#define CRASHDET_TIMER 45 //seconds
+#define CRASHDET_COUNTER_MAX 3 
+
+// New XYZ calibration
+#define NEW_XYZCAL
+
+// Watchdog support
+#define WATCHDOG
+
+// Power panic
+#define UVLO_SUPPORT
+
+// Fan check
+#define FANCHECK
+
+// Safety timer
+#define SAFETYTIMER
+#define DEFAULT_SAFETYTIMER_TIME_MINS 30
+
+// Filament sensor
+#define PAT9125
+
+
+// Disable some commands
+#define _DISABLE_M42_M226
+
+// Minimum ambient temperature limit to start triggering MINTEMP errors [C]
+// 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      25
+#define MINTEMP_MINAMBIENT_RAW  978
+
+//#define DEBUG_BUILD
+//#define DEBUG_SEC_LANG   //secondary language debug output at startup
+//#define DEBUG_W25X20CL   //debug external spi flash
+#ifdef DEBUG_BUILD
+//#define _NO_ASM
+#define DEBUG_DCODES //D codes
+#define DEBUG_STACK_MONITOR        //Stack monitor in stepper ISR
+//#define DEBUG_FSENSOR_LOG          //Reports fsensor status to serial
+//#define DEBUG_CRASHDET_COUNTERS  //Display crash-detection counters on LCD
+//#define DEBUG_RESUME_PRINT       //Resume/save print debug enable 
+//#define DEBUG_UVLO_AUTOMATIC_RECOVER // Power panic automatic recovery debug output 
+//#define DEBUG_DISABLE_XMINLIMIT  //x min limit ignored
+//#define DEBUG_DISABLE_XMAXLIMIT  //x max limit ignored
+//#define DEBUG_DISABLE_YMINLIMIT  //y min limit ignored
+//#define DEBUG_DISABLE_YMAXLIMIT  //y max limit ignored
+//#define DEBUG_DISABLE_ZMINLIMIT  //z min limit ignored
+//#define DEBUG_DISABLE_ZMAXLIMIT  //z max limit ignored
+#define DEBUG_DISABLE_STARTMSGS //no startup messages 
+//#define DEBUG_DISABLE_MINTEMP   //mintemp error ignored
+//#define DEBUG_DISABLE_SWLIMITS  //sw limits ignored
+//#define DEBUG_DISABLE_LCD_STATUS_LINE  //empty four lcd line
+//#define DEBUG_DISABLE_PREVENT_EXTRUDER //cold extrusion and long extrusion allowed
+//#define DEBUG_DISABLE_PRUSA_STATISTICS //disable prusa_statistics() mesages
+//#define DEBUG_DISABLE_FORCE_SELFTEST //disable force selftest
+//#define DEBUG_XSTEP_DUP_PIN 21   //duplicate x-step output to pin 21 (SCL on P3)
+//#define DEBUG_YSTEP_DUP_PIN 21   //duplicate y-step output to pin 21 (SCL on P3)
+//#define DEBUG_BLINK_ACTIVE
+//#define DEBUG_DISABLE_FANCHECK     //disable fan check (no ISR INT7, check disabled)
+//#define DEBUG_DISABLE_FSENSORCHECK //disable fsensor check (no ISR INT7, check disabled)
+#define DEBUG_DUMP_TO_2ND_SERIAL   //dump received characters to 2nd serial line
+#define DEBUG_STEPPER_TIMER_MISSED // Stop on stepper timer overflow, beep and display a message.
+#define PLANNER_DIAGNOSTICS // Show the planner queue status on printer display.
+#define CMD_DIAGNOSTICS //Show cmd queue length on printer display
+#endif /* DEBUG_BUILD */
+
+//#define EXPERIMENTAL_FEATURES
+#define TMC2130_LINEARITY_CORRECTION
+#define TMC2130_LINEARITY_CORRECTION_XYZ
+//#define TMC2130_VARIABLE_RESOLUTION
+
+
+
+/*------------------------------------
+ TMC2130 default settings
+ *------------------------------------*/
+
+#define TMC2130_FCLK 12000000       // fclk = 12MHz
+
+#define TMC2130_USTEPS_XY   16        // microstep resolution for XY axes
+#define TMC2130_USTEPS_Z    16        // microstep resolution for Z axis
+#define TMC2130_USTEPS_E    32        // microstep resolution for E axis
+#define TMC2130_INTPOL_XY   1         // extrapolate 256 for XY axes
+#define TMC2130_INTPOL_Z    1         // extrapolate 256 for Z axis
+#define TMC2130_INTPOL_E    1         // extrapolate 256 for E axis
+
+#define TMC2130_PWM_GRAD_X  2         // PWMCONF
+#define TMC2130_PWM_AMPL_X  230       // PWMCONF
+#define TMC2130_PWM_AUTO_X  1         // PWMCONF
+#define TMC2130_PWM_FREQ_X  2         // PWMCONF
+
+#define TMC2130_PWM_GRAD_Y  2         // PWMCONF
+#define TMC2130_PWM_AMPL_Y  235       // PWMCONF
+#define TMC2130_PWM_AUTO_Y  1         // PWMCONF
+#define TMC2130_PWM_FREQ_Y  2         // PWMCONF
+
+#define TMC2130_PWM_GRAD_Z  4         // PWMCONF
+#define TMC2130_PWM_AMPL_Z  200       // PWMCONF
+#define TMC2130_PWM_AUTO_Z  1         // PWMCONF
+#define TMC2130_PWM_FREQ_Z  2         // PWMCONF
+
+#define TMC2130_PWM_GRAD_E  4         // PWMCONF
+#define TMC2130_PWM_AMPL_E  240       // PWMCONF
+#define TMC2130_PWM_AUTO_E  1         // PWMCONF
+#define TMC2130_PWM_FREQ_E  2         // PWMCONF
+
+#define TMC2130_TOFF_XYZ    3         // CHOPCONF // fchop = 27.778kHz
+#define TMC2130_TOFF_E      3         // CHOPCONF // fchop = 27.778kHz
+//#define TMC2130_TOFF_E      4         // CHOPCONF // fchop = 21.429kHz
+//#define TMC2130_TOFF_E      5         // CHOPCONF // fchop = 17.442kHz
+
+//#define TMC2130_STEALTH_E // Extruder stealthChop mode
+//#define TMC2130_CNSTOFF_E // Extruder constant-off-time mode (similar to MK2)
+
+//#define TMC2130_PWM_DIV   683         // PWM frequency divider (1024, 683, 512, 410)
+#define TMC2130_PWM_DIV   512         // PWM frequency divider (1024, 683, 512, 410)
+#define TMC2130_PWM_CLK   (2 * TMC2130_FCLK / TMC2130_PWM_DIV) // PWM frequency (23.4kHz, 35.1kHz, 46.9kHz, 58.5kHz for 12MHz fclk)
+
+#define TMC2130_TPWMTHRS  0         // TPWMTHRS - Sets the switching speed threshold based on TSTEP from stealthChop to spreadCycle mode
+#define TMC2130_THIGH     0         // THIGH - unused
+
+//#define TMC2130_TCOOLTHRS_X 450       // TCOOLTHRS - coolstep treshold
+//#define TMC2130_TCOOLTHRS_Y 450       // TCOOLTHRS - coolstep treshold
+#define TMC2130_TCOOLTHRS_X 430       // TCOOLTHRS - coolstep treshold
+#define TMC2130_TCOOLTHRS_Y 430       // TCOOLTHRS - coolstep treshold
+#define TMC2130_TCOOLTHRS_Z 500       // TCOOLTHRS - coolstep treshold
+#define TMC2130_TCOOLTHRS_E 500       // TCOOLTHRS - coolstep treshold
+
+#define TMC2130_SG_HOMING       1     // stallguard homing
+#define TMC2130_SG_THRS_X       3     // stallguard sensitivity for X axis
+#define TMC2130_SG_THRS_Y       3     // stallguard sensitivity for Y axis
+#define TMC2130_SG_THRS_Z       4     // stallguard sensitivity for Z axis
+#define TMC2130_SG_THRS_E       3     // stallguard sensitivity for E axis
+
+//new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only)
+#define TMC2130_CURRENTS_H {16, 20, 35, 30}  // default holding currents for all axes
+#define TMC2130_CURRENTS_R {16, 20, 35, 30}  // default running currents for all axes
+#define TMC2130_UNLOAD_CURRENT_R 12			 // lowe current for M600 to protect filament sensor 
+
+#define TMC2130_STEALTH_Z
+
+//#define TMC2130_DEBUG
+//#define TMC2130_DEBUG_WR
+//#define TMC2130_DEBUG_RD
+
+
+/*------------------------------------
+ EXTRUDER SETTINGS
+ *------------------------------------*/
+
+// Mintemps
+#define HEATER_0_MINTEMP 15
+#define HEATER_1_MINTEMP 5
+#define HEATER_2_MINTEMP 5
+#define BED_MINTEMP 15
+
+// Maxtemps
+#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
+#define HEATER_0_MAXTEMP 410
+#else
+#define HEATER_0_MAXTEMP 305
+#endif
+#define HEATER_1_MAXTEMP 305
+#define HEATER_2_MAXTEMP 305
+#define BED_MAXTEMP 125
+
+#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
+// Define PID constants for extruder with PT100
+#define  DEFAULT_Kp 21.70
+#define  DEFAULT_Ki 1.60
+#define  DEFAULT_Kd 73.76
+#else
+// Define PID constants for extruder
+//#define  DEFAULT_Kp 40.925
+//#define  DEFAULT_Ki 4.875
+//#define  DEFAULT_Kd 86.085
+#define  DEFAULT_Kp 16.13
+#define  DEFAULT_Ki 1.1625
+#define  DEFAULT_Kd 56.23
+#endif
+
+// Extrude mintemp
+#define EXTRUDE_MINTEMP 190
+
+// Extruder cooling fans
+#define EXTRUDER_0_AUTO_FAN_PIN   8
+#define EXTRUDER_1_AUTO_FAN_PIN   -1
+#define EXTRUDER_2_AUTO_FAN_PIN   -1
+#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
+#define EXTRUDER_AUTO_FAN_SPEED   255  // == full speed
+
+
+
+/*------------------------------------
+ LOAD/UNLOAD FILAMENT SETTINGS
+ *------------------------------------*/
+
+// Load filament commands
+#define LOAD_FILAMENT_0 "M83"
+#define LOAD_FILAMENT_1 "G1 E70 F400"
+#define LOAD_FILAMENT_2 "G1 E40 F100"
+
+// Unload filament commands
+#define UNLOAD_FILAMENT_0 "M83"
+#define UNLOAD_FILAMENT_1 "G1 E-80 F7000"
+
+/*------------------------------------
+ CHANGE FILAMENT SETTINGS
+ *------------------------------------*/
+
+// Filament change configuration
+#define FILAMENTCHANGEENABLE
+#ifdef FILAMENTCHANGEENABLE
+#define FILAMENTCHANGE_XPOS 211
+#define FILAMENTCHANGE_YPOS 0
+#define FILAMENTCHANGE_ZADD 2
+#define FILAMENTCHANGE_FIRSTRETRACT -2
+#define FILAMENTCHANGE_FINALRETRACT -80
+
+#define FILAMENTCHANGE_FIRSTFEED 70
+#define FILAMENTCHANGE_FINALFEED 50
+#define FILAMENTCHANGE_RECFEED 5
+
+#define FILAMENTCHANGE_XYFEED 50
+#define FILAMENTCHANGE_EFEED 20
+//#define FILAMENTCHANGE_RFEED 400
+#define FILAMENTCHANGE_RFEED 7000 / 60
+#define FILAMENTCHANGE_EXFEED 2
+#define FILAMENTCHANGE_ZFEED 15
+
+#endif
+
+/*------------------------------------
+ ADDITIONAL FEATURES SETTINGS
+ *------------------------------------*/
+
+// Define Prusa filament runout sensor
+//#define FILAMENT_RUNOUT_SUPPORT
+
+#ifdef FILAMENT_RUNOUT_SUPPORT
+#define FILAMENT_RUNOUT_SENSOR 1
+#endif
+
+// temperature runaway
+#define TEMP_RUNAWAY_BED_HYSTERESIS 5
+#define TEMP_RUNAWAY_BED_TIMEOUT 360
+
+#define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15
+#define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45
+
+/*------------------------------------
+ MOTOR CURRENT SETTINGS
+ *------------------------------------*/
+
+// Motor Current setting for BIG RAMBo
+#define DIGIPOT_MOTOR_CURRENT {135,135,135,135,135} // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
+#define DIGIPOT_MOTOR_CURRENT_LOUD {135,135,135,135,135}
+
+// Motor Current settings for RAMBo mini PWM value = MotorCurrentSetting * 255 / range
+#if MOTHERBOARD == BOARD_RAMBO_MINI_1_0 || MOTHERBOARD == BOARD_RAMBO_MINI_1_3
+#define MOTOR_CURRENT_PWM_RANGE 2000
+#define DEFAULT_PWM_MOTOR_CURRENT  {400, 750, 750} // {XY,Z,E}
+#define DEFAULT_PWM_MOTOR_CURRENT_LOUD  {400, 750, 750} // {XY,Z,E}
+#endif
+
+/*------------------------------------
+ PAT9125 SETTINGS
+ *------------------------------------*/
+
+#define PAT9125_XRES			0
+#define PAT9125_YRES			255
+
+/*------------------------------------
+ BED SETTINGS
+ *------------------------------------*/
+
+// Define Mesh Bed Leveling system to enable it
+#define MESH_BED_LEVELING
+#ifdef MESH_BED_LEVELING
+
+#define MBL_Z_STEP 0.01
+
+// Mesh definitions
+#define MESH_MIN_X 35
+#define MESH_MAX_X 238
+#define MESH_MIN_Y 6
+#define MESH_MAX_Y 202
+
+// Mesh upsample definition
+#define MESH_NUM_X_POINTS 7
+#define MESH_NUM_Y_POINTS 7
+// Mesh measure definition
+#define MESH_MEAS_NUM_X_POINTS 3
+#define MESH_MEAS_NUM_Y_POINTS 3
+
+#define MESH_HOME_Z_CALIB 0.2
+#define MESH_HOME_Z_SEARCH 5 //Z lift for homing, mesh bed leveling etc.
+
+#define X_PROBE_OFFSET_FROM_EXTRUDER 23     // Z probe to nozzle X offset: -left  +right
+#define Y_PROBE_OFFSET_FROM_EXTRUDER 5     // Z probe to nozzle Y offset: -front +behind
+#define Z_PROBE_OFFSET_FROM_EXTRUDER -0.4  // Z probe to nozzle Z offset: -below (always!)
+#endif
+
+// Bed Temperature Control
+// Select PID or bang-bang with PIDTEMPBED. If bang-bang, BED_LIMIT_SWITCHING will enable hysteresis
+//
+// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
+// If your PID_dT above is the default, and correct for your hardware/configuration, that means 7.689Hz,
+// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
+// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
+// If your configuration is significantly different than this and you don't understand the issues involved, you probably
+// shouldn't use bed PID until someone else verifies your hardware works.
+// If this is enabled, find your own PID constants below.
+#define PIDTEMPBED
+//
+//#define BED_LIMIT_SWITCHING
+
+// This sets the max power delivered to the bed, and replaces the HEATER_BED_DUTY_CYCLE_DIVIDER option.
+// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis)
+// setting this to anything other than 255 enables a form of PWM to the bed just like HEATER_BED_DUTY_CYCLE_DIVIDER did,
+// so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
+#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
+
+// Bed temperature compensation settings
+#define BED_OFFSET 10
+#define BED_OFFSET_START 40
+#define BED_OFFSET_CENTER 50
+
+
+#ifdef PIDTEMPBED
+//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
+//from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
+#if defined(E3D_PT100_BED_WITH_AMP) || defined(E3D_PT100_BED_NO_AMP)
+// Define PID constants for extruder with PT100
+#define  DEFAULT_bedKp 21.70
+#define  DEFAULT_bedKi 1.60
+#define  DEFAULT_bedKd 73.76
+#else
+#define  DEFAULT_bedKp 126.13
+#define  DEFAULT_bedKi 4.30
+#define  DEFAULT_bedKd 924.76
+#endif
+
+//120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
+//from pidautotune
+//    #define  DEFAULT_bedKp 97.1
+//    #define  DEFAULT_bedKi 1.41
+//    #define  DEFAULT_bedKd 1675.16
+
+// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
+#endif // PIDTEMPBED
+
+//connect message when communication with monitoring broken
+//#define FARM_CONNECT_MESSAGE
+
+/*-----------------------------------
+ PREHEAT SETTINGS
+ *------------------------------------*/
+
+#define FARM_PREHEAT_HOTEND_TEMP 250
+#define FARM_PREHEAT_HPB_TEMP 60
+#define FARM_PREHEAT_FAN_SPEED 0
+
+#define PLA_PREHEAT_HOTEND_TEMP 215
+#define PLA_PREHEAT_HPB_TEMP 60
+#define PLA_PREHEAT_FAN_SPEED 0
+
+#define ABS_PREHEAT_HOTEND_TEMP 255
+#define ABS_PREHEAT_HPB_TEMP 100
+#define ABS_PREHEAT_FAN_SPEED 0
+
+#define HIPS_PREHEAT_HOTEND_TEMP 220
+#define HIPS_PREHEAT_HPB_TEMP 100
+#define HIPS_PREHEAT_FAN_SPEED 0
+
+#define PP_PREHEAT_HOTEND_TEMP 254
+#define PP_PREHEAT_HPB_TEMP 100
+#define PP_PREHEAT_FAN_SPEED 0
+
+#define PET_PREHEAT_HOTEND_TEMP 230
+#define PET_PREHEAT_HPB_TEMP 85
+#define PET_PREHEAT_FAN_SPEED 0
+
+#define FLEX_PREHEAT_HOTEND_TEMP 240
+#define FLEX_PREHEAT_HPB_TEMP 50
+#define FLEX_PREHEAT_FAN_SPEED 0
+
+/*------------------------------------
+ THERMISTORS SETTINGS
+ *------------------------------------*/
+
+//
+//--NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table
+//
+//// Temperature sensor settings:
+// -2 is thermocouple with MAX6675 (only for sensor 0)
+// -1 is thermocouple with AD595
+// 0 is not used
+// 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup)
+// 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup)
+// 3 is Mendel-parts thermistor (4.7k pullup)
+// 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !!
+// 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup)
+// 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup)
+// 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup)
+// 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup)
+// 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup)
+// 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup)
+// 10 is 100k RS thermistor 198-961 (4.7k pullup)
+// 11 is 100k beta 3950 1% thermistor (4.7k pullup)
+// 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed)
+// 13 is 100k Hisens 3950  1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE"
+// 20 is the PT100 circuit found in the Ultimainboard V2.x
+// 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950
+//
+//    1k ohm pullup tables - This is not normal, you would have to have changed out your 4.7k for 1k
+//                          (but gives greater accuracy and more stable PID)
+// 51 is 100k thermistor - EPCOS (1k pullup)
+// 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup)
+// 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup)
+//
+// 1047 is Pt1000 with 4k7 pullup
+// 1010 is Pt1000 with 1k pullup (non standard)
+// 147 is Pt100 with 4k7 pullup
+// 148 is E3D Pt100 with 4k7 pullup and no PT100 Amplifier on a MiniRambo 1.3a
+// 247 is Pt100 with 4k7 pullup and PT100 Amplifier
+// 110 is Pt100 with 1k pullup (non standard)
+
+#if defined(E3D_PT100_EXTRUDER_WITH_AMP)
+#define TEMP_SENSOR_0 247
+#elif defined(E3D_PT100_EXTRUDER_NO_AMP)
+#define TEMP_SENSOR_0 148
+#else
+#define TEMP_SENSOR_0 5
+#endif
+#define TEMP_SENSOR_1 0
+#define TEMP_SENSOR_2 0
+#if defined(E3D_PT100_BED_WITH_AMP)
+#define TEMP_SENSOR_BED 247
+#elif defined(E3D_PT100_BED_NO_AMP)
+#define TEMP_SENSOR_BED 148
+#else
+#define TEMP_SENSOR_BED 1
+#endif
+#define TEMP_SENSOR_PINDA 1
+#define TEMP_SENSOR_AMBIENT 2000
+
+#define STACK_GUARD_TEST_VALUE 0xA2A2
+
+#define MAX_BED_TEMP_CALIBRATION 50
+#define MAX_HOTEND_TEMP_CALIBRATION 50
+
+#define MAX_E_STEPS_PER_UNIT 250
+#define MIN_E_STEPS_PER_UNIT 100
+
+#define Z_BABYSTEP_MIN -3999
+#define Z_BABYSTEP_MAX 0
+
+#define PINDA_PREHEAT_X 20
+#define PINDA_PREHEAT_Y 60
+#define PINDA_PREHEAT_Z 0.15
+/*
+#define PINDA_PREHEAT_X 70
+#define PINDA_PREHEAT_Y -3
+#define PINDA_PREHEAT_Z 1*/
+#define PINDA_HEAT_T 120 //time in s
+
+#define PINDA_MIN_T 50
+#define PINDA_STEP_T 10
+#define PINDA_MAX_T 100
+
+#define PING_TIME 60 //time in s
+#define PING_TIME_LONG 600 //10 min; used when length of commands buffer > 0 to avoid 0 triggering when dealing with long gcodes
+#define PING_ALLERT_PERIOD 60 //time in s
+
+#define NC_TIME 10 //time in s for periodic important status messages sending which needs reponse from monitoring
+#define NC_BUTTON_LONG_PRESS 15 //time in s
+
+#define LONG_PRESS_TIME 1000 //time in ms for button long press
+#define BUTTON_BLANKING_TIME 200 //time in ms for blanking after button release
+
+#define DEFAULT_PID_TEMP 210
+
+#define MIN_PRINT_FAN_SPEED 75
+
+#if defined (SNMM) || defined (SNMM_V2)
+#define DEFAULT_RETRACTION 4 //used for PINDA temp calibration and pause print
+#else
+#define DEFAULT_RETRACTION 1 //used for PINDA temp calibration and pause print
+#endif
+
+// How much shall the print head be lifted on power panic?
+// Ideally the Z axis will reach a zero phase of the stepper driver on power outage. To simplify this,
+// UVLO_Z_AXIS_SHIFT shall be an integer multiply of the stepper driver cycle, that is 4x full step.
+// For example, the Prusa i3 MK2 with 16 microsteps per full step has Z stepping of 400 microsteps per mm.
+// At 400 microsteps per mm, a full step lifts the Z axis by 0.04mm, and a stepper driver cycle is 0.16mm.
+// The following example, 12 * (4 * 16 / 400) = 12 * 0.16mm = 1.92mm.
+//#define UVLO_Z_AXIS_SHIFT 1.92
+#define UVLO_Z_AXIS_SHIFT 0.64
+// If power panic occured, and the current temperature is higher then target temperature before interrupt minus this offset, print will be recovered automatically. 
+#define AUTOMATIC_UVLO_BED_TEMP_OFFSET 5 
+
+#define HEATBED_V2
+
+#define M600_TIMEOUT 600  //seconds
+
+//#define SUPPORT_VERBOSITY
+
+#endif //__CONFIGURATION_PRUSA_H

+ 61 - 0
lang/fw-clean.sh

@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# fw-clean.sh - multi-language support script
+#  Remove all firmware output files from lang folder.
+#
+
+result=0
+
+rm_if_exists()
+{
+ if [ -e $1 ]; then
+  echo -n " removing '$1'..." >&2
+  if rm $1; then
+   echo "OK" >&2
+  else
+   echo "NG!" >&2
+   result=1
+  fi
+ fi
+}
+
+echo "fw-clean.sh started" >&2
+
+rm_if_exists text.sym
+rm_if_exists progmem1.sym
+rm_if_exists progmem1.lss
+rm_if_exists progmem1.hex
+rm_if_exists progmem1.chr
+rm_if_exists progmem1.var
+rm_if_exists progmem1.txt
+rm_if_exists textaddr.txt
+rm_if_exists firmware.bin
+rm_if_exists firmware.hex
+rm_if_exists firmware_cz.hex
+rm_if_exists firmware_de.hex
+rm_if_exists firmware_es.hex
+rm_if_exists firmware_it.hex
+rm_if_exists firmware_pl.hex
+rm_if_exists progmem.out
+rm_if_exists textaddr.out
+rm_if_exists update_lang.out
+rm_if_exists update_lang_cz.out
+rm_if_exists update_lang_de.out
+rm_if_exists update_lang_es.out
+rm_if_exists update_lang_it.out
+rm_if_exists update_lang_pl.out
+rm_if_exists lang.bin
+rm_if_exists lang.hex
+
+echo -n "fw-clean.sh finished" >&2
+if [ $result -eq 0 ]; then
+ echo " with success" >&2
+else
+ echo " with errors!" >&2
+fi
+
+case "$-" in
+ *i*) echo "press enter key"; read ;;
+esac
+
+exit $result

+ 10 - 0
lang/iso639-1.txt

@@ -0,0 +1,10 @@
+#language codes ISO639-1
+# iso english  localized
+#-----------------------
+# en  English  English
+# de  German   Deutsch
+# cs  Czech    Cestina
+# es  Spanish  Espanol
+# fr  
+# it  Italian  Italiano
+# pl  Polish   Polski

+ 139 - 0
lang/lang-build.sh

@@ -0,0 +1,139 @@
+#!/bin/sh
+#
+# lang-build.sh - multi-language support script
+#  generate lang_xx.bin (language binary file)
+#
+# Input files:
+#  lang_en.txt or lang_en_xx.txt
+#  
+# Output files:
+#  lang_xx.bin
+#
+# Temporary files:
+#  lang_xx.tmp
+#  lang_xx.dat
+#
+
+#awk code to format ui16 variables for dd
+awk_ui16='{ h=int($1/256); printf("\\x%02x\\x%02x\n", int($1-256*h), h); }'
+
+#startup message
+echo "lang-build.sh started" >&2
+
+#exiting function
+finish()
+{
+ if [ $1 -eq 0 ]; then
+  echo "lang-build.sh finished with success" >&2
+ else
+  echo "lang-build.sh finished with errors!" >&2
+ fi
+ exit $1
+}
+
+#returns hexadecial data for lang code
+lang_code_hex_data()
+# $1 - language code ('en', 'cz'...)
+{
+ case "$1" in
+  *en*) echo '\x6e\x65' ;;
+  *cz*) echo '\x73\x63' ;;
+  *de*) echo '\x65\x64' ;;
+  *es*) echo '\x73\x65' ;;
+  *fr*) echo '\x72\x66' ;;
+  *it*) echo '\x74\x69' ;;
+  *pl*) echo '\x6c\x70' ;;
+ esac
+ echo '??'
+}
+
+write_header()
+# $1 - lang
+# $2 - size
+# $3 - count
+# $4 - checksum
+# $5 - signature
+{
+ /bin/echo -n -e "\xa5\x5a\xb4\x4b" |\
+  dd of=lang_$1.bin bs=1 count=4 seek=0 conv=notrunc 2>/dev/null
+ /bin/echo -n -e $(echo -n "$(($2))" | awk "$awk_ui16") |\
+  dd of=lang_$1.bin bs=1 count=2 seek=4 conv=notrunc 2>/dev/null
+ /bin/echo -n -e $(echo -n "$(($3))" | awk "$awk_ui16") |\
+  dd of=lang_$1.bin bs=1 count=2 seek=6 conv=notrunc 2>/dev/null
+ /bin/echo -n -e $(echo -n "$(($4))" | awk "$awk_ui16") |\
+  dd of=lang_$1.bin bs=1 count=2 seek=8 conv=notrunc 2>/dev/null
+ /bin/echo -n -e "$(lang_code_hex_data $1)" |\
+  dd of=lang_$1.bin bs=1 count=2 seek=10 conv=notrunc 2>/dev/null
+ sig_h=$(($5 / 65536))
+ /bin/echo -n -e $(echo -n "$sig_h" | awk "$awk_ui16") |\
+  dd of=lang_$1.bin bs=1 count=2 seek=14 conv=notrunc 2>/dev/null
+ sig_l=$(($5 - $sig_h * 65536))
+ /bin/echo -n -e $(echo -n "$sig_l" | awk "$awk_ui16") |\
+  dd of=lang_$1.bin bs=1 count=2 seek=12 conv=notrunc 2>/dev/null
+}
+
+generate_binary()
+# $1 - language code ('en', 'cz'...)
+{
+ echo "lang="$1 >&2
+ #remove output and temporary files
+ rm -f lang_$1.bin
+ rm -f lang_$1.tmp
+ rm -f lang_$1.dat
+ LNG=$1
+ #create lang_xx.tmp - different processing for 'en' language
+ if [ "$1" = "en" ]; then
+  #remove comments and empty lines
+  cat lang_en.txt | sed '/^$/d;/^#/d'
+ else
+  #remove comments and empty lines, print lines with translated text only
+  cat lang_en_$1.txt | sed '/^$/d;/^#/d' | sed -n 'n;p'
+ fi | sed 's/^\"\\x00\"$/\"\"/' > lang_$1.tmp
+ #create lang_xx.dat (binary text data file)
+# cat lang_$1.tmp | sed 's/^\"/\/bin\/echo -e \"/;s/"$/\\x00\"/' > lang_$1.shx
+ cat lang_$1.tmp | sed 's/^\"/\/bin\/echo -e -n \"/;s/"$/\\x00\"/' | sh >lang_$1.dat
+ #calculate number of strings
+ count=$(grep -c '^"' lang_$1.tmp)
+ echo "count="$count >&2
+ #calculate text data offset
+ offs=$((16 + 2 * $count))
+ echo "offs="$offs >&2
+ #calculate text data size
+ size=$(($offs + $(wc -c lang_$1.dat | cut -f1 -d' ')))
+ echo "size="$size >&2
+ #write header with empty signature and checksum
+ write_header $1 $size $count 0x0000 0x00000000
+ #write offset table
+ offs_hex=$(cat lang_$1.tmp | sed 's/^\"//;s/\"$//' |\
+  sed 's/\\x[0-9a-f][0-9a-f]/\./g;s/\\[0-7][0-7][0-7]/\./g;s/\ /\./g' |\
+  awk 'BEGIN { o='$offs';} { h=int(o/256); printf("\\x%02x\\x%02x",int(o-256*h), h); o+=(length($0)+1); }')
+ /bin/echo -n -e "$offs_hex" | dd of=./lang_$1.bin bs=1 seek=16 conv=notrunc 2>/dev/null
+ #write binary text data
+ dd if=./lang_$1.dat of=./lang_$1.bin bs=1 seek=$offs conv=notrunc 2>/dev/null
+ #write signature
+ if [ "$1" != "en" ]; then
+  dd if=lang_en.bin of=lang_$1.bin bs=1 count=4 skip=6 seek=12 conv=notrunc 2>/dev/null
+ fi
+ #calculate and update checksum
+ chsum=$(cat lang_$1.bin | xxd | cut -c11-49 | tr ' ' "\n" | sed '/^$/d' | awk 'BEGIN { sum = 0; } { sum += strtonum("0x"$1); if (sum > 0xffff) sum -= 0x10000; } END { printf("%x\n", sum); }')
+ /bin/echo -n -e $(echo -n $((0x$chsum)) | awk "$awk_ui16") |\
+  dd of=lang_$1.bin bs=1 count=2 seek=8 conv=notrunc 2>/dev/null
+ #remove temporary files
+# rm -f lang_$1.tmp
+# rm -f lang_$1.dat
+}
+
+if [ -z "$1" ]; then set 'all'; fi
+
+if [ "$1" = "all" ]; then
+ generate_binary 'en'
+ generate_binary 'cz'
+ generate_binary 'de'
+ generate_binary 'es'
+ generate_binary 'it'
+ generate_binary 'pl'
+else
+ generate_binary $1
+fi
+
+finish 0

+ 75 - 0
lang/lang-check.sh

@@ -0,0 +1,75 @@
+#!/bin/sh
+#
+# lang_check.sh - multi-language support script
+#  check lang_xx.bin (language binary file)
+#
+# Input files:
+#  lang_$1.bin
+#  lang_en.txt or lang_en_$1.txt
+#  
+#
+
+#set 'cz'
+
+#dictionary txt file
+fn_t=lang_en_$1.txt
+if [ "$1" = "en" ]; then fn_t=lang_en.txt; fi
+#binary file to check
+fn_b=lang_$1.bin
+
+#check txt dictionary file
+echo -n "dictionary file: $fn_t"
+if [ -e $fn_t ]; then echo " - OK"; else echo " - Not found!"; exit 1; fi
+
+#create lang_xx.tmp - different processing for 'en' language
+if [ "$1" = "en" ]; then
+ #remove comments and empty lines
+ cat lang_en.txt | sed '/^$/d;/^#/d'
+else
+ #remove comments and empty lines, print lines with translated text only
+ cat lang_en_$1.txt | sed '/^$/d;/^#/d' | sed -n 'n;p'
+fi | sed 's/^\"\\x00\"$/\"\"/' > lang_$1.tmp
+
+count_txt=$(grep -c '^"' lang_$1.tmp)
+
+echo -n "language bin file: $fn_b"
+if [ -e $fn_b ]; then echo " - OK"; else echo " - Not found!"; exit 1; fi
+
+#read header and convert to hex
+header=$(dd if=$fn_b bs=1 count=16 2>/dev/null | xxd | cut -c11-49 | sed 's/\([0-9a-f][0-9a-f]\)[\ ]*/\1 /g')
+echo "header='$header'"
+magic=0x$(echo $header | tr -d ' ' | cut -c1-8)
+echo "magic='$magic'"
+size=$(echo $header | tr -d ' ' | cut -c9-12)
+size=0x${size:2:2}${size:0:2}
+echo "size='$size' ($(($size)))"
+count=$(echo $header | tr -d ' ' | cut -c13-16)
+count=0x${count:2:2}${count:0:2}
+echo "count='$count' ($(($count)))"
+o=0
+l=0
+#create lang_xx_1.tmp (temporary text file from binary data)
+(dd if=$fn_b bs=1 count=$((2*$count)) skip=16 2>/dev/null | xxd | cut -c11-49 | tr ' ' "\n" |\
+ sed 's/\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)/\2\1 /g;/^$/d'; printf "%04x\n" $(($size)) ) |\
+ while read offs; do
+  if [ $o -ne 0 ]; then
+   l=$((0x$offs - $o))
+   echo -n '"'
+   dd if=$fn_b bs=1 count=$((l-1)) skip=$o 2>/dev/null
+   echo '"'
+  fi
+  o=$((0x$offs))
+ done > lang_$1_1.tmp
+#create lang_xx_2.tmp (temporary text file from dictionary)
+cat lang_$1.tmp | sed 's/^\"/printf \"\\x22/;s/"$/\\x22\\x0a\"/' | sh >lang_$1_2.tmp
+#compare temporary files
+diff -a lang_$1_1.tmp lang_$1_2.tmp >lang_$1_check.dif
+dif=$(cat lang_$1_check.dif)
+if [ -z "$dif" ]; then
+ echo 'binary data OK'
+else
+ echo 'binary data NG!'
+fi
+
+read
+exit

+ 57 - 0
lang/lang-clean.sh

@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# clean.sh - multi-language support script
+#  Remove all language output files from lang folder.
+#
+
+result=0
+
+rm_if_exists()
+{
+ if [ -e $1 ]; then
+  echo -n " removing '$1'..." >&2
+  if rm $1; then
+   echo "OK" >&2
+  else
+   echo "NG!" >&2
+   result=1
+  fi
+ fi
+}
+
+clean_lang()
+{
+ if [ "$1" = "en" ]; then
+  rm_if_exists lang_$1.tmp
+ else
+  rm_if_exists lang_en_$1.tmp
+  rm_if_exists lang_en_$1.dif
+  rm_if_exists lang_$1.ofs
+  rm_if_exists lang_$1.txt
+ fi
+ rm_if_exists lang_$1.bin
+ rm_if_exists lang_$1.dat
+}
+
+echo "lang-clean.sh started" >&2
+
+clean_lang en
+clean_lang cz
+clean_lang de
+clean_lang es
+clean_lang fr
+clean_lang it
+clean_lang pl
+
+echo -n "lang-clean.sh finished" >&2
+if [ $result -eq 0 ]; then
+ echo " with success" >&2
+else
+ echo " with errors!" >&2
+fi
+
+case "$-" in
+ *i*) echo "press enter key" >&2; read ;;
+esac
+
+exit $result

+ 13 - 13
lang/lang_en_es.txt

@@ -76,7 +76,7 @@
 
 
 #MSG_AUTOLOADING_ONLY_IF_FSENS_ON c=20 r=4
 #MSG_AUTOLOADING_ONLY_IF_FSENS_ON c=20 r=4
 "Autoloading filament available only when filament sensor is turned on..."
 "Autoloading filament available only when filament sensor is turned on..."
-"La carga automatica de filamento solo funciona si el sensor de filamento está activado..."
+"La carga automatica de filamento solo funciona si el sensor de filamento esta activado..."
 
 
 #MSG_AUTOLOADING_ENABLED c=20 r=4
 #MSG_AUTOLOADING_ENABLED c=20 r=4
 "Autoloading filament is active, just press the knob and insert filament..."
 "Autoloading filament is active, just press the knob and insert filament..."
@@ -132,7 +132,7 @@
 
 
 #MSG_RECOVER_PRINT c=20 r=2
 #MSG_RECOVER_PRINT c=20 r=2
 "Blackout occurred. Recover print?"
 "Blackout occurred. Recover print?"
-"Se fue la luz. ¿Reanudar la impresion?"
+"Se fue la luz. Reanudar la impresion?"
 
 
 #MSG_CALIBRATE_BED c=0 r=0
 #MSG_CALIBRATE_BED c=0 r=0
 "Calibrate XYZ"
 "Calibrate XYZ"
@@ -252,7 +252,7 @@
 
 
 #MSG_STACK_ERROR c=20 r=4
 #MSG_STACK_ERROR c=20 r=4
 "Error - static memory has been overwritten"
 "Error - static memory has been overwritten"
-"Error - se ha sobre-escrito la memoria estática"
+"Error - se ha sobre-escrito la memoria estatica"
 
 
 #MSG_SD_ERR_WRITE_TO_FILE c=0 r=0
 #MSG_SD_ERR_WRITE_TO_FILE c=0 r=0
 "error writing to file"
 "error writing to file"
@@ -260,7 +260,7 @@
 
 
 #MSG_FSENS_NOT_RESPONDING c=20 r=4
 #MSG_FSENS_NOT_RESPONDING c=20 r=4
 "ERROR: Filament sensor is not responding, please check connection."
 "ERROR: Filament sensor is not responding, please check connection."
-"ERROR: El sensor de filamento no responde, por favor comprueba la conexión."
+"ERROR: El sensor de filamento no responde, por favor comprueba la conexion."
 
 
 #MSG_ERROR c=0 r=0
 #MSG_ERROR c=0 r=0
 "ERROR:"
 "ERROR:"
@@ -336,7 +336,7 @@
 
 
 #MSG_FILE_INCOMPLETE c=20 r=2
 #MSG_FILE_INCOMPLETE c=20 r=2
 "File incomplete. Continue anyway?"
 "File incomplete. Continue anyway?"
-"Archivo incompleto. ¿Continuar de todos modos?"
+"Archivo incompleto. Continuar de todos modos?"
 
 
 #MSG_SD_FILE_OPENED c=0 r=0
 #MSG_SD_FILE_OPENED c=0 r=0
 "File opened: "
 "File opened: "
@@ -508,7 +508,7 @@
 
 
 #MSG_STEEL_SHEET_CHECK c=20 r=2
 #MSG_STEEL_SHEET_CHECK c=20 r=2
 "Is steel sheet on heatbed?"
 "Is steel sheet on heatbed?"
-"¿Esta colocada la lamina de acero sobre la base?"
+"Esta colocada la lamina de acero sobre la base?"
 
 
 #MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION c=20 r=0
 #MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION c=20 r=0
 "Iteration "
 "Iteration "
@@ -584,7 +584,7 @@
 
 
 #MSG_MESH_BED_LEVELING c=0 r=0
 #MSG_MESH_BED_LEVELING c=0 r=0
 "Mesh Bed Leveling"
 "Mesh Bed Leveling"
-"Nivelación Mesh Level"
+"Nivelacion Mesh Level"
 
 
 #MSG_STEALTH_MODE_OFF c=0 r=0
 #MSG_STEALTH_MODE_OFF c=0 r=0
 "Mode     [Normal]"
 "Mode     [Normal]"
@@ -668,7 +668,7 @@
 
 
 #MSG_DEFAULT_SETTINGS_LOADED c=20 r=4
 #MSG_DEFAULT_SETTINGS_LOADED c=20 r=4
 "Old settings found. Default PID, Esteps etc. will be set."
 "Old settings found. Default PID, Esteps etc. will be set."
-"Se han encontrado ajustes anteriores. Se ajustará el PID, los pasos del extrusor, etc"
+"Se han encontrado ajustes anteriores. Se ajustara el PID, los pasos del extrusor, etc"
 
 
 #MSG_SD_OPEN_FILE_FAIL c=0 r=0
 #MSG_SD_OPEN_FILE_FAIL c=0 r=0
 "open failed, File: "
 "open failed, File: "
@@ -820,7 +820,7 @@
 
 
 #MSG_RECOVERING_PRINT c=20 r=1
 #MSG_RECOVERING_PRINT c=20 r=1
 "Recovering print    "
 "Recovering print    "
-"Recuperando impresión"
+"Recuperando impresion"
 
 
 #MSG_M119_REPORT c=0 r=0
 #MSG_M119_REPORT c=0 r=0
 "Reporting endstop status"
 "Reporting endstop status"
@@ -908,7 +908,7 @@
 
 
 #MSG_FORCE_SELFTEST c=20 r=8
 #MSG_FORCE_SELFTEST c=20 r=8
 "Selftest will be run to calibrate accurate sensorless rehoming."
 "Selftest will be run to calibrate accurate sensorless rehoming."
-"Se realizará el auto-test para calibrar con precisión la vuelta a la posición inicial sin sensores."
+"Se realizara el auto-test para calibrar con precision la vuelta a la posicion inicial sin sensores."
 
 
 #MSG_SET_TEMPERATURE c=19 r=1
 #MSG_SET_TEMPERATURE c=19 r=1
 "Set temperature:"
 "Set temperature:"
@@ -940,7 +940,7 @@
 
 
 #MSG_SORT_ALPHA c=17 r=1
 #MSG_SORT_ALPHA c=17 r=1
 "Sort:  [Alphabet]"
 "Sort:  [Alphabet]"
-"Orden:[Alfabétic]"
+"Orden:[Alfabetic]"
 
 
 #MSG_SORTING c=20 r=1
 #MSG_SORTING c=20 r=1
 "Sorting files"
 "Sorting files"
@@ -1052,7 +1052,7 @@
 
 
 #MSG_WAITING_TEMP_PINDA c=20 r=3
 #MSG_WAITING_TEMP_PINDA c=20 r=3
 "Waiting for PINDA probe cooling"
 "Waiting for PINDA probe cooling"
-"Esperando a que se enfríe la sonda PINDA"
+"Esperando a que se enfrie la sonda PINDA"
 
 
 #MSG_CHANGED_BOTH c=20 r=4
 #MSG_CHANGED_BOTH c=20 r=4
 "Warning: both printer type and motherboard type changed."
 "Warning: both printer type and motherboard type changed."
@@ -1068,7 +1068,7 @@
 
 
 #MSG_UNLOAD_SUCCESSFUL c=20 r=2
 #MSG_UNLOAD_SUCCESSFUL c=20 r=2
 "Was filament unload successful?"
 "Was filament unload successful?"
-"¿Se cargocon exito el filamento?"
+"Se cargocon exito el filamento?"
 
 
 #MSG_SELFTEST_WIRINGERROR c=0 r=0
 #MSG_SELFTEST_WIRINGERROR c=0 r=0
 "Wiring error"
 "Wiring error"

+ 15 - 15
lang/lang_en_it.txt

@@ -76,11 +76,11 @@
 
 
 #MSG_AUTOLOADING_ONLY_IF_FSENS_ON c=20 r=4
 #MSG_AUTOLOADING_ONLY_IF_FSENS_ON c=20 r=4
 "Autoloading filament available only when filament sensor is turned on..."
 "Autoloading filament available only when filament sensor is turned on..."
-"Il caricamento automatico del filamento è disponibile solo quando il sensore è acceso..."
+"Il caricamento automatico del filamento e disponibile solo quando il sensore e acceso..."
 
 
 #MSG_AUTOLOADING_ENABLED c=20 r=4
 #MSG_AUTOLOADING_ENABLED c=20 r=4
 "Autoloading filament is active, just press the knob and insert filament..."
 "Autoloading filament is active, just press the knob and insert filament..."
-"Il caricamento automatico è attivo, premete la manopola e inserite il filamento..."
+"Il caricamento automatico e attivo, premete la manopola e inserite il filamento..."
 
 
 #MSG_SELFTEST_AXIS_LENGTH c=0 r=0
 #MSG_SELFTEST_AXIS_LENGTH c=0 r=0
 "Axis length"
 "Axis length"
@@ -132,7 +132,7 @@
 
 
 #MSG_RECOVER_PRINT c=20 r=2
 #MSG_RECOVER_PRINT c=20 r=2
 "Blackout occurred. Recover print?"
 "Blackout occurred. Recover print?"
-"C'è stato un Blackout. Recuperare la stampa?"
+"C'e stato un Blackout. Recuperare la stampa?"
 
 
 #MSG_CALIBRATE_BED c=0 r=0
 #MSG_CALIBRATE_BED c=0 r=0
 "Calibrate XYZ"
 "Calibrate XYZ"
@@ -252,7 +252,7 @@
 
 
 #MSG_STACK_ERROR c=20 r=4
 #MSG_STACK_ERROR c=20 r=4
 "Error - static memory has been overwritten"
 "Error - static memory has been overwritten"
-"Errore - la memoria statica è stata sovrascritta"
+"Errore - la memoria statica e stata sovrascritta"
 
 
 #MSG_SD_ERR_WRITE_TO_FILE c=0 r=0
 #MSG_SD_ERR_WRITE_TO_FILE c=0 r=0
 "error writing to file"
 "error writing to file"
@@ -292,7 +292,7 @@
 
 
 #MSG_FAN_SPEED c=14 r=0
 #MSG_FAN_SPEED c=14 r=0
 "Fan speed"
 "Fan speed"
-"Velocità ventola"
+"Velocita ventola"
 
 
 #MSG_SELFTEST_FAN c=20 r=0
 #MSG_SELFTEST_FAN c=20 r=0
 "Fan test"
 "Fan test"
@@ -356,7 +356,7 @@
 
 
 #MSG_WIZARD_SELFTEST c=20 r=8
 #MSG_WIZARD_SELFTEST c=20 r=8
 "First, I will run the selftest to check most common assembly problems."
 "First, I will run the selftest to check most common assembly problems."
-"Per primo avvierò l'autotest per controllare gli errori di assemblaggio più comuni."
+"Per primo avviero l'autotest per controllare gli errori di assemblaggio piu comuni."
 
 
 #MSG_FLOW c=0 r=0
 #MSG_FLOW c=0 r=0
 "Flow"
 "Flow"
@@ -456,11 +456,11 @@
 
 
 #MSG_WIZARD_XYZ_CAL c=20 r=8
 #MSG_WIZARD_XYZ_CAL c=20 r=8
 "I will run xyz calibration now. It will take approx. 12 mins."
 "I will run xyz calibration now. It will take approx. 12 mins."
-"Adesso avviero una Calibrazione XYZ. Può durare circa 12 min."
+"Adesso avviero una Calibrazione XYZ. Puo durare circa 12 min."
 
 
 #MSG_WIZARD_Z_CAL c=20 r=8
 #MSG_WIZARD_Z_CAL c=20 r=8
 "I will run z calibration now."
 "I will run z calibration now."
-"Adesso avvierò la Calibrazione Z."
+"Adesso avviero la Calibrazione Z."
 
 
 #MSG_WIZARD_V2_CAL_2 c=20 r=12
 #MSG_WIZARD_V2_CAL_2 c=20 r=12
 "I will start to print line and you will gradually lower the nozzle by rotating the knob, until you reach optimal height. Check the pictures in our handbook in chapter Calibration."
 "I will start to print line and you will gradually lower the nozzle by rotating the knob, until you reach optimal height. Check the pictures in our handbook in chapter Calibration."
@@ -656,7 +656,7 @@
 
 
 #MSG_WIZARD_WILL_PREHEAT c=20 r=4
 #MSG_WIZARD_WILL_PREHEAT c=20 r=4
 "Now I will preheat nozzle for PLA."
 "Now I will preheat nozzle for PLA."
-"Adesso preriscalderò l'ugello per PLA."
+"Adesso preriscaldero l'ugello per PLA."
 
 
 #MSG_NOZZLE c=0 r=0
 #MSG_NOZZLE c=0 r=0
 "Nozzle"
 "Nozzle"
@@ -804,7 +804,7 @@
 
 
 #MSG_ERR_STOPPED c=0 r=0
 #MSG_ERR_STOPPED c=0 r=0
 "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
 "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
-"La stampante si è fermata a causa di errori. Correggete l'errore e usate M999 per riavviare. (La temperatura viene resettate. Impostatela dopo il riavvio)"
+"La stampante si e fermata a causa di errori. Correggete l'errore e usate M999 per riavviare. (La temperatura viene resettate. Impostatela dopo il riavvio)"
 
 
 #WELCOME_MSG c=20 r=0
 #WELCOME_MSG c=20 r=0
 "Prusa i3 MK3 ready."
 "Prusa i3 MK3 ready."
@@ -908,7 +908,7 @@
 
 
 #MSG_FORCE_SELFTEST c=20 r=8
 #MSG_FORCE_SELFTEST c=20 r=8
 "Selftest will be run to calibrate accurate sensorless rehoming."
 "Selftest will be run to calibrate accurate sensorless rehoming."
-"Verrà effettuato un self test per calibrare l'homing senza sensori"
+"Verra effettuato un self test per calibrare l'homing senza sensori"
 
 
 #MSG_SET_TEMPERATURE c=19 r=1
 #MSG_SET_TEMPERATURE c=19 r=1
 "Set temperature:"
 "Set temperature:"
@@ -928,7 +928,7 @@
 
 
 #MSG_FILE_CNT c=20 r=4
 #MSG_FILE_CNT c=20 r=4
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
-"Alcuni file non saranno ordinati. Il numero massimo di file in una cartella è 100 perché siano ordinati."
+"Alcuni file non saranno ordinati. Il numero massimo di file in una cartella e 100 perche siano ordinati."
 
 
 #MSG_SORT_NONE c=17 r=1
 #MSG_SORT_NONE c=17 r=1
 "Sort:      [None]"
 "Sort:      [None]"
@@ -948,7 +948,7 @@
 
 
 #MSG_SPEED c=0 r=0
 #MSG_SPEED c=0 r=0
 "Speed"
 "Speed"
-"Velocità"
+"Velocita"
 
 
 #MSG_SELFTEST_FAN_YES c=19 r=0
 #MSG_SELFTEST_FAN_YES c=19 r=0
 "Spinning"
 "Spinning"
@@ -964,7 +964,7 @@
 
 
 #MSG_STEPPER_TOO_HIGH c=0 r=0
 #MSG_STEPPER_TOO_HIGH c=0 r=0
 "Steprate too high: "
 "Steprate too high: "
-"Velocità passo troppo alta: "
+"Velocita passo troppo alta: "
 
 
 #MSG_STOP_PRINT c=0 r=0
 #MSG_STOP_PRINT c=0 r=0
 "Stop print"
 "Stop print"
@@ -1004,7 +1004,7 @@
 
 
 #MSG_TEMP_CALIBRATION_DONE c=20 r=12
 #MSG_TEMP_CALIBRATION_DONE c=20 r=12
 "Temperature calibration is finished and active. Temp. calibration can be disabled in menu Settings->Temp. cal."
 "Temperature calibration is finished and active. Temp. calibration can be disabled in menu Settings->Temp. cal."
-"Calibrazione temperatura completata e attiva. Può essere disattivata dal menù Impostazioni ->Cal. Temp."
+"Calibrazione temperatura completata e attiva. Puo essere disattivata dal menu Impostazioni ->Cal. Temp."
 
 
 #MSG_TEMPERATURE c=0 r=0
 #MSG_TEMPERATURE c=0 r=0
 "Temperature"
 "Temperature"

+ 208 - 208
lang/lang_en_pl.txt

@@ -1,6 +1,6 @@
 #MSG_EXTRUDER_CORRECTION_OFF c=6 r=0
 #MSG_EXTRUDER_CORRECTION_OFF c=6 r=0
 "  [off"
 "  [off"
-"\x00"
+"[wyl"
 
 
 #MSG_PLANNER_BUFFER_BYTES c=0 r=0
 #MSG_PLANNER_BUFFER_BYTES c=0 r=0
 "  PlannerBufferBytes: "
 "  PlannerBufferBytes: "
@@ -8,15 +8,15 @@
 
 
 #MSG_ERR_COLD_EXTRUDE_STOP c=0 r=0
 #MSG_ERR_COLD_EXTRUDE_STOP c=0 r=0
 " cold extrusion prevented"
 " cold extrusion prevented"
-"\x00"
+" nie dopuszczono do zimnej ekstruzji"
 
 
 #MSG_FREE_MEMORY c=0 r=0
 #MSG_FREE_MEMORY c=0 r=0
 " Free Memory: "
 " Free Memory: "
-"\x00"
+" Wolna pamiec:"
 
 
 #MSG_CONFIGURATION_VER c=0 r=0
 #MSG_CONFIGURATION_VER c=0 r=0
 " Last Updated: "
 " Last Updated: "
-"\x00"
+" Ostatnia aktualizacja: "
 
 
 #MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0
 #MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 c=14 r=0
 " of 4"
 " of 4"
@@ -28,7 +28,7 @@
 
 
 #MSG_MEASURED_OFFSET c=0 r=0
 #MSG_MEASURED_OFFSET c=0 r=0
 "[0;0] point offset"
 "[0;0] point offset"
-"\x00"
+"[0;0] przesuniecie punktu"
 
 
 #MSG_CRASH_DET_ONLY_IN_NORMAL c=20 r=4
 #MSG_CRASH_DET_ONLY_IN_NORMAL c=20 r=4
 "\x1b[2JCrash detection can\x1b[1;0Hbe turned on only in\x1b[2;0HNormal mode"
 "\x1b[2JCrash detection can\x1b[1;0Hbe turned on only in\x1b[2;0HNormal mode"
@@ -40,11 +40,11 @@
 
 
 #MSG_REFRESH c=0 r=0
 #MSG_REFRESH c=0 r=0
 "\xf8Refresh"
 "\xf8Refresh"
-"\xf8Obnovit"
+"\x00"
 
 
 #MSG_BABYSTEPPING_Z c=20 r=0
 #MSG_BABYSTEPPING_Z c=20 r=0
 "Adjusting Z"
 "Adjusting Z"
-"Dostrojenie Z"
+"Dostrajanie Z"
 
 
 #MSG_SELFTEST_CHECK_ALLCORRECT c=20 r=0
 #MSG_SELFTEST_CHECK_ALLCORRECT c=20 r=0
 "All correct      "
 "All correct      "
@@ -52,15 +52,15 @@
 
 
 #MSG_WIZARD_DONE c=20 r=8
 #MSG_WIZARD_DONE c=20 r=8
 "All is done. Happy printing!"
 "All is done. Happy printing!"
-"Gotowe. Udanego druku!"
+"Gotowe. Udanego drukowania!"
 
 
 #MSG_PRESS c=20 r=0
 #MSG_PRESS c=20 r=0
 "and press the knob"
 "and press the knob"
-"Nacisnij przycisk"
+"i nacisnij pokretlo"
 
 
 #MSG_CONFIRM_CARRIAGE_AT_THE_TOP c=20 r=2
 #MSG_CONFIRM_CARRIAGE_AT_THE_TOP c=20 r=2
 "Are left and right Z~carriages all up?"
 "Are left and right Z~carriages all up?"
-"Oba wozki dojechaly do gornej ramy?"
+"Obydwa konce osi dojechaly do gornych ogranicznikow?"
 
 
 #MSG_ADJUSTZ c=0 r=0
 #MSG_ADJUSTZ c=0 r=0
 "Auto adjust Z?"
 "Auto adjust Z?"
@@ -68,71 +68,71 @@
 
 
 #MSG_AUTO_HOME c=0 r=0
 #MSG_AUTO_HOME c=0 r=0
 "Auto home"
 "Auto home"
-"\x00"
+"Auto zerowanie"
 
 
 #MSG_AUTOLOAD_FILAMENT c=17 r=0
 #MSG_AUTOLOAD_FILAMENT c=17 r=0
 "AutoLoad filament"
 "AutoLoad filament"
-"\x00"
+"AutoLadowanie filamentu"
 
 
 #MSG_AUTOLOADING_ONLY_IF_FSENS_ON c=20 r=4
 #MSG_AUTOLOADING_ONLY_IF_FSENS_ON c=20 r=4
 "Autoloading filament available only when filament sensor is turned on..."
 "Autoloading filament available only when filament sensor is turned on..."
-"\x00"
+"Autoladowanie filamentu dostepne tylko gdy czujnik filamentu jest wlaczony..."
 
 
 #MSG_AUTOLOADING_ENABLED c=20 r=4
 #MSG_AUTOLOADING_ENABLED c=20 r=4
 "Autoloading filament is active, just press the knob and insert filament..."
 "Autoloading filament is active, just press the knob and insert filament..."
-"\x00"
+"Autoladowanie filamentu wlaczone, nacisnij pokretlo i wsun filament..."
 
 
 #MSG_SELFTEST_AXIS_LENGTH c=0 r=0
 #MSG_SELFTEST_AXIS_LENGTH c=0 r=0
 "Axis length"
 "Axis length"
-"\x00"
+"Dlugosc osi"
 
 
 #MSG_SELFTEST_AXIS c=0 r=0
 #MSG_SELFTEST_AXIS c=0 r=0
 "Axis"
 "Axis"
-"\x00"
+"Os"
 
 
 #MSG_SELFTEST_BEDHEATER c=0 r=0
 #MSG_SELFTEST_BEDHEATER c=0 r=0
 "Bed / Heater"
 "Bed / Heater"
-"\x00"
+"Stol / Grzanie"
 
 
 #MSG_BED_DONE c=0 r=0
 #MSG_BED_DONE c=0 r=0
 "Bed done"
 "Bed done"
-"Stolik OK."
+"Stol OK"
 
 
 #MSG_BED_HEATING c=0 r=0
 #MSG_BED_HEATING c=0 r=0
 "Bed Heating"
 "Bed Heating"
-"Grzanie stolika.."
+"Grzanie stolu.."
 
 
 #MSG_BED_CORRECTION_MENU c=0 r=0
 #MSG_BED_CORRECTION_MENU c=0 r=0
 "Bed level correct"
 "Bed level correct"
-"Korekta podkladki"
+"Korekta poziomowania stolu"
 
 
 #MSG_BED_LEVELING_FAILED_POINT_LOW c=20 r=4
 #MSG_BED_LEVELING_FAILED_POINT_LOW c=20 r=4
 "Bed leveling failed. Sensor didnt trigger. Debris on nozzle? Waiting for reset."
 "Bed leveling failed. Sensor didnt trigger. Debris on nozzle? Waiting for reset."
-"Kalibracja nieudana. Sensor nie dotknal. Zanieczysz. dysza? Czekam na reset."
+"Kalibracja nieudana. Sensor nie aktywowal sie. Zanieczysz. dysza? Czekam na reset."
 
 
 #MSG_BED_LEVELING_FAILED_PROBE_DISCONNECTED c=20 r=4
 #MSG_BED_LEVELING_FAILED_PROBE_DISCONNECTED c=20 r=4
 "Bed leveling failed. Sensor disconnected or cable broken. Waiting for reset."
 "Bed leveling failed. Sensor disconnected or cable broken. Waiting for reset."
-"Kalibracja nieudana. Sensor odlaczony lub uszkodz. kabel. Czekam na reset."
+"Poziomowanie stolu nieudane. Sensor odlacz. lub uszkodz. przewod. Czekam na reset."
 
 
 #MSG_BED_LEVELING_FAILED_POINT_HIGH c=20 r=4
 #MSG_BED_LEVELING_FAILED_POINT_HIGH c=20 r=4
 "Bed leveling failed. Sensor triggered too high. Waiting for reset."
 "Bed leveling failed. Sensor triggered too high. Waiting for reset."
-"Kalibracja Z nieudana. Sensor dotk. za wysoko. Czekam na reset."
+"Kalibracja Z nieudana. Sensor aktywowal za wysoko. Czekam na reset."
 
 
 #MSG_BED c=0 r=0
 #MSG_BED c=0 r=0
 "Bed"
 "Bed"
-"Stolik"
+"Stol"
 
 
 #MSG_BEGIN_FILE_LIST c=0 r=0
 #MSG_BEGIN_FILE_LIST c=0 r=0
 "Begin file list"
 "Begin file list"
-"\x00"
+"Poczatek listy plikowogranicznikow"
 
 
 #MSG_MENU_BELT_STATUS c=15 r=1
 #MSG_MENU_BELT_STATUS c=15 r=1
 "Belt status"
 "Belt status"
-"\x00"
+"Stan paskow"
 
 
 #MSG_RECOVER_PRINT c=20 r=2
 #MSG_RECOVER_PRINT c=20 r=2
 "Blackout occurred. Recover print?"
 "Blackout occurred. Recover print?"
-"\x00"
+"Wykryto zanik napiecia. Kontynowac?"
 
 
 #MSG_CALIBRATE_BED c=0 r=0
 #MSG_CALIBRATE_BED c=0 r=0
 "Calibrate XYZ"
 "Calibrate XYZ"
@@ -144,11 +144,11 @@
 
 
 #MSG_CALIBRATE_PINDA c=17 r=1
 #MSG_CALIBRATE_PINDA c=17 r=1
 "Calibrate"
 "Calibrate"
-"Skalibrowac"
+"Kalibruj"
 
 
 #MSG_MOVE_CARRIAGE_TO_THE_TOP c=20 r=8
 #MSG_MOVE_CARRIAGE_TO_THE_TOP c=20 r=8
 "Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
 "Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
-"Kalibracja XYZ. Przekrec galke, aby przesunac os Z do gornych krancowek. Nacisnij, by potwierdzic."
+"Kalibracja XYZ. Przekrec pokretlo, aby przesunac os Z do gornych ogranicznikow. Nacisnij, by potwierdzic."
 
 
 #MSG_CALIBRATE_Z_AUTO c=20 r=2
 #MSG_CALIBRATE_Z_AUTO c=20 r=2
 "Calibrating Z"
 "Calibrating Z"
@@ -156,7 +156,7 @@
 
 
 #MSG_MOVE_CARRIAGE_TO_THE_TOP_Z c=20 r=8
 #MSG_MOVE_CARRIAGE_TO_THE_TOP_Z c=20 r=8
 "Calibrating Z. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
 "Calibrating Z. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
-"Kalibracja Z. Przekrec galke, aby przesunac os Z do gornych krancowek. Nacisnij, by potwierdzic."
+"Kalibracja XYZ. Przekrec pokretlo, aby przesunac os Z do gornych ogranicznikow. Nacisnij, by potwierdzic."
 
 
 #MSG_HOMEYZ_DONE c=0 r=0
 #MSG_HOMEYZ_DONE c=0 r=0
 "Calibration done"
 "Calibration done"
@@ -168,7 +168,7 @@
 
 
 #MSG_SD_CANT_ENTER_SUBDIR c=0 r=0
 #MSG_SD_CANT_ENTER_SUBDIR c=0 r=0
 "Cannot enter subdir: "
 "Cannot enter subdir: "
-"\x00"
+"Brak dostepu do subdir: "
 
 
 #MSG_SD_INSERTED c=0 r=0
 #MSG_SD_INSERTED c=0 r=0
 "Card inserted"
 "Card inserted"
@@ -184,27 +184,27 @@
 
 
 #MSG_COOLDOWN c=0 r=0
 #MSG_COOLDOWN c=0 r=0
 "Cooldown"
 "Cooldown"
-"Wychlodzic"
+"Chlodzenie"
 
 
 #MSG_CRASHDETECT_ON c=0 r=0
 #MSG_CRASHDETECT_ON c=0 r=0
 "Crash det.   [on]"
 "Crash det.   [on]"
-"\x00"
+"Wykr. zderzen [wl]"
 
 
 #MSG_CRASHDETECT_NA c=0 r=0
 #MSG_CRASHDETECT_NA c=0 r=0
 "Crash det.  [N/A]"
 "Crash det.  [N/A]"
-"\x00"
+"Wykr. zderzen [n/d]"
 
 
 #MSG_CRASHDETECT_OFF c=0 r=0
 #MSG_CRASHDETECT_OFF c=0 r=0
 "Crash det.  [off]"
 "Crash det.  [off]"
-"\x00"
+"Wykr. zderzen [wyl]"
 
 
 #MSG_CRASH_DETECTED c=20 r=1
 #MSG_CRASH_DETECTED c=20 r=1
 "Crash detected."
 "Crash detected."
-"\x00"
+"Zderzenie wykryte"
 
 
 #MSG_CURRENT c=19 r=1
 #MSG_CURRENT c=19 r=1
 "Current"
 "Current"
-"Tylko aktualne"
+"Aktualne"
 
 
 #MSG_DATE c=17 r=1
 #MSG_DATE c=17 r=1
 "Date:"
 "Date:"
@@ -212,39 +212,39 @@
 
 
 #MSG_DISABLE_STEPPERS c=0 r=0
 #MSG_DISABLE_STEPPERS c=0 r=0
 "Disable steppers"
 "Disable steppers"
-"Wylaczyc silniki"
+"Wylaczenie silnikow"
 
 
 #MSG_BABYSTEP_Z_NOT_SET c=20 r=12
 #MSG_BABYSTEP_Z_NOT_SET c=20 r=12
 "Distance between tip of the nozzle and the bed surface has not been set yet. Please follow the manual, chapter First steps, section First layer calibration."
 "Distance between tip of the nozzle and the bed surface has not been set yet. Please follow the manual, chapter First steps, section First layer calibration."
-"Odleglosc dyszy od podkladki nie jest skalibrowana. Postepuj zgodnie z instrukcja rozdzial Zaczynamy, podrozdzial Kalibracja pierwszej warstwy."
+"Odleglosc dyszy od powierzchni druku nie jest skalibrowana. Postepuj zgodnie z instrukcja: rozdzial Wprowadzenie - Kalibracja pierwszej warstwy."
 
 
 #MSG_WIZARD_REPEAT_V2_CAL c=20 r=7
 #MSG_WIZARD_REPEAT_V2_CAL c=20 r=7
 "Do you want to repeat last step to readjust distance between nozzle and heatbed?"
 "Do you want to repeat last step to readjust distance between nozzle and heatbed?"
-"Chcesz powtorzyc ostatni krok i przestawic odleglosc miedzy dysza a stolikiem?"
+"Chcesz powtorzyc ostatni krok i ponownie ustawic odleglosc miedzy dysza a stolikiem?"
 
 
 #MSG_EXTRUDER_CORRECTION c=9 r=0
 #MSG_EXTRUDER_CORRECTION c=9 r=0
 "E-correct"
 "E-correct"
-"\x00"
+"Korekcja E"
 
 
 #MSG_END_FILE_LIST c=0 r=0
 #MSG_END_FILE_LIST c=0 r=0
 "End file list"
 "End file list"
-"\x00"
+"Koniec listy plikow"
 
 
 #MSG_SELFTEST_ENDSTOP_NOTHIT c=20 r=1
 #MSG_SELFTEST_ENDSTOP_NOTHIT c=20 r=1
 "Endstop not hit"
 "Endstop not hit"
-"\x00"
+"Krancowka nie aktyw."
 
 
 #MSG_SELFTEST_ENDSTOP c=0 r=0
 #MSG_SELFTEST_ENDSTOP c=0 r=0
 "Endstop"
 "Endstop"
-"\x00"
+"Krancowka"
 
 
 #MSG_ENDSTOPS_HIT c=0 r=0
 #MSG_ENDSTOPS_HIT c=0 r=0
 "endstops hit: "
 "endstops hit: "
-"\x00"
+"krancowki aktywowane:"
 
 
 #MSG_SELFTEST_ENDSTOPS c=0 r=0
 #MSG_SELFTEST_ENDSTOPS c=0 r=0
 "Endstops"
 "Endstops"
-"\x00"
+"Krancowki"
 
 
 #MSG_Enqueing c=0 r=0
 #MSG_Enqueing c=0 r=0
 "enqueing \x22"
 "enqueing \x22"
@@ -252,15 +252,15 @@
 
 
 #MSG_STACK_ERROR c=20 r=4
 #MSG_STACK_ERROR c=20 r=4
 "Error - static memory has been overwritten"
 "Error - static memory has been overwritten"
-"\x00"
+"Blad - pamiec statyczna zostala nadpisana"
 
 
 #MSG_SD_ERR_WRITE_TO_FILE c=0 r=0
 #MSG_SD_ERR_WRITE_TO_FILE c=0 r=0
 "error writing to file"
 "error writing to file"
-"\x00"
+"blad zapisywania pliku"
 
 
 #MSG_FSENS_NOT_RESPONDING c=20 r=4
 #MSG_FSENS_NOT_RESPONDING c=20 r=4
 "ERROR: Filament sensor is not responding, please check connection."
 "ERROR: Filament sensor is not responding, please check connection."
-"\x00"
+"BLAD: Czujnik filamentu nie odpowiada, sprawdz polaczenie."
 
 
 #MSG_ERROR c=0 r=0
 #MSG_ERROR c=0 r=0
 "ERROR:"
 "ERROR:"
@@ -268,27 +268,27 @@
 
 
 #MSG_SELFTEST_EXTRUDER_FAN_SPEED c=18 r=0
 #MSG_SELFTEST_EXTRUDER_FAN_SPEED c=18 r=0
 "Extruder fan:"
 "Extruder fan:"
-"\x00"
+"Went. ekstrudera:"
 
 
 #MSG_INFO_EXTRUDER c=15 r=1
 #MSG_INFO_EXTRUDER c=15 r=1
 "Extruder info"
 "Extruder info"
-"\x00"
+"Informacje o ekstruderze"
 
 
 #MSG_MOVE_E c=0 r=0
 #MSG_MOVE_E c=0 r=0
 "Extruder"
 "Extruder"
-"\x00"
+"Ekstruder"
 
 
 #MSG_FSENS_AUTOLOAD_ON c=17 r=1
 #MSG_FSENS_AUTOLOAD_ON c=17 r=1
 "F. autoload  [on]"
 "F. autoload  [on]"
-"\x00"
+"Autoladowanie fil. [wl]"
 
 
 #MSG_FSENS_AUTOLOAD_NA c=17 r=1
 #MSG_FSENS_AUTOLOAD_NA c=17 r=1
 "F. autoload [N/A]"
 "F. autoload [N/A]"
-"\x00"
+"Autoladowanie fil. [N/D]"
 
 
 #MSG_FSENS_AUTOLOAD_OFF c=17 r=1
 #MSG_FSENS_AUTOLOAD_OFF c=17 r=1
 "F. autoload [off]"
 "F. autoload [off]"
-"\x00"
+"Autoladowanie [wyl]"
 
 
 #MSG_FAN_SPEED c=14 r=0
 #MSG_FAN_SPEED c=14 r=0
 "Fan speed"
 "Fan speed"
@@ -300,51 +300,51 @@
 
 
 #MSG_FANS_CHECK_ON c=17 r=1
 #MSG_FANS_CHECK_ON c=17 r=1
 "Fans check   [on]"
 "Fans check   [on]"
-"\x00"
+"Sprawdzanie wentylatorow [wl]"
 
 
 #MSG_FANS_CHECK_OFF c=17 r=1
 #MSG_FANS_CHECK_OFF c=17 r=1
 "Fans check  [off]"
 "Fans check  [off]"
-"\x00"
+"Sprawdzanie wentylatorow [wyl]"
 
 
 #MSG_FSENSOR_ON c=0 r=0
 #MSG_FSENSOR_ON c=0 r=0
 "Fil. sensor  [on]"
 "Fil. sensor  [on]"
-"\x00"
+"Czuj. filamentu. [wl]"
 
 
 #MSG_FSENSOR_NA c=0 r=0
 #MSG_FSENSOR_NA c=0 r=0
 "Fil. sensor [N/A]"
 "Fil. sensor [N/A]"
-"\x00"
+"Czuj. filamentu [N/D]"
 
 
 #MSG_FSENSOR_OFF c=0 r=0
 #MSG_FSENSOR_OFF c=0 r=0
 "Fil. sensor [off]"
 "Fil. sensor [off]"
-"\x00"
+"Czuj. fil. [wyl]"
 
 
 #MSG_FILAMENT_CLEAN c=20 r=2
 #MSG_FILAMENT_CLEAN c=20 r=2
 "Filament extruding & with correct color?"
 "Filament extruding & with correct color?"
-"Czy kolor jest czysty?"
+"Filament wychodzi z dyszy a kolor jest czysty?"
 
 
 #MSG_NOT_LOADED c=19 r=0
 #MSG_NOT_LOADED c=19 r=0
 "Filament not loaded"
 "Filament not loaded"
-"Brak filamentu"
+"Filament nie zaladowany"
 
 
 #MSG_FILAMENT_SENSOR c=20 r=0
 #MSG_FILAMENT_SENSOR c=20 r=0
 "Filament sensor"
 "Filament sensor"
-"\x00"
+"Czujnik filamentu"
 
 
 #MSG_SELFTEST_FILAMENT_SENSOR c=18 r=0
 #MSG_SELFTEST_FILAMENT_SENSOR c=18 r=0
 "Filament sensor:"
 "Filament sensor:"
-"\x00"
+"Czujnik filamentu:"
 
 
 #MSG_FILE_INCOMPLETE c=20 r=2
 #MSG_FILE_INCOMPLETE c=20 r=2
 "File incomplete. Continue anyway?"
 "File incomplete. Continue anyway?"
-"\x00"
+"Plik niekompletny. Kontynowac?"
 
 
 #MSG_SD_FILE_OPENED c=0 r=0
 #MSG_SD_FILE_OPENED c=0 r=0
 "File opened: "
 "File opened: "
-"\x00"
+"Otwarty plik:"
 
 
 #MSG_SD_FILE_SELECTED c=0 r=0
 #MSG_SD_FILE_SELECTED c=0 r=0
 "File selected"
 "File selected"
-"\x00"
+"Wybrano plik"
 
 
 #MSG_FINISHING_MOVEMENTS c=20 r=1
 #MSG_FINISHING_MOVEMENTS c=20 r=1
 "Finishing movements"
 "Finishing movements"
@@ -356,7 +356,7 @@
 
 
 #MSG_WIZARD_SELFTEST c=20 r=8
 #MSG_WIZARD_SELFTEST c=20 r=8
 "First, I will run the selftest to check most common assembly problems."
 "First, I will run the selftest to check most common assembly problems."
-"Najpierw wlacze autotest w celu kontrolli najczestszych problemow z montazem."
+"Najpierw wlacze selftest w celu sprawdzenia najczestszych problemow podczas montazu."
 
 
 #MSG_FLOW c=0 r=0
 #MSG_FLOW c=0 r=0
 "Flow"
 "Flow"
@@ -364,7 +364,7 @@
 
 
 #MSG_PRUSA3D_FORUM c=0 r=0
 #MSG_PRUSA3D_FORUM c=0 r=0
 "forum.prusa3d.com"
 "forum.prusa3d.com"
-"forum.prusa3d.cz"
+"\x00"
 
 
 #MSG_SELFTEST_COOLING_FAN c=20 r=0
 #MSG_SELFTEST_COOLING_FAN c=20 r=0
 "Front print fan?"
 "Front print fan?"
@@ -372,23 +372,23 @@
 
 
 #MSG_BED_CORRECTION_FRONT c=14 r=1
 #MSG_BED_CORRECTION_FRONT c=14 r=1
 "Front side[um]"
 "Front side[um]"
-"Do przodu [um]"
+"Przod [um]"
 
 
 #MSG_SELFTEST_FANS c=0 r=0
 #MSG_SELFTEST_FANS c=0 r=0
 "Front/left fans"
 "Front/left fans"
-"\x00"
+"Przedni/lewy wentylator"
 
 
 #MSG_SELFTEST_HEATERTHERMISTOR c=0 r=0
 #MSG_SELFTEST_HEATERTHERMISTOR c=0 r=0
 "Heater/Thermistor"
 "Heater/Thermistor"
-"\x00"
+"Grzalka/Termistor"
 
 
 #MSG_BED_HEATING_SAFETY_DISABLED c=0 r=0
 #MSG_BED_HEATING_SAFETY_DISABLED c=0 r=0
 "Heating disabled by safety timer."
 "Heating disabled by safety timer."
-"\x00"
+"Grzanie wylaczone przez wyl. czasowy"
 
 
 #MSG_HEATING_COMPLETE c=20 r=0
 #MSG_HEATING_COMPLETE c=20 r=0
 "Heating done."
 "Heating done."
-"Grzanie OK."
+"Grzanie zakonczone"
 
 
 #MSG_HEATING c=0 r=0
 #MSG_HEATING c=0 r=0
 "Heating"
 "Heating"
@@ -396,15 +396,15 @@
 
 
 #MSG_WIZARD_WELCOME c=20 r=7
 #MSG_WIZARD_WELCOME c=20 r=7
 "Hi, I am your Original Prusa i3 printer. Would you like me to guide you through the setup process?"
 "Hi, I am your Original Prusa i3 printer. Would you like me to guide you through the setup process?"
-"Czesc, jestem Twoja drukarka Original Prusa i3. Czy potrzebujesz pomocy z instalacja?"
+"Czesc, jestem Twoja drukarka Original Prusa i3. Czy potrzebujesz pomocy z ustawieniem?"
 
 
 #MSG_PRUSA3D_HOWTO c=0 r=0
 #MSG_PRUSA3D_HOWTO c=0 r=0
 "howto.prusa3d.com"
 "howto.prusa3d.com"
-"howto.prusa3d.cz"
+"\x00"
 
 
 #MSG_FILAMENTCHANGE c=0 r=0
 #MSG_FILAMENTCHANGE c=0 r=0
 "Change filament"
 "Change filament"
-"Wymienic filament"
+"Wymiana filamentu"
 
 
 #MSG_CHANGE_SUCCESS c=0 r=0
 #MSG_CHANGE_SUCCESS c=0 r=0
 "Change success!"
 "Change success!"
@@ -416,79 +416,79 @@
 
 
 #MSG_CHANGING_FILAMENT c=20 r=0
 #MSG_CHANGING_FILAMENT c=20 r=0
 "Changing filament!"
 "Changing filament!"
-"Wymiana filamentu"
+"Wymiana filamentu!"
 
 
 #MSG_SELFTEST_CHECK_BED c=20 r=0
 #MSG_SELFTEST_CHECK_BED c=20 r=0
 "Checking bed     "
 "Checking bed     "
-"Kontrola bed "
+"Kontrola stolu"
 
 
 #MSG_SELFTEST_CHECK_ENDSTOPS c=20 r=0
 #MSG_SELFTEST_CHECK_ENDSTOPS c=20 r=0
 "Checking endstops"
 "Checking endstops"
-"Kontrola endstops"
+"Kontrola krancowek"
 
 
 #MSG_SELFTEST_CHECK_HOTEND c=20 r=0
 #MSG_SELFTEST_CHECK_HOTEND c=20 r=0
 "Checking hotend  "
 "Checking hotend  "
-"Kontrola hotend "
+"Kontrola hotendu"
 
 
 #MSG_SELFTEST_CHECK_FSENSOR c=20 r=0
 #MSG_SELFTEST_CHECK_FSENSOR c=20 r=0
 "Checking sensors "
 "Checking sensors "
-"\x00"
+"Sprawdzanie czujnikow"
 
 
 #MSG_SELFTEST_CHECK_X c=20 r=0
 #MSG_SELFTEST_CHECK_X c=20 r=0
 "Checking X axis  "
 "Checking X axis  "
-"Kontrola X axis "
+"Kontrola osi X"
 
 
 #MSG_SELFTEST_CHECK_Y c=20 r=0
 #MSG_SELFTEST_CHECK_Y c=20 r=0
 "Checking Y axis  "
 "Checking Y axis  "
-"Kontrola Y axis "
+"Kontrola osi Y"
 
 
 #MSG_SELFTEST_CHECK_Z c=20 r=0
 #MSG_SELFTEST_CHECK_Z c=20 r=0
 "Checking Z axis  "
 "Checking Z axis  "
-"Kontrola Z axis "
+"Kontrola osi Z"
 
 
 #MSG_ERR_CHECKSUM_MISMATCH c=0 r=0
 #MSG_ERR_CHECKSUM_MISMATCH c=0 r=0
 "checksum mismatch, Last Line: "
 "checksum mismatch, Last Line: "
-"\x00"
+"suma kontrolna niezgodna, ostatnia linia:"
 
 
 #MSG_CHOOSE_EXTRUDER c=20 r=1
 #MSG_CHOOSE_EXTRUDER c=20 r=1
 "Choose extruder:"
 "Choose extruder:"
-"Wybierz ekstruder"
+"Wybierz ekstruder:"
 
 
 #MSG_WIZARD_XYZ_CAL c=20 r=8
 #MSG_WIZARD_XYZ_CAL c=20 r=8
 "I will run xyz calibration now. It will take approx. 12 mins."
 "I will run xyz calibration now. It will take approx. 12 mins."
-"Wlaczam kalibracje xyz. Zajmie to ok. 12 min."
+"Przeprowadze teraz kalibracje XYZ. Zajmie ok. 12 min."
 
 
 #MSG_WIZARD_Z_CAL c=20 r=8
 #MSG_WIZARD_Z_CAL c=20 r=8
 "I will run z calibration now."
 "I will run z calibration now."
-"Wlaczam kalibracje z."
+"Przeprowadze kalibracje Z."
 
 
 #MSG_WIZARD_V2_CAL_2 c=20 r=12
 #MSG_WIZARD_V2_CAL_2 c=20 r=12
 "I will start to print line and you will gradually lower the nozzle by rotating the knob, until you reach optimal height. Check the pictures in our handbook in chapter Calibration."
 "I will start to print line and you will gradually lower the nozzle by rotating the knob, until you reach optimal height. Check the pictures in our handbook in chapter Calibration."
-"Zaczne drukowac linie. Stopniowo opuszczaj dysze przekrecajac guzik, poki nie uzyskasz optymalnej wysokosci. Sprawdz obrazki w naszym poradniku w rozdz. Kalibracja"
+"Zaczne drukowac linie. Stopniowo opuszczaj dysze przekrecajac pokretlo, poki nie uzyskasz optymalnej wysokosci. Sprawdz obrazki w naszym Podreczniku w rozdz. Kalibracja"
 
 
 #MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 c=60 r=0
 #MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 c=60 r=0
 "Improving bed calibration point"
 "Improving bed calibration point"
-"Poprawiam precyzyjnosc punktu kalibracyjnego"
+"Poprawiam precyzje punktu kalibracyjnego"
 
 
 #MSG_WATCH c=0 r=0
 #MSG_WATCH c=0 r=0
 "Info screen"
 "Info screen"
-"Informacje"
+"Ekran informacyjny"
 
 
 #MSG_FILAMENT_LOADING_T0 c=20 r=4
 #MSG_FILAMENT_LOADING_T0 c=20 r=4
 "Insert filament into extruder 1. Click when done."
 "Insert filament into extruder 1. Click when done."
-"Wloz filament do ekstrudera 1. Potwierdz przyciskiem."
+"Wloz filament do ekstrudera 1. Potwierdz naciskajac pokretlo."
 
 
 #MSG_FILAMENT_LOADING_T1 c=20 r=4
 #MSG_FILAMENT_LOADING_T1 c=20 r=4
 "Insert filament into extruder 2. Click when done."
 "Insert filament into extruder 2. Click when done."
-"Wloz filament do ekstrudera 2. Potwierdz przyciskiem."
+"Wloz filament do ekstrudera 2. Potwierdz naciskajac pokretlo."
 
 
 #MSG_FILAMENT_LOADING_T2 c=20 r=4
 #MSG_FILAMENT_LOADING_T2 c=20 r=4
 "Insert filament into extruder 3. Click when done."
 "Insert filament into extruder 3. Click when done."
-"Wloz filament do ekstrudera 3. Potwierdz przyciskiem."
+"Wloz filament do ekstrudera 3. Potwierdz naciskajac pokretlo."
 
 
 #MSG_FILAMENT_LOADING_T3 c=20 r=4
 #MSG_FILAMENT_LOADING_T3 c=20 r=4
 "Insert filament into extruder 4. Click when done."
 "Insert filament into extruder 4. Click when done."
-"Wloz filament do ekstrudera 4. Potwierdz przyciskiem."
+"Wloz filament do ekstrudera 4. Potwierdz naciskajac pokretlo."
 
 
 #MSG_INSERT_FILAMENT c=20 r=0
 #MSG_INSERT_FILAMENT c=20 r=0
 "Insert filament"
 "Insert filament"
@@ -508,7 +508,7 @@
 
 
 #MSG_STEEL_SHEET_CHECK c=20 r=2
 #MSG_STEEL_SHEET_CHECK c=20 r=2
 "Is steel sheet on heatbed?"
 "Is steel sheet on heatbed?"
-"\x00"
+"Czy plyta stal. jest na podgrzew. stole?"
 
 
 #MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION c=20 r=0
 #MSG_FIND_BED_OFFSET_AND_SKEW_ITERATION c=20 r=0
 "Iteration "
 "Iteration "
@@ -516,23 +516,23 @@
 
 
 #MSG_KILLED c=0 r=0
 #MSG_KILLED c=0 r=0
 "KILLED. "
 "KILLED. "
-"\x00"
+"PRZERWANE."
 
 
 #MSG_SELFTEST_EXTRUDER_FAN c=20 r=0
 #MSG_SELFTEST_EXTRUDER_FAN c=20 r=0
 "Left hotend fan?"
 "Left hotend fan?"
-"Lewy went na dysze?"
+"Lewy went hotendu?"
 
 
 #MSG_BED_CORRECTION_LEFT c=14 r=1
 #MSG_BED_CORRECTION_LEFT c=14 r=1
 "Left side [um]"
 "Left side [um]"
-"W lewo [um]"
+"Lewo [um]"
 
 
 #MSG_BABYSTEP_Z c=0 r=0
 #MSG_BABYSTEP_Z c=0 r=0
 "Live adjust Z"
 "Live adjust Z"
-"Dostrojenie osy Z"
+"Dostrajanie osi Z"
 
 
 #MSG_LOAD_FILAMENT c=17 r=0
 #MSG_LOAD_FILAMENT c=17 r=0
 "Load filament"
 "Load filament"
-"Wprowadz filament"
+"Ladowanie filamentu"
 
 
 #MSG_LOADING_COLOR c=0 r=0
 #MSG_LOADING_COLOR c=0 r=0
 "Loading color"
 "Loading color"
@@ -540,23 +540,23 @@
 
 
 #MSG_LOADING_FILAMENT c=20 r=0
 #MSG_LOADING_FILAMENT c=20 r=0
 "Loading filament"
 "Loading filament"
-"Wprow. filamentu"
+"Ladowanie filamentu"
 
 
 #MSG_LOOSE_PULLEY c=20 r=1
 #MSG_LOOSE_PULLEY c=20 r=1
 "Loose pulley"
 "Loose pulley"
-"Kolo pasowe"
+"Luzne kolo pasowe"
 
 
 #MSG_M104_INVALID_EXTRUDER c=0 r=0
 #MSG_M104_INVALID_EXTRUDER c=0 r=0
 "M104 Invalid extruder "
 "M104 Invalid extruder "
-"\x00"
+"M104 Nieprawidlowy ekstruder"
 
 
 #MSG_M105_INVALID_EXTRUDER c=0 r=0
 #MSG_M105_INVALID_EXTRUDER c=0 r=0
 "M105 Invalid extruder "
 "M105 Invalid extruder "
-"\x00"
+"M105 Nieprawidlowy ekstruder"
 
 
 #MSG_M109_INVALID_EXTRUDER c=0 r=0
 #MSG_M109_INVALID_EXTRUDER c=0 r=0
 "M109 Invalid extruder "
 "M109 Invalid extruder "
-"\x00"
+"M109 Nieprawidlowy ekstruder"
 
 
 #MSG_M117_V2_CALIBRATION c=25 r=1
 #MSG_M117_V2_CALIBRATION c=25 r=1
 "M117 First layer cal."
 "M117 First layer cal."
@@ -564,15 +564,15 @@
 
 
 #MSG_M200_INVALID_EXTRUDER c=0 r=0
 #MSG_M200_INVALID_EXTRUDER c=0 r=0
 "M200 Invalid extruder "
 "M200 Invalid extruder "
-"\x00"
+"M200 Nieprawidlowy ekstruder"
 
 
 #MSG_M218_INVALID_EXTRUDER c=0 r=0
 #MSG_M218_INVALID_EXTRUDER c=0 r=0
 "M218 Invalid extruder "
 "M218 Invalid extruder "
-"\x00"
+"M218 Nieprawidlowy ekstruder"
 
 
 #MSG_M221_INVALID_EXTRUDER c=0 r=0
 #MSG_M221_INVALID_EXTRUDER c=0 r=0
 "M221 Invalid extruder "
 "M221 Invalid extruder "
-"\x00"
+"M221 Nieprawidlowy ekstruder"
 
 
 #MSG_MAIN c=0 r=0
 #MSG_MAIN c=0 r=0
 "Main"
 "Main"
@@ -584,11 +584,11 @@
 
 
 #MSG_MESH_BED_LEVELING c=0 r=0
 #MSG_MESH_BED_LEVELING c=0 r=0
 "Mesh Bed Leveling"
 "Mesh Bed Leveling"
-"\x00"
+"Poziomowanie stolu wg siatki"
 
 
 #MSG_STEALTH_MODE_OFF c=0 r=0
 #MSG_STEALTH_MODE_OFF c=0 r=0
 "Mode     [Normal]"
 "Mode     [Normal]"
-"\x00"
+"Tryb [normalny]"
 
 
 #MSG_SILENT_MODE_ON c=0 r=0
 #MSG_SILENT_MODE_ON c=0 r=0
 "Mode     [silent]"
 "Mode     [silent]"
@@ -596,15 +596,15 @@
 
 
 #MSG_STEALTH_MODE_ON c=0 r=0
 #MSG_STEALTH_MODE_ON c=0 r=0
 "Mode    [Stealth]"
 "Mode    [Stealth]"
-"\x00"
+"Tryb [Stealth]"
 
 
 #MSG_AUTO_MODE_ON c=0 r=0
 #MSG_AUTO_MODE_ON c=0 r=0
 "Mode [auto power]"
 "Mode [auto power]"
-"\x00"
+"Tryb [automatyczny]"
 
 
 #MSG_SILENT_MODE_OFF c=0 r=0
 #MSG_SILENT_MODE_OFF c=0 r=0
 "Mode [high power]"
 "Mode [high power]"
-"Tryb[w wydajnosc]"
+"Tryb [wysoka wydajnosc]"
 
 
 #MSG_SELFTEST_MOTOR c=0 r=0
 #MSG_SELFTEST_MOTOR c=0 r=0
 "Motor"
 "Motor"
@@ -616,23 +616,23 @@
 
 
 #MSG_MOVE_X c=0 r=0
 #MSG_MOVE_X c=0 r=0
 "Move X"
 "Move X"
-"Przesunac X"
+"Ruch osi X"
 
 
 #MSG_MOVE_Y c=0 r=0
 #MSG_MOVE_Y c=0 r=0
 "Move Y"
 "Move Y"
-"Przesunac Y"
+"Ruch osi Y"
 
 
 #MSG_MOVE_Z c=0 r=0
 #MSG_MOVE_Z c=0 r=0
 "Move Z"
 "Move Z"
-"Przesunac Z"
+"Ruch osi Z"
 
 
 #MSG_ERR_NO_CHECKSUM c=0 r=0
 #MSG_ERR_NO_CHECKSUM c=0 r=0
 "No Checksum with line number, Last Line: "
 "No Checksum with line number, Last Line: "
-"\x00"
+"Brak sumy kontrolnej z numerem linii, ostatnia linia:"
 
 
 #MSG_NO_MOVE c=0 r=0
 #MSG_NO_MOVE c=0 r=0
 "No move."
 "No move."
-"\x00"
+"Brak ruchu."
 
 
 #MSG_NO_CARD c=0 r=0
 #MSG_NO_CARD c=0 r=0
 "No SD card"
 "No SD card"
@@ -652,7 +652,7 @@
 
 
 #MSG_WIZARD_V2_CAL c=20 r=8
 #MSG_WIZARD_V2_CAL c=20 r=8
 "Now I will calibrate distance between tip of the nozzle and heatbed surface."
 "Now I will calibrate distance between tip of the nozzle and heatbed surface."
-"Kalibruje odleglosc miedzy koncowka dyszy a stolikiem."
+"Kalibruje odleglosc miedzy koncowka dyszy a powierzchnia druku."
 
 
 #MSG_WIZARD_WILL_PREHEAT c=20 r=4
 #MSG_WIZARD_WILL_PREHEAT c=20 r=4
 "Now I will preheat nozzle for PLA."
 "Now I will preheat nozzle for PLA."
@@ -668,27 +668,27 @@
 
 
 #MSG_DEFAULT_SETTINGS_LOADED c=20 r=4
 #MSG_DEFAULT_SETTINGS_LOADED c=20 r=4
 "Old settings found. Default PID, Esteps etc. will be set."
 "Old settings found. Default PID, Esteps etc. will be set."
-"\x00"
+"Znaleziono stare ustawienia. Zostana przywrocone domyslne ust. PID, Esteps, itp."
 
 
 #MSG_SD_OPEN_FILE_FAIL c=0 r=0
 #MSG_SD_OPEN_FILE_FAIL c=0 r=0
 "open failed, File: "
 "open failed, File: "
-"\x00"
+"niepowodzenie otwarcia, Plik:"
 
 
 #MSG_ENDSTOP_OPEN c=0 r=0
 #MSG_ENDSTOP_OPEN c=0 r=0
 "open"
 "open"
-"\x00"
+"otworz"
 
 
 #MSG_SD_OPENROOT_FAIL c=0 r=0
 #MSG_SD_OPENROOT_FAIL c=0 r=0
 "openRoot failed"
 "openRoot failed"
-"\x00"
+"niepowodzenie openRoot "
 
 
 #MSG_PAUSE_PRINT c=0 r=0
 #MSG_PAUSE_PRINT c=0 r=0
 "Pause print"
 "Pause print"
-"Przerwac druk"
+"Wstrzymanie wydruku"
 
 
 #MSG_PID_RUNNING c=20 r=1
 #MSG_PID_RUNNING c=20 r=1
 "PID cal.           "
 "PID cal.           "
-"Kal. PID"
+"Kalibracja PID"
 
 
 #MSG_PID_FINISHED c=20 r=1
 #MSG_PID_FINISHED c=20 r=1
 "PID cal. finished"
 "PID cal. finished"
@@ -700,59 +700,59 @@
 
 
 #MSG_PINDA_PREHEAT c=20 r=1
 #MSG_PINDA_PREHEAT c=20 r=1
 "PINDA Heating"
 "PINDA Heating"
-"Grzanie PINDA"
+"Grzanie sondy PINDA"
 
 
 #MSG_PAPER c=20 r=8
 #MSG_PAPER c=20 r=8
 "Place a sheet of paper under the nozzle during the calibration of first 4 points. If the nozzle catches the paper, power off the printer immediately."
 "Place a sheet of paper under the nozzle during the calibration of first 4 points. If the nozzle catches the paper, power off the printer immediately."
-"Umiesc kartke papieru na podkladce i trzymaj pod dysza podczas pomiaru pierwszych 4 punktow. Jesli dysza zahaczy o papier, wylacz drukarke."
+"Umiesc kartke papieru na stole roboczym i podczas pomiaru pierwszych 4 punktow. Jesli dysza zahaczy o papier, natychmiast wylacz drukarke."
 
 
 #MSG_WIZARD_CLEAN_HEATBED c=20 r=8
 #MSG_WIZARD_CLEAN_HEATBED c=20 r=8
 "Please clean heatbed and then press the knob."
 "Please clean heatbed and then press the knob."
-"Prosze oczysc stolik i nacisnij guzik."
+"Oczysc powierzchnie druku i nacisnij pokretlo."
 
 
 #MSG_CONFIRM_NOZZLE_CLEAN c=20 r=8
 #MSG_CONFIRM_NOZZLE_CLEAN c=20 r=8
 "Please clean the nozzle for calibration. Click when done."
 "Please clean the nozzle for calibration. Click when done."
-"Dla prawidl. kalibracji prosze oczyscic dysze. Potw. guzikiem."
+"Dla prawidl. kalibracji nalezy oczyscic dysze. Potw. guzikiem."
 
 
 #MSG_SELFTEST_PLEASECHECK c=0 r=0
 #MSG_SELFTEST_PLEASECHECK c=0 r=0
 "Please check :"
 "Please check :"
-"Skontroluj :"
+"Sprawdz :"
 
 
 #MSG_WIZARD_CALIBRATION_FAILED c=20 r=8
 #MSG_WIZARD_CALIBRATION_FAILED c=20 r=8
 "Please check our handbook and fix the problem. Then resume the Wizard by rebooting the printer."
 "Please check our handbook and fix the problem. Then resume the Wizard by rebooting the printer."
-"Prosze sprawdz nasz poradnik i napraw problem. Potem przywroc Wizard restartujac drukarke."
+"Przeczytaj nasz Podrecznik druku 3D aby naprawic problem. Potem wznow Asystenta przez restart drukarki."
 
 
 #MSG_WIZARD_LOAD_FILAMENT c=20 r=8
 #MSG_WIZARD_LOAD_FILAMENT c=20 r=8
 "Please insert PLA filament to the extruder, then press knob to load it."
 "Please insert PLA filament to the extruder, then press knob to load it."
-"Prosze umiesc filament PLA w ekstruderze i nacisnij przycisk by zaladowac."
+"Umiesc filament PLA w ekstruderze i nacisnij pokretlo, aby zaladowac."
 
 
 #MSG_WIZARD_INSERT_CORRECT_FILAMENT c=20 r=8
 #MSG_WIZARD_INSERT_CORRECT_FILAMENT c=20 r=8
 "Please load PLA filament and then resume Wizard by rebooting the printer."
 "Please load PLA filament and then resume Wizard by rebooting the printer."
-"Prosze zaladuj filament PLA i przywroc Wizard przez restart drukarki."
+"Zaladuj filament PLA i przywroc Asystenta przez restart drukarki."
 
 
 #MSG_PLEASE_LOAD_PLA c=20 r=4
 #MSG_PLEASE_LOAD_PLA c=20 r=4
 "Please load PLA filament first."
 "Please load PLA filament first."
-"Prosze, najpierw zaladuj filament PLA."
+"Najpierw zaladuj filament PLA."
 
 
 #MSG_CHECK_IDLER c=20 r=4
 #MSG_CHECK_IDLER c=20 r=4
 "Please open idler and remove filament manually."
 "Please open idler and remove filament manually."
-"\x00"
+"Prosze odciagnac dzwignie dociskowa ekstrudera i recznie usunac filament."
 
 
 #MSG_PLACE_STEEL_SHEET c=20 r=4
 #MSG_PLACE_STEEL_SHEET c=20 r=4
 "Please place steel sheet on heatbed."
 "Please place steel sheet on heatbed."
-"\x00"
+"Prosze umiescic plyte stalowa na stole podgrzewanym."
 
 
 #MSG_PRESS_TO_UNLOAD c=20 r=4
 #MSG_PRESS_TO_UNLOAD c=20 r=4
 "Please press the knob to unload filament"
 "Please press the knob to unload filament"
-"\x00"
+"Nacisnij pokretlo aby rozladowac filament"
 
 
 #MSG_PULL_OUT_FILAMENT c=20 r=4
 #MSG_PULL_OUT_FILAMENT c=20 r=4
 "Please pull out filament immediately"
 "Please pull out filament immediately"
-"\x00"
+"Wyciagnij filament teraz"
 
 
 #MSG_REMOVE_STEEL_SHEET c=20 r=4
 #MSG_REMOVE_STEEL_SHEET c=20 r=4
 "Please remove steel sheet from heatbed."
 "Please remove steel sheet from heatbed."
-"\x00"
+"Prosze zdjac plyte stalowa z podgrzewanego stolu."
 
 
 #MSG_PLEASE_WAIT c=20 r=0
 #MSG_PLEASE_WAIT c=20 r=0
 "Please wait"
 "Please wait"
@@ -760,7 +760,7 @@
 
 
 #MSG_POWERUP c=0 r=0
 #MSG_POWERUP c=0 r=0
 "PowerUp"
 "PowerUp"
-"\x00"
+"Uruchamianie"
 
 
 #MSG_PREHEAT_NOZZLE c=20 r=0
 #MSG_PREHEAT_NOZZLE c=20 r=0
 "Preheat the nozzle!"
 "Preheat the nozzle!"
@@ -776,7 +776,7 @@
 
 
 #MSG_PRESS_TO_PREHEAT c=20 r=4
 #MSG_PRESS_TO_PREHEAT c=20 r=4
 "Press knob to preheat nozzle and continue."
 "Press knob to preheat nozzle and continue."
-"\x00"
+"Wcisnij pokretlo aby rozgrzac dysze i kontynuowac."
 
 
 #MSG_PRINT_ABORTED c=20 r=0
 #MSG_PRINT_ABORTED c=20 r=0
 "Print aborted"
 "Print aborted"
@@ -784,27 +784,27 @@
 
 
 #MSG_SELFTEST_PRINT_FAN_SPEED c=18 r=0
 #MSG_SELFTEST_PRINT_FAN_SPEED c=18 r=0
 "Print fan:"
 "Print fan:"
-"\x00"
+"Went. wydruku:"
 
 
 #MSG_CARD_MENU c=0 r=0
 #MSG_CARD_MENU c=0 r=0
 "Print from SD"
 "Print from SD"
-"Druk z SD"
+"Druk z karty SD"
 
 
 #MSG_PRINT_PAUSED c=20 r=1
 #MSG_PRINT_PAUSED c=20 r=1
 "Print paused"
 "Print paused"
-"Druk zatrzymany"
+"Druk wstrzymany"
 
 
 #MSG_ERR_KILLED c=0 r=0
 #MSG_ERR_KILLED c=0 r=0
 "Printer halted. kill() called!"
 "Printer halted. kill() called!"
-"\x00"
+"Drukarka zatrzymana. Wywolano komende kill()!"
 
 
 #MSG_FOLLOW_CALIBRATION_FLOW c=20 r=8
 #MSG_FOLLOW_CALIBRATION_FLOW c=20 r=8
 "Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow."
 "Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow."
-"Drukarka nie zostala jeszcze skalibrowana. Prosze kierowac sie instrukcja, rozdzial Zaczynamy, podrozdzial Selftest."
+"Drukarka nie zostala jeszcze skalibrowana. Kieruj sie Samouczkiem: rozdzial Pierwsze Kroki, sekcja Konfiguracja przed drukowaniem."
 
 
 #MSG_ERR_STOPPED c=0 r=0
 #MSG_ERR_STOPPED c=0 r=0
 "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
 "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
-"\x00"
+"Drukarka zatrzymana z powodu bledow. Usun problem i uzyj M999 aby zrestartowac. (Temperatura jest zresetowana, ustaw ja po restarcie)"
 
 
 #WELCOME_MSG c=20 r=0
 #WELCOME_MSG c=20 r=0
 "Prusa i3 MK3 ready."
 "Prusa i3 MK3 ready."
@@ -812,19 +812,19 @@
 
 
 #MSG_PRUSA3D c=0 r=0
 #MSG_PRUSA3D c=0 r=0
 "prusa3d.com"
 "prusa3d.com"
-"prusa3d.cz"
+"\x00"
 
 
 #MSG_BED_CORRECTION_REAR c=14 r=1
 #MSG_BED_CORRECTION_REAR c=14 r=1
 "Rear side [um]"
 "Rear side [um]"
-"Do tylu [um]"
+"Tyl [um]"
 
 
 #MSG_RECOVERING_PRINT c=20 r=1
 #MSG_RECOVERING_PRINT c=20 r=1
 "Recovering print    "
 "Recovering print    "
-"\x00"
+"Wznawianie wydruku"
 
 
 #MSG_M119_REPORT c=0 r=0
 #MSG_M119_REPORT c=0 r=0
 "Reporting endstop status"
 "Reporting endstop status"
-"\x00"
+"Raportowanie statusu krancowek"
 
 
 #MSG_CALIBRATE_BED_RESET c=0 r=0
 #MSG_CALIBRATE_BED_RESET c=0 r=0
 "Reset XYZ calibr."
 "Reset XYZ calibr."
@@ -836,43 +836,43 @@
 
 
 #MSG_RESUME_PRINT c=0 r=0
 #MSG_RESUME_PRINT c=0 r=0
 "Resume print"
 "Resume print"
-"Kontynuowac"
+"Wznowic wydruk"
 
 
 #MSG_RESUMING_PRINT c=20 r=1
 #MSG_RESUMING_PRINT c=20 r=1
 "Resuming print"
 "Resuming print"
-"Wznowienie druku"
+"Wznawianie druku"
 
 
 #MSG_BED_CORRECTION_RIGHT c=14 r=1
 #MSG_BED_CORRECTION_RIGHT c=14 r=1
 "Right side[um]"
 "Right side[um]"
-"W prawo [um]"
+"Prawo [um]"
 
 
 #MSG_SECOND_SERIAL_ON c=17 r=1
 #MSG_SECOND_SERIAL_ON c=17 r=1
 "RPi port     [on]"
 "RPi port     [on]"
-"\x00"
+"Port RPi [wl]"
 
 
 #MSG_SECOND_SERIAL_OFF c=17 r=1
 #MSG_SECOND_SERIAL_OFF c=17 r=1
 "RPi port    [off]"
 "RPi port    [off]"
-"\x00"
+"Port RPi [wyl]"
 
 
 #MSG_WIZARD_RERUN c=20 r=7
 #MSG_WIZARD_RERUN c=20 r=7
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
-"Wlaczenie Wizard usunie obecne dane kalibracyjne i zacznie od nowa. Kontynuowac?"
+"Wlaczenie Asystenta usunie obecne dane kalibracyjne i zacznie od poczatku. Kontynuowac?"
 
 
 #MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1
 #MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1
 "SD card  [normal]"
 "SD card  [normal]"
-"karta SD [normal]"
+"Karta SD [normalna]"
 
 
 #MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
 #MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
 "SD card [FlshAir]"
 "SD card [FlshAir]"
-"karta SD[FlshAir]"
+"Karta SD [FlashAir]"
 
 
 #MSG_SD_CARD_OK c=0 r=0
 #MSG_SD_CARD_OK c=0 r=0
 "SD card ok"
 "SD card ok"
-"\x00"
+"Karta SD OK"
 
 
 #MSG_SD_INIT_FAIL c=0 r=0
 #MSG_SD_INIT_FAIL c=0 r=0
 "SD init fail"
 "SD init fail"
-"\x00"
+"Inicjalizacja karty SD nieudana"
 
 
 #MSG_SD_PRINTING_BYTE c=0 r=0
 #MSG_SD_PRINTING_BYTE c=0 r=0
 "SD printing byte "
 "SD printing byte "
@@ -880,7 +880,7 @@
 
 
 #MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 c=60 r=0
 #MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 c=60 r=0
 "Searching bed calibration point"
 "Searching bed calibration point"
-"Szukam punktu kalibracyjnego podkladki"
+"Szukam punktu kalibracyjnego na stole"
 
 
 #MSG_LANGUAGE_SELECT c=0 r=0
 #MSG_LANGUAGE_SELECT c=0 r=0
 "Select language"
 "Select language"
@@ -888,11 +888,11 @@
 
 
 #MSG_SELFTEST_OK c=0 r=0
 #MSG_SELFTEST_OK c=0 r=0
 "Self test OK"
 "Self test OK"
-"\x00"
+"Selftest OK"
 
 
 #MSG_SELFTEST_START c=20 r=0
 #MSG_SELFTEST_START c=20 r=0
 "Self test start  "
 "Self test start  "
-"Self test start "
+"Rozpoczynanie Selftestu"
 
 
 #MSG_SELFTEST c=0 r=0
 #MSG_SELFTEST c=0 r=0
 "Selftest         "
 "Selftest         "
@@ -900,7 +900,7 @@
 
 
 #MSG_SELFTEST_ERROR c=0 r=0
 #MSG_SELFTEST_ERROR c=0 r=0
 "Selftest error !"
 "Selftest error !"
-"\x00"
+"Blad selftest !"
 
 
 #MSG_SELFTEST_FAILED c=20 r=0
 #MSG_SELFTEST_FAILED c=20 r=0
 "Selftest failed  "
 "Selftest failed  "
@@ -908,11 +908,11 @@
 
 
 #MSG_FORCE_SELFTEST c=20 r=8
 #MSG_FORCE_SELFTEST c=20 r=8
 "Selftest will be run to calibrate accurate sensorless rehoming."
 "Selftest will be run to calibrate accurate sensorless rehoming."
-"\x00"
+"Zostanie uruchomiony Selftest aby dokladnie skalibrowac punkt bazowy bez krancowek"
 
 
 #MSG_SET_TEMPERATURE c=19 r=1
 #MSG_SET_TEMPERATURE c=19 r=1
 "Set temperature:"
 "Set temperature:"
-"Ustawic temperature"
+"Ustaw. temperatury:"
 
 
 #MSG_SETTINGS c=0 r=0
 #MSG_SETTINGS c=0 r=0
 "Settings"
 "Settings"
@@ -924,27 +924,27 @@
 
 
 #MSG_DWELL c=0 r=0
 #MSG_DWELL c=0 r=0
 "Sleep..."
 "Sleep..."
-"\x00"
+"Czuwanie..."
 
 
 #MSG_FILE_CNT c=20 r=4
 #MSG_FILE_CNT c=20 r=4
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
-"\x00"
+"Niektore pliki nie zostana posortowane. Max. liczba plikow w 1 folderze = 100."
 
 
 #MSG_SORT_NONE c=17 r=1
 #MSG_SORT_NONE c=17 r=1
 "Sort:      [None]"
 "Sort:      [None]"
-"\x00"
+"Sortowanie:[brak]"
 
 
 #MSG_SORT_TIME c=17 r=1
 #MSG_SORT_TIME c=17 r=1
 "Sort:      [Time]"
 "Sort:      [Time]"
-"\x00"
+"Sortowanie:[czas]"
 
 
 #MSG_SORT_ALPHA c=17 r=1
 #MSG_SORT_ALPHA c=17 r=1
 "Sort:  [Alphabet]"
 "Sort:  [Alphabet]"
-"\x00"
+"Sort.:[alfabet]"
 
 
 #MSG_SORTING c=20 r=1
 #MSG_SORTING c=20 r=1
 "Sorting files"
 "Sorting files"
-"\x00"
+"Sortowanie plikow"
 
 
 #MSG_SPEED c=0 r=0
 #MSG_SPEED c=0 r=0
 "Speed"
 "Speed"
@@ -956,15 +956,15 @@
 
 
 #MSG_TEMP_CAL_WARNING c=20 r=4
 #MSG_TEMP_CAL_WARNING c=20 r=4
 "Stable ambient temperature 21-26C is needed a rigid stand is required."
 "Stable ambient temperature 21-26C is needed a rigid stand is required."
-"\x00"
+"Potrzebna jest stabilna temperatura otoczenia 21-26C i stabilne podloze."
 
 
 #MSG_STATISTICS c=0 r=0
 #MSG_STATISTICS c=0 r=0
 "Statistics  "
 "Statistics  "
-"Statystyka "
+"Statystyki"
 
 
 #MSG_STEPPER_TOO_HIGH c=0 r=0
 #MSG_STEPPER_TOO_HIGH c=0 r=0
 "Steprate too high: "
 "Steprate too high: "
-"\x00"
+"Liczba krokow zbyt wysoka:"
 
 
 #MSG_STOP_PRINT c=0 r=0
 #MSG_STOP_PRINT c=0 r=0
 "Stop print"
 "Stop print"
@@ -972,39 +972,39 @@
 
 
 #MSG_STOPPED c=0 r=0
 #MSG_STOPPED c=0 r=0
 "STOPPED. "
 "STOPPED. "
-"\x00"
+"ZATRZYMANO."
 
 
 #MSG_SUPPORT c=0 r=0
 #MSG_SUPPORT c=0 r=0
 "Support"
 "Support"
-"Pomoc"
+"Wsparcie"
 
 
 #MSG_SELFTEST_SWAPPED c=0 r=0
 #MSG_SELFTEST_SWAPPED c=0 r=0
 "Swapped"
 "Swapped"
-"\x00"
+"Zamieniono"
 
 
 #MSG_TEMP_CALIBRATION c=20 r=1
 #MSG_TEMP_CALIBRATION c=20 r=1
 "Temp. cal.          "
 "Temp. cal.          "
-"Ciepl. kal. "
+"Kalibracja temp."
 
 
 #MSG_TEMP_CALIBRATION_ON c=20 r=1
 #MSG_TEMP_CALIBRATION_ON c=20 r=1
 "Temp. cal.   [on]"
 "Temp. cal.   [on]"
-"Ciepl. kal. [ON]"
+"Kalibr. temp. [wl]"
 
 
 #MSG_TEMP_CALIBRATION_OFF c=20 r=1
 #MSG_TEMP_CALIBRATION_OFF c=20 r=1
 "Temp. cal.  [off]"
 "Temp. cal.  [off]"
-"Ciepl. kal. [OFF]"
+"Kalibr. temp. [wyl]"
 
 
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 "Temp. calibration"
 "Temp. calibration"
-"Cieplna kalibr."
+"Kalibracja temp."
 
 
 #MSG_TEMP_CAL_FAILED c=20 r=8
 #MSG_TEMP_CAL_FAILED c=20 r=8
 "Temperature calibration failed"
 "Temperature calibration failed"
-"\x00"
+"Kalibracja temperaturowa nieudana"
 
 
 #MSG_TEMP_CALIBRATION_DONE c=20 r=12
 #MSG_TEMP_CALIBRATION_DONE c=20 r=12
 "Temperature calibration is finished and active. Temp. calibration can be disabled in menu Settings->Temp. cal."
 "Temperature calibration is finished and active. Temp. calibration can be disabled in menu Settings->Temp. cal."
-"Cieplna kalibracja zakonczona. Kontynuuj przyciskiem"
+"Kalibracja temperaturowa zakonczona i wlaczona. Moze byc wylaczona z menu Ustawienia -> Kalibracja temp."
 
 
 #MSG_TEMPERATURE c=0 r=0
 #MSG_TEMPERATURE c=0 r=0
 "Temperature"
 "Temperature"
@@ -1012,63 +1012,63 @@
 
 
 #MSG_MENU_TEMPERATURES c=15 r=1
 #MSG_MENU_TEMPERATURES c=15 r=1
 "Temperatures"
 "Temperatures"
-"\x00"
+"Temperatury"
 
 
 #MSG_ENDSTOP_HIT c=0 r=0
 #MSG_ENDSTOP_HIT c=0 r=0
 "TRIGGERED"
 "TRIGGERED"
-"\x00"
+"AKTYWOWANO"
 
 
 #MSG_TUNE c=0 r=0
 #MSG_TUNE c=0 r=0
 "Tune"
 "Tune"
-"Nastroic"
+"Strojenie"
 
 
 #MSG_UNLOAD_FILAMENT c=17 r=0
 #MSG_UNLOAD_FILAMENT c=17 r=0
 "Unload filament"
 "Unload filament"
-"Wyjac filament"
+"Wyladowanie filamentu"
 
 
 #MSG_UNLOADING_FILAMENT c=20 r=1
 #MSG_UNLOADING_FILAMENT c=20 r=1
 "Unloading filament"
 "Unloading filament"
-"Wysuwam filament"
+"Rozladowuje filament"
 
 
 #MSG_USED c=19 r=1
 #MSG_USED c=19 r=1
 "Used during print"
 "Used during print"
-"Uzyte przy druku"
+"Uzyte podczas druku"
 
 
 #MSG_MENU_VOLTAGES c=15 r=1
 #MSG_MENU_VOLTAGES c=15 r=1
 "Voltages"
 "Voltages"
-"\x00"
+"Napiecia"
 
 
 #MSG_SD_VOL_INIT_FAIL c=0 r=0
 #MSG_SD_VOL_INIT_FAIL c=0 r=0
 "volume.init failed"
 "volume.init failed"
-"\x00"
+"niepowodzenie volume.init "
 
 
 #MSG_USERWAIT c=0 r=0
 #MSG_USERWAIT c=0 r=0
 "Wait for user..."
 "Wait for user..."
-"\x00"
+"Czekam na uzytkownika..."
 
 
 #MSG_WAITING_TEMP c=20 r=3
 #MSG_WAITING_TEMP c=20 r=3
 "Waiting for nozzle and bed cooling"
 "Waiting for nozzle and bed cooling"
-"Oczekiwanie na wychlodzenie dyszy i podkladki."
+"Oczekiwanie na wychlodzenie dyszy i stolu"
 
 
 #MSG_WAITING_TEMP_PINDA c=20 r=3
 #MSG_WAITING_TEMP_PINDA c=20 r=3
 "Waiting for PINDA probe cooling"
 "Waiting for PINDA probe cooling"
-"\x00"
+"Czekam az spadnie temp. sondy PINDA"
 
 
 #MSG_CHANGED_BOTH c=20 r=4
 #MSG_CHANGED_BOTH c=20 r=4
 "Warning: both printer type and motherboard type changed."
 "Warning: both printer type and motherboard type changed."
-"\x00"
+"Ostrzezenie: typ drukarki i plyta glowna ulegly zmianie."
 
 
 #MSG_CHANGED_MOTHERBOARD c=20 r=4
 #MSG_CHANGED_MOTHERBOARD c=20 r=4
 "Warning: motherboard type changed."
 "Warning: motherboard type changed."
-"\x00"
+"Ostrzezenie: plyta glowna ulegla zmianie."
 
 
 #MSG_CHANGED_PRINTER c=20 r=4
 #MSG_CHANGED_PRINTER c=20 r=4
 "Warning: printer type changed."
 "Warning: printer type changed."
-"\x00"
+"Ostrzezenie: rodzaj drukarki ulegl zmianie"
 
 
 #MSG_UNLOAD_SUCCESSFUL c=20 r=2
 #MSG_UNLOAD_SUCCESSFUL c=20 r=2
 "Was filament unload successful?"
 "Was filament unload successful?"
-"\x00"
+"Wyladowanie fil. ok?"
 
 
 #MSG_SELFTEST_WIRINGERROR c=0 r=0
 #MSG_SELFTEST_WIRINGERROR c=0 r=0
 "Wiring error"
 "Wiring error"
@@ -1076,23 +1076,23 @@
 
 
 #MSG_WIZARD c=17 r=1
 #MSG_WIZARD c=17 r=1
 "Wizard"
 "Wizard"
-"\x00"
+"Asystent"
 
 
 #MSG_SD_WORKDIR_FAIL c=0 r=0
 #MSG_SD_WORKDIR_FAIL c=0 r=0
 "workDir open failed"
 "workDir open failed"
-"\x00"
+"blad otwierania workDir"
 
 
 #MSG_SD_WRITE_TO_FILE c=0 r=0
 #MSG_SD_WRITE_TO_FILE c=0 r=0
 "Writing to file: "
 "Writing to file: "
-"\x00"
+"Zapis do pliku:"
 
 
 #MSG_XYZ_DETAILS c=19 r=1
 #MSG_XYZ_DETAILS c=19 r=1
 "XYZ cal. details"
 "XYZ cal. details"
-"Szczegoly kal.XYZ"
+"Szczegoly kal. XYZ"
 
 
 #MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED c=20 r=8
 #MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED c=20 r=8
 "XYZ calibration failed. Please consult the manual."
 "XYZ calibration failed. Please consult the manual."
-"Kalibracja XYZ niepowiedziona. Sprawdzic w instrukcji."
+"Kalibracja XYZ nieudana. Sprawdz przyczyny i rozwiazania w instrukcji."
 
 
 #MSG_YES c=0 r=0
 #MSG_YES c=0 r=0
 "Yes"
 "Yes"
@@ -1100,5 +1100,5 @@
 
 
 #MSG_WIZARD_QUIT c=20 r=8
 #MSG_WIZARD_QUIT c=20 r=8
 "You can always resume the Wizard from Calibration -> Wizard."
 "You can always resume the Wizard from Calibration -> Wizard."
-"Zawsze mozesz przywrocic Wizard przez Kalibracja -> Wizard."
+"Zawsze mozesz uruchomic Asystenta ponownie przez Kalibracja -> Asystent."
 
 

+ 53 - 42
lang/make_lang.sh

@@ -5,18 +5,18 @@
 #
 #
 # Input files:
 # Input files:
 #  lang_en.txt
 #  lang_en.txt
-#  lang_en_$LANG.txt
+#  lang_en_xx.txt
 #
 #
 # Output files:
 # Output files:
 #  lang_en.tmp (temporary, will be removed when finished)
 #  lang_en.tmp (temporary, will be removed when finished)
-#  lang_en_$LANG.tmp ==||==
-#  lang_en_$LANG.dif ==||==
-#  lang_$LANG.txt
+#  lang_en_xx.tmp ==||==
+#  lang_en_xx.dif ==||==
+#  lang_xx.txt
 #
 #
 #
 #
 # Selected language:
 # Selected language:
-LANG=$1
-if [ -z "$LANG" ]; then LANG='cz'; fi
+LNG=$1
+if [ -z "$LNG" ]; then LNG='cz'; fi
 #
 #
 #
 #
 
 
@@ -24,8 +24,8 @@ finish()
 {
 {
  if [ $1 -eq 0 ]; then
  if [ $1 -eq 0 ]; then
   if [ -e lang_en.tmp ]; then rm lang_en.tmp; fi
   if [ -e lang_en.tmp ]; then rm lang_en.tmp; fi
-  if [ -e lang_en_$LANG.tmp ]; then rm lang_en_$LANG.tmp; fi
-  if [ -e lang_en_$LANG.dif ]; then rm lang_en_$LANG.dif; fi
+  if [ -e lang_en_$LNG.tmp ]; then rm lang_en_$LNG.tmp; fi
+  if [ -e lang_en_$LNG.dif ]; then rm lang_en_$LNG.dif; fi
  fi
  fi
 # echo >&2
 # echo >&2
  if [ $1 -eq 0 ]; then
  if [ $1 -eq 0 ]; then
@@ -38,59 +38,59 @@ finish()
 
 
 make_lang()
 make_lang()
 {
 {
-LANG=$1
+LNG=$1
 
 
 echo "make_lang.sh started" >&2
 echo "make_lang.sh started" >&2
-echo "selected language=$LANG" >&2
+echo "selected language=$LNG" >&2
 
 
 #check if input files exists
 #check if input files exists
 echo -n " checking input files..." >&2
 echo -n " checking input files..." >&2
 if [ ! -e lang_en.txt ]; then echo "NG!  file lang_en.txt not found!" >&2; exit 1; fi
 if [ ! -e lang_en.txt ]; then echo "NG!  file lang_en.txt not found!" >&2; exit 1; fi
-if [ ! -e lang_en_$LANG.txt ]; then echo "NG!  file lang_en_$LANG.txt not found!" >&2; exit 1; fi
+if [ ! -e lang_en_$LNG.txt ]; then echo "NG!  file lang_en_$LNG.txt not found!" >&2; exit 1; fi
 echo "OK" >&2
 echo "OK" >&2
 
 
 #filter comment and empty lines from key and dictionary files, create temporary files
 #filter comment and empty lines from key and dictionary files, create temporary files
 echo -n " creating tmp files..." >&2
 echo -n " creating tmp files..." >&2
 cat lang_en.txt | sed "/^$/d;/^#/d" > lang_en.tmp
 cat lang_en.txt | sed "/^$/d;/^#/d" > lang_en.tmp
-cat lang_en_$LANG.txt | sed "/^$/d;/^#/d" > lang_en_$LANG.tmp
+cat lang_en_$LNG.txt | sed "/^$/d;/^#/d" > lang_en_$LNG.tmp
 echo "OK" >&2
 echo "OK" >&2
-#cat lang_en_$LANG.tmp | sed 'n;d' >test1.txt
+#cat lang_en_$LNG.tmp | sed 'n;d' >test1.txt
 
 
 #compare files using diff and check for differences
 #compare files using diff and check for differences
 echo -n " comparing tmp files..." >&2
 echo -n " comparing tmp files..." >&2
-if ! cat lang_en_$LANG.tmp | sed 'n;d' | diff lang_en.tmp - > lang_en_$LANG.dif; then
+if ! cat lang_en_$LNG.tmp | sed 'n;d' | diff lang_en.tmp - > lang_en_$LNG.dif; then
  echo "NG!" >&2
  echo "NG!" >&2
- echo "Entries in lang_en_$LANG.txt are different from lang_en.txt!" >&2
- echo "please check lang_en_$LANG.dif" >&2
+ echo "Entries in lang_en_$LNG.txt are different from lang_en.txt!" >&2
+ echo "please check lang_en_$LNG.dif" >&2
  finish 1
  finish 1
 fi
 fi
 echo "OK" >&2
 echo "OK" >&2
 
 
 #generate lang_xx.txt (secondary language text data sorted by ids)
 #generate lang_xx.txt (secondary language text data sorted by ids)
-echo -n " generating lang_$LANG.txt..." >&2
-cat lang_en_$LANG.tmp | sed '1~2d' | sed "s/^\"\\\\x00/\"/" > lang_$LANG.txt
+echo -n " generating lang_$LNG.txt..." >&2
+cat lang_en_$LNG.tmp | sed '1~2d' | sed "s/^\"\\\\x00/\"/" > lang_$LNG.txt
 echo "OK" >&2
 echo "OK" >&2
 
 
 #generate lang_xx.dat (secondary language text data in binary form)
 #generate lang_xx.dat (secondary language text data in binary form)
-echo -n " generating lang_$LANG.dat..." >&2
-cat lang_$LANG.txt | sed "s/\\\\/\\\\\\\\/g" | while read s; do
+echo -n " generating lang_$LNG.dat..." >&2
+cat lang_$LNG.txt | sed "s/\\\\/\\\\\\\\/g" | while read s; do
  s=${s#\"}
  s=${s#\"}
  s=${s%\"}
  s=${s%\"}
  /bin/echo -e -n "$s\x00"
  /bin/echo -e -n "$s\x00"
-done >lang_$LANG.dat
+done >lang_$LNG.dat
 echo "OK" >&2
 echo "OK" >&2
 
 
 #calculate variables
 #calculate variables
 lt_magic='\xa5\x5a\xb4\x4b'
 lt_magic='\xa5\x5a\xb4\x4b'
-lt_count=$(grep -c '^' lang_$LANG.txt)
-lt_data_size=$(wc -c lang_$LANG.dat | cut -f1 -d' ')
+lt_count=$(grep -c '^' lang_$LNG.txt)
+lt_data_size=$(wc -c lang_$LNG.dat | cut -f1 -d' ')
 lt_offs_size=$((2 * $lt_count))
 lt_offs_size=$((2 * $lt_count))
 lt_size=$((16 + $lt_offs_size + $lt_data_size))
 lt_size=$((16 + $lt_offs_size + $lt_data_size))
-lt_chsum=1
+lt_chsum=0
 lt_code='\xff\xff'
 lt_code='\xff\xff'
 lt_resv1='\xff\xff\xff\xff'
 lt_resv1='\xff\xff\xff\xff'
 
 
-case "$LANG" in
+case "$LNG" in
  *en*) lt_code='\x6e\x65' ;;
  *en*) lt_code='\x6e\x65' ;;
  *cz*) lt_code='\x73\x63' ;;
  *cz*) lt_code='\x73\x63' ;;
  *de*) lt_code='\x65\x64' ;;
  *de*) lt_code='\x65\x64' ;;
@@ -100,15 +100,15 @@ case "$LANG" in
 esac
 esac
 
 
 #generate lang_xx.ofs (secondary language text data offset table)
 #generate lang_xx.ofs (secondary language text data offset table)
-echo -n " generating lang_$LANG.ofs..." >&2
-cat lang_$LANG.txt | sed "s/\\\\x[0-9a-f][0-9a-f]/\./g;s/\\\\[0-7][0-7][0-7]/\./g" |\
- awk 'BEGIN { o='$((16 + $lt_offs_size))';} { printf("%d\n",o); o+=(length($0)-1); }' > lang_$LANG.ofs
+echo -n " generating lang_$LNG.ofs..." >&2
+cat lang_$LNG.txt | sed "s/\\\\x[0-9a-f][0-9a-f]/\./g;s/\\\\[0-7][0-7][0-7]/\./g" |\
+ awk 'BEGIN { o='$((16 + $lt_offs_size))';} { printf("%d\n",o); o+=(length($0)-1); }' > lang_$LNG.ofs
 echo "OK" >&2
 echo "OK" >&2
 
 
 #generate lang_xx.bin (secondary language result binary file)
 #generate lang_xx.bin (secondary language result binary file)
-echo " generating lang_$LANG.bin:" >&2
+echo " generating lang_$LNG.bin:" >&2
 #create empty file
 #create empty file
-dd if=/dev/zero of=lang_$LANG.bin bs=1 count=$lt_size 2>/dev/null
+dd if=/dev/zero of=lang_$LNG.bin bs=1 count=$lt_size 2>/dev/null
 #awk code to format ui16 variables for dd
 #awk code to format ui16 variables for dd
 awk_ui16='{ h=int($1/256); printf("\\x%02x\\x%02x\n", int($1-256*h), h); }'
 awk_ui16='{ h=int($1/256); printf("\\x%02x\\x%02x\n", int($1-256*h), h); }'
 
 
@@ -116,37 +116,48 @@ awk_ui16='{ h=int($1/256); printf("\\x%02x\\x%02x\n", int($1-256*h), h); }'
 
 
 echo -n "  writing header (16 bytes)..." >&2
 echo -n "  writing header (16 bytes)..." >&2
 /bin/echo -n -e "$lt_magic" |\
 /bin/echo -n -e "$lt_magic" |\
- dd of=lang_$LANG.bin bs=1 count=4 seek=0 conv=notrunc 2>/dev/null
+ dd of=lang_$LNG.bin bs=1 count=4 seek=0 conv=notrunc 2>/dev/null
 /bin/echo -n -e $(echo -n "$lt_size" | awk "$awk_ui16") |\
 /bin/echo -n -e $(echo -n "$lt_size" | awk "$awk_ui16") |\
- dd of=lang_$LANG.bin bs=1 count=2 seek=4 conv=notrunc 2>/dev/null
+ dd of=lang_$LNG.bin bs=1 count=2 seek=4 conv=notrunc 2>/dev/null
 /bin/echo -n -e $(echo -n "$lt_count" | awk "$awk_ui16") |\
 /bin/echo -n -e $(echo -n "$lt_count" | awk "$awk_ui16") |\
- dd of=lang_$LANG.bin bs=1 count=2 seek=6 conv=notrunc 2>/dev/null
+ dd of=lang_$LNG.bin bs=1 count=2 seek=6 conv=notrunc 2>/dev/null
 /bin/echo -n -e $(echo -n "$lt_chsum" | awk "$awk_ui16") |\
 /bin/echo -n -e $(echo -n "$lt_chsum" | awk "$awk_ui16") |\
- dd of=lang_$LANG.bin bs=1 count=2 seek=8 conv=notrunc 2>/dev/null
+ dd of=lang_$LNG.bin bs=1 count=2 seek=8 conv=notrunc 2>/dev/null
 /bin/echo -n -e "$lt_code" |\
 /bin/echo -n -e "$lt_code" |\
- dd of=lang_$LANG.bin bs=1 count=2 seek=10 conv=notrunc 2>/dev/null
+ dd of=lang_$LNG.bin bs=1 count=2 seek=10 conv=notrunc 2>/dev/null
 /bin/echo -n -e "$lt_resv1" |\
 /bin/echo -n -e "$lt_resv1" |\
- dd of=lang_$LANG.bin bs=1 count=4 seek=12 conv=notrunc 2>/dev/null
+ dd of=lang_$LNG.bin bs=1 count=4 seek=12 conv=notrunc 2>/dev/null
 echo "OK" >&2
 echo "OK" >&2
 
 
 echo -n "  writing offset table ($lt_offs_size bytes)..." >&2
 echo -n "  writing offset table ($lt_offs_size bytes)..." >&2
-/bin/echo -n -e $(cat lang_$LANG.ofs | awk "$awk_ui16" | tr -d '\n'; echo) |\
- dd of=./lang_$LANG.bin bs=1 count=$lt_offs_size seek=16 conv=notrunc 2>/dev/null
+/bin/echo -n -e $(cat lang_$LNG.ofs | awk "$awk_ui16" | tr -d '\n'; echo) |\
+ dd of=./lang_$LNG.bin bs=1 count=$lt_offs_size seek=16 conv=notrunc 2>/dev/null
 echo "OK" >&2
 echo "OK" >&2
 
 
 echo -n "  writing text data ($lt_data_size bytes)..." >&2
 echo -n "  writing text data ($lt_data_size bytes)..." >&2
-dd if=./lang_$LANG.dat of=./lang_$LANG.bin bs=1 count=$lt_data_size seek=$((16 + $lt_offs_size)) conv=notrunc 2>/dev/null
+dd if=./lang_$LNG.dat of=./lang_$LNG.bin bs=1 count=$lt_data_size seek=$((16 + $lt_offs_size)) conv=notrunc 2>/dev/null
 echo "OK" >&2
 echo "OK" >&2
 
 
+#update signature
+echo -n "  updating signature..." >&2
+dd if=lang_en.bin of=lang_$LNG.bin bs=1 count=4 skip=6 seek=12 conv=notrunc 2>/dev/null
+echo "OK" >&2
+
+#calculate and update checksum
+lt_chsum=$(cat lang_$LNG.bin | xxd | cut -c11-49 | tr ' ' "\n" | sed '/^$/d' | awk 'BEGIN { sum = 0; } { sum += strtonum("0x"$1); if (sum > 0xffff) sum -= 0x10000; } END { printf("%x\n", sum); }')
+/bin/echo -n -e $(echo -n $((0x$lt_chsum)) | awk "$awk_ui16") |\
+ dd of=lang_$LNG.bin bs=1 count=2 seek=8 conv=notrunc 2>/dev/null
+
 echo " lang_table details:" >&2
 echo " lang_table details:" >&2
 echo "  lt_count = $lt_count" >&2
 echo "  lt_count = $lt_count" >&2
 echo "  lt_size  = $lt_size" >&2
 echo "  lt_size  = $lt_size" >&2
 echo "  lt_chsum = $lt_chsum" >&2
 echo "  lt_chsum = $lt_chsum" >&2
 }
 }
 
 
-echo $LANG
+echo $LNG
 
 
-if [ "$LANG" = "all" ]; then
+if [ "$LNG" = "all" ]; then
+ ./lang-build.sh en
  make_lang cz
  make_lang cz
  make_lang de
  make_lang de
  make_lang es
  make_lang es
@@ -154,7 +165,7 @@ if [ "$LANG" = "all" ]; then
  make_lang pl
  make_lang pl
  exit 0
  exit 0
 else
 else
- make_lang $LANG
+ make_lang $LNG
 fi
 fi
 
 
 finish 0
 finish 0

+ 29 - 29
lang/po/make_po.sh

@@ -5,11 +5,11 @@
 #
 #
 SRCDIR="../../Firmware"
 SRCDIR="../../Firmware"
 #
 #
-LANG=$1
-if [ -z "$LANG" ]; then LANG=cz; fi
+LNG=$1
+if [ -z "$LNG" ]; then LNG=cz; fi
 #
 #
 
 
-if [ "$LANG" == "all" ]; then
+if [ "$LNG" == "all" ]; then
  ./make_po.sh cz
  ./make_po.sh cz
  ./make_po.sh de
  ./make_po.sh de
  ./make_po.sh es
  ./make_po.sh es
@@ -19,13 +19,13 @@ if [ "$LANG" == "all" ]; then
 fi
 fi
 
 
 echo "make_po.sh started" >&2
 echo "make_po.sh started" >&2
-echo " selected language=$LANG" >&2
+echo " selected language=$LNG" >&2
 
 
 #remove output file if exists
 #remove output file if exists
-if [ -e lang_$LANG.po ]; then rm lang_$LANG.po; fi
+if [ -e lang_$LNG.po ]; then rm lang_$LNG.po; fi
 
 
 lang_name=$(\
 lang_name=$(\
- case "$LANG" in
+ case "$LNG" in
   *en*) echo "English" ;;
   *en*) echo "English" ;;
   *cz*) echo "Czech" ;;
   *cz*) echo "Czech" ;;
   *de*) echo "German" ;;
   *de*) echo "German" ;;
@@ -35,7 +35,7 @@ lang_name=$(\
  esac)
  esac)
 
 
 lang_short=$(\
 lang_short=$(\
- case "$LANG" in
+ case "$LNG" in
   *en*) echo "en" ;;
   *en*) echo "en" ;;
   *cz*) echo "cs" ;;
   *cz*) echo "cs" ;;
   *de*) echo "de" ;;
   *de*) echo "de" ;;
@@ -47,29 +47,29 @@ lang_short=$(\
 po_date=$(date)
 po_date=$(date)
 
 
 #write po header
 #write po header
-echo "# Translation of Prusa-Firmware into $lang_name." > lang_$LANG.po
-echo "#" >> lang_$LANG.po
-echo 'msgid ""' >> lang_$LANG.po
-echo 'msgstr ""' >> lang_$LANG.po
-echo '"MIME-Version: 1.0\n"' >> lang_$LANG.po
-echo '"Content-Type: text/plain; charset=UTF-8\n"' >> lang_$LANG.po
-echo '"Content-Transfer-Encoding: 8bit\n"' >> lang_$LANG.po
-echo '"Language: '$lang_short'\n"' >> lang_$LANG.po
-echo '"Project-Id-Version: Prusa-Firmware\n"' >> lang_$LANG.po
-echo '"POT-Creation-Date: '$po_date'\n"' >> lang_$LANG.po
-echo '"PO-Revision-Date: '$po_date'\n"' >> lang_$LANG.po
-echo '"Language-Team: \n"' >> lang_$LANG.po
-echo '"X-Generator: Poedit 2.0.7\n"' >> lang_$LANG.po
-echo '"X-Poedit-SourceCharset: UTF-8\n"' >> lang_$LANG.po
-echo '"Last-Translator: \n"' >> lang_$LANG.po
-echo '"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"' >> lang_$LANG.po
-echo >> lang_$LANG.po
+echo "# Translation of Prusa-Firmware into $lang_name." > lang_$LNG.po
+echo "#" >> lang_$LNG.po
+echo 'msgid ""' >> lang_$LNG.po
+echo 'msgstr ""' >> lang_$LNG.po
+echo '"MIME-Version: 1.0\n"' >> lang_$LNG.po
+echo '"Content-Type: text/plain; charset=UTF-8\n"' >> lang_$LNG.po
+echo '"Content-Transfer-Encoding: 8bit\n"' >> lang_$LNG.po
+echo '"Language: '$lang_short'\n"' >> lang_$LNG.po
+echo '"Project-Id-Version: Prusa-Firmware\n"' >> lang_$LNG.po
+echo '"POT-Creation-Date: '$po_date'\n"' >> lang_$LNG.po
+echo '"PO-Revision-Date: '$po_date'\n"' >> lang_$LNG.po
+echo '"Language-Team: \n"' >> lang_$LNG.po
+echo '"X-Generator: Poedit 2.0.7\n"' >> lang_$LNG.po
+echo '"X-Poedit-SourceCharset: UTF-8\n"' >> lang_$LNG.po
+echo '"Last-Translator: \n"' >> lang_$LNG.po
+echo '"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"' >> lang_$LNG.po
+echo >> lang_$LNG.po
 
 
 #list .cpp, .c and .h files
 #list .cpp, .c and .h files
 files=$(ls "$SRCDIR"/*.cpp "$SRCDIR"/*.c "$SRCDIR"/*.h)
 files=$(ls "$SRCDIR"/*.cpp "$SRCDIR"/*.c "$SRCDIR"/*.h)
 
 
-num_texts=$(grep '^#' -c ../lang_en_$LANG.txt)
-num_texts_nt=$(grep '^\"\\x00\"' -c ../lang_en_$LANG.txt)
+num_texts=$(grep '^#' -c ../lang_en_$LNG.txt)
+num_texts_nt=$(grep '^\"\\x00\"' -c ../lang_en_$LNG.txt)
 echo " $num_texts texts, $num_texts_nt not translated" >&2
 echo " $num_texts texts, $num_texts_nt not translated" >&2
 
 
 #loop over all messages
 #loop over all messages
@@ -77,7 +77,7 @@ s0=''
 s1=''
 s1=''
 s2=''
 s2=''
 num=1
 num=1
-cat ../lang_en_$LANG.txt | sed "s/\\\\/\\\\\\\\/g" | while read -r s; do
+cat ../lang_en_$LNG.txt | sed "s/\\\\/\\\\\\\\/g" | while read -r s; do
  if [ "$s" == "" ]; then
  if [ "$s" == "" ]; then
   echo "  processing $num of $num_texts" >&2
   echo "  processing $num of $num_texts" >&2
   if [ "$s0" == "\"\\\\x00\"" ]; then
   if [ "$s0" == "\"\\\\x00\"" ]; then
@@ -103,11 +103,11 @@ cat ../lang_en_$LANG.txt | sed "s/\\\\/\\\\\\\\/g" | while read -r s; do
  s2=$s1
  s2=$s1
  s1=$s0
  s1=$s0
  s0=$s
  s0=$s
-done >> lang_$LANG.po
+done >> lang_$LNG.po
 
 
 #replace LF with CRLF
 #replace LF with CRLF
 sync
 sync
-sed -i 's/$/\r/' lang_$LANG.po
+sed -i 's/$/\r/' lang_$LNG.po
 
 
 echo "make_po.sh finished" >&2
 echo "make_po.sh finished" >&2
 #read
 #read

+ 6 - 6
lang/po_new/merge_lang.sh

@@ -2,14 +2,14 @@
 #
 #
 #
 #
 
 
-LANG=$1
-if [ -z "$LANG" ]; then exit -1; fi
+LNG=$1
+if [ -z "$LNG" ]; then exit -1; fi
 
 
 #convert '\\e' sequencies to 'x1b' and '\\' to '\'
 #convert '\\e' sequencies to 'x1b' and '\\' to '\'
-cat $LANG.po | sed 's/\\\\e/\\x1b/g;s/\\\\/\\/g' > $LANG'_filtered.po'
+cat $LNG.po | sed 's/\\\\e/\\x1b/g;s/\\\\/\\/g' > $LNG'_filtered.po'
 
 
 #join lines with multi-line string constants
 #join lines with multi-line string constants
-cat $LANG'_filtered.po' | sed ':a;N;$!ba;s/\x22\n\x22//g' > $LANG'_new.po'
+cat $LNG'_filtered.po' | sed ':a;N;$!ba;s/\x22\n\x22//g' > $LNG'_new.po'
 
 
 #generate dictionary
 #generate dictionary
 cat ../lang_en.txt | sed 's/\\/\\\\/g' | while read -r s; do
 cat ../lang_en.txt | sed 's/\\/\\\\/g' | while read -r s; do
@@ -17,7 +17,7 @@ cat ../lang_en.txt | sed 's/\\/\\\\/g' | while read -r s; do
  if [ "${s:0:1}" = "\"" ]; then
  if [ "${s:0:1}" = "\"" ]; then
 #  /bin/echo -e "$s"
 #  /bin/echo -e "$s"
   s=$(/bin/echo -e "$s")
   s=$(/bin/echo -e "$s")
-  s2=$(grep -F -A1 -B0  "$s" "$LANG"_new.po | tail -n1 | sed 's/^msgstr //')
+  s2=$(grep -F -A1 -B0  "$s" "$LNG"_new.po | tail -n1 | sed 's/^msgstr //')
   if [ -z "$s2" ]; then
   if [ -z "$s2" ]; then
    echo '"\x00"'
    echo '"\x00"'
   else
   else
@@ -25,4 +25,4 @@ cat ../lang_en.txt | sed 's/\\/\\\\/g' | while read -r s; do
   fi
   fi
 #  echo
 #  echo
  fi
  fi
-done > lang_en_$LANG.txt
+done > lang_en_$LNG.txt

+ 45 - 9
lang/postbuild.sh

@@ -23,8 +23,8 @@ if [ -z "$CONFIG_OK" ]; then eval "$(cat config.sh)"; fi
 if [ -z "$CONFIG_OK" ] | [ $CONFIG_OK -eq 0 ]; then echo 'Config NG!' >&2; exit 1; fi
 if [ -z "$CONFIG_OK" ] | [ $CONFIG_OK -eq 0 ]; then echo 'Config NG!' >&2; exit 1; fi
 #
 #
 # Selected language:
 # Selected language:
-LANG=$1
-#if [ -z "$LANG" ]; then LANG='cz'; fi
+LNG=$1
+#if [ -z "$LNG" ]; then LNG='cz'; fi
 #
 #
 # Params:
 # Params:
 IGNORE_MISSING_TEXT=1
 IGNORE_MISSING_TEXT=1
@@ -80,7 +80,7 @@ else
  echo "OK" >&2
  echo "OK" >&2
 fi
 fi
 
 
-#update progmem1 id entries in binary file
+#extract binary file
 echo -n " extracting binary..." >&2
 echo -n " extracting binary..." >&2
 $OBJCOPY -I ihex -O binary $INOHEX ./firmware.bin
 $OBJCOPY -I ihex -O binary $INOHEX ./firmware.bin
 echo "OK" >&2
 echo "OK" >&2
@@ -97,10 +97,35 @@ cat textaddr.txt | grep "^ADDR OK" | cut -f3- -d' ' | sed "s/^0000/0x/" |\
  done
  done
 echo "OK" >&2
 echo "OK" >&2
 
 
+#update primary language signature in binary file
+echo -n "  primary language signature..." >&2
+if [ -e lang_en.bin ]; then
+ #find symbol _PRI_LANG_SIGNATURE in section '.text'
+ pri_lang=$(cat text.sym | grep -E "\b_PRI_LANG_SIGNATURE\b")
+ if [ -z "$pri_lang" ]; then echo "NG!\n  symbol _PRI_LANG_SIGNATURE not found!" >&2; finish 1; fi
+ #get pri_lang address
+ pri_lang_addr='0x'$(echo $pri_lang | cut -f1 -d' ')
+ #read header from primary language binary file
+ header=$(dd if=lang_en.bin bs=1 count=16 2>/dev/null | xxd | cut -c11-49 | sed 's/\([0-9a-f][0-9a-f]\)[\ ]*/\1 /g')
+ #read checksum and count data as 4 byte signature
+ chscnt=$(echo $header | cut -c18-29 | sed "s/ /\\\\x/g")
+ /bin/echo -e -n "$chscnt" |\
+  dd of=firmware.bin bs=1 count=4 seek=$(($pri_lang_addr)) conv=notrunc 2>/dev/null
+ echo "OK" >&2
+else
+ echo "NG! - file lang_en.bin not found!" >&2;
+ finish 1
+fi
+
+#convert bin to hex
+echo -n " converting to hex..." >&2
+$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware.hex
+echo "OK" >&2
+
 #update _SEC_LANG in binary file if language is selected
 #update _SEC_LANG in binary file if language is selected
 echo -n "  secondary language data..." >&2
 echo -n "  secondary language data..." >&2
-if [ ! -z "$LANG" ]; then
- ./update_lang.sh $LANG 2>./update_lang.out
+if [ ! -z "$LNG" ]; then
+ ./update_lang.sh $LNG 2>./update_lang.out
  if [ $? -ne 0 ]; then echo "NG! - check update_lang.out file" >&2; finish 1; fi
  if [ $? -ne 0 ]; then echo "NG! - check update_lang.out file" >&2; finish 1; fi
  echo "OK" >&2
  echo "OK" >&2
  finish 0
  finish 0
@@ -134,9 +159,20 @@ else
 # echo "skipped" >&2
 # echo "skipped" >&2
 fi
 fi
 
 
-#convert bin to hex
-#echo -n " converting to hex..." >&2
-#$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware.hex
-#echo "OK" >&2
+#create binary file with all languages
+rm -f lang.bin
+if [ -e lang_cz.bin ]; then cat lang_cz.bin >> lang.bin; fi
+if [ -e lang_de.bin ]; then cat lang_de.bin >> lang.bin; fi
+if [ -e lang_es.bin ]; then cat lang_es.bin >> lang.bin; fi
+if [ -e lang_it.bin ]; then cat lang_it.bin >> lang.bin; fi
+if [ -e lang_pl.bin ]; then cat lang_pl.bin >> lang.bin; fi
+
+#convert lang.bin to lang.hex
+echo -n " converting to hex..." >&2
+$OBJCOPY -I binary -O ihex ./lang.bin ./lang.hex
+echo "OK" >&2
+
+#append languages to hex file
+cat ./lang.hex >> firmware.hex
 
 
 finish 0
 finish 0

+ 14 - 7
lang/update_lang.sh

@@ -9,8 +9,8 @@ if [ -z "$OBJCOPY" ]; then echo 'variable OBJCOPY not set!' >&2; exit 1; fi
 if [ -z "$CONFIG_OK" ] | [ $CONFIG_OK -eq 0 ]; then echo 'Config NG!' >&2; exit 1; fi
 if [ -z "$CONFIG_OK" ] | [ $CONFIG_OK -eq 0 ]; then echo 'Config NG!' >&2; exit 1; fi
 #
 #
 # Selected language:
 # Selected language:
-LANG=$1
-if [ -z "$LANG" ]; then LANG='cz'; fi
+LNG=$1
+if [ -z "$LNG" ]; then LNG='cz'; fi
 #
 #
 
 
 finish()
 finish()
@@ -28,11 +28,11 @@ finish()
 }
 }
 
 
 echo "update_lang.sh started" >&2
 echo "update_lang.sh started" >&2
-echo " selected language=$LANG" >&2
+echo " selected language=$LNG" >&2
 
 
 echo -n " checking files..." >&2
 echo -n " checking files..." >&2
 if [ ! -e text.sym ]; then echo "NG!  file text.sym not found!" >&2; finish 1; fi
 if [ ! -e text.sym ]; then echo "NG!  file text.sym not found!" >&2; finish 1; fi
-if [ ! -e lang_$LANG.bin ]; then echo "NG!  file lang_$LANG.bin not found!" >&2; finish 1; fi
+if [ ! -e lang_$LNG.bin ]; then echo "NG!  file lang_$LNG.bin not found!" >&2; finish 1; fi
 if [ ! -e firmware.bin ]; then echo "NG!  file firmware.bin not found!" >&2; finish 1; fi
 if [ ! -e firmware.bin ]; then echo "NG!  file firmware.bin not found!" >&2; finish 1; fi
 echo "OK" >&2
 echo "OK" >&2
 
 
@@ -40,9 +40,15 @@ echo -n " checking symbols..." >&2
 #find symbol _SEC_LANG in section '.text'
 #find symbol _SEC_LANG in section '.text'
 sec_lang=$(cat text.sym | grep -E "\b_SEC_LANG\b")
 sec_lang=$(cat text.sym | grep -E "\b_SEC_LANG\b")
 if [ -z "$sec_lang" ]; then echo "NG!\n  symbol _SEC_LANG not found!" >&2; finish 1; fi
 if [ -z "$sec_lang" ]; then echo "NG!\n  symbol _SEC_LANG not found!" >&2; finish 1; fi
+#find symbol _PRI_LANG_SIGNATURE in section '.text'
+pri_lang=$(cat text.sym | grep -E "\b_PRI_LANG_SIGNATURE\b")
+if [ -z "$pri_lang" ]; then echo "NG!\n  symbol _PRI_LANG_SIGNATURE not found!" >&2; finish 1; fi
 echo "OK" >&2
 echo "OK" >&2
 
 
 echo " calculating vars:" >&2
 echo " calculating vars:" >&2
+#get pri_lang addres
+pri_lang_addr='0x'$(echo $pri_lang | cut -f1 -d' ')
+echo "  pri_lang_addr   =$pri_lang_addr" >&2
 #get addres and size
 #get addres and size
 sec_lang_addr='0x'$(echo $sec_lang | cut -f1 -d' ')
 sec_lang_addr='0x'$(echo $sec_lang | cut -f1 -d' ')
 sec_lang_size='0x'$(echo $sec_lang | cut -f2 -d' ')
 sec_lang_size='0x'$(echo $sec_lang | cut -f2 -d' ')
@@ -56,16 +62,17 @@ lang_table_size=$((256*$((($sec_lang_size - ($lang_table_addr - $sec_lang_addr))
 printf "  lang_table_size =0x%04x (=%d bytes)\n" $lang_table_size $lang_table_size >&2
 printf "  lang_table_size =0x%04x (=%d bytes)\n" $lang_table_size $lang_table_size >&2
 
 
 #get lang_xx.bin file size
 #get lang_xx.bin file size
-lang_file_size=$(wc -c lang_$LANG.bin | cut -f1 -d' ')
+lang_file_size=$(wc -c lang_$LNG.bin | cut -f1 -d' ')
 printf "  lang_file_size  =0x%04x (=%d bytes)\n" $lang_file_size $lang_file_size >&2
 printf "  lang_file_size  =0x%04x (=%d bytes)\n" $lang_file_size $lang_file_size >&2
 
 
 if [ $lang_file_size -gt $lang_table_size ]; then echo "Lanaguage binary file size too big!" >&2; finish 1; fi
 if [ $lang_file_size -gt $lang_table_size ]; then echo "Lanaguage binary file size too big!" >&2; finish 1; fi
 
 
 echo "updating 'firmware.bin'..." >&2
 echo "updating 'firmware.bin'..." >&2
-dd if=lang_$LANG.bin of=firmware.bin bs=1 seek=$lang_table_addr conv=notrunc 2>/dev/null
+
+dd if=lang_$LNG.bin of=firmware.bin bs=1 seek=$lang_table_addr conv=notrunc 2>/dev/null
 
 
 #convert bin to hex
 #convert bin to hex
 echo "converting to hex..." >&2
 echo "converting to hex..." >&2
-$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware_$LANG.hex
+$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware_$LNG.hex
 
 
 finish 0
 finish 0