From 301d64042bcb1a68744da60ccda02d549b37b578 Mon Sep 17 00:00:00 2001
From: Yuri D'Elia <wavexx@thregr.org>
Date: Fri, 27 Dec 2019 19:29:02 +0100
Subject: [PATCH 1/5] Set fsensor_watch_runout earlier to prevent re-entry

Do not set/clear fsensor_watch_runout within fsensor_oq_meassure_start
which is used outside of fsensor_update where it could have a different
starting value.

Set it within fsensor_stop_and_save_print to immediately prevent
re-entry.
---
 Firmware/fsensor.cpp | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/Firmware/fsensor.cpp b/Firmware/fsensor.cpp
index 1c28d025..b9b1f068 100755
--- a/Firmware/fsensor.cpp
+++ b/Firmware/fsensor.cpp
@@ -124,14 +124,16 @@ unsigned long nIRsensorLastTime;
 void fsensor_stop_and_save_print(void)
 {
     printf_P(PSTR("fsensor_stop_and_save_print\n"));
-    stop_and_save_print_to_ram(0, 0); //XYZE - no change
+    stop_and_save_print_to_ram(0, 0);
+    fsensor_watch_runout = false;
 }
 
 void fsensor_restore_print_and_continue(void)
 {
     printf_P(PSTR("fsensor_restore_print_and_continue\n"));
+    fsensor_watch_runout = true;
 	fsensor_err_cnt = 0;
-    restore_print_from_ram_and_continue(0); //XYZ = orig, E - no change
+    restore_print_from_ram_and_continue(0);
 }
 
 // fsensor_checkpoint_print cuts the current print job at the current position,
@@ -379,7 +381,6 @@ void fsensor_oq_meassure_start(uint8_t skip)
 	fsensor_oq_sh_sum = 0;
 	pat9125_update();
 	pat9125_y = 0;
-	fsensor_watch_runout = false;
 	fsensor_oq_meassure = true;
 }
 
@@ -391,7 +392,6 @@ void fsensor_oq_meassure_stop(void)
 	printf_P(_N(" st_sum=%u yd_sum=%u er_sum=%u er_max=%hhu\n"), fsensor_oq_st_sum, fsensor_oq_yd_sum, fsensor_oq_er_sum, fsensor_oq_er_max);
 	printf_P(_N(" yd_min=%u yd_max=%u yd_avg=%u sh_avg=%u\n"), fsensor_oq_yd_min, fsensor_oq_yd_max, (uint16_t)((uint32_t)fsensor_oq_yd_sum * fsensor_chunk_len / fsensor_oq_st_sum), (uint16_t)(fsensor_oq_sh_sum / fsensor_oq_samples));
 	fsensor_oq_meassure = false;
-	fsensor_watch_runout = true;
 	fsensor_err_cnt = 0;
 }
 
@@ -578,12 +578,13 @@ void fsensor_update(void)
 #ifdef PAT9125
 		if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
 		{
+			fsensor_stop_and_save_print();
+
 			bool autoload_enabled_tmp = fsensor_autoload_enabled;
 			fsensor_autoload_enabled = false;
 			bool oq_meassure_enabled_tmp = fsensor_oq_meassure_enabled;
 			fsensor_oq_meassure_enabled = true;
 
-			fsensor_stop_and_save_print();
 
 			fsensor_err_cnt = 0;
 			fsensor_oq_meassure_start(0);

From fe4c00fb8a8ff32fcafecb2a730e432a7f065607 Mon Sep 17 00:00:00 2001
From: Yuri D'Elia <wavexx@thregr.org>
Date: Fri, 27 Dec 2019 19:35:08 +0100
Subject: [PATCH 2/5] Lift the extruder when checking for the filament

This avoids leaving marks on the print
---
 Firmware/fsensor.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Firmware/fsensor.cpp b/Firmware/fsensor.cpp
index b9b1f068..02f7d572 100755
--- a/Firmware/fsensor.cpp
+++ b/Firmware/fsensor.cpp
@@ -585,6 +585,11 @@ void fsensor_update(void)
 			bool oq_meassure_enabled_tmp = fsensor_oq_meassure_enabled;
 			fsensor_oq_meassure_enabled = true;
 
+            // move the nozzle away while checking the filament
+            current_position[Z_AXIS] += 0.8;
+            if(current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
+            plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder);
+            st_synchronize();
 
 			fsensor_err_cnt = 0;
 			fsensor_oq_meassure_start(0);

From 97170ed68dbfd5660f28f2f286d94bafee74d939 Mon Sep 17 00:00:00 2001
From: Yuri D'Elia <wavexx@thregr.org>
Date: Fri, 27 Dec 2019 19:37:20 +0100
Subject: [PATCH 3/5] Do not call process_commands() within fsensor_update()

Plan moves directly to reduce the required stack size.
---
 Firmware/fsensor.cpp | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/Firmware/fsensor.cpp b/Firmware/fsensor.cpp
index 02f7d572..f9875fa6 100755
--- a/Firmware/fsensor.cpp
+++ b/Firmware/fsensor.cpp
@@ -591,20 +591,15 @@ void fsensor_update(void)
             plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder);
             st_synchronize();
 
+            // check the filament in isolation
 			fsensor_err_cnt = 0;
 			fsensor_oq_meassure_start(0);
-
-			enquecommand_front_P((PSTR("G1 E-3 F200")));
-			process_commands();
-			KEEPALIVE_STATE(IN_HANDLER);
-			cmdqueue_pop_front();
-			st_synchronize();
-
-			enquecommand_front_P((PSTR("G1 E3 F200")));
-			process_commands();
-			KEEPALIVE_STATE(IN_HANDLER);
-			cmdqueue_pop_front();
-			st_synchronize();
+            float e_tmp = current_position[E_AXIS];
+            current_position[E_AXIS] -= 3;
+            plan_buffer_line_curposXYZE(200/60, active_extruder);
+            current_position[E_AXIS] = e_tmp;
+            plan_buffer_line_curposXYZE(200/60, active_extruder);
+            st_synchronize();
 
 			uint8_t err_cnt = fsensor_err_cnt;
 			fsensor_oq_meassure_stop();

From bd80ee88a0f0c8d5a354f7c81a8551d9ee297f5d Mon Sep 17 00:00:00 2001
From: Yuri D'Elia <wavexx@thregr.org>
Date: Sat, 28 Dec 2019 18:50:42 +0100
Subject: [PATCH 4/5] Set the IN_HANDLER busy state while checking the filament

---
 Firmware/fsensor.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Firmware/fsensor.cpp b/Firmware/fsensor.cpp
index f9875fa6..0113317e 100755
--- a/Firmware/fsensor.cpp
+++ b/Firmware/fsensor.cpp
@@ -579,6 +579,7 @@ void fsensor_update(void)
 		if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
 		{
 			fsensor_stop_and_save_print();
+            KEEPALIVE_STATE(IN_HANDLER);
 
 			bool autoload_enabled_tmp = fsensor_autoload_enabled;
 			fsensor_autoload_enabled = false;

From 186f8816000f0c8632fe3c8cfe0aac8c0b13d4b1 Mon Sep 17 00:00:00 2001
From: Yuri D'Elia <wavexx@thregr.org>
Date: Sun, 29 Dec 2019 22:08:44 +0100
Subject: [PATCH 5/5] Avoid calling fsensor_update() one level earlier

Move the common checks between filament sensors out of fsensor_update().

Disable the runout check if a saved state is already present (this check
was missing in the PAT9125 variant) as this is currently not supported.

Note that the CHECK_FSENSOR looks completely redundant besides
e_active().
---
 Firmware/Marlin_main.cpp | 3 ++-
 Firmware/fsensor.cpp     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp
index 4970091e..fc395900 100755
--- a/Firmware/Marlin_main.cpp
+++ b/Firmware/Marlin_main.cpp
@@ -8606,7 +8606,8 @@ if(0)
 #ifdef PAT9125
 				fsensor_autoload_check_stop();
 #endif //PAT9125
-				fsensor_update();
+                if (fsensor_enabled && !saved_printing)
+                    fsensor_update();
 			}
 		}
 	}
diff --git a/Firmware/fsensor.cpp b/Firmware/fsensor.cpp
index 0113317e..a7dbce97 100755
--- a/Firmware/fsensor.cpp
+++ b/Firmware/fsensor.cpp
@@ -576,7 +576,7 @@ void fsensor_enque_M600(){
 void fsensor_update(void)
 {
 #ifdef PAT9125
-		if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
+		if (fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
 		{
 			fsensor_stop_and_save_print();
             KEEPALIVE_STATE(IN_HANDLER);
@@ -621,7 +621,7 @@ void fsensor_update(void)
 				fsensor_enque_M600();
 		}
 #else //PAT9125
-		if (CHECK_FSENSOR && fsensor_enabled && ir_sensor_detected)
+		if (CHECK_FSENSOR && ir_sensor_detected)
         {
                if(digitalRead(IR_SENSOR_PIN))
                {                                  // IR_SENSOR_PIN ~ H