Browse Source

Merge branch 'MK3' into wizard

XPila 7 years ago
parent
commit
afb85865b6

+ 9 - 3
Firmware/Configuration.h

@@ -9,8 +9,8 @@
 
 // Firmware version
 #define FW_version "3.0.12-RC2"
-//#define FW_build   107
-#define FW_build   --BUILD-NUMBER--
+#define FW_build   108
+//#define FW_build   --BUILD-NUMBER--
 #define FW_version_build FW_version " b" STR(FW_build)
 
 
@@ -519,7 +519,13 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 // please keep turned on if you can.
 //#define EEPROM_CHITCHAT
 
-
+// Host Keepalive
+//
+// When enabled Marlin will send a busy status message to the host
+// every couple of seconds when it can't accept commands.
+//
+#define HOST_KEEPALIVE_FEATURE    // Disable this if your host doesn't like keepalive messages
+#define HOST_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113.
 
 //LCD and SD support
 #define ULTRA_LCD  //general LCD support, also 16x2

+ 1 - 1
Firmware/Configuration_prusa.h

@@ -84,7 +84,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 //#define _NO_ASM
 #define DEBUG_DCODES //D codes
 #if 1
-//#define DEBUG_FSENSOR_LOG          //Reports fsensor status to serial
+#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 

+ 82 - 13
Firmware/Dcodes.cpp

@@ -1,5 +1,7 @@
 #include "Dcodes.h"
 #include "Marlin.h"
+#
+#include "ConfigurationStore.h"
 #include "cmdqueue.h"
 #include "pat9125.h"
 #include <avr/wdt.h>
@@ -16,6 +18,10 @@
 #define BOOT_APP_FLG_COPY  0x02
 #define BOOT_APP_FLG_FLASH 0x04
 
+extern uint8_t fsensor_log;
+extern float current_temperature_pinda;
+extern float axis_steps_per_unit[NUM_AXIS];
+
 
 inline void serial_print_hex_nibble(uint8_t val)
 {
@@ -77,11 +83,12 @@ void dcode_0()
 
 void dcode_1()
 {
-	MYSERIAL.println("D1 - Clear EEPROM");
+	MYSERIAL.println("D1 - Clear EEPROM and RESET");
 	cli();
-	for (int i = 0; i < 4096; i++)
-		eeprom_write_byte((unsigned char*)i, (unsigned char)0);
-	sei();
+	for (int i = 0; i < 8192; i++)
+		eeprom_write_byte((unsigned char*)i, (unsigned char)0xff);
+	wdt_enable(WDTO_15MS);
+	while(1);
 }
 
 void dcode_2()
@@ -128,6 +135,7 @@ void dcode_2()
 		MYSERIAL.write('\n');
 	}
 }
+
 void dcode_3()
 {
 	MYSERIAL.println("D3 - Read/Write EEPROM");
@@ -272,6 +280,13 @@ void dcode_5()
 
 void dcode_6()
 {
+	MYSERIAL.println("D6 - Read/Write external FLASH");
+}
+
+void dcode_7()
+{
+	MYSERIAL.println("D7 - Read/Write Bootloader");
+/*
 	cli();
 	boot_app_magic = 0x55aa55aa;
 	boot_app_flags = BOOT_APP_FLG_ERASE | BOOT_APP_FLG_COPY | BOOT_APP_FLG_FLASH;
@@ -280,17 +295,68 @@ void dcode_6()
 	boot_dst_addr = (uint32_t)0x0003f400;
 	wdt_enable(WDTO_15MS);
 	while(1);
-
-/*	MYSERIAL.println("D6 - Test");
-	MYSERIAL.print("REGx90=0x");
-	MYSERIAL.println(REGx90, HEX);
-	REGx90 = 100;
-	MYSERIAL.print("REGx90=0x");
-	MYSERIAL.println(REGx90, HEX);*/
+*/
 }
 
-void dcode_7()
+void dcode_8()
 {
+	MYSERIAL.println("D8 - Read/Write PINDA");
+	uint8_t cal_status = calibration_status_pinda();
+	float temp_pinda = current_temperature_pinda;
+	float offset_z = temp_compensation_pinda_thermistor_offset(temp_pinda);
+	if ((strchr_pointer[1+1] == '?') || (strchr_pointer[1+1] == 0))
+	{
+		MYSERIAL.print("cal_status=");
+		MYSERIAL.println(cal_status?"1":"0");
+		for (uint8_t i = 0; i < 6; i++)
+		{
+			MYSERIAL.print("temp_pinda=");
+			MYSERIAL.print(35 + i * 5, DEC);
+			MYSERIAL.print("C, temp_shift=");
+			uint16_t offs = 0;
+			if (i > 0) offs = eeprom_read_word(((uint16_t*)EEPROM_PROBE_TEMP_SHIFT) + (i - 1));
+			MYSERIAL.print(((float)offs) / axis_steps_per_unit[Z_AXIS], 3);
+			MYSERIAL.println("mm");
+		}
+	}
+	else if (strchr_pointer[1+1] == '!')
+	{
+		cal_status = 1;
+		eeprom_write_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, cal_status);
+		eeprom_write_word(((uint16_t*)EEPROM_PROBE_TEMP_SHIFT) + 0, 50); //40C - 
+		eeprom_write_word(((uint16_t*)EEPROM_PROBE_TEMP_SHIFT) + 1, 100); //45C - 
+		eeprom_write_word(((uint16_t*)EEPROM_PROBE_TEMP_SHIFT) + 2, 150); //50C - 
+		eeprom_write_word(((uint16_t*)EEPROM_PROBE_TEMP_SHIFT) + 3, 200); //55C - 
+		eeprom_write_word(((uint16_t*)EEPROM_PROBE_TEMP_SHIFT) + 4, 250); //60C - 
+	}
+	else
+	{
+		if (code_seen('P')) // Pinda temperature [C]
+			temp_pinda = code_value();
+		offset_z = temp_compensation_pinda_thermistor_offset(temp_pinda);
+		if (code_seen('Z')) // Z Offset [mm]
+		{
+			offset_z = code_value();
+		}
+	}
+	MYSERIAL.print("temp_pinda=");
+	MYSERIAL.println(temp_pinda);
+	MYSERIAL.print("offset_z=");
+	MYSERIAL.println(offset_z, 3);
+}
+
+void dcode_10()
+{//Tell the printer that XYZ calibration went OK
+	MYSERIAL.println("D10 - XYZ calibration = OK");
+	calibration_status_store(CALIBRATION_STATUS_LIVE_ADJUST); 
+}
+
+void dcode_12()
+{//Reset Filament error, Power loss and crash counter ( Do it before every print and you can get stats for the print )
+	MYSERIAL.println("D12 - Reset failstat counters");
+    eeprom_update_byte((uint8_t*)EEPROM_CRASH_COUNT, 0x00);
+    eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, 0x00);
+    eeprom_update_byte((uint8_t*)EEPROM_POWER_COUNT, 0x00);
 }
 
 void dcode_2130()
@@ -350,5 +416,8 @@ void dcode_9125()
 		MYSERIAL.print("pat9125_y=");
 		MYSERIAL.print(pat9125_y, DEC);
 	}
+	if (code_seen('L'))
+	{
+		fsensor_log = (int)code_value();
+	}
 }
-

+ 5 - 2
Firmware/Dcodes.h

@@ -7,9 +7,12 @@ extern void dcode_2(); //D2 - Read/Write RAM
 extern void dcode_3(); //D3 - Read/Write EEPROM
 extern void dcode_4(); //D4 - Read/Write PIN
 extern void dcode_5(); //D5 - Read/Write FLASH
+extern void dcode_6(); //D6 - Read/Write external FLASH
+extern void dcode_7(); //D7 - Read/Write Bootloader
+extern void dcode_8(); //D8 - Read/Write PINDA
 
-extern void dcode_6(); //D6
-extern void dcode_7(); //D7
+extern void dcode_10(); //D10 - XYZ calibration = OK
+extern void dcode_12(); //D12 - Reset failstat counters
 
 extern void dcode_2130(); //D2130 - TMC2130
 extern void dcode_9125(); //D9125 - PAT9125

+ 23 - 1
Firmware/Marlin.h

@@ -290,6 +290,10 @@ extern float retract_length, retract_length_swap, retract_feedrate, retract_zlif
 extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate;
 #endif
 
+#ifdef HOST_KEEPALIVE_FEATURE
+extern uint8_t host_keepalive_interval;
+#endif
+
 extern unsigned long starttime;
 extern unsigned long stoptime;
 extern int bowden_length[4];
@@ -362,7 +366,7 @@ void temp_compensation_apply();
 void temp_compensation_start();
 
 #ifdef PINDA_THERMISTOR
-float temp_compensation_pinda_thermistor_offset();
+float temp_compensation_pinda_thermistor_offset(float temperature_pinda);
 #endif //PINDA_THERMISTOR
 
 void wait_for_heater(long codenum);
@@ -381,6 +385,24 @@ extern void print_world_coordinates();
 extern void print_physical_coordinates();
 extern void print_mesh_bed_leveling_table();
 
+#ifdef HOST_KEEPALIVE_FEATURE
+
+// States for managing Marlin and host communication
+// Marlin sends messages if blocked or busy
+enum MarlinBusyState {
+	NOT_BUSY,           // Not in a handler
+	IN_HANDLER,         // Processing a GCode
+	IN_PROCESS,         // Known to be blocking command input (as in G29)
+	PAUSED_FOR_USER,    // Blocking pending any input
+	PAUSED_FOR_INPUT    // Blocking pending text input (concept)
+};
+
+#define KEEPALIVE_STATE(n) do { busy_state = n;} while (0)
+extern void host_keepalive();
+extern MarlinBusyState busy_state;
+
+#endif //HOST_KEEPALIVE_FEATURE
+
 // G-codes
 bool gcode_M45(bool onlyZ);
 void gcode_M701();

+ 108 - 21
Firmware/Marlin_main.cpp

@@ -176,6 +176,7 @@
 //        Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling
 //        IF AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F
 // M112 - Emergency stop
+// M113 - Get or set the timeout interval for Host Keepalive "busy" messages
 // M114 - Output current position to serial port
 // M115 - Capabilities string
 // M117 - display message
@@ -396,6 +397,16 @@ int fanSpeed=0;
 
 bool cancel_heatup = false ;
 
+#ifdef HOST_KEEPALIVE_FEATURE
+  
+  MarlinBusyState busy_state = NOT_BUSY;
+  static long prev_busy_signal_ms = -1;
+  uint8_t host_keepalive_interval = HOST_KEEPALIVE_INTERVAL;
+#else
+  #define host_keepalive();
+  #define KEEPALIVE_STATE(n);
+#endif
+
 #ifdef FILAMENT_SENSOR
   //Variables for Filament Sensor input 
   float filament_width_nominal=DEFAULT_NOMINAL_FILAMENT_DIA;  //Set nominal filament width, can be changed with M404 
@@ -832,7 +843,7 @@ void setup()
 	// Reset the machine correction matrix.
 	// It does not make sense to load the correction matrix until the machine is homed.
 	world2machine_reset();
-    
+	KEEPALIVE_STATE(PAUSED_FOR_USER);
 	if (!READ(BTN_ENC))
 	{
 		_delay_ms(1000);
@@ -1021,7 +1032,7 @@ void setup()
 		  lcd_show_fullscreen_message_and_wait_P(MSG_FOLLOW_CALIBRATION_FLOW);
 	  }
   }
-
+  KEEPALIVE_STATE(IN_PROCESS);
 #endif //DEBUG_DISABLE_STARTMSGS
   lcd_update_enable(true);
   lcd_implementation_clear();
@@ -1029,6 +1040,7 @@ void setup()
   // Store the currently running firmware into an eeprom,
   // so the next time the firmware gets updated, it will know from which version it has been updated.
   update_current_firmware_version_to_eeprom();
+  
   if (eeprom_read_byte((uint8_t*)EEPROM_UVLO) == 1) { //previous print was terminated by UVLO
 /*
 	  if (lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_RECOVER_PRINT, false))	recover_print();
@@ -1068,7 +1080,7 @@ void setup()
       } 
 	   
   }
-  
+  KEEPALIVE_STATE(NOT_BUSY);
 }
 
 void trace();
@@ -1145,10 +1157,43 @@ int serial_read_stream() {
     }
 }
 
+#ifdef HOST_KEEPALIVE_FEATURE
+/**
+* Output a "busy" message at regular intervals
+* while the machine is not accepting commands.
+*/
+void host_keepalive() {
+  if (farm_mode) return;
+  long ms = millis();
+  if (host_keepalive_interval && busy_state != NOT_BUSY) {
+    if ((ms - prev_busy_signal_ms) < (long)(1000L * host_keepalive_interval)) return;
+     switch (busy_state) {
+      case IN_HANDLER:
+      case IN_PROCESS:
+        SERIAL_ECHO_START;
+        SERIAL_ECHOLNPGM("busy: processing");
+        break;
+      case PAUSED_FOR_USER:
+        SERIAL_ECHO_START;
+        SERIAL_ECHOLNPGM("busy: paused for user");
+        break;
+      case PAUSED_FOR_INPUT:
+        SERIAL_ECHO_START;
+        SERIAL_ECHOLNPGM("busy: paused for input");
+        break;
+      default:
+	break;
+    }
+  }
+  prev_busy_signal_ms = ms;
+}
+#endif
+
 // The loop() function is called in an endless loop by the Arduino framework from the default main() routine.
 // Before loop(), the setup() function is called by the main() routine.
 void loop()
 {
+	KEEPALIVE_STATE(NOT_BUSY);
 	bool stack_integrity = true;
 
 	if (usb_printing_counter > 0 && millis()-_usb_timer > 1000)
@@ -1218,6 +1263,7 @@ void loop()
 		    planner_add_sd_length(sdlen.value);
 		    sei();
 	  }
+	host_keepalive();
   }
 }
   //check heater every n milliseconds
@@ -1237,6 +1283,7 @@ void loop()
 		enquecommand_P((PSTR("D999")));
 	}
 #endif //TMC2130
+
 }
 
 #define DEFINE_PGM_READ_ANY(type, reader)       \
@@ -1787,9 +1834,11 @@ bool gcode_M45(bool onlyZ) {
 		//	lcd_wait_for_cool_down();
 		//}
 		if(!onlyZ){
+			KEEPALIVE_STATE(PAUSED_FOR_USER);
 			bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_STEEL_SHEET_CHECK, false, false);
 			if(result) lcd_show_fullscreen_message_and_wait_P(MSG_REMOVE_STEEL_SHEET);
 		    lcd_show_fullscreen_message_and_wait_P(MSG_PAPER);
+			KEEPALIVE_STATE(IN_HANDLER);
 			lcd_display_message_fullscreen_P(MSG_FIND_BED_OFFSET_AND_SKEW_LINE1);
 			lcd_implementation_print_at(0, 2, 1);
 			lcd_printPGM(MSG_FIND_BED_OFFSET_AND_SKEW_LINE2);
@@ -1937,12 +1986,14 @@ void process_commands()
 #endif
 
   // PRUSA GCODES
+  KEEPALIVE_STATE(IN_HANDLER);
 
 #ifdef SNMM
   float tmp_motor[3] = DEFAULT_PWM_MOTOR_CURRENT;
   float tmp_motor_loud[3] = DEFAULT_PWM_MOTOR_CURRENT_LOUD;
   int8_t SilentMode;
 #endif
+  
   if (code_seen("M117")) { //moved to highest priority place to be able to to print strings which includes "G", "PRUSA" and "^"
 	  starpos = (strchr(strchr_pointer + 5, '*'));
 	  if (starpos != NULL)
@@ -2782,6 +2833,7 @@ void process_commands()
 				enquecommand_front_P((PSTR("G28 W0")));
 				break;
 			}
+			KEEPALIVE_STATE(NOT_BUSY); //no need to print busy messages as we print current temperatures periodicaly
 			SERIAL_ECHOLNPGM("PINDA probe calibration start");
 
 			float zero_z;
@@ -3252,17 +3304,18 @@ void process_commands()
 			float offset_z = 0;
 
 #ifdef PINDA_THERMISTOR
-			offset_z = temp_compensation_pinda_thermistor_offset();
+			offset_z = temp_compensation_pinda_thermistor_offset(current_temperature_pinda);
 #endif //PINDA_THERMISTOR
-			#ifdef SUPPORT_VERBOSITY
-			if (verbosity_level >= 1) {
+//			#ifdef SUPPORT_VERBOSITY
+//			if (verbosity_level >= 1)
+			{
 				SERIAL_ECHOPGM("mesh bed leveling: ");
 				MYSERIAL.print(current_position[Z_AXIS], 5);
 				SERIAL_ECHOPGM(" offset: ");
 				MYSERIAL.print(offset_z, 5);
 				SERIAL_ECHOLNPGM("");
 			}
-			#endif // SUPPORT_VERBOSITY
+//			#endif // SUPPORT_VERBOSITY
 			mbl.set_z(ix, iy, current_position[Z_AXIS] - offset_z); //store measured z values z_values[iy][ix] = z - offset_z;
 
 			custom_message_state--;
@@ -3362,6 +3415,7 @@ void process_commands()
 			current_position[E_AXIS] += DEFAULT_RETRACTION;
 			plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 400, active_extruder);
 		}
+		KEEPALIVE_STATE(NOT_BUSY);
 		// Restore custom message state
 		custom_message = custom_message_old;
 		custom_message_type = custom_message_type_old;
@@ -3568,20 +3622,24 @@ void process_commands()
       previous_millis_cmd = millis();
       if (codenum > 0){
         codenum += millis();  // keep track of when we started waiting
+		KEEPALIVE_STATE(PAUSED_FOR_USER);
         while(millis() < codenum && !lcd_clicked()){
           manage_heater();
           manage_inactivity(true);
           lcd_update();
         }
+		KEEPALIVE_STATE(IN_HANDLER);
         lcd_ignore_click(false);
       }else{
           if (!lcd_detected())
             break;
+		KEEPALIVE_STATE(PAUSED_FOR_USER);
         while(!lcd_clicked()){
           manage_heater();
           manage_inactivity(true);
           lcd_update();
         }
+		KEEPALIVE_STATE(IN_HANDLER);
       }
       if (IS_SD_PRINTING)
         LCD_MESSAGERPGM(MSG_RESUMING);
@@ -3797,7 +3855,9 @@ void process_commands()
 
     case 47:
         // M47: Prusa3D: Show end stops dialog on the display.
+		KEEPALIVE_STATE(PAUSED_FOR_USER);
         lcd_diag_show_end_stops();
+		KEEPALIVE_STATE(IN_HANDLER);
         break;
 
 #if 0
@@ -4192,6 +4252,7 @@ Sigma_Exit:
           }}
         #endif
 		SERIAL_PROTOCOLLN("");
+		KEEPALIVE_STATE(NOT_BUSY);
       return;
       break;
     case 109:
@@ -4228,12 +4289,15 @@ Sigma_Exit:
 
       /* See if we are heating up or cooling down */
       target_direction = isHeatingHotend(tmp_extruder); // true if heating, false if cooling
+	  
+	  KEEPALIVE_STATE(NOT_BUSY);
 
       cancel_heatup = false;
 
 	  wait_for_heater(codenum); //loops until target temperature is reached
 
         LCD_MESSAGERPGM(MSG_HEATING_COMPLETE);
+		KEEPALIVE_STATE(IN_HANDLER);
 		heating_status = 2;
 		if (farm_mode) { prusa_statistics(2); };
         
@@ -4261,6 +4325,7 @@ Sigma_Exit:
         cancel_heatup = false;
         target_direction = isHeatingBed(); // true if heating, false if cooling
 
+		KEEPALIVE_STATE(NOT_BUSY);
         while ( (target_direction)&&(!cancel_heatup) ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false)) )
         {
           if(( millis() - codenum) > 1000 ) //Print Temp Reading every 1 second while heating up.
@@ -4283,6 +4348,7 @@ Sigma_Exit:
           lcd_update();
         }
         LCD_MESSAGERPGM(MSG_BED_DONE);
+		KEEPALIVE_STATE(IN_HANDLER);
 		heating_status = 4;
 
         previous_millis_cmd = millis();
@@ -4420,6 +4486,19 @@ Sigma_Exit:
         }
       }
       break;
+#ifdef HOST_KEEPALIVE_FEATURE
+	case 113: // M113 - Get or set Host Keepalive interval
+		if (code_seen('S')) {
+			host_keepalive_interval = (uint8_t)code_value_short();
+			NOMORE(host_keepalive_interval, 60);
+		}
+		else {
+			SERIAL_ECHO_START;
+			SERIAL_ECHOPAIR("M113 S", (unsigned long)host_keepalive_interval);
+			SERIAL_PROTOCOLLN("");
+		}
+		break;
+#endif
     case 115: // M115
       if (code_seen('V')) {
           // Report the Prusa version number.
@@ -5252,6 +5331,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
         int counterBeep = 0;
         lcd_wait_interact();
 		load_filament_time = millis();
+		KEEPALIVE_STATE(PAUSED_FOR_USER);
         while(!lcd_clicked()){
 
 		  cnt++;
@@ -5289,13 +5369,17 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 
         }
 		WRITE(BEEPER, LOW);
+		KEEPALIVE_STATE(IN_HANDLER);
+
 #ifdef SNMM
 		display_loading();
+		KEEPALIVE_STATE(PAUSED_FOR_USER);
 		do {
 			target[E_AXIS] += 0.002;
 			plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 500, active_extruder);
 			delay_keep_alive(2);
-		} while (!lcd_clicked());		
+		} while (!lcd_clicked());
+		KEEPALIVE_STATE(IN_HANDLER);
 		/*if (millis() - load_filament_time > 2) {
 			load_filament_time = millis();
 			target[E_AXIS] += 0.001;
@@ -5330,7 +5414,9 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
         lcd_loading_filament();
         while ((lcd_change_fil_state == 0)||(lcd_change_fil_state != 1)){
           lcd_change_fil_state = 0;
+		  KEEPALIVE_STATE(PAUSED_FOR_USER);
           lcd_alright();
+		  KEEPALIVE_STATE(IN_HANDLER);
           switch(lcd_change_fil_state){
             
              // Filament failed to load so load it again
@@ -5768,24 +5854,25 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 		dcode_4(); break;
 	case 5: // D5 - Read/Write FLASH
 		dcode_5(); break;
-	case 6: // D6 - Test
+	case 6: // D6 - Read/Write external FLASH
 		dcode_6(); break;
-	case 7: // D7 - Test
+	case 7: // D7 - Read/Write Bootloader
 		dcode_7(); break;
+	case 8: // D8 - Read/Write PINDA
+		dcode_8(); break;
+
+	case 10: // D10 - XYZ calibration = OK
+		dcode_10(); break;
+    
+    case 12: //D12 - Reset failstat counters
+		dcode_12(); break;
+
 	case 2130: // D9125 - TMC2130
 		dcode_2130(); break;
 	case 9125: // D9125 - PAT9125
 		dcode_9125(); break;
 
 
-	case 10: // D10 - Tell the printer that XYZ calibration went OK
-        calibration_status_store(CALIBRATION_STATUS_LIVE_ADJUST); 
-        break;
-    
-    case 12: //D12 - Reset Filament error, Power loss and crash counter ( Do it before every print and you can get stats for the print )
-        eeprom_update_byte((uint8_t*)EEPROM_CRASH_COUNT, 0x00);
-        eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, 0x00);
-        eeprom_update_byte((uint8_t*)EEPROM_POWER_COUNT, 0x00);
 	case 999:
 	{
 		MYSERIAL.println("D999 - crash");
@@ -5911,7 +5998,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
     SERIAL_ECHO(CMDBUFFER_CURRENT_STRING);
     SERIAL_ECHOLNPGM("\"(2)");
   }
-
+  KEEPALIVE_STATE(NOT_BUSY);
   ClearToSend();
 }
 
@@ -6880,11 +6967,11 @@ float temp_comp_interpolation(float inp_temperature) {
 }
 
 #ifdef PINDA_THERMISTOR
-float temp_compensation_pinda_thermistor_offset()
+float temp_compensation_pinda_thermistor_offset(float temperature_pinda)
 {
 	if (!temp_cal_active) return 0;
 	if (!calibration_status_pinda()) return 0;
-	return temp_comp_interpolation(current_temperature_pinda) / axis_steps_per_unit[Z_AXIS];
+	return temp_comp_interpolation(temperature_pinda) / axis_steps_per_unit[Z_AXIS];
 }
 #endif //PINDA_THERMISTOR
 

+ 22 - 10
Firmware/fsensor.cpp

@@ -35,6 +35,7 @@ bool fsensor_enabled = true;
 bool fsensor_M600 = false;
 uint8_t fsensor_err_cnt = 0;
 int16_t fsensor_st_cnt = 0;
+uint8_t fsensor_log = 0;
 
 
 void fsensor_enable()
@@ -86,35 +87,46 @@ ISR(PCINT2_vect)
 	if (st_cnt != 0)
 	{
 #ifdef DEBUG_FSENSOR_LOG
-		MYSERIAL.print("cnt=");
-		MYSERIAL.print(st_cnt, DEC);
-		MYSERIAL.print(" dy=");
-		MYSERIAL.print(pat9125_y, DEC);
+		if (fsensor_log)
+		{
+			MYSERIAL.print("cnt=");
+			MYSERIAL.print(st_cnt, DEC);
+			MYSERIAL.print(" dy=");
+			MYSERIAL.print(pat9125_y, DEC);
+		}
 #endif //DEBUG_FSENSOR_LOG
 		if (st_cnt != 0)
 		{
 			if( (pat9125_y == 0) || ((pat9125_y > 0) && (st_cnt < 0)) || ((pat9125_y < 0) && (st_cnt > 0)))
 			{ //invalid movement
-				fsensor_err_cnt++;
+				if (st_cnt > 0) //only positive movements
+					fsensor_err_cnt++;
 #ifdef DEBUG_FSENSOR_LOG
+			if (fsensor_log)
+			{
 				MYSERIAL.print("\tNG ! err=");
 				MYSERIAL.println(fsensor_err_cnt, DEC);
+			}
 #endif //DEBUG_FSENSOR_LOG
 			}
 			else
 			{ //propper movement
-//				if (fsensor_err_cnt > 0)
-//					fsensor_err_cnt--;
-					fsensor_err_cnt = 0;
+				if (fsensor_err_cnt > 0)
+					fsensor_err_cnt--;
+//					fsensor_err_cnt = 0;
 #ifdef DEBUG_FSENSOR_LOG
-				MYSERIAL.print("\tOK    err=");
-				MYSERIAL.println(fsensor_err_cnt, DEC);
+				if (fsensor_log)
+				{
+					MYSERIAL.print("\tOK    err=");
+					MYSERIAL.println(fsensor_err_cnt, DEC);
+				}
 #endif //DEBUG_FSENSOR_LOG
 			}
 		}
 		else
 		{ //no movement
 #ifdef DEBUG_FSENSOR_LOG
+		if (fsensor_log)
 			MYSERIAL.println("\tOK 0");
 #endif //DEBUG_FSENSOR_LOG
 		}

+ 3 - 0
Firmware/temperature.cpp

@@ -783,6 +783,9 @@ void manage_heater()
 		    	 volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]=0.01;
 	}
 #endif
+#ifdef HOST_KEEPALIVE_FEATURE
+  host_keepalive();
+#endif
 }
 
 #define PGM_RD_W(x)   (short)pgm_read_word(&x)

+ 25 - 9
Firmware/ultralcd.cpp

@@ -1989,13 +1989,14 @@ void lcd_menu_statistics()
 		lcd.print(itostr3(_days));
 
 
-
+		KEEPALIVE_STATE(PAUSED_FOR_USER);
 		while (!lcd_clicked())
 		{
 			manage_heater();
 			manage_inactivity(true);
 			delay(100);
 		}
+		KEEPALIVE_STATE(NOT_BUSY);
 
 		lcd_quick_feedback();
 		lcd_return_to_status();
@@ -2072,6 +2073,7 @@ void lcd_service_mode_show_result() {
 		} else lcd_print_at_PGM(11, i + 1, PSTR("N/A"));
 	}
 	delay_keep_alive(500);
+	KEEPALIVE_STATE(PAUSED_FOR_USER);
 	while (!lcd_clicked()) {
 		delay_keep_alive(100);
 	}
@@ -2098,6 +2100,7 @@ void lcd_service_mode_show_result() {
 	while (!lcd_clicked()) {
 		delay_keep_alive(100);
 	}
+	KEEPALIVE_STATE(NOT_BUSY);
 	delay_keep_alive(500);
 	lcd_set_custom_characters_arrows();
 	lcd_return_to_status();
@@ -2574,8 +2577,9 @@ void lcd_show_fullscreen_message_and_wait_P(const char *msg)
     const char *msg_next = lcd_display_message_fullscreen_P(msg);
     bool multi_screen = msg_next != NULL;
 	lcd_set_custom_characters_nextpage();
-    // Until confirmed by a button click.
-    for (;;) {
+	KEEPALIVE_STATE(PAUSED_FOR_USER);
+	// Until confirmed by a button click.
+	for (;;) {
 		if (!multi_screen) {
 			lcd.setCursor(19, 3);
 			// Display the confirm char.
@@ -2588,6 +2592,7 @@ void lcd_show_fullscreen_message_and_wait_P(const char *msg)
                 while (lcd_clicked()) ;
                 delay(10);
                 while (lcd_clicked()) ;
+				KEEPALIVE_STATE(IN_HANDLER);
 				lcd_set_custom_characters();
 				lcd_update_enable(true);
 				lcd_update(2);
@@ -2610,6 +2615,7 @@ void lcd_show_fullscreen_message_and_wait_P(const char *msg)
 
 void lcd_wait_for_click()
 {
+	KEEPALIVE_STATE(PAUSED_FOR_USER);
     for (;;) {
         manage_heater();
         manage_inactivity(true);
@@ -2617,6 +2623,7 @@ void lcd_wait_for_click()
             while (lcd_clicked()) ;
             delay(10);
             while (lcd_clicked()) ;
+			KEEPALIVE_STATE(IN_HANDLER);
             return;
         }
     }
@@ -2716,6 +2723,7 @@ int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow
 	// Wait for user confirmation or a timeout.
 	unsigned long previous_millis_cmd = millis();
 	int8_t        enc_dif = encoderDiff;
+	KEEPALIVE_STATE(PAUSED_FOR_USER);
 	for (;;) {
 		if (allow_timeouting && millis() - previous_millis_cmd > LCD_TIMEOUT_TO_STATUS)
 			return -1;
@@ -2741,6 +2749,7 @@ int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow
 			while (lcd_clicked());
 			delay(10);
 			while (lcd_clicked());
+			KEEPALIVE_STATE(IN_HANDLER);
 			return yes;
 		}
 	}
@@ -3047,7 +3056,7 @@ static void prusa_stat_printinfo()
 	SERIAL_ECHO("]");
 }
 
-
+/*
 void lcd_pick_babystep(){
     int enc_dif = 0;
     int cursor_pos = 1;
@@ -3149,7 +3158,7 @@ void lcd_pick_babystep(){
     lcd_implementation_clear();
     lcd_return_to_status();
 }
-
+*/
 void lcd_move_menu_axis()
 {
 	START_MENU();
@@ -3668,6 +3677,11 @@ static void lcd_settings_menu()
 	END_MENU();
 }
 
+static void lcd_selftest_()
+{
+	lcd_selftest();
+}
+
 static void lcd_calibration_menu()
 {
   START_MENU();
@@ -4017,7 +4031,7 @@ static char snmm_stop_print_menu() { //menu for choosing which filaments will be
 	lcd_print_at_PGM(1,3,MSG_CURRENT);
 	char cursor_pos = 1;
 	int enc_dif = 0;
-
+	KEEPALIVE_STATE(PAUSED_FOR_USER);
 	while (1) {
 		manage_heater();
 		manage_inactivity(true);
@@ -4045,6 +4059,7 @@ static char snmm_stop_print_menu() { //menu for choosing which filaments will be
 			while (lcd_clicked());
 			delay(10);
 			while (lcd_clicked());
+			KEEPALIVE_STATE(IN_HANDLER);
 			return(cursor_pos - 1);
 		}
 	}
@@ -4067,7 +4082,7 @@ char choose_extruder_menu() {
 	for (int i = 0; i < 3; i++) {
 		lcd_print_at_PGM(1, i + 1, MSG_EXTRUDER);
 	}
-
+	KEEPALIVE_STATE(PAUSED_FOR_USER);
 	while (1) {
 
 		for (int i = 0; i < 3; i++) {
@@ -4131,6 +4146,7 @@ char choose_extruder_menu() {
 			while (lcd_clicked());
 			delay(10);
 			while (lcd_clicked());
+			KEEPALIVE_STATE(IN_HANDLER);
 			return(cursor_pos + first - 1);
 			
 		}
@@ -4339,13 +4355,13 @@ static void extr_adj(int extruder) //loading filament for SNMM
 	case 3: lcd_display_message_fullscreen_P(MSG_FILAMENT_LOADING_T3); break;
 	default: lcd_display_message_fullscreen_P(MSG_FILAMENT_LOADING_T0); break;   
 	}
-			
+	KEEPALIVE_STATE(PAUSED_FOR_USER);
 	do{
 		extr_mov(0.001,1000);
 		delay_keep_alive(2);
 	} while (!lcd_clicked());
 	//delay_keep_alive(500);
-
+	KEEPALIVE_STATE(IN_HANDLER);
 	st_synchronize();
 	//correct = lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_FIL_LOADED_CHECK, false);
 	//if (!correct) goto	START;