Browse Source

Lcd optimization - 1K of flash saved

leptun 5 years ago
parent
commit
8b1c687629

+ 5 - 9
Firmware/Marlin_main.cpp

@@ -775,12 +775,8 @@ int uart_putchar(char c, FILE *)
 
 void lcd_splash()
 {
-//	lcd_puts_at_P(0, 1, PSTR("   Original Prusa   "));
-//	lcd_puts_at_P(0, 2, PSTR("    3D  Printers    "));
-//	lcd_puts_P(PSTR("\x1b[1;3HOriginal Prusa\x1b[2;4H3D  Printers"));
-//    fputs_P(PSTR(ESC_2J ESC_H(1,1) "Original Prusa i3" ESC_H(3,2) "Prusa Research"), lcdout);
-    lcd_puts_P(PSTR(ESC_2J ESC_H(1,1) "Original Prusa i3" ESC_H(3,2) "Prusa Research"));
-//	lcd_printf_P(_N(ESC_2J "x:%.3f\ny:%.3f\nz:%.3f\ne:%.3f"), _x, _y, _z, _e);
+	lcd_clear(); // clears display and homes screen
+	lcd_puts_P(PSTR("\n Original Prusa i3\n   Prusa Research"));
 }
 
 
@@ -910,7 +906,7 @@ void update_sec_lang_from_external_flash()
 		uint32_t src_addr;
 		if (lang_get_header(lang, &header, &src_addr))
 		{
-			fputs_P(PSTR(ESC_H(1,3) "Language update."), lcdout);
+			lcd_puts_at_P(1,3,PSTR("Language update."));
 			for (uint8_t i = 0; i < state; i++) fputc('.', lcdout);
 			_delay(100);
 			boot_reserved = (state + 1) | (lang << 4);
@@ -984,8 +980,8 @@ void list_sec_lang_from_external_flash()
 
 static void w25x20cl_err_msg()
 {
-    lcd_puts_P(_n(ESC_2J ESC_H(0,0) "External SPI flash" ESC_H(0,1) "W25X20CL is not res-"
-            ESC_H(0,2) "ponding. Language" ESC_H(0,3) "switch unavailable."));
+	lcd_clear();
+	lcd_puts_P(_n("External SPI flash\nW25X20CL is not res-\nponding. Language\nswitch unavailable."));
 }
 
 // "Setup" function is called by the Arduino framework on startup.

+ 110 - 172
Firmware/lcd.cpp

@@ -16,6 +16,13 @@
 //-//
 #include "sound.h"
 
+#define LCD_DEFAULT_DELAY 100
+
+#if (defined(LCD_PINS_D0) && defined(LCD_PINS_D1) && defined(LCD_PINS_D2) && defined(LCD_PINS_D3))
+	#define LCD_8BIT
+#endif
+
+// #define VT100
 
 // commands
 #define LCD_CLEARDISPLAY 0x01
@@ -55,73 +62,63 @@
 #define LCD_5x10DOTS 0x04
 #define LCD_5x8DOTS 0x00
 
+// bitmasks for flag argument settings
+#define LCD_RS_FLAG 0x01
+#define LCD_HALF_FLAG 0x02
 
 FILE _lcdout; // = {0}; Global variable is always zero initialized, no need to explicitly state that.
 
+uint8_t lcd_displayfunction = 0;
+uint8_t lcd_displaycontrol = 0;
+uint8_t lcd_displaymode = 0;
 
-uint8_t lcd_rs_pin; // LOW: command.  HIGH: character.
-uint8_t lcd_rw_pin; // LOW: write to LCD.  HIGH: read from LCD.
-uint8_t lcd_enable_pin; // activated by a HIGH pulse.
-uint8_t lcd_data_pins[8];
-
-uint8_t lcd_displayfunction;
-uint8_t lcd_displaycontrol;
-uint8_t lcd_displaymode;
-
-uint8_t lcd_numlines;
 uint8_t lcd_currline;
 
+#ifdef VT100
 uint8_t lcd_escape[8];
-
+#endif
 
 void lcd_pulseEnable(void)
-{
-	digitalWrite(lcd_enable_pin, LOW);
-	delayMicroseconds(1);    
-	digitalWrite(lcd_enable_pin, HIGH);
-	delayMicroseconds(1);    // enable pulse must be >450ns
-	digitalWrite(lcd_enable_pin, LOW);
-	delayMicroseconds(100);   // commands need > 37us to settle
-}
-
-void lcd_write4bits(uint8_t value)
-{
-	for (int i = 0; i < 4; i++)
-	{
-		pinMode(lcd_data_pins[i], OUTPUT);
-		digitalWrite(lcd_data_pins[i], (value >> i) & 0x01);
-	}
-	lcd_pulseEnable();
-}
-
-void lcd_write8bits(uint8_t value)
-{
-	for (int i = 0; i < 8; i++)
-	{
-		pinMode(lcd_data_pins[i], OUTPUT);
-		digitalWrite(lcd_data_pins[i], (value >> i) & 0x01);
-	}
+{  
+	WRITE(LCD_PINS_ENABLE,HIGH);
+	_delay_us(1);    // enable pulse must be >450ns
+	WRITE(LCD_PINS_ENABLE,LOW);
+}
+
+void lcd_writebits(uint8_t value)
+{
+#ifdef LCD_8BIT
+	WRITE(LCD_PINS_D0, value & 0x01);
+	WRITE(LCD_PINS_D1, value & 0x02);
+	WRITE(LCD_PINS_D2, value & 0x04);
+	WRITE(LCD_PINS_D3, value & 0x08);
+#endif
+	WRITE(LCD_PINS_D4, value & 0x10);
+	WRITE(LCD_PINS_D5, value & 0x20);
+	WRITE(LCD_PINS_D6, value & 0x40);
+	WRITE(LCD_PINS_D7, value & 0x80);
+	
 	lcd_pulseEnable();
 }
 
-// write either command or data, with automatic 4/8-bit selection
-void lcd_send(uint8_t value, uint8_t mode)
+void lcd_send(uint8_t data, uint8_t flags, uint16_t duration = LCD_DEFAULT_DELAY)
 {
-	digitalWrite(lcd_rs_pin, mode);
-	// if there is a RW pin indicated, set it low to Write
-	if (lcd_rw_pin != 255) digitalWrite(lcd_rw_pin, LOW);
-	if (lcd_displayfunction & LCD_8BITMODE)
-		lcd_write8bits(value); 
-	else
+	WRITE(LCD_PINS_RS,flags&LCD_RS_FLAG);
+	_delay_us(5);
+	lcd_writebits(data);
+#ifndef LCD_8BIT
+	if (!(flags & LCD_HALF_FLAG))
 	{
-		lcd_write4bits(value>>4);
-		lcd_write4bits(value);
+		_delay_us(LCD_DEFAULT_DELAY);
+		lcd_writebits(data<<4);
 	}
+#endif
+	delayMicroseconds(duration);
 }
 
-void lcd_command(uint8_t value)
+void lcd_command(uint8_t value, uint16_t delayExtra = 0)
 {
-	lcd_send(value, LOW);
+	lcd_send(value, LOW, LCD_DEFAULT_DELAY + delayExtra);
 }
 
 void lcd_clear(void);
@@ -141,141 +138,98 @@ void lcd_no_autoscroll(void);
 void lcd_set_cursor(uint8_t col, uint8_t row);
 void lcd_createChar_P(uint8_t location, const uint8_t* charmap);
 
-uint8_t lcd_escape_write(uint8_t chr);
+#ifdef VT100
+void lcd_escape_write(uint8_t chr);
+#endif
 
-uint8_t lcd_write(uint8_t value)
+void lcd_write(uint8_t value)
 {
-	if (value == '\n')
+	if (value == '\n' || value == '\r')
 	{
 		if (lcd_currline > 3) lcd_currline = -1;
 		lcd_set_cursor(0, lcd_currline + 1); // LF
-		return 1;
+		return;
 	}
-	if (lcd_escape[0] || (value == 0x1b))
-		return lcd_escape_write(value);
+	#ifdef VT100
+	if (lcd_escape[0] || (value == 0x1b)){
+		lcd_escape_write(value);
+		return;
+	}
+	#endif
 	lcd_send(value, HIGH);
-	return 1; // assume sucess
 }
 
-static void lcd_begin(uint8_t lines, uint8_t dotsize, uint8_t clear)
+static void lcd_begin(uint8_t clear)
 {
-	if (lines > 1) lcd_displayfunction |= LCD_2LINE;
-	lcd_numlines = lines;
 	lcd_currline = 0;
-	// for some 1 line displays you can select a 10 pixel high font
-	if ((dotsize != 0) && (lines == 1)) lcd_displayfunction |= LCD_5x10DOTS;
-	// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
-	// according to datasheet, we need at least 40ms after power rises above 2.7V
-	// before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
-	_delay_us(50000); 
-	// Now we pull both RS and R/W low to begin commands
-	digitalWrite(lcd_rs_pin, LOW);
-	digitalWrite(lcd_enable_pin, LOW);
-	if (lcd_rw_pin != 255)
-		digitalWrite(lcd_rw_pin, LOW);
-	//put the LCD into 4 bit or 8 bit mode
-	if (!(lcd_displayfunction & LCD_8BITMODE))
-	{
-		// this is according to the hitachi HD44780 datasheet
-		// figure 24, pg 46
-		// we start in 8bit mode, try to set 4 bit mode
-		lcd_write4bits(0x03);
-		_delay_us(4500); // wait min 4.1ms
-		// second try
-		lcd_write4bits(0x03);
-		_delay_us(4500); // wait min 4.1ms
-		// third go!
-		lcd_write4bits(0x03); 
-		_delay_us(150);
-		// finally, set to 4-bit interface
-		lcd_write4bits(0x02); 
-	}
-	else
-	{
-		// this is according to the hitachi HD44780 datasheet
-		// page 45 figure 23
-		// Send function set command sequence
-		lcd_command(LCD_FUNCTIONSET | lcd_displayfunction);
-		_delay_us(4500);  // wait more than 4.1ms
-		// second try
-		lcd_command(LCD_FUNCTIONSET | lcd_displayfunction);
-		_delay_us(150);
-		// third go
-		lcd_command(LCD_FUNCTIONSET | lcd_displayfunction);
-	}
-	// finally, set # lines, font size, etc.
-	lcd_command(LCD_FUNCTIONSET | lcd_displayfunction);  
-	_delay_us(60);
+
+	lcd_send(LCD_FUNCTIONSET | LCD_8BITMODE, LOW | LCD_HALF_FLAG, 4500); // wait min 4.1ms
+	// second try
+	lcd_send(LCD_FUNCTIONSET | LCD_8BITMODE, LOW | LCD_HALF_FLAG, 150);
+	// third go!
+	lcd_send(LCD_FUNCTIONSET | LCD_8BITMODE, LOW | LCD_HALF_FLAG, 150);
+#ifndef LCD_8BIT
+	// set to 4-bit interface
+	lcd_send(LCD_FUNCTIONSET | LCD_4BITMODE, LOW | LCD_HALF_FLAG, 150);
+#endif
+
+	// finally, set # lines, font size, etc.0
+	lcd_command(LCD_FUNCTIONSET | lcd_displayfunction);
 	// turn the display on with no cursor or blinking default
-	lcd_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;  
+	lcd_displaycontrol = LCD_CURSOROFF | LCD_BLINKOFF;  
 	lcd_display();
-	_delay_us(60);
 	// clear it off
 	if (clear) lcd_clear();
-	_delay_us(3000);
 	// Initialize to default text direction (for romance languages)
 	lcd_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
 	// set the entry mode
 	lcd_command(LCD_ENTRYMODESET | lcd_displaymode);
-	_delay_us(60);
+	
+	#ifdef VT100
 	lcd_escape[0] = 0;
+	#endif
 }
 
 int lcd_putchar(char c, FILE *)
 {
 	lcd_write(c);
-	return 0;
 }
 
 void lcd_init(void)
 {
-	uint8_t fourbitmode = 1;
-	lcd_rs_pin = LCD_PINS_RS;
-	lcd_rw_pin = 255;
-	lcd_enable_pin = LCD_PINS_ENABLE;
-	lcd_data_pins[0] = LCD_PINS_D4;
-	lcd_data_pins[1] = LCD_PINS_D5;
-	lcd_data_pins[2] = LCD_PINS_D6;
-	lcd_data_pins[3] = LCD_PINS_D7; 
-	lcd_data_pins[4] = 0;
-	lcd_data_pins[5] = 0;
-	lcd_data_pins[6] = 0;
-	lcd_data_pins[7] = 0;
-	pinMode(lcd_rs_pin, OUTPUT);
-	// we can save 1 pin by not using RW. Indicate by passing 255 instead of pin#
-	if (lcd_rw_pin != 255) pinMode(lcd_rw_pin, OUTPUT);
-	pinMode(lcd_enable_pin, OUTPUT);
-	if (fourbitmode) lcd_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
-	else lcd_displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
-	lcd_begin(LCD_HEIGHT, LCD_5x8DOTS, 1);
-	//lcd_clear();
+	SET_OUTPUT(LCD_PINS_RS);
+	SET_OUTPUT(LCD_PINS_ENABLE);
+#ifdef LCD_8BIT
+	lcd_displayfunction |= LCD_8BITMODE;
+#endif
+	lcd_displayfunction |= LCD_2LINE;
+	_delay_us(50000); 
+	lcd_begin(1); //first time init
 	fdev_setup_stream(lcdout, lcd_putchar, NULL, _FDEV_SETUP_WRITE); //setup lcdout stream
 }
 
 void lcd_refresh(void)
 {
-    lcd_begin(LCD_HEIGHT, LCD_5x8DOTS, 1);
+    lcd_begin(1);
     lcd_set_custom_characters();
 }
 
 void lcd_refresh_noclear(void)
 {
-    lcd_begin(LCD_HEIGHT, LCD_5x8DOTS, 0);
+    lcd_begin(0);
     lcd_set_custom_characters();
 }
 
-
-
 void lcd_clear(void)
 {
-	lcd_command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero
-	_delay_us(1600);  // this command takes a long time
+	lcd_command(LCD_CLEARDISPLAY, 1600);  // clear display, set cursor position to zero
+	lcd_currline = 0;
 }
 
 void lcd_home(void)
 {
-	lcd_command(LCD_RETURNHOME);  // set cursor position to zero
-	_delay_us(1600);  // this command takes a long time!
+	lcd_command(LCD_RETURNHOME, 1600);  // set cursor position to zero
+	lcd_currline = 0;
 }
 
 // Turn the display on/off (quickly)
@@ -359,8 +313,8 @@ void lcd_no_autoscroll(void)
 void lcd_set_cursor(uint8_t col, uint8_t row)
 {
 	int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
-	if ( row >= lcd_numlines )
-		row = lcd_numlines-1;    // we count rows starting w/0
+	if (row >= LCD_HEIGHT)
+		row = LCD_HEIGHT - 1;    // we count rows starting w/0
 	lcd_currline = row;  
 	lcd_command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
 }
@@ -375,12 +329,14 @@ void lcd_createChar_P(uint8_t location, const uint8_t* charmap)
     lcd_send(pgm_read_byte(&charmap[i]), HIGH);
 }
 
+#ifdef VT100
+
 //Supported VT100 escape codes:
 //EraseScreen  "\x1b[2J"
 //CursorHome   "\x1b[%d;%dH"
 //CursorShow   "\x1b[?25h"
 //CursorHide   "\x1b[?25l"
-uint8_t lcd_escape_write(uint8_t chr)
+void lcd_escape_write(uint8_t chr)
 {
 #define escape_cnt (lcd_escape[0])        //escape character counter
 #define is_num_msk (lcd_escape[1])        //numeric character bit mask
@@ -410,26 +366,26 @@ uint8_t lcd_escape_write(uint8_t chr)
 	switch (escape_cnt++)
 	{
 	case 0:
-		if (chr == 0x1b) return 1;  // escape = "\x1b"
+		if (chr == 0x1b) return;  // escape = "\x1b"
 		break;
 	case 1:
 		is_num_msk = 0x00; // reset 'is number' bit mask
-		if (chr == '[') return 1; // escape = "\x1b["
+		if (chr == '[') return; // escape = "\x1b["
 		break;
 	case 2:
 		switch (chr)
 		{
-		case '2': return 1; // escape = "\x1b[2"
-		case '?': return 1; // escape = "\x1b[?"
+		case '2': return; // escape = "\x1b[2"
+		case '?': return; // escape = "\x1b[?"
 		default:
-			if (chr_is_num) return 1; // escape = "\x1b[%1d"
+			if (chr_is_num) return; // escape = "\x1b[%1d"
 		}
 		break;
 	case 3:
 		switch (lcd_escape[2])
 		{
 		case '?': // escape = "\x1b[?"
-			if (chr == '2') return 1; // escape = "\x1b[?2"
+			if (chr == '2') return; // escape = "\x1b[?2"
 			break;
 		case '2':
 			if (chr == 'J') // escape = "\x1b[2J"
@@ -438,20 +394,20 @@ uint8_t lcd_escape_write(uint8_t chr)
 			if (e_2_is_num && // escape = "\x1b[%1d"
 				((chr == ';') || // escape = "\x1b[%1d;"
 				chr_is_num)) // escape = "\x1b[%2d"
-				return 1;
+				return;
 		}
 		break;
 	case 4:
 		switch (lcd_escape[2])
 		{
 		case '?': // "\x1b[?"
-			if ((lcd_escape[3] == '2') && (chr == '5')) return 1; // escape = "\x1b[?25"
+			if ((lcd_escape[3] == '2') && (chr == '5')) return; // escape = "\x1b[?25"
 			break;
 		default:
 			if (e_2_is_num) // escape = "\x1b[%1d"
 			{
-				if ((lcd_escape[3] == ';') && chr_is_num) return 1; // escape = "\x1b[%1d;%1d"
-				else if (e_3_is_num && (chr == ';')) return 1; // escape = "\x1b[%2d;"
+				if ((lcd_escape[3] == ';') && chr_is_num) return; // escape = "\x1b[%1d;%1d"
+				else if (e_3_is_num && (chr == ';')) return; // escape = "\x1b[%2d;"
 			}
 		}
 		break;
@@ -478,10 +434,10 @@ uint8_t lcd_escape_write(uint8_t chr)
 					if (chr == 'H') // escape = "\x1b%1d;%1dH"
 						lcd_set_cursor(e4_num, e2_num); // CursorHome
 					else if (chr_is_num)
-						return 1; // escape = "\x1b%1d;%2d"
+						return; // escape = "\x1b%1d;%2d"
 				}
 				else if (e_3_is_num && (lcd_escape[4] == ';') && chr_is_num)
-					return 1; // escape = "\x1b%2d;%1d"
+					return; // escape = "\x1b%2d;%1d"
 			}
 		}
 		break;
@@ -495,7 +451,7 @@ uint8_t lcd_escape_write(uint8_t chr)
 				if (chr == 'H') // escape = "\x1b%2d;%1dH"
 					lcd_set_cursor(e5_num, e23_num); // CursorHome
 				else if (chr_is_num) // "\x1b%2d;%2d"
-					return 1;
+					return;
 			}
 		}
 		break;
@@ -506,10 +462,9 @@ uint8_t lcd_escape_write(uint8_t chr)
 		break;
 	}
 	escape_cnt = 0; // reset escape
-	return 1; // assume sucess
 }
 
-
+#endif //VT100
 
 
 int lcd_putc(int c)
@@ -648,16 +603,6 @@ void lcd_printFloat(double number, uint8_t digits)
 }
 
 
-
-
-
-
-
-
-
-
-
-
 uint8_t lcd_draw_update = 2;
 int32_t lcd_encoder = 0;
 uint8_t lcd_encoder_bits = 0;
@@ -710,7 +655,7 @@ Sound_MakeSound(e_SOUND_TYPE_ButtonEcho);
 	for(int8_t i = 0; i < 10; i++)
 	{
 		Sound_MakeCustom(100,0,false);
-		delayMicroseconds(100);
+		_delay_us(100);
 	}
 */
 }
@@ -722,13 +667,6 @@ void lcd_quick_feedback(void)
   lcd_beeper_quick_feedback();
 }
 
-
-
-
-
-
-
-
 void lcd_update(uint8_t lcdDrawUpdateOverride)
 {
 	if (lcd_draw_update < lcdDrawUpdateOverride)

+ 2 - 40
Firmware/lcd.h

@@ -13,20 +13,16 @@ extern FILE _lcdout;
 #define lcdout (&_lcdout)
 extern int lcd_putchar(char c, FILE *stream);
 
-
 extern void lcd_init(void);
 
 extern void lcd_refresh(void);
 
 extern void lcd_refresh_noclear(void);
 
-
-
 extern void lcd_clear(void);
 
 extern void lcd_home(void);
 
-
 /*extern void lcd_no_display(void);
 extern void lcd_display(void);
 extern void lcd_no_blink(void);
@@ -45,7 +41,6 @@ extern void lcd_set_cursor(uint8_t col, uint8_t row);
 extern void lcd_createChar_P(uint8_t, const uint8_t*);
 
 
-
 extern int lcd_putc(int c);
 extern int lcd_puts_P(const char* str);
 extern int lcd_puts_at_P(uint8_t c, uint8_t r, const char* str);
@@ -66,7 +61,9 @@ extern void lcd_print(double, int = 2);
 
 //! @brief Clear screen
 #define ESC_2J     "\x1b[2J"
+//! @brief Show cursor
 #define ESC_25h    "\x1b[?25h"
+//! @brief Hide cursor
 #define ESC_25l    "\x1b[?25l"
 //! @brief Set cursor to
 //! @param c column
@@ -118,9 +115,6 @@ extern lcd_lcdupdate_func_t lcd_lcdupdate_func;
 
 
 
-
-
-
 extern uint8_t lcd_clicked(void);
 
 extern void lcd_beeper_quick_feedback(void);
@@ -128,13 +122,6 @@ extern void lcd_beeper_quick_feedback(void);
 //Cause an LCD refresh, and give the user visual or audible feedback that something has happened
 extern void lcd_quick_feedback(void);
 
-
-
-
-
-
-
-
 extern void lcd_update(uint8_t lcdDrawUpdateOverride);
 
 extern void lcd_update_enable(uint8_t enabled);
@@ -165,29 +152,6 @@ private:
 };
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**
-* Implementation of the LCD display routines for a Hitachi HD44780 display. These are common LCD character displays.
-* When selecting the Russian language, a slightly different LCD implementation is used to handle UTF8 characters.
-**/
-
-
 ////////////////////////////////////
 // Setup button and encode mappings for each panel (into 'lcd_buttons' variable
 //
@@ -223,8 +187,6 @@ private:
 #define encrot3 1
 
 
-
-
 //Custom characters defined in the first 8 characters of the LCD
 #define LCD_STR_BEDTEMP     "\x00"
 #define LCD_STR_DEGREE      "\x01"

+ 50 - 47
Firmware/ultralcd.cpp

@@ -1771,8 +1771,8 @@ void lcd_menu_extruder_info()                     // NOT static due to using ins
 
 	lcd_timeoutToStatus.stop(); //infinite timeout
 
+	lcd_home();
 	lcd_printf_P(_N(
-	  ESC_H(0,0)
 	  "%S: %4d RPM\n"
 	  "%S:  %4d RPM\n"
 	 ),
@@ -1833,8 +1833,8 @@ static void lcd_menu_fails_stats_mmu_print()
 	lcd_timeoutToStatus.stop(); //infinite timeout
     uint8_t fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL);
     uint16_t load_fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL);
-//	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) "%S" ESC_H(1,1) "%S  %-3d" ESC_H(1,2) "%S  %-3d" ESC_H(1,3)), _i("Last print failures"), _i("MMU fails"), fails, _i("MMU load fails"), load_fails);
+	lcd_home();
+	lcd_printf_P(PSTR("%S\n" " %S  %-3d\n" " %S  %-3d"), _i("Last print failures"), _i("MMU fails"), fails, _i("MMU load fails"), load_fails);
 	menu_back_if_clicked_fb();
 }
 
@@ -1850,8 +1850,8 @@ static void lcd_menu_fails_stats_mmu_total()
 	lcd_timeoutToStatus.stop(); //infinite timeout
     uint8_t fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL_TOT);
     uint16_t load_fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL_TOT);
-//	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) "%S" ESC_H(1,1) "%S  %-3d" ESC_H(1,2) "%S  %-3d" ESC_H(1,3) "%S %-3d"), _i("Total failures"), _i("MMU fails"), fails, _i("MMU load fails"), load_fails, _i("MMU power fails"), mmu_power_failures);
+	lcd_home();
+	lcd_printf_P(PSTR("%S\n" " %S  %-3d\n" " %S  %-3d\n" " %S %-3d"), _i("Total failures"), _i("MMU fails"), fails, _i("MMU load fails"), load_fails, _i("MMU power fails"), mmu_power_failures);
 	menu_back_if_clicked_fb();
 }
 
@@ -1869,8 +1869,8 @@ static void lcd_menu_fails_stats_total()
     uint16_t filam = eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_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);
-//	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) "%S" ESC_H(1,1) "%S  %-3d" ESC_H(1,2) "%S  %-3d" ESC_H(1,3) "%S  X %-3d  Y %-3d"), _i("Total failures"), _i("Power failures"), power, _i("Filam. runouts"), filam, _i("Crash"), crashX, crashY);
+	lcd_home();
+	lcd_printf_P(PSTR("%S\n" " %S  %-3d\n" " %S  %-3d\n" " %S  X %-3d  Y %-3d"), _i("Total failures"), _i("Power failures"), power, _i("Filam. runouts"), filam, _i("Crash"), crashX, crashY);
 	menu_back_if_clicked_fb();
 }
 
@@ -1887,8 +1887,8 @@ static void lcd_menu_fails_stats_print()
     uint8_t filam = eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT);
     uint8_t crashX = eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_X);
     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) "%S" ESC_H(1,1) "%S  %-3d" ESC_H(1,2) "%S  %-3d" ESC_H(1,3) "%S  X %-3d  Y %-3d"), _i("Last print failures"), _i("Power failures"), power, _i("Filam. runouts"), filam, _i("Crash"), crashX, crashY);
+	lcd_home();
+	lcd_printf_P(PSTR("%S\n" " %S  %-3d\n" " %S  %-3d\n" " %S  X %-3d  Y %-3d"), _i("Last print failures"), _i("Power failures"), power, _i("Filam. runouts"), filam, _i("Crash"), crashX, crashY);
 	menu_back_if_clicked_fb();
 }
 
@@ -1929,7 +1929,8 @@ static void lcd_menu_fails_stats()
 	lcd_timeoutToStatus.stop(); //infinite timeout
     uint8_t filamentLast = eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT);
     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_home();
+    lcd_printf_P(PSTR("Last print failures\n" " Filam. runouts  %-3d\n" "Total failures\n" " Filam. runouts  %-3d"), filamentLast, filamentTotal);
     menu_back_if_clicked();
 }
 #else
@@ -1953,7 +1954,8 @@ extern char* __malloc_heap_end;
 static void lcd_menu_debug()
 {
 #ifdef DEBUG_STACK_MONITOR
-	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_home();
+	lcd_printf_P(PSTR("RAM statistics\n" " SP_min: 0x%04x\n" " heap_start: 0x%04x\n" " heap_end: 0x%04x"), SP_min, __malloc_heap_start, __malloc_heap_end);
 #endif //DEBUG_STACK_MONITOR
 
 	menu_back_if_clicked_fb();
@@ -1963,12 +1965,13 @@ static void lcd_menu_debug()
 static void lcd_menu_temperatures()
 {
 	lcd_timeoutToStatus.stop(); //infinite timeout
-
-	lcd_printf_P(PSTR(ESC_H(1,0) "%S:   %d%c" ESC_H(1,1) "%S:      %d%c"), _i("Nozzle"), (int)current_temperature[0], '\x01', _i("Bed"), (int)current_temperature_bed, '\x01');
+	
+	lcd_home();
+	lcd_printf_P(PSTR(" %S:   %d%c \n" " %S:      %d%c \n"), _i("Nozzle"), (int)current_temperature[0], '\x01', _i("Bed"), (int)current_temperature_bed, '\x01');
 #ifdef AMBIENT_THERMISTOR
-	lcd_printf_P(PSTR(ESC_H(1,2) "%S:  %d%c" ESC_H(1,3) "PINDA:    %d%c"), _i("Ambient"), (int)current_temperature_ambient, '\x01', (int)current_temperature_pinda, '\x01');
+	lcd_printf_P(PSTR(" %S:  %d%c\n" " PINDA:    %d%c"), _i("Ambient"), (int)current_temperature_ambient, '\x01', (int)current_temperature_pinda, '\x01');
 #else //AMBIENT_THERMISTOR
-	lcd_printf_P(PSTR(ESC_H(1,2) "PINDA:    %d%c"), (int)current_temperature_pinda, '\x01');
+	lcd_printf_P(PSTR(" PINDA:    %d%c"), (int)current_temperature_pinda, '\x01');
 #endif //AMBIENT_THERMISTOR
 
     menu_back_if_clicked();
@@ -1984,7 +1987,8 @@ static void lcd_menu_voltages()
 	lcd_timeoutToStatus.stop(); //infinite timeout
 	float volt_pwr = VOLT_DIV_REF * ((float)current_voltage_raw_pwr / (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_home();
+	lcd_printf_P(PSTR(" PWR:      %d.%01dV\n" " 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)));
     menu_back_if_clicked();
 }
 #endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN
@@ -1992,7 +1996,8 @@ static void lcd_menu_voltages()
 #ifdef TMC2130
 static void lcd_menu_belt_status()
 {
-    lcd_printf_P(PSTR(ESC_H(1,0) "%S" ESC_H(2,1) "X %d" ESC_H(2,2) "Y %d" ), _i("Belt status"), eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_X)), eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_Y)));
+	lcd_home();
+    lcd_printf_P(PSTR("%S\n" " X %d\n" " Y %d"), _i("Belt status"), eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_X)), eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_Y)));
     menu_back_if_clicked();
 }
 #endif //TMC2130
@@ -2817,18 +2822,14 @@ void lcd_menu_statistics()
 		const int _m = (_t - (_h * 3600ul)) / 60ul;
 		const int _s = _t - ((_h * 3600ul) + (_m * 60ul));
 
+		lcd_clear();
 		lcd_printf_P(_N(
-		  ESC_2J
-		  "%S:"
-		  ESC_H(6,1) "%8.2fm \n"
-		  "%S :"
-		  ESC_H(8,3) "%2dh %02dm %02ds"
-		  ),
-		 _i("Filament used"),
-		 _met,
-		 _i("Print time"),
-		 _h, _m, _s
-		);
+			"%S:\n"
+			"%8.2fm\n"
+			"%S:\n"
+			"%2dh %02dm %02ds"
+		),_i("Filament used"), _met, _i("Print time"), _h, _m, _s);
+		
 		menu_back_if_clicked_fb();
 	}
 	else
@@ -2844,18 +2845,14 @@ void lcd_menu_statistics()
 		_hours = (_time - (_days * 1440)) / 60;
 		_minutes = _time - ((_days * 1440) + (_hours * 60));
 
+		lcd_clear();
 		lcd_printf_P(_N(
-		  ESC_2J
-		  "%S :"
-		  ESC_H(9,1) "%8.2f m\n"
-		  "%S :\n"
-		  "%7ldd :%2hhdh :%02hhd m"
-		 ),
-		 _i("Total filament"),
-		 _filament_m,
-		 _i("Total print time"),
-		 _days, _hours, _minutes
-		);
+			"%S:\n"
+			"%8.2fm\n"
+			"%S:\n"
+			"%7ldd :%2hhdh :%02hhdm"
+		), _i("Total filament"), _filament_m, _i("Total print time"), _days, _hours, _minutes);
+		
 		KEEPALIVE_STATE(PAUSED_FOR_USER);
 		while (!lcd_clicked())
 		{
@@ -2953,8 +2950,8 @@ static void lcd_menu_xyz_y_min()
 //----------------------
 	float distanceMin[2];
     count_xyz_details(distanceMin);
+	lcd_home();
 	lcd_printf_P(_N(
-	  ESC_H(0,0)
 	  "%S:\n"
 	  "%S\n"
 	  "%S:\n"
@@ -2990,8 +2987,8 @@ static void lcd_menu_xyz_skew()
 //|Severe skew:   0.25d|
 //----------------------
     float angleDiff = eeprom_read_float((float*)(EEPROM_XYZ_CAL_SKEW));
+	lcd_home();
 	lcd_printf_P(_N(
-	  ESC_H(0,0)
 	  "%S:\n"
 	  "%S\n"
 	  "%S:  %5.2f\x01\n"
@@ -3002,10 +2999,14 @@ static void lcd_menu_xyz_skew()
 	 _i("Slight skew"), _deg(bed_skew_angle_mild),
 	 _i("Severe skew"), _deg(bed_skew_angle_extreme)
 	);
-	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 (angleDiff < 100){
+		lcd_set_cursor(15,0);
+		lcd_printf_P(_N("%4.2f\x01"), _deg(angleDiff));
+	}
+	else{
+		lcd_set_cursor(15,0);
+		lcd_puts_P(_N("N/A"));
+	}
     if (lcd_clicked())
         menu_goto(lcd_menu_xyz_offset, 0, true, true);
 }
@@ -4355,7 +4356,8 @@ static void lcd_crash_mode_info()
 	static uint32_t tim = 0;
 	if ((tim + 1000) < _millis())
 	{
-		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
+		lcd_clear();
+		fputs_P(_i("Crash detection can\rbe turned on only in\rNormal mode"), lcdout);////MSG_CRASH_DET_ONLY_IN_NORMAL c=20 r=4
 		tim = _millis();
 	}
     menu_back_if_clicked();
@@ -4367,7 +4369,8 @@ static void lcd_crash_mode_info2()
 	static uint32_t tim = 0;
 	if ((tim + 1000) < _millis())
 	{
-		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
+		lcd_clear();
+		fputs_P(_i("WARNING:\rCrash detection\rdisabled in\rStealth mode"), lcdout);////MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
 		tim = _millis();
 	}
     menu_back_if_clicked();

+ 2 - 2
lang/lang_en.txt

@@ -8,10 +8,10 @@
 "[0;0] point offset"
 
 #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"
+"Crash detection can\rbe turned on only in\rNormal mode"
 
 #MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
-"\x1b[2JWARNING:\x1b[1;0HCrash detection\x1b[2;0Hdisabled in\x1b[3;0HStealth mode"
+"WARNING:\rCrash detection\rdisabled in\rStealth mode"
 
 #
 ">Cancel"

+ 4 - 4
lang/lang_en_cz.txt

@@ -11,12 +11,12 @@
 "[0;0] odsazeni bodu"
 
 #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 detekce muze\x1b[1;0Hbyt zapnuta pouze v\x1b[2;0HNormal modu"
+Crash detection can\rbe turned on only in\rNormal mode"
+Crash detekce muze\rbyt zapnuta pouze v\rNormal modu"
 
 #MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
-"\x1b[2JWARNING:\x1b[1;0HCrash detection\x1b[2;0Hdisabled in\x1b[3;0HStealth mode"
-"\x1b[2JPOZOR:\x1b[1;0HCrash detekce\x1b[2;0Hdeaktivovana ve\x1b[3;0HStealth modu"
+WARNING:\rCrash detection\rdisabled in\rStealth mode"
+POZOR:\rCrash detekce\rdeaktivovana ve\rStealth modu"
 
 #
 ">Cancel"

+ 4 - 4
lang/lang_en_de.txt

@@ -11,12 +11,12 @@
 "[0;0] Punktversatz"
 
 #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 Erkennung kann\x1b[1;0Hnur im Modus Normal\x1b[2;0Hgenutzt werden"
+Crash detection can\rbe turned on only in\rNormal mode"
+Crash Erkennung kann\rnur im Modus Normal\rgenutzt werden"
 
 #MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
-"\x1b[2JWARNING:\x1b[1;0HCrash detection\x1b[2;0Hdisabled in\x1b[3;0HStealth mode"
-"\x1b[2JWARNUNG:\x1b[1;0HCrash Erkennung\x1b[2;0Hdeaktiviert im\x1b[3;0HStealth Modus"
+WARNING:\rCrash detection\rdisabled in\rStealth mode"
+WARNUNG:\rCrash Erkennung\rdeaktiviert im\rStealth Modus"
 
 #
 ">Cancel"

+ 4 - 4
lang/lang_en_es.txt

@@ -11,12 +11,12 @@
 "[0;0] punto offset"
 
 #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[2JDec. choque\x1b[1;0Hpuede ser activada solo en\x1b[2;0HModo normal"
+Crash detection can\rbe turned on only in\rNormal mode"
+Dec. choque\rpuede ser activada solo en\rModo normal"
 
 #MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
-"\x1b[2JWARNING:\x1b[1;0HCrash detection\x1b[2;0Hdisabled in\x1b[3;0HStealth mode"
-"\x1b[2JATENCION:\x1b[1;0HDec. choque\x1b[2;0Hdesactivada en\x1b[3;0HModo silencio"
+WARNING:\rCrash detection\rdisabled in\rStealth mode"
+ATENCION:\rDec. choque\rdesactivada en\rModo silencio"
 
 #
 ">Cancel"

+ 4 - 4
lang/lang_en_fr.txt

@@ -11,12 +11,12 @@
 "Offset point [0;0]"
 
 #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[2JLa detection de crash peut etre\x1b[1;0Hactive seulement\x1b[2;0Hen mode Normal"
+Crash detection can\rbe turned on only in\rNormal mode"
+La detection de crash peut etre\ractive seulement\ren mode Normal"
 
 #MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
-"\x1b[2JWARNING:\x1b[1;0HCrash detection\x1b[2;0Hdisabled in\x1b[3;0HStealth mode"
-"\x1b[2JATTENTION :\x1b[1;0HDetection de crash\x1b[2;0H desactivee en\x1b[3;0Hmode Furtif"
+WARNING:\rCrash detection\rdisabled in\rStealth mode"
+ATTENTION :\rDetection de crash\r desactivee en\rmode Furtif"
 
 #
 ">Cancel"

+ 4 - 4
lang/lang_en_it.txt

@@ -11,12 +11,12 @@
 "[0;0] punto offset"
 
 #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[2JRilev. impatto\x1b[1;0Hattivabile solo\x1b[2;0Hin Modalita normale"
+Crash detection can\rbe turned on only in\rNormal mode"
+Rilev. impatto\rattivabile solo\rin Modalita normale"
 
 #MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
-"\x1b[2JWARNING:\x1b[1;0HCrash detection\x1b[2;0Hdisabled in\x1b[3;0HStealth mode"
-"\x1b[2JATTENZIONE:\x1b[1;0HRilev. impatto\x1b[2;0Hdisattivato in\x1b[3;0HModalita silenziosa"
+WARNING:\rCrash detection\rdisabled in\rStealth mode"
+ATTENZIONE:\rRilev. impatto\rdisattivato in\rModalita silenziosa"
 
 #
 ">Cancel"

+ 4 - 4
lang/lang_en_pl.txt

@@ -11,12 +11,12 @@
 "[0;0] przesuniecie punktu"
 
 #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[2JWykrywanie zderzen moze\x1b[1;0Hbyc wlaczone tylko w\x1b[2;0Htrybie Normalnym"
+Crash detection can\rbe turned on only in\rNormal mode"
+Wykrywanie zderzen moze\rbyc wlaczone tylko w\rtrybie Normalnym"
 
 #MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
-"\x1b[2JWARNING:\x1b[1;0HCrash detection\x1b[2;0Hdisabled in\x1b[3;0HStealth mode"
-"\x1b[2JUWAGA:\x1b[1;0HWykrywanie zderzen\x1b[2;0Hwylaczone w\x1b[3;0Htrybie Stealth"
+WARNING:\rCrash detection\rdisabled in\rStealth mode"
+UWAGA:\rWykrywanie zderzen\rwylaczone w\rtrybie Stealth"
 
 #
 ">Cancel"