Browse Source

Merge remote-tracking branch 'origin/MK3' into MK3

michalprusa 7 years ago
parent
commit
14a8c33096

+ 19 - 15
Firmware/Configuration_prusa.h

@@ -62,7 +62,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 #define Z_PAUSE_LIFT 20
 #define Z_PAUSE_LIFT 20
 
 
 #define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
 #define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
-#define HOMING_FEEDRATE {3000, 3000, 800, 0}  // set the homing speeds (mm/min) // 3000 is also valid for stallGuard homing. Valid range: 2200 - 3000
+#define HOMING_FEEDRATE {2500, 3000, 800, 0}  // set the homing speeds (mm/min) // 3000 is also valid for stallGuard homing. Valid range: 2200 - 3000
 
 
 //#define DEFAULT_MAX_FEEDRATE          {400, 400, 12, 120}    // (mm/sec)
 //#define DEFAULT_MAX_FEEDRATE          {400, 400, 12, 120}    // (mm/sec)
 #define DEFAULT_MAX_FEEDRATE          {500, 500, 12, 120}    // (mm/sec)
 #define DEFAULT_MAX_FEEDRATE          {500, 500, 12, 120}    // (mm/sec)
@@ -78,18 +78,18 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 
 
 //DEBUG
 //DEBUG
 #define DEBUG_DCODES //D codes
 #define DEBUG_DCODES //D codes
-#if 0
-#define DEBUG_DISABLE_XMINLIMIT  //x min limit ignored
-#define DEBUG_DISABLE_XMAXLIMIT  //x max limit ignored
-#define DEBUG_DISABLE_YMINLIMIT  //y min limit ignored
-#define DEBUG_DISABLE_YMAXLIMIT  //y max limit ignored
-#define DEBUG_DISABLE_ZMINLIMIT  //z min limit ignored
-#define DEBUG_DISABLE_ZMAXLIMIT  //z max limit ignored
+#if 1
+//#define DEBUG_DISABLE_XMINLIMIT  //x min limit ignored
+//#define DEBUG_DISABLE_XMAXLIMIT  //x max limit ignored
+//#define DEBUG_DISABLE_YMINLIMIT  //y min limit ignored
+//#define DEBUG_DISABLE_YMAXLIMIT  //y max limit ignored
+//#define DEBUG_DISABLE_ZMINLIMIT  //z min limit ignored
+//#define DEBUG_DISABLE_ZMAXLIMIT  //z max limit ignored
 #define DEBUG_DISABLE_STARTMSGS //no startup messages 
 #define DEBUG_DISABLE_STARTMSGS //no startup messages 
-#define DEBUG_DISABLE_MINTEMP   //mintemp error ignored
-#define DEBUG_DISABLE_SWLIMITS  //sw limits ignored
+//#define DEBUG_DISABLE_MINTEMP   //mintemp error ignored
+//#define DEBUG_DISABLE_SWLIMITS  //sw limits ignored
 #define DEBUG_DISABLE_LCD_STATUS_LINE  //empty four lcd line
 #define DEBUG_DISABLE_LCD_STATUS_LINE  //empty four lcd line
-#define DEBUG_DISABLE_PREVENT_EXTRUDER //cold extrusion and long extrusion allowed
+//#define DEBUG_DISABLE_PREVENT_EXTRUDER //cold extrusion and long extrusion allowed
 #define DEBUG_DISABLE_PRUSA_STATISTICS //disable prusa_statistics() mesages
 #define DEBUG_DISABLE_PRUSA_STATISTICS //disable prusa_statistics() mesages
 //#define DEBUG_XSTEP_DUP_PIN 21   //duplicate x-step output to pin 21 (SCL on P3)
 //#define DEBUG_XSTEP_DUP_PIN 21   //duplicate x-step output to pin 21 (SCL on P3)
 //#define DEBUG_YSTEP_DUP_PIN 21   //duplicate y-step output to pin 21 (SCL on P3)
 //#define DEBUG_YSTEP_DUP_PIN 21   //duplicate y-step output to pin 21 (SCL on P3)
@@ -137,19 +137,23 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 #define TMC2130_TPWMTHRS  0         // TPWMTHRS - Sets the switching speed threshold based on TSTEP from stealthChop to spreadCycle mode
 #define TMC2130_TPWMTHRS  0         // TPWMTHRS - Sets the switching speed threshold based on TSTEP from stealthChop to spreadCycle mode
 #define TMC2130_THIGH     0         // THIGH - unused
 #define TMC2130_THIGH     0         // THIGH - unused
 
 
-#define TMC2130_TCOOLTHRS 500       // TCOOLTHRS - coolstep treshold
+#define TMC2130_TCOOLTHRS_X 400       // TCOOLTHRS - coolstep treshold
+#define TMC2130_TCOOLTHRS_Y 400       // TCOOLTHRS - coolstep treshold
+#define TMC2130_TCOOLTHRS_Z 500       // TCOOLTHRS - coolstep treshold
+#define TMC2130_TCOOLTHRS_E 500       // TCOOLTHRS - coolstep treshold
 
 
 #define TMC2130_SG_HOMING       1     // stallguard homing
 #define TMC2130_SG_HOMING       1     // stallguard homing
 //#define TMC2130_SG_HOMING_SW_XY  1    // stallguard "software" homing for XY axes
 //#define TMC2130_SG_HOMING_SW_XY  1    // stallguard "software" homing for XY axes
 #define TMC2130_SG_HOMING_SW_Z  1     // stallguard "software" homing for Z axis
 #define TMC2130_SG_HOMING_SW_Z  1     // stallguard "software" homing for Z axis
-#define TMC2130_SG_THRS_X       6     // stallguard sensitivity for X axis
-#define TMC2130_SG_THRS_Y       6     // stallguard sensitivity for Y axis
+#define TMC2130_SG_THRS_X       1     // stallguard sensitivity for X axis
+#define TMC2130_SG_THRS_Y       3     // stallguard sensitivity for Y axis
 #define TMC2130_SG_THRS_Z       3     // stallguard sensitivity for Z axis
 #define TMC2130_SG_THRS_Z       3     // stallguard sensitivity for Z axis
+#define TMC2130_SG_THRS_E       3     // stallguard sensitivity for E axis
 #define TMC2130_SG_DELTA      128    // stallguard delta [usteps] (minimum usteps before stallguard readed - SW homing)
 #define TMC2130_SG_DELTA      128    // stallguard delta [usteps] (minimum usteps before stallguard readed - SW homing)
 
 
 //new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only)
 //new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only)
 #define TMC2130_CURRENTS_H {3, 3, 5, 8}  // default holding currents for all axes
 #define TMC2130_CURRENTS_H {3, 3, 5, 8}  // default holding currents for all axes
-#define TMC2130_CURRENTS_R {13, 31, 20, 22}  // default running currents for all axes
+#define TMC2130_CURRENTS_R {13, 20, 20, 22}  // default running currents for all axes
 
 
 //#define TMC2130_DEBUG
 //#define TMC2130_DEBUG
 //#define TMC2130_DEBUG_WR
 //#define TMC2130_DEBUG_WR

+ 0 - 1
Firmware/Marlin.h

@@ -373,7 +373,6 @@ void uvlo_();
 void recover_print();
 void recover_print();
 void setup_uvlo_interrupt();
 void setup_uvlo_interrupt();
 
 
-extern void save_print_to_eeprom();
 extern void recover_machine_state_after_power_panic();
 extern void recover_machine_state_after_power_panic();
 extern void restore_print_from_eeprom();
 extern void restore_print_from_eeprom();
 extern void position_menu();
 extern void position_menu();

+ 163 - 156
Firmware/Marlin_main.cpp

@@ -589,12 +589,23 @@ void crashdet_restore_print_and_continue()
 }
 }
 
 
 
 
+void crashdet_stop_and_save_print2()
+{
+	cli();
+	planner_abort_hard(); //abort printing
+	cmdqueue_reset(); //empty cmdqueue
+	card.sdprinting = false;
+	card.closefile();
+	sei();
+}
+
+
 #ifdef PAT9125
 #ifdef PAT9125
 
 
 void fsensor_stop_and_save_print()
 void fsensor_stop_and_save_print()
 {
 {
 //	stop_and_save_print_to_ram(10, -0.8); //XY - no change, Z 10mm up, E 0.8mm in
 //	stop_and_save_print_to_ram(10, -0.8); //XY - no change, Z 10mm up, E 0.8mm in
-	stop_and_save_print_to_ram(0, 0); //XY - no change, Z 10mm up, E 0.8mm in
+	stop_and_save_print_to_ram(0, 0); //XYZE - no change
 }
 }
 
 
 void fsensor_restore_print_and_continue()
 void fsensor_restore_print_and_continue()
@@ -971,6 +982,22 @@ void setup()
 #endif
 #endif
 	setup_homepin();
 	setup_homepin();
 
 
+  if (1) {
+    SERIAL_ECHOPGM("initial zsteps on power up: "); MYSERIAL.println(tmc2130_rd_MSCNT(Z_TMC2130_CS));
+    // try to run to zero phase before powering the Z motor.    
+    // Move in negative direction
+    WRITE(Z_DIR_PIN,INVERT_Z_DIR);
+    // Round the current micro-micro steps to micro steps.
+    for (uint16_t phase = (tmc2130_rd_MSCNT(Z_TMC2130_CS) + 8) >> 4; phase > 0; -- phase) {
+      // Until the phase counter is reset to zero.
+      WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN);
+      delay(2);
+      WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN);
+      delay(2);
+    }
+    SERIAL_ECHOPGM("initial zsteps after reset: "); MYSERIAL.println(tmc2130_rd_MSCNT(Z_TMC2130_CS));
+  }
+
 #if defined(Z_AXIS_ALWAYS_ON)
 #if defined(Z_AXIS_ALWAYS_ON)
 	enable_z();
 	enable_z();
 #endif
 #endif
@@ -1026,25 +1053,6 @@ void setup()
 		eeprom_write_byte((uint8_t*)EEPROM_UVLO, 0);
 		eeprom_write_byte((uint8_t*)EEPROM_UVLO, 0);
 	}
 	}
 
 
-  {
-    SERIAL_ECHOPGM("power up "); print_world_coordinates();
-    SERIAL_ECHOPGM("power up "); print_physical_coordinates();
-    SERIAL_ECHOPGM("initial zsteps on power up: "); MYSERIAL.println(tmc2130_rd_MSCNT(Z_TMC2130_CS));
-    float z0 = current_position[Z_AXIS];
-    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], z0 + 0.04, current_position[E_AXIS], feedrate/60, active_extruder);
-    st_synchronize();
-    SERIAL_ECHOPGM("full step: "); MYSERIAL.println(tmc2130_rd_MSCNT(Z_TMC2130_CS));
-    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], z0 + 0.08, current_position[E_AXIS], feedrate/60, active_extruder);
-    st_synchronize();
-    SERIAL_ECHOPGM("two full steps: "); MYSERIAL.println(tmc2130_rd_MSCNT(Z_TMC2130_CS));
-    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], z0 + 0.16 - 0.01, current_position[E_AXIS], feedrate/60, active_extruder);
-    st_synchronize();
-    SERIAL_ECHOPGM("nearly full cycle: "); MYSERIAL.println(tmc2130_rd_MSCNT(Z_TMC2130_CS));
-    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], z0 + 0.16, current_position[E_AXIS], feedrate/60, active_extruder);
-    st_synchronize();
-    SERIAL_ECHOPGM("full cycle: "); MYSERIAL.println(tmc2130_rd_MSCNT(Z_TMC2130_CS));
-  }
-
 #ifndef DEBUG_DISABLE_STARTMSGS
 #ifndef DEBUG_DISABLE_STARTMSGS
 	check_babystep(); //checking if Z babystep is in allowed range
 	check_babystep(); //checking if Z babystep is in allowed range
 	setup_uvlo_interrupt();
 	setup_uvlo_interrupt();
@@ -1248,7 +1256,7 @@ void loop()
 	if (tmc2130_sg_crash)
 	if (tmc2130_sg_crash)
 	{
 	{
 		tmc2130_sg_crash = false;
 		tmc2130_sg_crash = false;
-		crashdet_stop_and_save_print();
+//		crashdet_stop_and_save_print();
 		enquecommand_P((PSTR("D999")));
 		enquecommand_P((PSTR("D999")));
 	}
 	}
 #endif //TMC2130
 #endif //TMC2130
@@ -1514,66 +1522,72 @@ void homeaxis(int axis)
     if ((axis==X_AXIS)?HOMEAXIS_DO(X):(axis==Y_AXIS)?HOMEAXIS_DO(Y):0)
     if ((axis==X_AXIS)?HOMEAXIS_DO(X):(axis==Y_AXIS)?HOMEAXIS_DO(Y):0)
 	{
 	{
         int axis_home_dir = home_dir(axis);
         int axis_home_dir = home_dir(axis);
+        feedrate = homing_feedrate[axis];
+
 #ifdef TMC2130
 #ifdef TMC2130
-		tmc2130_home_enter(X_AXIS_MASK << axis);
+    		tmc2130_home_enter(X_AXIS_MASK << axis);
 #endif
 #endif
+
+        // Move right a bit, so that the print head does not touch the left end position,
+        // and the following left movement has a chance to achieve the required velocity
+        // for the stall guard to work.
         current_position[axis] = 0;
         current_position[axis] = 0;
         plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
         plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
-        destination[axis] = 1.5 * max_length(axis) * axis_home_dir;
-        feedrate = homing_feedrate[axis];
-#ifdef TMC2130
-		tmc2130_home_restart(axis);
-#endif
+//        destination[axis] = 11.f;
+        destination[axis] = 3.f;
         plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
         plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
         st_synchronize();
         st_synchronize();
-/*
-		tmc2130_home_pause(axis);
-
+        // Move left away from the possible collision with the collision detection disabled.
+        endstops_hit_on_purpose();
+        enable_endstops(false);
         current_position[axis] = 0;
         current_position[axis] = 0;
         plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
         plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
-        destination[axis] = -home_retract_mm(axis) * axis_home_dir;
-#ifdef TMC2130
-		tmc2130_home_restart(axis);
-#endif
+        destination[axis] = - 1.;
         plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
         plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
         st_synchronize();
         st_synchronize();
-
-		tmc2130_home_resume(axis);
-
-        destination[axis] = 2*home_retract_mm(axis) * axis_home_dir;
-//#ifdef TMC2130
-//		feedrate = homing_feedrate[axis];
-//#else
-		feedrate = homing_feedrate[axis] / 2;
-//#endif
-#ifdef TMC2130
-		tmc2130_home_restart(axis);
-#endif
+        // Now continue to move up to the left end stop with the collision detection enabled.
+        enable_endstops(true);
+        destination[axis] = - 1.1 * max_length(axis);
         plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
         plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
         st_synchronize();
         st_synchronize();
-*/
-		tmc2130_home_pause(axis);
-
+        // Move right from the collision to a known distance from the left end stop with the collision detection disabled.
+        endstops_hit_on_purpose();
+        enable_endstops(false);
         current_position[axis] = 0;
         current_position[axis] = 0;
         plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
         plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
-        destination[axis] = -0.32 * axis_home_dir;
+        destination[axis] = 10.f;
+        plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+        st_synchronize();
+        endstops_hit_on_purpose();
+        // Now move left up to the collision, this time with a repeatable velocity.
+        enable_endstops(true);
+        destination[axis] = - 15.f;
+        feedrate = homing_feedrate[axis]/2;
         plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
         plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
         st_synchronize();
         st_synchronize();
 
 
-		axis_is_at_home(axis);
-		destination[axis] = current_position[axis];
-		feedrate = 0.0;
-
-		endstops_hit_on_purpose();
+        axis_is_at_home(axis);
         axis_known_position[axis] = true;
         axis_known_position[axis] = true;
 
 
-
 #ifdef TMC2130
 #ifdef TMC2130
-		tmc2130_home_exit();
-//        destination[axis] += 2;
-//        plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], homing_feedrate[axis]/60, active_extruder);
-//        st_synchronize();
+        tmc2130_home_exit();
 #endif
 #endif
+        // Move the X carriage away from the collision.
+        // If this is not done, the X cariage will jump from the collision at the instant the Trinamic driver reduces power on idle.
+        endstops_hit_on_purpose();
+        enable_endstops(false);
+        {
+          // Two full periods (4 full steps).
+          float gap = 0.32f * 2.f;
+          current_position[axis] -= gap;
+          plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
+          current_position[axis] += gap;
+        }
+        destination[axis] = current_position[axis];
+        plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], 0.3f*feedrate/60, active_extruder);
+        st_synchronize();
+
+    		feedrate = 0.0;
     }
     }
     else if ((axis==Z_AXIS)?HOMEAXIS_DO(Z):0)
     else if ((axis==Z_AXIS)?HOMEAXIS_DO(Z):0)
 	{
 	{
@@ -5472,15 +5486,18 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 
 
 	case 916: // M916 Set sg_thrs
 	case 916: // M916 Set sg_thrs
     {
     {
-		if (code_seen('X')) tmc2130_axis_sg_thr[X_AXIS] = code_value();
-		if (code_seen('Y')) tmc2130_axis_sg_thr[Y_AXIS] = code_value();
-		if (code_seen('Z')) tmc2130_axis_sg_thr[Z_AXIS] = code_value();
-		MYSERIAL.print("tmc2130_axis_sg_thr[X]=");
-		MYSERIAL.print(tmc2130_axis_sg_thr[X_AXIS], DEC);
-		MYSERIAL.print("tmc2130_axis_sg_thr[Y]=");
-		MYSERIAL.print(tmc2130_axis_sg_thr[Y_AXIS], DEC);
-		MYSERIAL.print("tmc2130_axis_sg_thr[Z]=");
-		MYSERIAL.print(tmc2130_axis_sg_thr[Z_AXIS], DEC);
+		if (code_seen('X')) tmc2130_sg_thr[X_AXIS] = code_value();
+		if (code_seen('Y')) tmc2130_sg_thr[Y_AXIS] = code_value();
+		if (code_seen('Z')) tmc2130_sg_thr[Z_AXIS] = code_value();
+		if (code_seen('E')) tmc2130_sg_thr[E_AXIS] = code_value();
+		MYSERIAL.print("tmc2130_sg_thr[X]=");
+		MYSERIAL.println(tmc2130_sg_thr[X_AXIS], DEC);
+		MYSERIAL.print("tmc2130_sg_thr[Y]=");
+		MYSERIAL.println(tmc2130_sg_thr[Y_AXIS], DEC);
+		MYSERIAL.print("tmc2130_sg_thr[Z]=");
+		MYSERIAL.println(tmc2130_sg_thr[Z_AXIS], DEC);
+		MYSERIAL.print("tmc2130_sg_thr[E]=");
+		MYSERIAL.println(tmc2130_sg_thr[E_AXIS], DEC);
     }
     }
     break;
     break;
 
 
@@ -6882,53 +6899,98 @@ void serialecho_temperatures() {
 	SERIAL_PROTOCOLLN("");
 	SERIAL_PROTOCOLLN("");
 }
 }
 
 
+extern uint32_t sdpos_atomic;
 
 
+void uvlo_() 
+{
+    // Conserve power as soon as possible.
+    disable_x();
+    disable_y();
 
 
-void uvlo_() {
+    // Indicate that the interrupt has been triggered.
 		SERIAL_ECHOLNPGM("UVLO");
 		SERIAL_ECHOLNPGM("UVLO");
 
 
-    // Saves the current position of the start of the command queue in the file,
-    // the mesh bed leveling table and the current Z axis micro steps value into EEPROM.
-		save_print_to_eeprom();
+    // Read out the current Z motor microstep counter. This will be later used
+    // for reaching the zero full step before powering off.
+    uint16_t z_microsteps = tmc2130_rd_MSCNT(Z_TMC2130_CS);
 
 
-    // feedrate in mm/min
-		int feedrate_bckp = blocks_queued() ? (block_buffer[block_buffer_tail].nominal_speed * 60.f) : feedrate;
+    // Calculate the file position, from which to resume this print.
+    long sd_position = sdpos_atomic; //atomic sd position of last command added in queue
+    {
+      uint16_t sdlen_planner = planner_calc_sd_length(); //length of sd commands in planner
+      sd_position -= sdlen_planner;
+      uint16_t sdlen_cmdqueue = cmdqueue_calc_sd_length(); //length of sd commands in cmdqueue
+      sd_position -= sdlen_cmdqueue;
+      if (sd_position < 0) sd_position = 0;
+    }
+
+    // Backup the feedrate in mm/min.
+    int feedrate_bckp = blocks_queued() ? (block_buffer[block_buffer_tail].nominal_speed * 60.f) : feedrate;
 
 
-    disable_x();
-    disable_y();
     // After this call, the planner queue is emptied and the current_position is set to a current logical coordinate.
     // After this call, the planner queue is emptied and the current_position is set to a current logical coordinate.
     // The logical coordinate will likely differ from the machine coordinate if the skew calibration and mesh bed leveling
     // The logical coordinate will likely differ from the machine coordinate if the skew calibration and mesh bed leveling
     // are in action.
     // are in action.
     planner_abort_hard();
     planner_abort_hard();
 
 
-		eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0), current_position[X_AXIS]);
-		eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4), current_position[Y_AXIS]);
-		eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z), current_position[Z_AXIS]);
-		EEPROM_save_B(EEPROM_UVLO_FEEDRATE, &feedrate_bckp);
-		eeprom_update_byte((uint8_t*)EEPROM_UVLO_TARGET_HOTEND, target_temperature[active_extruder]);
-		eeprom_update_byte((uint8_t*)EEPROM_UVLO_TARGET_BED, target_temperature_bed);
-		eeprom_update_byte((uint8_t*)EEPROM_UVLO_FAN_SPEED, fanSpeed);
-		// Because the planner_abort_hard() initialized current_position[Z] from the stepper,
-		// Z baystep is no more applied. Reset it.
-		//babystep_reset();
-		// Clean the input command queue.
-		cmdqueue_reset();
-		card.sdprinting = false;
-		card.closefile();
+    // Clean the input command queue.
+    cmdqueue_reset();
+    card.sdprinting = false;
+//    card.closefile();
+
+    // Enable stepper driver interrupt to move Z axis.
+    // This should be fine as the planner and command queues are empty and the SD card printing is disabled.
+    //FIXME one may want to disable serial lines at this point of time to avoid interfering with the command queue,
+    // though it should not happen that the command queue is touched as the plan_buffer_line always succeed without blocking.
+		sei();
+		plan_buffer_line(
+      current_position[X_AXIS], 
+      current_position[Y_AXIS], 
+      current_position[Z_AXIS], 
+      current_position[E_AXIS] - DEFAULT_RETRACTION, 
+      400, active_extruder);
+		plan_buffer_line(
+      current_position[X_AXIS], 
+      current_position[Y_AXIS], 
+      current_position[Z_AXIS] + UVLO_Z_AXIS_SHIFT + float((1024 - z_microsteps + 7) >> 4) / axis_steps_per_unit[Z_AXIS], 
+      current_position[E_AXIS] - DEFAULT_RETRACTION,
+      40, active_extruder);
 
 
-		current_position[E_AXIS] -= DEFAULT_RETRACTION;
-		sei(); //enable stepper driver interrupt to move Z axis
-		plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 400, active_extruder);
-		st_synchronize();
     // Move Z up to the next 0th full step.
     // Move Z up to the next 0th full step.
-    current_position[Z_AXIS] += UVLO_Z_AXIS_SHIFT + float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS)) + 8) >> 4) / axis_steps_per_unit[Z_AXIS];
+    // Write the file position.
+    eeprom_update_dword((uint32_t*)(EEPROM_FILE_POSITION), sd_position);
+    // Store the mesh bed leveling offsets. This is 2*9=18 bytes, which takes 18*3.4us=52us in worst case.
+    for (int8_t mesh_point = 0; mesh_point < 9; ++ mesh_point) {
+      uint8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1
+      uint8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS;
+      // Scale the z value to 1u resolution.
+      int16_t v = mbl.active ? int16_t(floor(mbl.z_values[iy*3][ix*3] * 1000.f + 0.5f)) : 0;
+      eeprom_update_word((uint16_t*)(EEPROM_UVLO_MESH_BED_LEVELING+2*mesh_point), *reinterpret_cast<uint16_t*>(&v));
+    }
+    // Read out the current Z motor microstep counter. This will be later used
+    // for reaching the zero full step before powering off.
+    eeprom_update_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS), z_microsteps);
+    // Store the current position.
+    eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0), current_position[X_AXIS]);
+    eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4), current_position[Y_AXIS]);
+    eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z), current_position[Z_AXIS]);
+    // Store the current feed rate, temperatures and fan speed.
+    EEPROM_save_B(EEPROM_UVLO_FEEDRATE, &feedrate_bckp);
+    eeprom_update_byte((uint8_t*)EEPROM_UVLO_TARGET_HOTEND, target_temperature[active_extruder]);
+    eeprom_update_byte((uint8_t*)EEPROM_UVLO_TARGET_BED, target_temperature_bed);
+    eeprom_update_byte((uint8_t*)EEPROM_UVLO_FAN_SPEED, fanSpeed);
+    // Finaly store the "power outage" flag.
     eeprom_update_byte((uint8_t*)EEPROM_UVLO, 1);
     eeprom_update_byte((uint8_t*)EEPROM_UVLO, 1);
-		plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 40, active_extruder);
+
+    st_synchronize();
+    SERIAL_ECHOPGM("stps");
+    MYSERIAL.println(tmc2130_rd_MSCNT(Z_TMC2130_CS));
+#if 0
     // Move the print head to the side of the print until all the power stored in the power supply capacitors is depleted.
     // Move the print head to the side of the print until all the power stored in the power supply capacitors is depleted.
     current_position[X_AXIS] = (current_position[X_AXIS] < 0.5f * (X_MIN_POS + X_MAX_POS)) ? X_MIN_POS : X_MAX_POS;
     current_position[X_AXIS] = (current_position[X_AXIS] < 0.5f * (X_MIN_POS + X_MAX_POS)) ? X_MIN_POS : X_MAX_POS;
     plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 500, active_extruder);
     plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 500, active_extruder);
     st_synchronize();
     st_synchronize();
-//    disable_z();
+#endif
+    disable_z();
 
 
 		SERIAL_ECHOLNPGM("UVLO - end");
 		SERIAL_ECHOLNPGM("UVLO - end");
 		cli();
 		cli();
@@ -6953,56 +7015,6 @@ ISR(INT4_vect) {
 	if (IS_SD_PRINTING) uvlo_();
 	if (IS_SD_PRINTING) uvlo_();
 }
 }
 
 
-#define POWERPANIC_NEW_SD_POS
-extern uint32_t sdpos_atomic;
-
-void save_print_to_eeprom() {
-	//eeprom_update_word((uint16_t*)(EPROM_UVLO_CMD_QUEUE), bufindw - bufindr );
-	//BLOCK_BUFFER_SIZE: max. 16 linear moves in planner buffer
-#define TYP_GCODE_LENGTH 30 //G1 X117.489 Y22.814 E1.46695 + cr lf
-	//card.get_sdpos() -> byte currently read from SD card
-	//bufindw -> position in circular buffer where to write
-	//bufindr -> position in circular buffer where to read
-	//bufflen -> number of lines in buffer -> for each line one special character??
-	//number_of_blocks() returns number of linear movements buffered in planner
-#ifdef POWERPANIC_NEW_SD_POS
-	long sd_position = sdpos_atomic; //atomic sd position of last command added in queue
-	uint16_t sdlen_planner = planner_calc_sd_length(); //length of sd commands in planner
-	sd_position -= sdlen_planner;
-	uint16_t sdlen_cmdqueue = cmdqueue_calc_sd_length(); //length of sd commands in cmdqueue
-	sd_position -= sdlen_cmdqueue;
-#else //POWERPANIC_NEW_SD_POS
-	long sd_position = card.get_sdpos() - ((bufindw > bufindr) ? (bufindw - bufindr) : sizeof(cmdbuffer) - bufindr + bufindw) - TYP_GCODE_LENGTH* number_of_blocks();
-#endif //POWERPANIC_NEW_SD_POS
-	if (sd_position < 0) sd_position = 0;
-	/*SERIAL_ECHOPGM("sd position before correction:");
-	MYSERIAL.println(card.get_sdpos());
-	SERIAL_ECHOPGM("bufindw:");
-	MYSERIAL.println(bufindw);
-	SERIAL_ECHOPGM("bufindr:");
-	MYSERIAL.println(bufindr);
-	SERIAL_ECHOPGM("sizeof(cmd_buffer):");
-	MYSERIAL.println(sizeof(cmdbuffer));
-	SERIAL_ECHOPGM("sd position after correction:");
-	MYSERIAL.println(sd_position);*/
-	eeprom_update_dword((uint32_t*)(EEPROM_FILE_POSITION), sd_position);
-
-  // Store the mesh bed leveling offsets. This is 2*9=18 bytes, which takes 18*3.4us=52us in worst case.
-  for (int8_t mesh_point = 0; mesh_point < 9; ++ mesh_point) {
-    uint8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1
-    uint8_t iy = mesh_point / MESH_MEAS_NUM_X_POINTS;
-    // Scale the z value to 1u resolution.
-    int16_t v = mbl.active ? int16_t(floor(mbl.z_values[iy*3][ix*3] * 1000.f + 0.5f)) : 0;
-    eeprom_update_word((uint16_t*)(EEPROM_UVLO_MESH_BED_LEVELING+2*mesh_point), *reinterpret_cast<uint16_t*>(&v));
-  }
-  SERIAL_ECHOPGM("INT4 ");
-  print_mesh_bed_leveling_table();
-
-  // Read out the current Z motor microstep counter. This will be later used
-  // for reaching the zero full step before powering off.
-  eeprom_update_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS), tmc2130_rd_MSCNT(Z_TMC2130_CS));
-}
-
 void recover_print() {
 void recover_print() {
 	char cmd[30];
 	char cmd[30];
 	lcd_update_enable(true);
 	lcd_update_enable(true);
@@ -7051,7 +7063,7 @@ void recover_machine_state_after_power_panic()
   // Recover the logical coordinate of the Z axis at the time of the power panic.
   // Recover the logical coordinate of the Z axis at the time of the power panic.
   // The current position after power panic is moved to the next closest 0th full step.
   // The current position after power panic is moved to the next closest 0th full step.
   current_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z)) + 
   current_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z)) + 
-    UVLO_Z_AXIS_SHIFT + float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS)) + 8) >> 4) / axis_steps_per_unit[Z_AXIS];
+    UVLO_Z_AXIS_SHIFT + float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS)) + 7) >> 4) / axis_steps_per_unit[Z_AXIS];
   memcpy(destination, current_position, sizeof(destination));
   memcpy(destination, current_position, sizeof(destination));
 
 
   SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial ");
   SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial ");
@@ -7357,13 +7369,8 @@ void print_mesh_bed_leveling_table()
   SERIAL_ECHOPGM("mesh bed leveling: ");
   SERIAL_ECHOPGM("mesh bed leveling: ");
   for (int8_t y = 0; y < MESH_NUM_Y_POINTS; ++ y)
   for (int8_t y = 0; y < MESH_NUM_Y_POINTS; ++ y)
     for (int8_t x = 0; x < MESH_NUM_Y_POINTS; ++ x) {
     for (int8_t x = 0; x < MESH_NUM_Y_POINTS; ++ x) {
-      SERIAL_ECHOPGM("(");
-      MYSERIAL.print(st_get_position_mm(X_AXIS), 3);
-      SERIAL_ECHOPGM(", ");
-      MYSERIAL.print(st_get_position_mm(Y_AXIS), 3);
-      SERIAL_ECHOPGM(", ");
-      MYSERIAL.print(st_get_position_mm(Z_AXIS), 3);
-      SERIAL_ECHOPGM(") ");
+      MYSERIAL.print(mbl.z_values[y][x], 3);
+      SERIAL_ECHOPGM(" ");
     }
     }
   SERIAL_ECHOLNPGM("");
   SERIAL_ECHOLNPGM("");
 }
 }

+ 111 - 51
Firmware/tmc2130.cpp

@@ -4,6 +4,10 @@
 
 
 #include "tmc2130.h"
 #include "tmc2130.h"
 #include <SPI.h>
 #include <SPI.h>
+#include "LiquidCrystal.h"
+#include "ultralcd.h"
+
+extern LiquidCrystal lcd;
 
 
 #define TMC2130_GCONF_NORMAL 0x00000000 // spreadCycle
 #define TMC2130_GCONF_NORMAL 0x00000000 // spreadCycle
 #define TMC2130_GCONF_SGSENS 0x00003180 // spreadCycle with stallguard (stall activates DIAG0 and DIAG1 [pushpull])
 #define TMC2130_GCONF_SGSENS 0x00003180 // spreadCycle with stallguard (stall activates DIAG0 and DIAG1 [pushpull])
@@ -14,6 +18,7 @@ extern float current_position[4];
 extern void st_get_position_xy(long &x, long &y);
 extern void st_get_position_xy(long &x, long &y);
 extern long st_get_position(uint8_t axis);
 extern long st_get_position(uint8_t axis);
 extern void crashdet_stop_and_save_print();
 extern void crashdet_stop_and_save_print();
+extern void crashdet_stop_and_save_print2();
 
 
 //chipselect pins
 //chipselect pins
 uint8_t tmc2130_cs[4] = { X_TMC2130_CS, Y_TMC2130_CS, Z_TMC2130_CS, E0_TMC2130_CS };
 uint8_t tmc2130_cs[4] = { X_TMC2130_CS, Y_TMC2130_CS, Z_TMC2130_CS, E0_TMC2130_CS };
@@ -44,16 +49,19 @@ uint8_t tmc2130_pwm_freq[2] = {TMC2130_PWM_FREQ_X, TMC2130_PWM_FREQ_Y};
 uint8_t tmc2130_mres[4] = {0, 0, 0, 0}; //will be filed at begin of init
 uint8_t tmc2130_mres[4] = {0, 0, 0, 0}; //will be filed at begin of init
 
 
 
 
-uint8_t tmc2130_axis_sg_thr[4] = {TMC2130_SG_THRS_X, TMC2130_SG_THRS_Y, TMC2130_SG_THRS_Z, 0};
-uint8_t tmc2130_axis_sg_thr_home[4] = {3, 3, TMC2130_SG_THRS_Z, 0};
+uint8_t tmc2130_sg_thr[4] = {TMC2130_SG_THRS_X, TMC2130_SG_THRS_Y, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E};
+uint8_t tmc2130_sg_thr_home[4] = {3, 3, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E};
 
 
-uint32_t tmc2130_axis_sg_pos[4] = {0, 0, 0, 0};
+uint32_t tmc2130_sg_pos[4] = {0, 0, 0, 0};
 
 
 uint8_t sg_homing_axes_mask = 0x00;
 uint8_t sg_homing_axes_mask = 0x00;
 
 
 bool tmc2130_sg_stop_on_crash = false;
 bool tmc2130_sg_stop_on_crash = false;
 bool tmc2130_sg_crash = false;
 bool tmc2130_sg_crash = false;
 uint8_t tmc2130_diag_mask = 0x00;
 uint8_t tmc2130_diag_mask = 0x00;
+uint16_t tmc2130_sg_err[4] = {0, 0, 0, 0};
+uint16_t tmc2130_sg_cnt[4] = {0, 0, 0, 0};
+bool tmc2130_sg_change = false;
 
 
 
 
 bool skip_debug_msg = false;
 bool skip_debug_msg = false;
@@ -134,59 +142,69 @@ void tmc2130_init()
 	SET_INPUT(Z_TMC2130_DIAG);
 	SET_INPUT(Z_TMC2130_DIAG);
 	SET_INPUT(E0_TMC2130_DIAG);
 	SET_INPUT(E0_TMC2130_DIAG);
 	SPI.begin();
 	SPI.begin();
-	for (int i = 0; i < 2; i++) // X Y axes
+	for (int axis = 0; axis < 2; axis++) // X Y axes
 	{
 	{
-/*		if (tmc2130_current_r[i] <= 31)
+/*		if (tmc2130_current_r[axis] <= 31)
 		{
 		{
-			tmc2130_wr_CHOPCONF(tmc2130_cs[i], 3, 5, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, mres, TMC2130_INTPOL_XY, 0, 0);
-			tmc2130_wr(tmc2130_cs[i], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((tmc2130_current_r[i] & 0x1f) << 8) | (tmc2130_current_h[i] & 0x1f));
+			tmc2130_wr_CHOPCONF(tmc2130_cs[axis], 3, 5, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, mres, TMC2130_INTPOL_XY, 0, 0);
+			tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((tmc2130_current_r[axis] & 0x1f) << 8) | (tmc2130_current_h[axis] & 0x1f));
 		}
 		}
 		else
 		else
 		{
 		{
-			tmc2130_wr_CHOPCONF(tmc2130_cs[i], 3, 5, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, mres, TMC2130_INTPOL_XY, 0, 0);
-			tmc2130_wr(tmc2130_cs[i], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | (((tmc2130_current_r[i] >> 1) & 0x1f) << 8) | ((tmc2130_current_h[i] >> 1) & 0x1f));
+			tmc2130_wr_CHOPCONF(tmc2130_cs[axis], 3, 5, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, mres, TMC2130_INTPOL_XY, 0, 0);
+			tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | (((tmc2130_current_r[axis] >> 1) & 0x1f) << 8) | ((tmc2130_current_h[axis] >> 1) & 0x1f));
 		}*/
 		}*/
-		tmc2130_setup_chopper(i, tmc2130_mres[i], tmc2130_current_h[i], tmc2130_current_r[i]);
-
-//		tmc2130_wr_CHOPCONF(tmc2130_cs[i], 3, 5, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, mres, TMC2130_INTPOL_XY, 0, 0);
-//		tmc2130_wr(tmc2130_cs[i], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((tmc2130_current_r[i] & 0x1f) << 8) | (tmc2130_current_h[i] & 0x1f));
-		tmc2130_wr(tmc2130_cs[i], TMC2130_REG_TPOWERDOWN, 0x00000000);
-		tmc2130_wr(tmc2130_cs[i], TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_axis_sg_thr[i]) << 16) | ((uint32_t)1 << 24));
-		tmc2130_wr(tmc2130_cs[i], TMC2130_REG_TCOOLTHRS, (tmc2130_mode == TMC2130_MODE_SILENT)?0:TMC2130_TCOOLTHRS);
-		tmc2130_wr(tmc2130_cs[i], TMC2130_REG_GCONF, (tmc2130_mode == TMC2130_MODE_SILENT)?TMC2130_GCONF_SILENT:TMC2130_GCONF_SGSENS);
-		tmc2130_wr_PWMCONF(tmc2130_cs[i], tmc2130_pwm_ampl[i], tmc2130_pwm_grad[i], tmc2130_pwm_freq[i], tmc2130_pwm_auto[i], 0, 0);
-		tmc2130_wr_TPWMTHRS(tmc2130_cs[i], TMC2130_TPWMTHRS);
-		//tmc2130_wr_THIGH(tmc2130_cs[i], TMC2130_THIGH);
+		tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
+
+//		tmc2130_wr_CHOPCONF(tmc2130_cs[axis], 3, 5, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, mres, TMC2130_INTPOL_XY, 0, 0);
+//		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((tmc2130_current_r[axis] & 0x1f) << 8) | (tmc2130_current_h[axis] & 0x1f));
+		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_TPOWERDOWN, 0x00000000);
+//		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16) | ((uint32_t)1 << 24));
+		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16));
+		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_TCOOLTHRS, (tmc2130_mode == TMC2130_MODE_SILENT)?0:((axis==X_AXIS)?TMC2130_TCOOLTHRS_X:TMC2130_TCOOLTHRS_Y));
+		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_GCONF, (tmc2130_mode == TMC2130_MODE_SILENT)?TMC2130_GCONF_SILENT:TMC2130_GCONF_SGSENS);
+		tmc2130_wr_PWMCONF(tmc2130_cs[axis], tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
+		tmc2130_wr_TPWMTHRS(tmc2130_cs[axis], TMC2130_TPWMTHRS);
+		//tmc2130_wr_THIGH(tmc2130_cs[axis], TMC2130_THIGH);
 	}
 	}
-	for (int i = 2; i < 3; i++) // Z axis
+	for (int axis = 2; axis < 3; axis++) // Z axis
 	{
 	{
 //		uint8_t mres = tmc2130_mres(TMC2130_USTEPS_Z);
 //		uint8_t mres = tmc2130_mres(TMC2130_USTEPS_Z);
-/*		if (tmc2130_current_r[i] <= 31)
+/*		if (tmc2130_current_r[axis] <= 31)
 		{
 		{
-			tmc2130_wr_CHOPCONF(tmc2130_cs[i], 3, 5, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, mres, TMC2130_INTPOL_Z, 0, 0);
-			tmc2130_wr(tmc2130_cs[i], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((tmc2130_current_r[i] & 0x1f) << 8) | (tmc2130_current_h[i] & 0x1f));
+			tmc2130_wr_CHOPCONF(tmc2130_cs[axis], 3, 5, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, mres, TMC2130_INTPOL_Z, 0, 0);
+			tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((tmc2130_current_r[axis] & 0x1f) << 8) | (tmc2130_current_h[axis] & 0x1f));
 		}
 		}
 		else
 		else
 		{
 		{
-			tmc2130_wr_CHOPCONF(tmc2130_cs[i], 3, 5, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, mres, TMC2130_INTPOL_Z, 0, 0);
-			tmc2130_wr(tmc2130_cs[i], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | (((tmc2130_current_r[i] >> 1) & 0x1f) << 8) | ((tmc2130_current_h[i] >> 1) & 0x1f));
+			tmc2130_wr_CHOPCONF(tmc2130_cs[axis], 3, 5, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, mres, TMC2130_INTPOL_Z, 0, 0);
+			tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | (((tmc2130_current_r[axis] >> 1) & 0x1f) << 8) | ((tmc2130_current_h[axis] >> 1) & 0x1f));
 		}*/
 		}*/
-		tmc2130_setup_chopper(i, tmc2130_mres[i], tmc2130_current_h[i], tmc2130_current_r[i]);
+		tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
 
 
-		tmc2130_wr(tmc2130_cs[i], TMC2130_REG_TPOWERDOWN, 0x00000000);
-		tmc2130_wr(tmc2130_cs[i], TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
+		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_TPOWERDOWN, 0x00000000);
+		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
 	}
 	}
-	for (int i = 3; i < 4; i++) // E axis
+	for (int axis = 3; axis < 4; axis++) // E axis
 	{
 	{
 //		uint8_t mres = tmc2130_mres(TMC2130_USTEPS_E);
 //		uint8_t mres = tmc2130_mres(TMC2130_USTEPS_E);
-		tmc2130_setup_chopper(i, tmc2130_mres[i], tmc2130_current_h[i], tmc2130_current_r[i]);
+		tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
 
 
-//		tmc2130_wr_CHOPCONF(tmc2130_cs[i], 3, 5, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, mres, TMC2130_INTPOL_E, 0, 0);
-//		tmc2130_wr(tmc2130_cs[i], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((tmc2130_current_r[i] & 0x1f) << 8) | (tmc2130_current_h[i] & 0x1f));
+//		tmc2130_wr_CHOPCONF(tmc2130_cs[axis], 3, 5, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, mres, TMC2130_INTPOL_E, 0, 0);
+//		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((tmc2130_current_r[axis] & 0x1f) << 8) | (tmc2130_current_h[axis] & 0x1f));
 
 
-		tmc2130_wr(tmc2130_cs[i], TMC2130_REG_TPOWERDOWN, 0x00000000);
-		tmc2130_wr(tmc2130_cs[i], TMC2130_REG_GCONF, 0x00000000);
+		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_TPOWERDOWN, 0x00000000);
+		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
 	}
 	}
+
+	tmc2130_sg_err[0] = 0;
+	tmc2130_sg_err[1] = 0;
+	tmc2130_sg_err[2] = 0;
+	tmc2130_sg_err[3] = 0;
+	tmc2130_sg_cnt[0] = 0;
+	tmc2130_sg_cnt[1] = 0;
+	tmc2130_sg_cnt[2] = 0;
+	tmc2130_sg_cnt[3] = 0;
 }
 }
 
 
 uint8_t tmc2130_sample_diag()
 uint8_t tmc2130_sample_diag()
@@ -194,29 +212,52 @@ uint8_t tmc2130_sample_diag()
 	uint8_t mask = 0;
 	uint8_t mask = 0;
 	if (READ(X_TMC2130_DIAG)) mask |= X_AXIS_MASK;
 	if (READ(X_TMC2130_DIAG)) mask |= X_AXIS_MASK;
 	if (READ(Y_TMC2130_DIAG)) mask |= Y_AXIS_MASK;
 	if (READ(Y_TMC2130_DIAG)) mask |= Y_AXIS_MASK;
-//	if (READ(Z_TMC2130_DIAG)) mask |= Z_AXIS_MASK;
-//	if (READ(E0_TMC2130_DIAG)) mask |= E_AXIS_MASK;
+	if (READ(Z_TMC2130_DIAG)) mask |= Z_AXIS_MASK;
+	if (READ(E0_TMC2130_DIAG)) mask |= E_AXIS_MASK;
 	return mask;
 	return mask;
 }
 }
 
 
 void tmc2130_st_isr(uint8_t last_step_mask)
 void tmc2130_st_isr(uint8_t last_step_mask)
 {
 {
 	if (tmc2130_mode == TMC2130_MODE_SILENT) return;
 	if (tmc2130_mode == TMC2130_MODE_SILENT) return;
-	bool error = false;
+	bool crash = false;
 	uint8_t diag_mask = tmc2130_sample_diag();
 	uint8_t diag_mask = tmc2130_sample_diag();
-	for (uint8_t axis = X_AXIS; axis <= Y_AXIS; axis++)
+	for (uint8_t axis = X_AXIS; axis <= E_AXIS; axis++)
 	{
 	{
 		uint8_t mask = (X_AXIS_MASK << axis);
 		uint8_t mask = (X_AXIS_MASK << axis);
-		if ((diag_mask & mask) && !(tmc2130_diag_mask & mask))
-			error = true;
+		if (diag_mask & mask) tmc2130_sg_err[axis]++;
+		else
+			if (tmc2130_sg_err[axis] > 0) tmc2130_sg_err[axis]--;
+		if (tmc2130_sg_cnt[axis] < tmc2130_sg_err[axis])
+		{
+			tmc2130_sg_cnt[axis] = tmc2130_sg_err[axis];
+			tmc2130_sg_change = true;
+			if (tmc2130_sg_err[axis] >= 64)
+			{
+				tmc2130_sg_err[axis] = 0;
+				crash = true;
+			}
+		}
+//		if ((diag_mask & mask)/* && !(tmc2130_diag_mask & mask)*/)
+//			crash = true;
 	}
 	}
 	tmc2130_diag_mask = diag_mask;
 	tmc2130_diag_mask = diag_mask;
 	if (sg_homing_axes_mask == 0)
 	if (sg_homing_axes_mask == 0)
-		if (tmc2130_sg_stop_on_crash && error)
+	{
+/*		if (crash)
+		{
+			if (diag_mask & 0x01) tmc2130_sg_cnt[0]++;
+			if (diag_mask & 0x02) tmc2130_sg_cnt[1]++;
+			if (diag_mask & 0x04) tmc2130_sg_cnt[2]++;
+			if (diag_mask & 0x08) tmc2130_sg_cnt[3]++;
+		}*/
+		if (tmc2130_sg_stop_on_crash && crash)
 		{
 		{
 			tmc2130_sg_crash = true;
 			tmc2130_sg_crash = true;
 			tmc2130_sg_stop_on_crash = false;
 			tmc2130_sg_stop_on_crash = false;
+			crashdet_stop_and_save_print();
 		}
 		}
+	}
 }
 }
 
 
 void tmc2130_update_sg_axis(uint8_t axis)
 void tmc2130_update_sg_axis(uint8_t axis)
@@ -225,10 +266,10 @@ void tmc2130_update_sg_axis(uint8_t axis)
 	{
 	{
 		uint8_t cs = tmc2130_cs[axis];
 		uint8_t cs = tmc2130_cs[axis];
 		uint16_t tstep = tmc2130_rd_TSTEP(cs);
 		uint16_t tstep = tmc2130_rd_TSTEP(cs);
-		if (tstep < TMC2130_TCOOLTHRS)
+		if (tstep < TMC2130_TCOOLTHRS_Z)
 		{
 		{
 			long pos = st_get_position(axis);
 			long pos = st_get_position(axis);
-			if (abs(pos - tmc2130_axis_sg_pos[axis]) > TMC2130_SG_DELTA)
+			if (abs(pos - tmc2130_sg_pos[axis]) > TMC2130_SG_DELTA)
 			{
 			{
 				uint16_t sg = tmc2130_rd_DRV_STATUS(cs) & 0x3ff;
 				uint16_t sg = tmc2130_rd_DRV_STATUS(cs) & 0x3ff;
 				if (sg == 0)
 				if (sg == 0)
@@ -240,6 +281,10 @@ void tmc2130_update_sg_axis(uint8_t axis)
 
 
 bool tmc2130_update_sg()
 bool tmc2130_update_sg()
 {
 {
+//	uint16_t tstep = tmc2130_rd_TSTEP(tmc2130_cs[0]);
+//	MYSERIAL.print("TSTEP_X=");
+//	MYSERIAL.println((int)tstep);
+	
 #ifdef TMC2130_SG_HOMING_SW_XY
 #ifdef TMC2130_SG_HOMING_SW_XY
 	if (sg_homing_axes_mask & X_AXIS_MASK) tmc2130_update_sg_axis(X_AXIS);
 	if (sg_homing_axes_mask & X_AXIS_MASK) tmc2130_update_sg_axis(X_AXIS);
 	if (sg_homing_axes_mask & Y_AXIS_MASK) tmc2130_update_sg_axis(Y_AXIS);
 	if (sg_homing_axes_mask & Y_AXIS_MASK) tmc2130_update_sg_axis(Y_AXIS);
@@ -269,7 +314,7 @@ bool tmc2130_update_sg()
 				if (tstep < TMC2130_TCOOLTHRS)
 				if (tstep < TMC2130_TCOOLTHRS)
 				{
 				{
 					long pos = st_get_position(axis);
 					long pos = st_get_position(axis);
-					if (abs(pos - tmc2130_axis_sg_pos[axis]) > TMC2130_SG_DELTA)
+					if (abs(pos - tmc2130_sg_pos[axis]) > TMC2130_SG_DELTA)
 					{
 					{
 						uint16_t sg = tmc2130_rd_DRV_STATUS(cs) & 0x3ff;
 						uint16_t sg = tmc2130_rd_DRV_STATUS(cs) & 0x3ff;
 						if (sg == 0)
 						if (sg == 0)
@@ -304,13 +349,13 @@ void tmc2130_home_enter(uint8_t axes_mask)
 		if (axes_mask & mask)
 		if (axes_mask & mask)
 		{
 		{
 			sg_homing_axes_mask |= mask;
 			sg_homing_axes_mask |= mask;
-			tmc2130_axis_sg_pos[axis] = st_get_position(axis);
+			tmc2130_sg_pos[axis] = st_get_position(axis);
 			tmc2130_axis_stalled[axis] = false;
 			tmc2130_axis_stalled[axis] = false;
 			//Configuration to spreadCycle
 			//Configuration to spreadCycle
 			tmc2130_wr(cs, TMC2130_REG_GCONF, TMC2130_GCONF_NORMAL);
 			tmc2130_wr(cs, TMC2130_REG_GCONF, TMC2130_GCONF_NORMAL);
-			tmc2130_wr(cs, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_axis_sg_thr_home[axis]) << 16));
-//			tmc2130_wr(cs, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_axis_sg_thr[axis]) << 16) | ((uint32_t)1 << 24));
-			tmc2130_wr(cs, TMC2130_REG_TCOOLTHRS, TMC2130_TCOOLTHRS);
+			tmc2130_wr(cs, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr_home[axis]) << 16));
+//			tmc2130_wr(cs, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16) | ((uint32_t)1 << 24));
+			tmc2130_wr(cs, TMC2130_REG_TCOOLTHRS, (axis==X_AXIS)?TMC2130_TCOOLTHRS_X:TMC2130_TCOOLTHRS_Y);
 			tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r_home[axis]);
 			tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r_home[axis]);
 #ifndef TMC2130_SG_HOMING_SW_XY
 #ifndef TMC2130_SG_HOMING_SW_XY
 			if (mask & (X_AXIS_MASK | Y_AXIS_MASK))
 			if (mask & (X_AXIS_MASK | Y_AXIS_MASK))
@@ -346,8 +391,11 @@ void tmc2130_home_exit()
 #ifdef TMC2130_SG_HOMING_SW_XY
 #ifdef TMC2130_SG_HOMING_SW_XY
 					tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_GCONF, TMC2130_GCONF_NORMAL);
 					tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_GCONF, TMC2130_GCONF_NORMAL);
 #else //TMC2130_SG_HOMING_SW_XY
 #else //TMC2130_SG_HOMING_SW_XY
+//					tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_GCONF, TMC2130_GCONF_NORMAL);
 					tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
 					tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
-					tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_axis_sg_thr[axis]) << 16) | ((uint32_t)1 << 24));
+//					tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16) | ((uint32_t)1 << 24));
+					tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16));
+					tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_TCOOLTHRS, (tmc2130_mode == TMC2130_MODE_SILENT)?0:((axis==X_AXIS)?TMC2130_TCOOLTHRS_X:TMC2130_TCOOLTHRS_Y));
 					tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
 					tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
 #endif //TMC2130_SG_HOMING_SW_XY
 #endif //TMC2130_SG_HOMING_SW_XY
 				}
 				}
@@ -377,7 +425,7 @@ void tmc2130_home_resume(uint8_t axis)
 
 
 void tmc2130_home_restart(uint8_t axis)
 void tmc2130_home_restart(uint8_t axis)
 {
 {
-	tmc2130_axis_sg_pos[axis] = st_get_position(axis);
+	tmc2130_sg_pos[axis] = st_get_position(axis);
 	tmc2130_axis_stalled[axis] = false;
 	tmc2130_axis_stalled[axis] = false;
 }
 }
 
 
@@ -400,8 +448,20 @@ void tmc2130_check_overtemp()
 					tmc2130_wr(tmc2130_cs[j], TMC2130_REG_CHOPCONF, 0x00010000);
 					tmc2130_wr(tmc2130_cs[j], TMC2130_REG_CHOPCONF, 0x00010000);
 				kill(TMC_OVERTEMP_MSG);
 				kill(TMC_OVERTEMP_MSG);
 			}
 			}
+
 		}
 		}
 		checktime = millis();
 		checktime = millis();
+		tmc2130_sg_change = true;
+	}
+	if (tmc2130_sg_change)
+	{
+		for (int i = 0; i < 4; i++)
+		{
+			tmc2130_sg_change = false;
+			lcd.setCursor(0 + i*4, 3);
+			lcd.print(itostr3(tmc2130_sg_cnt[i]));
+			lcd.print(' ');
+		}
 	}
 	}
 }
 }
 
 

+ 1 - 1
Firmware/tmc2130.h

@@ -11,7 +11,7 @@ extern uint8_t tmc2130_current_r[4];
 //flags for axis stall detection
 //flags for axis stall detection
 extern uint8_t tmc2130_axis_stalled[4];
 extern uint8_t tmc2130_axis_stalled[4];
 
 
-extern uint8_t tmc2130_axis_sg_thr[4];
+extern uint8_t tmc2130_sg_thr[4];
 
 
 extern bool tmc2130_sg_stop_on_crash;
 extern bool tmc2130_sg_stop_on_crash;
 extern bool tmc2130_sg_crash;
 extern bool tmc2130_sg_crash;

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

@@ -62,7 +62,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 #define Z_PAUSE_LIFT 20
 #define Z_PAUSE_LIFT 20
 
 
 #define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
 #define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
-#define HOMING_FEEDRATE {3000, 3000, 800, 0}  // set the homing speeds (mm/min) // 3000 is also valid for stallGuard homing. Valid range: 2200 - 3000
+#define HOMING_FEEDRATE {2500, 3000, 800, 0}  // set the homing speeds (mm/min) // 3000 is also valid for stallGuard homing. Valid range: 2200 - 3000
 
 
 //#define DEFAULT_MAX_FEEDRATE          {400, 400, 12, 120}    // (mm/sec)
 //#define DEFAULT_MAX_FEEDRATE          {400, 400, 12, 120}    // (mm/sec)
 #define DEFAULT_MAX_FEEDRATE          {500, 500, 12, 120}    // (mm/sec)
 #define DEFAULT_MAX_FEEDRATE          {500, 500, 12, 120}    // (mm/sec)