Browse Source

Checkpoint: jam detection

Alex Voinea 2 years ago
parent
commit
340bc87110

+ 0 - 7
Firmware/Dcodes.cpp

@@ -912,13 +912,6 @@ void dcode_9125()
 		pat9125_y = (int)code_value();
 		LOG("pat9125_y=%d\n", pat9125_y);
 	}
-#ifdef DEBUG_FSENSOR_LOG
-	if (code_seen('L'))
-	{
-		fsensor_log = (int)code_value();
-		LOG("fsensor_log=%d\n", fsensor_log);
-	}
-#endif //DEBUG_FSENSOR_LOG
 }
 #endif //PAT9125
 

+ 103 - 16
Firmware/Filament_sensor.h

@@ -144,29 +144,38 @@ protected:
     
     void triggerFilamentInserted() {
         if (autoLoadEnabled && (eFilamentAction == FilamentAction::None) && !(moves_planned() || IS_SD_PRINTING || usb_timer.running() || (lcd_commands_type == LcdCommands::Layer1Cal) || eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE))) {
-            eFilamentAction = FilamentAction::AutoLoad;
-            if(target_temperature[0] >= EXTRUDE_MINTEMP){
-                bFilamentPreheatState = true;
-                menu_submenu(mFilamentItemForce);
-            } else {
-                menu_submenu(lcd_generic_preheat_menu);
-                lcd_timeoutToStatus.start();
-            }
+            filAutoLoad();
         }
     }
     
     void triggerFilamentRemoved() {
         if (runoutEnabled && (eFilamentAction == FilamentAction::None) && !saved_printing && (moves_planned() || IS_SD_PRINTING || usb_timer.running() || (lcd_commands_type == LcdCommands::Layer1Cal) || eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE))) {
-            runoutEnabled = false;
-            autoLoadEnabled = false;
-            stop_and_save_print_to_ram(0, 0);
-            restore_print_from_ram_and_continue(0);
-            eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1);
-            eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
-            enquecommand_front_P((PSTR("M600")));
+            filRunout();
         }
     }
     
+    void filAutoLoad() {
+        eFilamentAction = FilamentAction::AutoLoad;
+        if(target_temperature[0] >= EXTRUDE_MINTEMP){
+            bFilamentPreheatState = true;
+            menu_submenu(mFilamentItemForce);
+        }
+        else {
+            menu_submenu(lcd_generic_preheat_menu);
+            lcd_timeoutToStatus.start();
+        }
+    }
+    
+    void filRunout() {
+        runoutEnabled = false;
+        autoLoadEnabled = false;
+        stop_and_save_print_to_ram(0, 0);
+        restore_print_from_ram_and_continue(0);
+        eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1);
+        eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
+        enquecommand_front_P((PSTR("M600")));
+    }
+    
     void triggerError() {
         state = State::error;
         
@@ -450,6 +459,8 @@ public:
         
         settings_init(); //also sets the state to State::initializing
         
+        calcChunkSteps(cs.axis_steps_per_unit[E_AXIS]); //for jam detection
+        
         if (!pat9125_init()) {
             deinit();
             triggerError();
@@ -476,6 +487,7 @@ public:
                     break; // still not stable. Stay in the initialization state.
                 }
                 oldFilamentPresent = getFilamentPresent(); //initialize the current filament state so that we don't create a switching event right after the sensor is ready.
+                oldPos = pat9125_y;
                 state = State::ready;
                 break;
             case State::ready: {
@@ -499,9 +511,28 @@ public:
         return filterFilPresent;
     }
     
+    void setJamDetectionEnabled(bool state, bool updateEEPROM = false) {
+        jamDetection = state;
+        oldPos = pat9125_y;
+        resetStepCount();
+        jamErrCnt = 0;
+        if (updateEEPROM) {
+            eeprom_update_byte((uint8_t *)EEPROM_FSENSOR_JAM_DETECTION, state);
+        }
+    }
+    
+    bool getJamDetectionEnabled() {
+        return jamDetection;
+    }
+    
+    void stStep(bool rev) { //from stepper isr
+        stepCount += rev ? -1 : 1;
+    }
+    
     void settings_init() {
+        puts_P(PSTR("settings_init"));
         Filament_sensor::settings_init();
-        jamDetection = eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_JAM_DETECTION);
+        setJamDetectionEnabled(eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_JAM_DETECTION));
     }
 private:
     static constexpr uint16_t pollingPeriod = 10; //[ms]
@@ -509,9 +540,65 @@ private:
     ShortTimer pollingTimer;
     uint8_t filter;
     uint8_t filterFilPresent;
+    
     bool jamDetection;
+    int16_t oldPos;
+    volatile int16_t stepCount;
+    int16_t chunkSteps;
+    uint8_t jamErrCnt;
+    
+    void calcChunkSteps(float u) {
+        chunkSteps = (int16_t)(1.25 * u); //[mm]
+    }
+    
+    int16_t getStepCount() {
+        int16_t st_cnt;
+        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+            st_cnt = stepCount;
+        }
+        return st_cnt;
+    }
+    
+    void resetStepCount() {
+        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+            stepCount = 0;
+        }
+    }
+    
+    void filJam() {
+        runoutEnabled = false;
+        autoLoadEnabled = false;
+        jamDetection = false;
+        stop_and_save_print_to_ram(0, 0);
+        restore_print_from_ram_and_continue(0);
+        eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1);
+        eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
+        enquecommand_front_P((PSTR("M600")));
+    }
     
     bool updatePAT9125() {
+        if (jamDetection) {
+            int16_t _stepCount = getStepCount();
+            if (abs(_stepCount) >= chunkSteps) { //end of chunk. Check distance
+                resetStepCount();
+                if (!pat9125_update()) { //get up to date data. reinit on error.
+                    init(); //try to reinit.
+                }
+                bool fsDir = (pat9125_y - oldPos) > 0;
+                bool stDir = _stepCount > 0;
+                if (fsDir != stDir) {
+                    jamErrCnt++;
+                }
+                else if (jamErrCnt) {
+                    jamErrCnt--;
+                }
+                oldPos = pat9125_y;
+            }
+            if (jamErrCnt > 10) {
+                jamErrCnt = 0;
+                filJam();
+            }
+        }
         
         if (!pollingTimer.running() || pollingTimer.expired(pollingPeriod)) {
             pollingTimer.start();

+ 18 - 10
Firmware/Marlin_main.cpp

@@ -95,13 +95,7 @@
 
 #include "spi.h"
 
-#ifdef FILAMENT_SENSOR
 #include "Filament_sensor.h"
-#include "fsensor.h"
-#ifdef IR_SENSOR
-#include "pat9125.h" // for pat9125_probe
-#endif
-#endif //FILAMENT_SENSOR
 
 #ifdef TMC2130
 #include "tmc2130.h"
@@ -768,6 +762,9 @@ static void factory_reset(char level)
 		fsensor.setEnabled(true);
 		fsensor.setAutoLoadEnabled(true, true);
 		fsensor.setRunoutEnabled(true, true);
+#if (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+		fsensor.setJamDetectionEnabled(true, true);
+#endif //(FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
 #endif //FILAMENT_SENSOR
 		break;
 
@@ -3490,7 +3487,7 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
     st_synchronize();
     float lastpos[4];
 
-    prusa_statistics(22);
+        prusa_statistics(22);
 
     //First backup current position and settings
     int feedmultiplyBckp = feedmultiply;
@@ -3530,6 +3527,14 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
     //finish moves
     st_synchronize();
 
+#ifdef FILAMENT_SENSOR
+    fsensor.setRunoutEnabled(false); //suppress filament runouts while loading filament.
+    fsensor.setAutoLoadEnabled(false); //suppress filament autoloads while loading filament.
+#if (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+    fsensor.setJamDetectionEnabled(false); //suppress filament jam detection while loading filament.
+#endif //(FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+#endif
+
     if (!mmu_enabled)
     {
         KEEPALIVE_STATE(PAUSED_FOR_USER);
@@ -3616,6 +3621,9 @@ void gcode_M701()
 #ifdef FILAMENT_SENSOR
 	fsensor.setRunoutEnabled(false); //suppress filament runouts while loading filament.
 	fsensor.setAutoLoadEnabled(false); //suppress filament autoloads while loading filament.
+#if (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+	fsensor.setJamDetectionEnabled(false); //suppress filament jam detection while loading filament.
+#endif //(FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
 #endif
 
 	prusa_statistics(22);
@@ -6512,7 +6520,7 @@ Sigma_Exit:
             }
             cs.axis_steps_per_unit[i] = value;
 #if defined(FILAMENT_SENSOR) && defined(PAT9125)
-            fsensor_set_axis_steps_per_unit(value);
+            fsensor.init();
 #endif
           }
           else {
@@ -8448,8 +8456,8 @@ Sigma_Exit:
 						position[i] /= fac;
 					}
 #if defined(FILAMENT_SENSOR) && defined(PAT9125)
-                    if (i == E_AXIS)
-                        fsensor_set_axis_steps_per_unit(cs.axis_steps_per_unit[i]);
+					if (i == E_AXIS)
+						fsensor.init();
 #endif
 				}
 			}

+ 4 - 1
Firmware/eeprom.h

@@ -333,6 +333,8 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
 | ^					| ^			| ^										| 03h 3			| ^						| bad_isr											| ^				| ^
 | ^					| ^			| ^										| 04h 4			| ^						| bad_pullup_temp_isr								| ^				| ^
 | ^					| ^			| ^										| 05h 5			| ^						| bad_pullup_step_isr								| ^				| ^
+| 0x0D03 3321		| uint8_t	| EEPROM_FW_CRASH_FLAG					| 01h 1			| ff/00					| Last FW crash reason (dump_crash_reason)			| D21/D22		| D3 Ax0d03 C1
+| 0x0D03 3320		| uint8_t	| EEPROM_FSENSOR_JAM_DETECTION			| 01h 1			| ff/01					| fsensor pat9125 jam detection feature				| LCD menu		| D3 Ax0d02 C1
 
 | Address begin		| Bit/Type 	| Name 									| Valid values	| Default/FactoryReset	| Description 										| Gcode/Function| Debug code
 | :--:				| :--: 		| :--: 									| :--:			| :--:					| :--:												| :--:			| :--:
@@ -556,8 +558,9 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
 #define EEPROM_TEMP_MODEL_W (EEPROM_TEMP_MODEL_Ta_corr-4) // float
 #define EEPROM_TEMP_MODEL_E (EEPROM_TEMP_MODEL_W-4) // float
 
+#define EEPROM_FSENSOR_JAM_DETECTION (EEPROM_TEMP_MODEL_E-1) // uint8_t
 //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items.
-#define EEPROM_LAST_ITEM EEPROM_TEMP_MODEL_E
+#define EEPROM_LAST_ITEM EEPROM_FSENSOR_JAM_DETECTION
 // !!!!!
 // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
 // !!!!!

+ 0 - 692
Firmware/fsensor.cpp

@@ -1,692 +0,0 @@
-//! @file
-
-#include "Marlin.h"
-
-#include "fsensor.h"
-#include <avr/pgmspace.h>
-#include "pat9125.h"
-#include "stepper.h"
-#include "cmdqueue.h"
-#include "ultralcd.h"
-#include "mmu.h"
-#include "cardreader.h"
-
-#include "adc.h"
-#include "temperature.h"
-#include "config.h"
-
-#include "Filament_sensor.h" //temporary
-
-//! @name Basic parameters
-//! @{
-#define FSENSOR_CHUNK_LEN      1.25 //!< filament sensor chunk length (mm)
-#define FSENSOR_ERR_MAX           4 //!< filament sensor maximum error/chunk count for runout detection
-
-#define FSENSOR_SOFTERR_CMAX      3 //!< number of contiguous soft failures before a triggering a runout
-#define FSENSOR_SOFTERR_DELTA 30000 //!< maximum interval (ms) to consider soft failures contiguous
-//! @}
-
-//! @name Optical quality measurement parameters
-//! @{
-#define FSENSOR_OQ_MAX_ES      2    //!< maximum sum of error blocks during filament recheck
-#define FSENSOR_OQ_MIN_YD      2    //!< minimum yd sum during filament check (counts per inch)
-#define FSENSOR_OQ_MIN_BR      80   //!< minimum brightness value
-#define FSENSOR_OQ_MAX_SH      10   //!< maximum shutter value
-//! @}
-
-const char ERRMSG_PAT9125_NOT_RESP[] PROGMEM = "PAT9125 not responding (%d)!\n";
-
-//! enabled = initialized and sampled every chunk event
-bool fsensor_enabled = true;
-//! runout watching is done in fsensor_update (called from main loop)
-bool fsensor_watch_runout = true;
-//! not responding - is set if any communication error occurred during initialization or readout
-bool fsensor_not_responding = false;
-
-#ifdef PAT9125
-//! optical checking "chunk lenght" (already in steps)
-int16_t fsensor_chunk_len = 0;
-//! number of errors, updated in ISR
-uint8_t fsensor_err_cnt = 0;
-//! variable for accumulating step count (updated callbacks from stepper and ISR)
-int16_t fsensor_st_cnt = 0;
-//! count of total sensor "soft" failures (filament status checks)
-uint8_t fsensor_softfail = 0;
-//! timestamp of last soft failure
-unsigned long fsensor_softfail_last = 0;
-//! count of soft failures within the configured time
-uint8_t fsensor_softfail_ccnt = 0;
-#endif
-
-#ifdef DEBUG_FSENSOR_LOG
-//! log flag: 0=log disabled, 1=log enabled
-uint8_t fsensor_log = 1;
-#endif //DEBUG_FSENSOR_LOG
-
-
-//! @name filament autoload variables
-//! @{
-
-//! autoload feature enabled
-bool fsensor_autoload_enabled = true;
-
-
-//! @name filament optical quality measurement variables
-//! @{
-
-//! Measurement enable/disable flag
-bool fsensor_oq_meassure = false;
-//! skip-chunk counter, for accurate measurement is necessary to skip first chunk...
-uint8_t  fsensor_oq_skipchunk;
-//! number of samples from start of measurement
-uint8_t fsensor_oq_samples;
-//! sum of steps in positive direction movements
-uint16_t fsensor_oq_st_sum;
-//! sum of deltas in positive direction movements
-uint16_t fsensor_oq_yd_sum;
-//! sum of errors during measurement
-uint16_t fsensor_oq_er_sum;
-//! max error counter value during measurement
-uint8_t  fsensor_oq_er_max;
-//! minimum delta value
-int16_t fsensor_oq_yd_min;
-//! maximum delta value
-int16_t fsensor_oq_yd_max;
-//! sum of shutter value
-uint16_t fsensor_oq_sh_sum;
-//! @}
-
-#ifdef IR_SENSOR_ANALOG
-ClFsensorActionNA oFsensorActionNA;
-bool bIRsensorStateFlag=false;
-ShortTimer tIRsensorCheckTimer;
-#endif //IR_SENSOR_ANALOG
-
-#ifdef PAT9125
-// Reset all internal counters to zero, including stepper callbacks
-void fsensor_reset_err_cnt()
-{
-    fsensor_err_cnt = 0;
-    pat9125_y = 0;
-    st_reset_fsensor();
-}
-
-void fsensor_set_axis_steps_per_unit(float u)
-{
-    fsensor_chunk_len = (int16_t)(FSENSOR_CHUNK_LEN * u);
-}
-#endif
-
-
-// fsensor_checkpoint_print cuts the current print job at the current position,
-// allowing new instructions to be inserted in the middle
-void fsensor_checkpoint_print(void)
-{
-    puts_P(PSTR("fsensor_checkpoint_print"));
-    stop_and_save_print_to_ram(0, 0);
-    restore_print_from_ram_and_continue(0);
-}
-
-#ifdef IR_SENSOR_ANALOG
-const char* FsensorIRVersionText()
-{
-	switch(oFsensorPCB)
-	{
-		case ClFsensorPCB::_Old:
-			return _T(MSG_IR_03_OR_OLDER);
-		case ClFsensorPCB::_Rev04:
-			return _T(MSG_IR_04_OR_NEWER);
-		default:
-			return _T(MSG_IR_UNKNOWN);
-	}
-}
-#endif //IR_SENSOR_ANALOG
-
-void fsensor_init(void)
-{
-#ifdef PAT9125
-	uint8_t pat9125 = pat9125_init();
-	printf_P(PSTR("PAT9125_init:%u\n"), pat9125);
-#endif //PAT9125
-	uint8_t fsensor_enabled = eeprom_read_byte((uint8_t*)EEPROM_FSENSOR);
-	fsensor_autoload_enabled=eeprom_read_byte((uint8_t*)EEPROM_FSENS_AUTOLOAD_ENABLED);
-	fsensor_not_responding = false;
-#ifdef PAT9125
-	uint8_t oq_meassure_enabled = eeprom_read_byte((uint8_t*)EEPROM_FSENS_OQ_MEASS_ENABLED);
-	fsensor_oq_meassure_enabled = (oq_meassure_enabled == 1)?true:false;
-	fsensor_set_axis_steps_per_unit(cs.axis_steps_per_unit[E_AXIS]);
-	
-	if (!pat9125){
-		fsensor_enabled = 0; //disable sensor
-		fsensor_not_responding = true;
-	}
-#endif //PAT9125
-#ifdef IR_SENSOR_ANALOG
-	bIRsensorStateFlag=false;
-	oFsensorPCB = (ClFsensorPCB)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_PCB);
-	oFsensorActionNA = (ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA);
-
-	// If the fsensor is not responding even at the start of the printer,
-	// set this flag accordingly to show N/A in Settings->Filament sensor.
-	// This is even valid for both fsensor board revisions (0.3 or older and 0.4).
-	// Must be done after reading what type of fsensor board we have
-	fsensor_not_responding = ! fsensor_IR_check();
-#endif //IR_SENSOR_ANALOG
-	if (fsensor_enabled){
-		fsensor_enable(false);                  // (in this case) EEPROM update is not necessary
-	} else {
-		fsensor_disable(false);                 // (in this case) EEPROM update is not necessary
-	}
-	printf_P(PSTR("FSensor %S"), (fsensor_enabled?PSTR("ENABLED"):PSTR("DISABLED")));
-#ifdef IR_SENSOR_ANALOG
-	printf_P(PSTR(" (sensor board revision:%S)\n"), FsensorIRVersionText());
-#else //IR_SENSOR_ANALOG
-	MYSERIAL.println();
-#endif //IR_SENSOR_ANALOG
-	if (check_for_ir_sensor()){
-		ir_sensor_detected = true;
-	}
-}
-
-bool fsensor_enable(bool bUpdateEEPROM)
-{
-#ifdef PAT9125
-    (void)bUpdateEEPROM; // silence unused warning in this variant
-
-	if (mmu_enabled == false) { //filament sensor is pat9125, enable only if it is working
-		uint8_t pat9125 = pat9125_init();
-		printf_P(PSTR("PAT9125_init:%u\n"), pat9125);
-		if (pat9125)
-			fsensor_not_responding = false;
-		else
-			fsensor_not_responding = true;
-		fsensor_enabled = pat9125 ? true : false;
-		fsensor_watch_runout = true;
-		fsensor_oq_meassure = false;
-        fsensor_reset_err_cnt();
-		eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, fsensor_enabled ? 0x01 : 0x00);
-		FSensorStateMenu = fsensor_enabled ? 1 : 0;
-	}
-	else //filament sensor is FINDA, always enable 
-	{
-		fsensor_enabled = true;
-		eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, 0x01);
-		FSensorStateMenu = 1;
-	}
-#else // PAT9125
-#ifdef IR_SENSOR_ANALOG
-     if(!fsensor.checkVoltage(fsensor.getVoltRaw()))
-          {
-          bUpdateEEPROM=true;
-          fsensor_enabled=false;
-          fsensor_not_responding=true;
-          FSensorStateMenu=0;
-          }
-     else {
-#endif //IR_SENSOR_ANALOG
-     fsensor_enabled=true;
-     fsensor_not_responding=false;
-     FSensorStateMenu=1;
-#ifdef IR_SENSOR_ANALOG
-          }
-#endif //IR_SENSOR_ANALOG
-     if(bUpdateEEPROM)
-          eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, FSensorStateMenu);
-#endif //PAT9125
-	return fsensor_enabled;
-}
-
-void fsensor_disable(bool bUpdateEEPROM)
-{ 
-	fsensor_enabled = false;
-	FSensorStateMenu = 0;
-     if(bUpdateEEPROM)
-          eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, 0x00); 
-}
-
-void fsensor_autoload_set(bool State)
-{
-#ifdef PAT9125
-	if (!State) fsensor_autoload_check_stop();
-#endif //PAT9125
-	fsensor_autoload_enabled = State;
-	eeprom_update_byte((unsigned char *)EEPROM_FSENS_AUTOLOAD_ENABLED, fsensor_autoload_enabled);
-}
-
-void pciSetup(byte pin)
-{
-// !!! "digitalPinTo?????bit()" does not provide the correct results for some MCU pins
-	*digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin)); // enable pin
-	PCIFR |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
-	PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group 
-}
-
-#ifdef PAT9125
-void fsensor_autoload_check_start(void)
-{
-//	puts_P(_N("fsensor_autoload_check_start\n"));
-	if (!fsensor_enabled) return;
-	if (!fsensor_autoload_enabled) return;
-	if (fsensor_watch_autoload) return;
-	if (!pat9125_update()) //update sensor
-	{
-		fsensor_disable();
-		fsensor_not_responding = true;
-		fsensor_watch_autoload = false;
-		printf_P(ERRMSG_PAT9125_NOT_RESP, 3);
-		return;
-	}
-	puts_P(_N("fsensor_autoload_check_start - autoload ENABLED"));
-	fsensor_autoload_y = pat9125_y; //save current y value
-	fsensor_autoload_c = 0; //reset number of changes counter
-	fsensor_autoload_sum = 0;
-	fsensor_autoload_last_millis = _millis();
-	fsensor_watch_runout = false;
-	fsensor_watch_autoload = true;
-}
-
-
-void fsensor_autoload_check_stop(void)
-{
-//	puts_P(_N("fsensor_autoload_check_stop\n"));
-	if (!fsensor_enabled) return;
-//	puts_P(_N("fsensor_autoload_check_stop 1\n"));
-	if (!fsensor_autoload_enabled) return;
-//	puts_P(_N("fsensor_autoload_check_stop 2\n"));
-	if (!fsensor_watch_autoload) return;
-	puts_P(_N("fsensor_autoload_check_stop - autoload DISABLED"));
-	fsensor_autoload_sum = 0;
-	fsensor_watch_autoload = false;
-	fsensor_watch_runout = true;
-    fsensor_reset_err_cnt();
-}
-#endif //PAT9125
-
-bool fsensor_check_autoload(void)
-{
-	if (!fsensor_enabled) return false;
-	if (!fsensor_autoload_enabled) return false;
-	if (ir_sensor_detected) {
-		if (READ(IR_SENSOR_PIN)) {
-			fsensor_watch_autoload = true;
-		}
-		else if (fsensor_watch_autoload == true) {
-			fsensor_watch_autoload = false;
-			return true;
-		}
-	}
-#ifdef PAT9125
-	if (!fsensor_watch_autoload)
-	{
-		fsensor_autoload_check_start();
-		return false;
-	}
-#if 0
-	uint8_t fsensor_autoload_c_old = fsensor_autoload_c;
-#endif
-	if ((_millis() - fsensor_autoload_last_millis) < 25) return false;
-	fsensor_autoload_last_millis = _millis();
-	if (!pat9125_update_y()) //update sensor
-	{
-		fsensor_disable();
-		fsensor_not_responding = true;
-		printf_P(ERRMSG_PAT9125_NOT_RESP, 2);
-		return false;
-	}
-	int16_t dy = pat9125_y - fsensor_autoload_y;
-	if (dy) //? dy value is nonzero
-	{
-		if (dy > 0) //? delta-y value is positive (inserting)
-		{
-			fsensor_autoload_sum += dy;
-			fsensor_autoload_c += 3; //increment change counter by 3
-		}
-		else if (fsensor_autoload_c > 1)
-			fsensor_autoload_c -= 2; //decrement change counter by 2 
-		fsensor_autoload_y = pat9125_y; //save current value
-	}
-	else if (fsensor_autoload_c > 0)
-		fsensor_autoload_c--;
-	if (fsensor_autoload_c == 0) fsensor_autoload_sum = 0;
-#if 0
-  	puts_P(_N("fsensor_check_autoload\n"));
-  	if (fsensor_autoload_c != fsensor_autoload_c_old)
-  		printf_P(PSTR("fsensor_check_autoload dy=%d c=%d sum=%d\n"), dy, fsensor_autoload_c, fsensor_autoload_sum);
-#endif
-//	if ((fsensor_autoload_c >= 15) && (fsensor_autoload_sum > 30))
-	if ((fsensor_autoload_c >= 12) && (fsensor_autoload_sum > 20))
-	{
-//		puts_P(_N("fsensor_check_autoload = true !!!\n"));
-		return true;
-	}
-#endif //PAT9125
-	return false;
-}
-
-#ifdef PAT9125
-void fsensor_oq_meassure_set(bool State)
-{
-	fsensor_oq_meassure_enabled = State;
-	eeprom_update_byte((unsigned char *)EEPROM_FSENS_OQ_MEASS_ENABLED, fsensor_oq_meassure_enabled);
-}
-
-void fsensor_oq_meassure_start(uint8_t skip)
-{
-	if (!fsensor_enabled) return;
-	if (!fsensor_oq_meassure_enabled) return;
-	puts_P(PSTR("fsensor_oq_meassure_start"));
-	fsensor_oq_skipchunk = skip;
-	fsensor_oq_samples = 0;
-	fsensor_oq_st_sum = 0;
-	fsensor_oq_yd_sum = 0;
-	fsensor_oq_er_sum = 0;
-	fsensor_oq_er_max = 0;
-	fsensor_oq_yd_min = INT16_MAX;
-	fsensor_oq_yd_max = 0;
-	fsensor_oq_sh_sum = 0;
-	pat9125_update();
-	pat9125_y = 0;
-	fsensor_oq_meassure = true;
-}
-
-void fsensor_oq_meassure_stop(void)
-{
-	if (!fsensor_enabled) return;
-	if (!fsensor_oq_meassure_enabled) return;
-	printf_P(PSTR("fsensor_oq_meassure_stop, %u samples\n"), fsensor_oq_samples);
-	printf_P(_N(" st_sum=%u yd_sum=%u er_sum=%u er_max=%u\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;
-}
-
-#ifdef FSENSOR_QUALITY
-const char _OK[] PROGMEM = "OK";
-const char _NG[] PROGMEM = "NG!";
-
-bool fsensor_oq_result(void)
-{
-	if (!fsensor_enabled) return true;
-	if (!fsensor_oq_meassure_enabled) return true;
-	puts_P(_N("fsensor_oq_result"));
-	bool res_er_sum = (fsensor_oq_er_sum <= FSENSOR_OQ_MAX_ES);
-	printf_P(_N(" er_sum = %u %S\n"), fsensor_oq_er_sum, (res_er_sum?_OK:_NG));
-	bool res_er_max = (fsensor_oq_er_max <= FSENSOR_OQ_MAX_EM);
-	printf_P(_N(" er_max = %u %S\n"), fsensor_oq_er_max, (res_er_max?_OK:_NG));
-	uint8_t yd_avg = ((uint32_t)fsensor_oq_yd_sum * fsensor_chunk_len / fsensor_oq_st_sum);
-	bool res_yd_avg = (yd_avg >= FSENSOR_OQ_MIN_YD) && (yd_avg <= FSENSOR_OQ_MAX_YD);
-	printf_P(_N(" yd_avg = %u %S\n"), yd_avg, (res_yd_avg?_OK:_NG));
-	bool res_yd_max = (fsensor_oq_yd_max <= (yd_avg * FSENSOR_OQ_MAX_PD));
-	printf_P(_N(" yd_max = %u %S\n"), fsensor_oq_yd_max, (res_yd_max?_OK:_NG));
-	bool res_yd_min = (fsensor_oq_yd_min >= (yd_avg / FSENSOR_OQ_MAX_ND));
-	printf_P(_N(" yd_min = %u %S\n"), fsensor_oq_yd_min, (res_yd_min?_OK:_NG));
-
-	uint16_t yd_dev = (fsensor_oq_yd_max - yd_avg) + (yd_avg - fsensor_oq_yd_min);
-	printf_P(_N(" yd_dev = %u\n"), yd_dev);
-
-	uint16_t yd_qua = 10 * yd_avg / (yd_dev + 1);
-	printf_P(_N(" yd_qua = %u %S\n"), yd_qua, ((yd_qua >= 8)?_OK:_NG));
-
-	uint8_t sh_avg = (fsensor_oq_sh_sum / fsensor_oq_samples);
-	bool res_sh_avg = (sh_avg <= FSENSOR_OQ_MAX_SH);
-	if (yd_qua >= 8) res_sh_avg = true;
-
-	printf_P(_N(" sh_avg = %u %S\n"), sh_avg, (res_sh_avg?_OK:_NG));
-	bool res = res_er_sum && res_er_max && res_yd_avg && res_yd_max && res_yd_min && res_sh_avg;
-	printf_P(_N("fsensor_oq_result %S\n"), (res?_OK:_NG));
-	return res;
-}
-#endif //FSENSOR_QUALITY
-
-FORCE_INLINE static void fsensor_isr(int st_cnt)
-{
-	uint8_t old_err_cnt = fsensor_err_cnt;
-	uint8_t pat9125_res = fsensor_oq_meassure?pat9125_update():pat9125_update_y();
-	if (!pat9125_res)
-	{
-		fsensor_disable();
-		fsensor_not_responding = true;
-		printf_P(ERRMSG_PAT9125_NOT_RESP, 1);
-	}
-
-	if (st_cnt != 0)
-	{
-        // movement was planned, check for sensor movement
-        int8_t st_dir = st_cnt >= 0;
-        int8_t pat9125_dir = pat9125_y >= 0;
-
-        if (pat9125_y == 0)
-        {
-            if (st_dir)
-            {
-                // no movement detected: we might be within a blind sensor range,
-                // update the frame and shutter parameters we didn't earlier
-                if (!fsensor_oq_meassure)
-                    pat9125_update_bs();
-
-                // increment the error count only if underexposed: filament likely missing
-                if ((pat9125_b < FSENSOR_OQ_MIN_BR) && (pat9125_s > FSENSOR_OQ_MAX_SH))
-                {
-                    // check for a dark frame (<30% avg brightness) with long exposure
-                    ++fsensor_err_cnt;
-                }
-                else
-                {
-                    // good frame, filament likely present
-                    if(fsensor_err_cnt) --fsensor_err_cnt;
-                }
-            }
-        }
-        else if (pat9125_dir != st_dir)
-        {
-            // detected direction opposite of motor movement
-            if (st_dir) ++fsensor_err_cnt;
-        }
-        else if (pat9125_dir == st_dir)
-        {
-            // direction agreeing with planned movement
-            if (fsensor_err_cnt) --fsensor_err_cnt;
-        }
-
-        if (st_dir && fsensor_oq_meassure)
-        {
-            // extruding with quality assessment
-            if (fsensor_oq_skipchunk)
-            {
-                fsensor_oq_skipchunk--;
-                fsensor_err_cnt = 0;
-            }
-            else
-            {
-                if (st_cnt == fsensor_chunk_len)
-                {
-                    if (pat9125_y > 0) if (fsensor_oq_yd_min > pat9125_y) fsensor_oq_yd_min = (fsensor_oq_yd_min + pat9125_y) / 2;
-                    if (pat9125_y >= 0) if (fsensor_oq_yd_max < pat9125_y) fsensor_oq_yd_max = (fsensor_oq_yd_max + pat9125_y) / 2;
-                }
-                fsensor_oq_samples++;
-                fsensor_oq_st_sum += st_cnt;
-                if (pat9125_y > 0) fsensor_oq_yd_sum += pat9125_y;
-                if (fsensor_err_cnt > old_err_cnt)
-                    fsensor_oq_er_sum += (fsensor_err_cnt - old_err_cnt);
-                if (fsensor_oq_er_max < fsensor_err_cnt)
-                    fsensor_oq_er_max = fsensor_err_cnt;
-                fsensor_oq_sh_sum += pat9125_s;
-            }
-        }
-	}
-
-#ifdef DEBUG_FSENSOR_LOG
-	if (fsensor_log)
-	{
-		printf_P(_N("FSENSOR cnt=%d dy=%d err=%u %S\n"), st_cnt, pat9125_y, fsensor_err_cnt, (fsensor_err_cnt > old_err_cnt)?_N("NG!"):_N("OK"));
-		if (fsensor_oq_meassure) printf_P(_N("FSENSOR st_sum=%u yd_sum=%u er_sum=%u er_max=%u yd_max=%u\n"), fsensor_oq_st_sum, fsensor_oq_yd_sum, fsensor_oq_er_sum, fsensor_oq_er_max, fsensor_oq_yd_max);
-	}
-#endif //DEBUG_FSENSOR_LOG
-
-	pat9125_y = 0;
-}
-
-ISR(FSENSOR_INT_PIN_VECT)
-{
-    if (mmu_enabled || ir_sensor_detected) return;
-    if (!((fsensor_int_pin_old ^ FSENSOR_INT_PIN_PIN_REG) & FSENSOR_INT_PIN_MASK)) return;
-    fsensor_int_pin_old = FSENSOR_INT_PIN_PIN_REG;
-
-    // prevent isr re-entry
-    static bool _lock = false;
-    if (!_lock)
-    {
-        // fetch fsensor_st_cnt atomically
-        int st_cnt = fsensor_st_cnt;
-        fsensor_st_cnt = 0;
-
-        _lock = true;
-        sei();
-        fsensor_isr(st_cnt);
-        cli();
-        _lock = false;
-    }
-}
-
-void fsensor_setup_interrupt(void)
-{
-	WRITE(FSENSOR_INT_PIN, 0);
-	SET_OUTPUT(FSENSOR_INT_PIN);
-	fsensor_int_pin_old = 0;
-
-	//pciSetup(FSENSOR_INT_PIN);
-// !!! "pciSetup()" does not provide the correct results for some MCU pins
-// so interrupt registers settings:
-     FSENSOR_INT_PIN_PCMSK_REG |= bit(FSENSOR_INT_PIN_PCMSK_BIT); // enable corresponding PinChangeInterrupt (individual pin)
-     PCIFR |= bit(FSENSOR_INT_PIN_PCICR_BIT);     // clear previous occasional interrupt (set of pins)
-     PCICR |= bit(FSENSOR_INT_PIN_PCICR_BIT);     // enable corresponding PinChangeInterrupt (set of pins)
-}
-
-void fsensor_st_block_chunk(int cnt)
-{
-	if (!fsensor_enabled) return;
-	fsensor_st_cnt += cnt;
-
-	// !!! bit toggling (PINxn <- 1) (for PinChangeInterrupt) does not work for some MCU pins
-	WRITE(FSENSOR_INT_PIN, !READ(FSENSOR_INT_PIN));
-}
-#endif //PAT9125
-
-
-//! Common code for enqueing M600 and supplemental codes into the command queue.
-//! Used both for the IR sensor and the PAT9125
-void fsensor_enque_M600(){
-	puts_P(PSTR("fsensor_update - M600"));
-	eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1);
-	eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
-	enquecommand_front_P((PSTR("M600")));
-}
-
-//! @brief filament sensor update (perform M600 on filament runout)
-//!
-//! Works only if filament sensor is enabled.
-//! When the filament sensor error count is larger then FSENSOR_ERR_MAX, pauses print, tries to move filament back and forth.
-//! If there is still no plausible signal from filament sensor plans M600 (Filament change).
-void fsensor_update(void)
-{
-#ifdef PAT9125
-    if (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;
-            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]);
-            st_synchronize();
-
-            // check the filament in isolation
-            fsensor_reset_err_cnt();
-            fsensor_oq_meassure_start(0);
-            float e_tmp = current_position[E_AXIS];
-            current_position[E_AXIS] -= 3;
-            plan_buffer_line_curposXYZE(250/60);
-            current_position[E_AXIS] = e_tmp;
-            plan_buffer_line_curposXYZE(200/60);
-            st_synchronize();
-            fsensor_oq_meassure_stop();
-
-            bool err = false;
-            err |= (fsensor_err_cnt > 0);                   // final error count is non-zero
-            err |= (fsensor_oq_er_sum > FSENSOR_OQ_MAX_ES); // total error count is above limit
-            err |= (fsensor_oq_yd_sum < FSENSOR_OQ_MIN_YD); // total measured distance is below limit
-
-            fsensor_restore_print_and_continue();
-            fsensor_autoload_enabled = autoload_enabled_tmp;
-            fsensor_oq_meassure_enabled = oq_meassure_enabled_tmp;
-            unsigned long now = _millis();
-            if (!err && (now - fsensor_softfail_last) > FSENSOR_SOFTERR_DELTA)
-                fsensor_softfail_ccnt = 0;
-            if (!err && fsensor_softfail_ccnt <= FSENSOR_SOFTERR_CMAX)
-            {
-                puts_P(PSTR("fsensor_err_cnt = 0"));
-                ++fsensor_softfail;
-                ++fsensor_softfail_ccnt;
-                fsensor_softfail_last = now;
-            }
-            else
-            {
-                fsensor_softfail_ccnt = 0;
-                fsensor_softfail_last = 0;
-                fsensor_enque_M600();
-            }
-        }
-#else //PAT9125
-        if (CHECK_FSENSOR && ir_sensor_detected)
-        {
-            if (READ(IR_SENSOR_PIN))
-            {                                  // IR_SENSOR_PIN ~ H
-                fsensor_checkpoint_print();
-                fsensor_enque_M600();
-            }
-        }
-#endif //PAT9125
-}
-
-#ifdef IR_SENSOR_ANALOG
-/// This is called only upon start of the printer or when switching the fsensor ON in the menu
-/// We cannot do temporal window checks here (aka the voltage has been in some range for a period of time)
-bool fsensor_IR_check(uint16_t raw){
-    if( IRsensor_Lmax_TRESHOLD <= raw && raw <= IRsensor_Hmin_TRESHOLD ){
-        /// If the voltage is in forbidden range, the fsensor is ok, but the lever is mounted improperly.
-        /// Or the user is so creative so that he can hold a piece of fillament in the hole in such a genius way,
-        /// that the IR fsensor reading is within 1.5 and 3V ... this would have been highly unusual
-        /// and would have been considered more like a sabotage than normal printer operation
-        puts_P(PSTR("fsensor in forbidden range 1.5-3V - check sensor"));
-        return false; 
-    }
-    if( oFsensorPCB == ClFsensorPCB::_Rev04 ){
-        /// newer IR sensor cannot normally produce 4.6-5V, this is considered a failure/bad mount
-        if( IRsensor_Hopen_TRESHOLD <= raw && raw <= IRsensor_VMax_TRESHOLD ){
-            puts_P(PSTR("fsensor v0.4 in fault range 4.6-5V - unconnected"));
-            return false;
-        }
-        /// newer IR sensor cannot normally produce 0-0.3V, this is considered a failure 
-#if 0	//Disabled as it has to be decided if we gonna use this or not.
-        if( IRsensor_Hopen_TRESHOLD <= raw && raw <= IRsensor_VMax_TRESHOLD ){
-            puts_P(PSTR("fsensor v0.4 in fault range 0.0-0.3V - wrong IR sensor"));
-            return false;
-        }
-#endif
-    }
-    /// If IR sensor is "uknown state" and filament is not loaded > 1.5V return false
-#if 0
-    if( (oFsensorPCB == ClFsensorPCB::_Undef) && ( raw > IRsensor_Lmax_TRESHOLD ) ){
-        puts_P(PSTR("Unknown IR sensor version and no filament loaded detected."));
-        return false;
-    }
-#endif
-    // otherwise the IR fsensor is considered working correctly
-    return true;
-}
-#endif //IR_SENSOR_ANALOG

+ 0 - 33
Firmware/fsensor.h

@@ -1,33 +0,0 @@
-//! @file
-#ifndef FSENSOR_H
-#define FSENSOR_H
-
-#include <inttypes.h>
-#include "config.h"
-
-
-#ifdef PAT9125
-// optical checking "chunk lenght" (already in steps)
-extern int16_t fsensor_chunk_len;
-// count of soft failures
-extern uint8_t fsensor_softfail;
-
-//! update axis resolution
-extern void fsensor_set_axis_steps_per_unit(float u);
-
-//! @name callbacks from stepper
-//! @{
-extern void fsensor_st_block_chunk(int cnt);
-
-// debugging
-extern uint8_t fsensor_log;
-
-// There's really nothing to do in block_begin: the stepper ISR likely has
-// called us already at the end of the last block, making this integration
-// redundant. LA1.5 might not always do that during a coasting move, so attempt
-// to drain fsensor_st_cnt anyway at the beginning of the new block.
-#define fsensor_st_block_begin(rev) fsensor_st_block_chunk(0)
-//! @}
-#endif //PAT9125
-
-#endif //FSENSOR_H

+ 1 - 0
Firmware/messages.cpp

@@ -43,6 +43,7 @@ const char MSG_FOLLOW_CALIBRATION_FLOW[] PROGMEM_I1 = ISTR("Printer has not been
 const char MSG_FOLLOW_Z_CALIBRATION_FLOW[] PROGMEM_I1 = ISTR("There is still a need to make Z calibration. Please follow the manual, chapter First steps, section Calibration flow."); ////MSG_FOLLOW_Z_CALIBRATION_FLOW c=20 r=9
 const char MSG_FSENSOR_RUNOUT[] PROGMEM_I1 = ISTR("F. runout"); ////c=13
 const char MSG_FSENSOR_AUTOLOAD[] PROGMEM_I1 = ISTR("F. autoload"); ////MSG_FSENSOR_AUTOLOAD c=13
+const char MSG_FSENSOR_JAM_DETECTION[] PROGMEM_I1 = ISTR("F. jam detect"); ////c=13
 const char MSG_FSENSOR[] PROGMEM_I1 = ISTR("Fil. sensor"); ////MSG_FSENSOR c=12
 const char MSG_HEATING[] PROGMEM_I1 = ISTR("Heating"); ////MSG_HEATING c=20
 const char MSG_HEATING_COMPLETE[] PROGMEM_I1 = ISTR("Heating done."); ////MSG_HEATING_COMPLETE c=20

+ 1 - 0
Firmware/messages.h

@@ -49,6 +49,7 @@ extern const char MSG_FOLLOW_CALIBRATION_FLOW[];
 extern const char MSG_FOLLOW_Z_CALIBRATION_FLOW[];
 extern const char MSG_FSENSOR_RUNOUT[];
 extern const char MSG_FSENSOR_AUTOLOAD[];
+extern const char MSG_FSENSOR_JAM_DETECTION[];
 extern const char MSG_FSENSOR[];
 extern const char MSG_HEATING[];
 extern const char MSG_HEATING_COMPLETE[];

+ 0 - 1
Firmware/mmu.cpp

@@ -7,7 +7,6 @@
 #include "uart2.h"
 #include "temperature.h"
 #include "Configuration_prusa.h"
-#include "fsensor.h"
 #include "cardreader.h"
 #include "cmdqueue.h"
 #include "stepper.h"

+ 10 - 46
Firmware/stepper.cpp

@@ -36,10 +36,7 @@
 #include "tmc2130.h"
 #endif //TMC2130
 
-#if defined(FILAMENT_SENSOR) && defined(PAT9125)
-#include "fsensor.h"
-int fsensor_counter; //counter for e-steps
-#endif //FILAMENT_SENSOR
+#include "Filament_sensor.h"
 
 #include "mmu.h"
 #include "ConfigurationStore.h"
@@ -457,9 +454,6 @@ FORCE_INLINE void stepper_next_block()
 #endif /* LIN_ADVANCE */
       count_direction[E_AXIS] = 1;
     }
-#if defined(FILAMENT_SENSOR) && defined(PAT9125)
-    fsensor_st_block_begin(count_direction[E_AXIS] < 0);
-#endif //FILAMENT_SENSOR
   }
   else {
       _NEXT_ISR(2000); // 1kHz.
@@ -704,9 +698,9 @@ FORCE_INLINE void stepper_tick_lowres()
 #ifdef LIN_ADVANCE
       e_steps += count_direction[E_AXIS];
 #else
-	#ifdef FILAMENT_SENSOR
-	  fsensor_counter += count_direction[E_AXIS];
-	#endif //FILAMENT_SENSOR
+#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+      fsensor.stStep(count_direction[E_AXIS] < 0);
+#endif //defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
       STEP_NC_LO(E_AXIS);
 #endif
     }
@@ -766,9 +760,9 @@ FORCE_INLINE void stepper_tick_highres()
 #ifdef LIN_ADVANCE
       e_steps += count_direction[E_AXIS];
 #else
-    #ifdef FILAMENT_SENSOR
-      fsensor_counter += count_direction[E_AXIS];
-    #endif //FILAMENT_SENSOR
+#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+      fsensor.stStep(count_direction[E_AXIS] < 0);
+#endif //defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
       STEP_NC_LO(E_AXIS);
 #endif
     }
@@ -963,21 +957,9 @@ FORCE_INLINE void isr() {
 
     // If current block is finished, reset pointer
     if (step_events_completed.wide >= current_block->step_event_count.wide) {
-#if !defined(LIN_ADVANCE) && defined(FILAMENT_SENSOR)
-		fsensor_st_block_chunk(fsensor_counter);
-		fsensor_counter = 0;
-#endif //FILAMENT_SENSOR
-
       current_block = NULL;
       plan_discard_current_block();
     }
-#if !defined(LIN_ADVANCE) && defined(FILAMENT_SENSOR)
-	else if ((abs(fsensor_counter) >= fsensor_chunk_len))
-  	{
-      fsensor_st_block_chunk(fsensor_counter);
-  	  fsensor_counter = 0;
-  	}
-#endif //FILAMENT_SENSOR
   }
 
 #ifdef TMC2130
@@ -1073,19 +1055,11 @@ FORCE_INLINE void advance_isr_scheduler() {
             STEP_NC_HI(E_AXIS);
             e_steps += (rev? 1: -1);
             STEP_NC_LO(E_AXIS);
-#if defined(FILAMENT_SENSOR) && defined(PAT9125)
-            fsensor_counter += (rev? -1: 1);
-#endif
+#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+            fsensor.stStep(rev);
+#endif //defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
         }
         while(--max_ticks);
-
-#if defined(FILAMENT_SENSOR) && defined(PAT9125)
-        if (abs(fsensor_counter) >= fsensor_chunk_len)
-        {
-            fsensor_st_block_chunk(fsensor_counter);
-            fsensor_counter = 0;
-        }
-#endif
     }
 
     // Schedule the next closest tick, ignoring advance if scheduled too
@@ -1668,13 +1642,3 @@ void microstep_readings()
       #endif
 }
 #endif //TMC2130
-
-
-#if defined(FILAMENT_SENSOR) && defined(PAT9125)
-void st_reset_fsensor()
-{
-    CRITICAL_SECTION_START;
-    fsensor_counter = 0;
-    CRITICAL_SECTION_END;
-}
-#endif //FILAMENT_SENSOR

+ 0 - 5
Firmware/stepper.h

@@ -87,9 +87,4 @@ void microstep_readings();
   void babystep(const uint8_t axis,const bool direction); // perform a short step with a single stepper motor, outside of any convention
 #endif
 
-#if defined(FILAMENT_SENSOR) && defined(PAT9125)
-// reset the internal filament sensor state
-void st_reset_fsensor();
-#endif
-
 #endif

+ 26 - 8
Firmware/ultralcd.cpp

@@ -6,7 +6,6 @@
 #include "temperature.h"
 #include "ultralcd.h"
 #include "conv2str.h"
-#include "fsensor.h"
 #include "Marlin.h"
 #include "language.h"
 #include "cardreader.h"
@@ -29,11 +28,7 @@
 //#include "Configuration.h"
 #include "cmdqueue.h"
 
-#ifdef FILAMENT_SENSOR
-#include "pat9125.h"
-#include "fsensor.h"
 #include "Filament_sensor.h"
-#endif //FILAMENT_SENSOR
 
 #ifdef TMC2130
 #include "tmc2130.h"
@@ -46,7 +41,6 @@
 #include "static_assert.h"
 #include "first_lay_cal.h"
 
-#include "fsensor.h"
 #include "adc.h"
 #include "config.h"
 
@@ -1269,11 +1263,11 @@ static void lcd_menu_fails_stats_print()
     // On the MK3 include detailed PAT9125 statistics about soft failures
     lcd_printf_P(PSTR("%S\n"
                       " %-16.16S%-3d\n"
-                      " %-7.7S H %-3d S %-3d\n"
+                      " %-7.7S: %-3d\n"
                       " %-7.7S X %-3d Y %-3d"),
                  _T(MSG_LAST_PRINT_FAILURES),
                  _T(MSG_POWER_FAILURES), power,
-                 _i("Runouts"), filam, fsensor_softfail, ////MSG_RUNOUTS c=7
+                 _i("Runouts"), filam, //MSG_RUNOUTS c=7
                  _T(MSG_CRASH), crashX, crashY);
 #endif
     menu_back_if_clicked_fb();
@@ -4187,6 +4181,12 @@ static void lcd_fsensor_autoload_set() {
     fsensor.setAutoLoadEnabled(!fsensor.getAutoLoadEnabled(), true);
 }
 
+#if FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125
+static void lcd_fsensor_jam_detection_set() {
+    fsensor.setJamDetectionEnabled(!fsensor.getJamDetectionEnabled(), true);
+}
+#endif //FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125
+
 static void lcd_fsensor_actionNA_set(void)
 {
     Filament_sensor::SensorActionOnError act = fsensor.getActionOnError();
@@ -4213,10 +4213,16 @@ static void lcd_fsensor_settings_menu() {
         if (fsensor.isError()) {
             MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_RUNOUT), _T(MSG_NA), fsensor_reinit);
             MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_AUTOLOAD), _T(MSG_NA), fsensor_reinit);
+#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+            MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_JAM_DETECTION), _T(MSG_NA), fsensor_reinit);
+#endif //defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
         }
         else {
             MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_RUNOUT), fsensor.getRunoutEnabled() ? _T(MSG_ON) : _T(MSG_OFF), lcd_fsensor_runout_set);
             MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_AUTOLOAD), fsensor.getAutoLoadEnabled() ? _T(MSG_ON) : _T(MSG_OFF), lcd_fsensor_autoload_set);
+#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+            MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_JAM_DETECTION), fsensor.getJamDetectionEnabled() ? _T(MSG_ON) : _T(MSG_OFF), lcd_fsensor_jam_detection_set);
+#endif //defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
         }
         
         switch(fsensor.getActionOnError()) {
@@ -5135,6 +5141,14 @@ void unload_filament(bool automatic)
 	custom_message_type = CustomMsg::FilamentLoading;
 	lcd_setstatuspgm(_T(MSG_UNLOADING_FILAMENT));
 
+#ifdef FILAMENT_SENSOR
+	fsensor.setRunoutEnabled(false); //suppress filament runouts while loading filament.
+	fsensor.setAutoLoadEnabled(false); //suppress filament autoloads while loading filament.
+#if (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+	fsensor.setJamDetectionEnabled(false); //suppress filament jam detection while loading filament.
+#endif //(FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+#endif
+
     raise_z_above(automatic? MIN_Z_FOR_SWAP: MIN_Z_FOR_UNLOAD);
 
 	//		extr_unload2();
@@ -5172,6 +5186,10 @@ void unload_filament(bool automatic)
 	custom_message_type = CustomMsg::Status;
 
 	eFilamentAction = FilamentAction::None;
+
+#ifdef FILAMENT_SENSOR
+	fsensor.settings_init(); //restore filament runout state.
+#endif
 }
 
 #include "xflash.h"

+ 1 - 1
Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h

@@ -135,7 +135,7 @@
 //#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

+ 1 - 1
Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h

@@ -136,7 +136,7 @@
 //#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

+ 1 - 1
Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h

@@ -135,7 +135,7 @@
 //#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

+ 1 - 1
Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h

@@ -136,7 +136,7 @@
 //#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

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

@@ -177,7 +177,7 @@
 //#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

+ 1 - 1
Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h

@@ -179,7 +179,7 @@
 //#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