Browse Source

Merge branch 'MK3' into fix_lcd_stop

Alex Voinea 5 years ago
parent
commit
df0d781c20

+ 14 - 6
Firmware/Marlin_main.cpp

@@ -63,6 +63,7 @@
 
 #include "menu.h"
 #include "ultralcd.h"
+#include "backlight.h"
 
 #include "planner.h"
 #include "stepper.h"
@@ -999,10 +1000,6 @@ void setup()
 
 	ultralcd_init();
 
-#if (LCD_BL_PIN != -1) && defined (LCD_BL_PIN)
-	analogWrite(LCD_BL_PIN, 255); //set full brightnes
-#endif //(LCD_BL_PIN != -1) && defined (LCD_BL_PIN)
-
 	spi_init();
 
 	lcd_splash();
@@ -2824,7 +2821,10 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level)
 	#ifdef TMC2130
 	FORCE_HIGH_POWER_START;
 	#endif // TMC2130
-	// Only Z calibration?
+    
+    FORCE_BL_ON_START;
+	
+    // Only Z calibration?
 	if (!onlyZ)
 	{
 		setTargetBed(0);
@@ -3012,6 +3012,9 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level)
 #ifdef TMC2130
 	FORCE_HIGH_POWER_END;
 #endif // TMC2130
+    
+    FORCE_BL_ON_END;
+    
 	return final_result;
 }
 
@@ -6207,7 +6210,6 @@ Sigma_Exit:
           LCD_MESSAGERPGM(_T(WELCOME_MSG));
           lcd_update(0);
         break;
-      #endif
 
       //! ### M81 - Turn off Power Supply
       // --------------------------------------
@@ -6231,6 +6233,7 @@ Sigma_Exit:
         LCD_MESSAGERPGM(CAT4(CUSTOM_MENDEL_NAME,PSTR(" "),MSG_OFF,PSTR(".")));
         lcd_update(0);
 	  break;
+    #endif
 
     //! ### M82 - Set E axis to absolute mode
     // ---------------------------------------
@@ -9604,6 +9607,11 @@ void uvlo_()
 	unsigned long time_start = _millis();
 	bool sd_print = card.sdprinting;
     // Conserve power as soon as possible.
+#ifdef LCD_BL_PIN
+    backlightMode = BACKLIGHT_MODE_DIM;
+    backlightLevel_LOW = 0;
+    backlight_update();
+#endif //LCD_BL_PIN
     disable_x();
     disable_y();
     

+ 16 - 0
Firmware/Sd2Card.cpp

@@ -319,6 +319,22 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
       goto fail;
     }
   }
+
+  // send 0xFF until 0xFF received to give card some clock cycles
+  t0 = (uint16_t)_millis();
+  SERIAL_ECHOLNRPGM(PSTR("Sending 0xFF"));
+  spiSend(0XFF);
+  while ((status_ = spiRec()) != 0xFF)
+  {
+    spiSend(0XFF);
+    if (((uint16_t)_millis() - t0) > SD_CARD_ERROR_FF_TIMEOUT)
+    {
+      error(SD_CARD_ERROR_CMD8);
+      SERIAL_ECHOLNRPGM(PSTR("No 0xFF received"));
+      goto fail;
+    }
+  }
+
   // check SD version
   if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
     type(SD_CARD_TYPE_SD1);

+ 2 - 0
Firmware/Sd2Card.h

@@ -105,6 +105,8 @@ uint8_t const SD_CARD_ERROR_SCK_RATE = 0X18;
 uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0X19;
 /** crc check error */
 uint8_t const SD_CARD_ERROR_CRC = 0X20;
+/** no response to sent 0xFF */
+uint8_t const SD_CARD_ERROR_FF_TIMEOUT = 0X21;
 
 /** Toshiba FlashAir: iSDIO */
 uint8_t const SD_CARD_ERROR_CMD48 = 0x80;

+ 120 - 0
Firmware/backlight.cpp

@@ -0,0 +1,120 @@
+//backlight.cpp
+
+#include "backlight.h"
+#include <avr/eeprom.h>
+#include <Arduino.h>
+#include "eeprom.h"
+#include "Marlin.h"
+#include "pins.h"
+#include "fastio.h"
+#include "Timer.h"
+
+#ifdef LCD_BL_PIN
+
+#define BL_FLASH_DELAY_MS 25
+
+bool backlightSupport = 0; //only if it's true will any of the settings be visible to the user
+int16_t backlightLevel_HIGH = 0;
+int16_t backlightLevel_LOW = 0;
+uint8_t backlightMode = BACKLIGHT_MODE_BRIGHT;
+int16_t backlightTimer_period = 10;
+LongTimer backlightTimer;
+
+static void backlightTimer_reset() //used for resetting the timer and waking the display. Triggered on user interactions.
+{
+    if (!backlightSupport) return;
+    backlightTimer.start();
+    backlight_update();
+}
+
+void force_bl_on(bool section_start)
+{
+    if (section_start)
+    {
+        backlightMode = BACKLIGHT_MODE_BRIGHT;
+        if (backlightLevel_HIGH < 30) backlightLevel_HIGH = 30;
+    }
+    else
+    {
+        backlightMode = eeprom_read_byte((uint8_t *)EEPROM_BACKLIGHT_MODE);
+        backlightLevel_HIGH = eeprom_read_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_HIGH);
+    }
+    backlight_update();
+}
+
+void backlight_wake(const uint8_t flashNo)
+{
+    if (!backlightSupport) return;
+    
+    if (flashNo)
+    {
+        uint8_t backlightMode_bck = backlightMode;
+        for (uint8_t i = 0; i < (((backlightMode_bck == BACKLIGHT_MODE_AUTO) && !backlightTimer.running()) + (flashNo * 2)); i++)
+        {
+            backlightMode = !backlightMode; //toggles between BACKLIGHT_MODE_BRIGHT and BACKLIGHT_MODE_DIM
+            backlight_update();
+            _delay(BL_FLASH_DELAY_MS);
+        }
+        backlightMode = backlightMode_bck;
+    }
+    backlightTimer_reset();
+}
+
+void backlight_save() //saves all backlight data to eeprom.
+{
+    eeprom_update_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_HIGH, (uint8_t)backlightLevel_HIGH);
+    eeprom_update_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_LOW, (uint8_t)backlightLevel_LOW);
+    eeprom_update_byte((uint8_t *)EEPROM_BACKLIGHT_MODE, backlightMode);
+    eeprom_update_word((uint16_t *)EEPROM_BACKLIGHT_TIMEOUT, backlightTimer_period);
+}
+
+void backlight_update()
+{
+    if (!backlightSupport) return;
+    
+    if (backlightMode == BACKLIGHT_MODE_AUTO)
+    {
+        if (backlightTimer.expired((uint32_t)backlightTimer_period * 1000ul)) analogWrite(LCD_BL_PIN, backlightLevel_LOW);
+        else if (backlightTimer.running()) analogWrite(LCD_BL_PIN, backlightLevel_HIGH);
+        else {/*do nothing*/;} //display is dimmed.
+    }
+    else if (backlightMode == BACKLIGHT_MODE_DIM) analogWrite(LCD_BL_PIN, backlightLevel_LOW);
+    else analogWrite(LCD_BL_PIN, backlightLevel_HIGH);
+}
+
+void backlight_init()
+{
+//check for backlight support on lcd
+    SET_INPUT(LCD_BL_PIN);
+    WRITE(LCD_BL_PIN,HIGH);
+    _delay(10);
+    backlightSupport = !READ(LCD_BL_PIN);
+    if (!backlightSupport) return;
+
+//initialize backlight
+    backlightMode = eeprom_read_byte((uint8_t *)EEPROM_BACKLIGHT_MODE);
+    if (backlightMode == 0xFF) //set default values
+    {
+        backlightMode = BACKLIGHT_MODE_AUTO;
+        backlightLevel_HIGH = 130;
+        backlightLevel_LOW = 50;
+        backlightTimer_period = 10; //in seconds
+        backlight_save();
+    }
+    backlightLevel_HIGH = eeprom_read_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_HIGH);
+    backlightLevel_LOW = eeprom_read_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_LOW);
+    backlightTimer_period = eeprom_read_word((uint16_t *)EEPROM_BACKLIGHT_TIMEOUT);
+    
+    SET_OUTPUT(LCD_BL_PIN);
+    backlightTimer_reset();
+}
+
+#else //LCD_BL_PIN
+
+void force_bl_on(__attribute__((unused)) bool section_start) {}
+void backlight_update() {}
+void backlight_init() {}
+void backlight_save() {}
+void backlight_wake(__attribute__((unused)) const uint8_t flashNo) {}
+
+#endif //LCD_BL_PIN

+ 32 - 0
Firmware/backlight.h

@@ -0,0 +1,32 @@
+//backlight.h
+#ifndef _BACKLIGHT_H
+#define _BACKLIGHT_H
+
+#include <inttypes.h>
+#include "Marlin.h"
+#include "pins.h"
+
+enum Backlight_Mode
+{
+	BACKLIGHT_MODE_DIM     = 0,
+	BACKLIGHT_MODE_BRIGHT  = 1,
+	BACKLIGHT_MODE_AUTO    = 2,
+};
+
+extern int16_t backlightLevel_HIGH;
+extern int16_t backlightLevel_LOW;
+extern uint8_t backlightMode;
+extern bool backlightSupport;
+extern int16_t backlightTimer_period;
+
+#define FORCE_BL_ON_START force_bl_on(true)
+#define FORCE_BL_ON_END force_bl_on(false)
+
+extern void force_bl_on(bool section_start);
+extern void backlight_update();
+extern void backlight_init();
+extern void backlight_save();
+extern void backlight_wake(const uint8_t flashNo = 0);
+
+
+#endif //_BACKLIGHT_H

+ 7 - 1
Firmware/eeprom.h

@@ -207,8 +207,14 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
 #define EEPROM_UVLO_SAVED_TARGET (EEPROM_FSENSOR_ACTION_NA - 4*4) // 4 x float for saved target for all axes
 #define EEPROM_UVLO_FEEDMULTIPLY (EEPROM_UVLO_SAVED_TARGET - 2) // uint16_t for feedmultiply
 
+#define EEPROM_BACKLIGHT_LEVEL_HIGH (EEPROM_UVLO_FEEDMULTIPLY-1) // uint8
+#define EEPROM_BACKLIGHT_LEVEL_LOW (EEPROM_BACKLIGHT_LEVEL_HIGH-1) // uint8
+#define EEPROM_BACKLIGHT_MODE (EEPROM_BACKLIGHT_LEVEL_LOW-1) // uint8
+#define EEPROM_BACKLIGHT_TIMEOUT (EEPROM_BACKLIGHT_MODE-2) // uint16
+
+
 //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items.
-#define EEPROM_LAST_ITEM EEPROM_UVLO_FEEDMULTIPLY
+#define EEPROM_LAST_ITEM EEPROM_BACKLIGHT_TIMEOUT
 // !!!!!
 // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
 // !!!!!

+ 3 - 3
Firmware/language.c

@@ -17,10 +17,10 @@ uint8_t lang_selected = 0;
 
 #if (LANG_MODE == 0) //primary language only
 
-uint8_t lang_select(uint8_t lang) { return 0; }
+uint8_t lang_select(__attribute__((unused)) uint8_t lang) { return 0; }
 uint8_t lang_get_count() { return 1; }
-uint16_t lang_get_code(uint8_t lang) { return LANG_CODE_EN; }
-const char* lang_get_name_by_code(uint16_t code) { return _n("English"); }
+uint16_t lang_get_code(__attribute__((unused)) uint8_t lang) { return LANG_CODE_EN; }
+const char* lang_get_name_by_code(__attribute__((unused)) uint16_t code) { return _n("English"); }
 void lang_reset(void) { }
 uint8_t lang_is_selected(void) { return 1; }
 

+ 7 - 0
Firmware/messages.c

@@ -131,6 +131,13 @@ const char MSG_MAGNETS_COMP[] PROGMEM_I1 = ISTR("Magnets comp."); ////
 const char MSG_FS_ACTION[] PROGMEM_I1 = ISTR("FS Action"); ////
 const char MSG_FS_CONTINUE[] PROGMEM_I1 = ISTR("Cont."); ////
 const char MSG_FS_PAUSE[] PROGMEM_I1 = ISTR("Pause"); ////
+const char MSG_BRIGHTNESS[] PROGMEM_I1 = ISTR("Brightness"); ////
+const char MSG_BL_HIGH[] PROGMEM_I1 = ISTR("Level Bright"); ////
+const char MSG_BL_LOW[] PROGMEM_I1 = ISTR("Level Dimmed"); ////
+const char MSG_TIMEOUT[] PROGMEM_I1 = ISTR("Timeout"); ////
+const char MSG_BRIGHT[] PROGMEM_I1 = ISTR("Bright"); ////
+const char MSG_DIM[] PROGMEM_I1 = ISTR("Dim"); ////
+const char MSG_AUTO[] PROGMEM_I1 = ISTR("Auto"); ////
 
 //not internationalized messages
 const char MSG_SD_WORKDIR_FAIL[] PROGMEM_N1 = "workDir open failed"; ////

+ 7 - 0
Firmware/messages.h

@@ -131,6 +131,13 @@ extern const char MSG_MAGNETS_COMP[];
 extern const char MSG_FS_ACTION[];
 extern const char MSG_FS_CONTINUE[];
 extern const char MSG_FS_PAUSE[];
+extern const char MSG_BRIGHTNESS[];
+extern const char MSG_BL_HIGH[];
+extern const char MSG_BL_LOW[];
+extern const char MSG_TIMEOUT[];
+extern const char MSG_BRIGHT[];
+extern const char MSG_DIM[];
+extern const char MSG_AUTO[];
 
 //not internationalized messages
 extern const char MSG_BROWNOUT_RESET[];

+ 1 - 12
Firmware/mmu.cpp

@@ -1578,18 +1578,7 @@ void mmu_continue_loading(bool blocking)
             break;
         case Ls::Unload:
             stop_and_save_print_to_ram(0, 0);
-
-            //lift z
-            current_position[Z_AXIS] += Z_PAUSE_LIFT;
-            if (current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
-            plan_buffer_line_curposXYZE(15, active_extruder);
-            st_synchronize();
-
-            //Move XY to side
-            current_position[X_AXIS] = X_PAUSE_POS;
-            current_position[Y_AXIS] = Y_PAUSE_POS;
-            plan_buffer_line_curposXYZE(50, active_extruder);
-            st_synchronize();
+            long_pause();
 
             mmu_command(MmuCmd::U0);
             manage_response(false, true, MMU_UNLOAD_MOVE);

+ 1 - 1
Firmware/pins_Einsy_1_0.h

@@ -100,7 +100,7 @@
 
 //#define KILL_PIN            32
 
-//#define LCD_BL_PIN          5   //backlight control pin
+#define LCD_BL_PIN          5   //backlight control pin
 #define BEEPER              84  // Beeper on AUX-4
 #define LCD_PINS_RS         82
 #define LCD_PINS_ENABLE     61 // !!! changed from 18 (EINY03)

+ 7 - 0
Firmware/sound.cpp

@@ -5,6 +5,7 @@
 //#include <inttypes.h>
 //#include <avr/eeprom.h>
 //#include "eeprom.h"
+#include "backlight.h"
 
 
 //eSOUND_MODE eSoundMode=e_SOUND_MODE_LOUD;
@@ -63,6 +64,7 @@ Sound_SaveMode();
 
 //if critical is true then silend and once mode is ignored
 void Sound_MakeCustom(uint16_t ms,uint16_t tone_,bool critical){
+    backlight_wake();
      if (!critical){
           if (eSoundMode != e_SOUND_MODE_SILENT){
                if(!tone_){
@@ -135,6 +137,7 @@ switch(eSoundMode)
 
 static void Sound_DoSound_Blind_Alert(void)
 {
+    backlight_wake(1);
      uint8_t nI;
 
      for(nI=0; nI<20; nI++)
@@ -148,6 +151,7 @@ static void Sound_DoSound_Blind_Alert(void)
 
  static void Sound_DoSound_Encoder_Move(void)
 {
+    backlight_wake();
 uint8_t nI;
 
  for(nI=0;nI<5;nI++)
@@ -161,6 +165,7 @@ uint8_t nI;
 
 static void Sound_DoSound_Echo(void)
 {
+    backlight_wake();
 uint8_t nI;
 
 for(nI=0;nI<10;nI++)
@@ -174,6 +179,7 @@ for(nI=0;nI<10;nI++)
 
 static void Sound_DoSound_Prompt(void)
 {
+    backlight_wake(2);
 WRITE(BEEPER,HIGH);
 _delay_ms(500);
 WRITE(BEEPER,LOW);
@@ -181,6 +187,7 @@ WRITE(BEEPER,LOW);
 
 static void Sound_DoSound_Alert(bool bOnce)
 {
+    backlight_wake();
 uint8_t nI,nMax;
 
 nMax=bOnce?1:3;

+ 4 - 4
Firmware/tmc2130.cpp

@@ -807,15 +807,15 @@ void tmc2130_goto_step(uint8_t axis, uint8_t step, uint8_t dir, uint16_t delay_u
 	{
 		dir = tmc2130_get_inv(axis)?0:1;
 		int steps = (int)step - (int)(mscnt >> shift);
-		if (steps < 0)
+		if (steps > static_cast<int>(cnt / 2))
 		{
 			dir ^= 1;
-			steps = -steps;
+			steps = cnt - steps; // This can create a negative step value
 		}
-		if (steps > static_cast<int>(cnt / 2))
+        if (steps < 0)
 		{
 			dir ^= 1;
-			steps = cnt - steps;
+			steps = -steps;
 		}
 		cnt = steps;
 	}

+ 80 - 8
Firmware/ultralcd.cpp

@@ -19,6 +19,8 @@
 #include "lcd.h"
 #include "menu.h"
 
+#include "backlight.h"
+
 #include "util.h"
 #include "mesh_bed_leveling.h"
 #include "mesh_bed_calibration.h"
@@ -56,6 +58,7 @@ char longFilenameOLD[LONG_FILENAME_LENGTH];
 
 static void lcd_sd_updir();
 static void lcd_mesh_bed_leveling_settings();
+static void lcd_backlight_menu();
 
 int8_t ReInitLCD = 0;
 
@@ -112,7 +115,9 @@ static const char* lcd_display_message_fullscreen_nonBlocking_P(const char *msg,
 
 /* Different menus */
 static void lcd_status_screen();
+#if (LANG_MODE != 0)
 static void lcd_language_menu();
+#endif
 static void lcd_main_menu();
 static void lcd_tune_menu();
 //static void lcd_move_menu();
@@ -4929,6 +4934,7 @@ void lcd_wizard() {
 	}
 }
 
+#if (LANG_MODE != 0)
 void lcd_language()
 {
 	lcd_update_enable(true);
@@ -4948,6 +4954,7 @@ void lcd_language()
 	else
 		lang_select(LANG_ID_PRI);
 }
+#endif
 
 static void wait_preheat()
 {
@@ -5056,8 +5063,10 @@ void lcd_wizard(WizState state)
 	// Make sure EEPROM_WIZARD_ACTIVE is true if entering using different entry point
 	// other than WizState::Run - it is useful for debugging wizard.
 	if (state != S::Run) eeprom_update_byte((uint8_t*)EEPROM_WIZARD_ACTIVE, 1);
-
-	while (!end) {
+    
+    FORCE_BL_ON_START;
+	
+    while (!end) {
 		printf_P(PSTR("Wizard state: %d\n"), state);
 		switch (state) {
 		case S::Run: //Run wizard?
@@ -5193,7 +5202,9 @@ void lcd_wizard(WizState state)
 		default: break;
 		}
 	}
-
+    
+    FORCE_BL_ON_END;
+    
 	printf_P(_N("Wizard end state: %d\n"), state);
 	switch (state) { //final message
 	case S::Restore: //printer was already calibrated
@@ -5830,6 +5841,13 @@ static void lcd_settings_menu()
 	SETTINGS_SD;
 	SETTINGS_SOUND;
 
+#ifdef LCD_BL_PIN
+    if (backlightSupport)
+    {
+        MENU_ITEM_SUBMENU_P(_T(MSG_BRIGHTNESS), lcd_backlight_menu);
+    }
+#endif //LCD_BL_PIN
+
 	if (farm_mode)
 	{
 		MENU_ITEM_SUBMENU_P(PSTR("Farm number"), lcd_farm_no);
@@ -6752,10 +6770,10 @@ void lcd_resume_print()
 
     if (fan_error_selftest()) return; //abort if error persists
 
+    isPrintPaused = false;
     restore_print_from_ram_and_continue(0.0);
     pause_time += (_millis() - start_pause_print); //accumulate time when print is paused for correct statistics calculation
     refresh_cmd_timeout();
-    isPrintPaused = false;
     SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_RESUMED); //resume octoprint
 }
 
@@ -6907,7 +6925,7 @@ static void lcd_main_menu()
 			{
 				MENU_ITEM_FUNCTION_P(_i("Pause print"), lcd_pause_print);////MSG_PAUSE_PRINT
 			}
-			else
+			else if(isPrintPaused)
 			{
 				#ifdef FANCHECK
 					if((fan_check_error == EFCE_FIXED) || (fan_check_error == EFCE_OK))
@@ -7159,6 +7177,12 @@ static void lcd_tune_menu()
 #endif //TMC2130
 	SETTINGS_MMU_MODE;
     SETTINGS_SOUND;
+#ifdef LCD_BL_PIN
+    if (backlightSupport)
+    {
+        MENU_ITEM_SUBMENU_P(_T(MSG_BRIGHTNESS), lcd_backlight_menu);
+    }
+#endif //LCD_BL_PIN
 	MENU_END();
 }
 
@@ -7208,6 +7232,36 @@ static void lcd_mesh_bed_leveling_settings()
 	//SETTINGS_MBL_MODE;
 }
 
+#ifdef LCD_BL_PIN
+static void backlight_mode_toggle()
+{
+    switch (backlightMode)
+    {
+        case BACKLIGHT_MODE_BRIGHT: backlightMode = BACKLIGHT_MODE_DIM; break;
+        case BACKLIGHT_MODE_DIM: backlightMode = BACKLIGHT_MODE_AUTO; break;
+        case BACKLIGHT_MODE_AUTO: backlightMode = BACKLIGHT_MODE_BRIGHT; break;
+        default: backlightMode = BACKLIGHT_MODE_BRIGHT; break;
+    }
+    backlight_save();
+}
+
+static void lcd_backlight_menu()
+{
+    MENU_BEGIN();
+    ON_MENU_LEAVE(
+        backlight_save();
+    );
+    
+    MENU_ITEM_BACK_P(_T(MSG_BACK));
+    MENU_ITEM_EDIT_int3_P(_T(MSG_BL_HIGH), &backlightLevel_HIGH, backlightLevel_LOW, 255);
+    MENU_ITEM_EDIT_int3_P(_T(MSG_BL_LOW), &backlightLevel_LOW, 0, backlightLevel_HIGH);
+	MENU_ITEM_TOGGLE_P(_T(MSG_MODE), ((backlightMode==BACKLIGHT_MODE_BRIGHT) ? _T(MSG_BRIGHT) : ((backlightMode==BACKLIGHT_MODE_DIM) ? _T(MSG_DIM) : _T(MSG_AUTO))), backlight_mode_toggle);
+    MENU_ITEM_EDIT_int3_P(_T(MSG_TIMEOUT), &backlightTimer_period, 1, 999);
+    
+    MENU_END();
+}
+#endif //LCD_BL_PIN
+
 static void lcd_control_temperature_menu()
 {
 #ifdef PIDTEMP
@@ -7491,6 +7545,10 @@ bool lcd_selftest()
 #if !IR_SENSOR_ANALOG
      _delay(2000);
 #endif //!IR_SENSOR_ANALOG
+    
+    FORCE_BL_ON_START;
+    
+	_delay(2000);
 	KEEPALIVE_STATE(IN_HANDLER);
 #if IR_SENSOR_ANALOG
      bool bAction;
@@ -7723,7 +7781,10 @@ bool lcd_selftest()
 	#ifdef TMC2130
 	  FORCE_HIGH_POWER_END;
 	#endif // TMC2130
-	KEEPALIVE_STATE(NOT_BUSY);
+    
+    FORCE_BL_ON_END;
+	
+    KEEPALIVE_STATE(NOT_BUSY);
 	return(_result);
 }
 
@@ -8132,7 +8193,9 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
 static void lcd_selftest_error(TestError testError, const char *_error_1, const char *_error_2)
 {
 	lcd_beeper_quick_feedback();
-
+    
+    FORCE_BL_ON_END;
+    
 	target_temperature[0] = 0;
 	target_temperature_bed = 0;
 	manage_heater();
@@ -8731,6 +8794,7 @@ void ultralcd_init()
         else lcd_autoDeplete = autoDepleteRaw;
 
     }
+    backlight_init();
 	lcd_init();
 	lcd_refresh();
 	lcd_longpress_func = menu_lcd_longpress_func;
@@ -8879,6 +8943,7 @@ uint8_t get_message_level()
 
 void menu_lcd_longpress_func(void)
 {
+	backlight_wake();
     if (homing_flag || mesh_bed_leveling_flag || menu_menu == lcd_babystep_z || menu_menu == lcd_move_z)
     {
         // disable longpress during re-entry, while homing or calibration
@@ -8960,6 +9025,7 @@ void menu_lcd_lcdupdate_func(void)
 		lcd_draw_update = 2;
 		lcd_oldcardstatus = IS_SD_INSERTED;
 		lcd_refresh(); // to maybe revive the LCD if static electricity killed it.
+        backlight_wake();
 		if (lcd_oldcardstatus)
 		{
 			card.initsd();
@@ -8977,6 +9043,7 @@ void menu_lcd_lcdupdate_func(void)
 		}
 	}
 #endif//CARDINSERTED
+    backlight_update();
 	if (lcd_next_update_millis < _millis())
 	{
 		if (abs(lcd_encoder_diff) >= ENCODER_PULSES_PER_STEP)
@@ -8987,9 +9054,14 @@ void menu_lcd_lcdupdate_func(void)
 			Sound_MakeSound(e_SOUND_TYPE_EncoderMove);
 			lcd_encoder_diff = 0;
 			lcd_timeoutToStatus.start();
+			backlight_wake();
 		}
 
-		if (LCD_CLICKED) lcd_timeoutToStatus.start();
+		if (LCD_CLICKED)
+		{
+			lcd_timeoutToStatus.start();
+			backlight_wake();
+		}
 
 		(*menu_menu)();
 

+ 3 - 0
Firmware/ultralcd.h

@@ -6,6 +6,7 @@
 #include "conv2str.h"
 #include "menu.h"
 #include "mesh_bed_calibration.h"
+#include "config.h"
 
 #include "config.h"
 
@@ -220,7 +221,9 @@ void lcd_set_degree();
 void lcd_set_progress();
 #endif
 
+#if (LANG_MODE != 0)
 void lcd_language();
+#endif
 
 void lcd_wizard();
 bool lcd_autoDepleteEnabled();

+ 1 - 0
README.md

@@ -178,6 +178,7 @@ Example:
 
 # 4. Documentation
 run [doxygen](http://www.doxygen.nl/) in Firmware folder
+or visit https://prusa3d.github.io/Prusa-Firmware-Doc for doxygen generated output
 
 # 5. FAQ
 Q:I built firmware using Arduino and I see "?" instead of numbers in printer user interface.