Переглянути джерело

Merge branch 'MK3' into MK3_fast_dbg

bubnikv 7 роки тому
батько
коміт
9652cf2d5b

+ 51 - 24
Firmware/Configuration.h

@@ -7,18 +7,32 @@
 #define STR(x) STR_HELPER(x)
 
 // Firmware version
-#define FW_VERSION "3.1.1-RC5"
-#define FW_COMMIT_NR   150
-#define FW_DEV_VERSION FW_VERSION_DEBUG
+#define FW_VERSION "3.1.1"
+#define FW_COMMIT_NR   197
+// FW_VERSION_UNKNOWN means this is an unofficial build.
+// The firmware should only be checked into github with this symbol.
+#define FW_DEV_VERSION FW_VERSION_UNKNOWN
 #define FW_REPOSITORY "Prusa3D/MK3"
 #define FW_VERSION_FULL FW_VERSION "-" STR(FW_COMMIT_NR)
 
-#define FW_VERSION_DEBUG 5
-#define FW_VERSION_UNKNOWN 4
-#define FW_VERSION_ALPHA 3
-#define FW_VERSION_BETA 2
-#define FW_VERSION_RC 1
-#define FW_VERSION_GOLD 0
+// Debug version has debugging enabled (the symbol DEBUG_BUILD is set).
+// The debug build may be a bit slower than the non-debug build, therefore the debug build should
+// not be shipped to a customer.
+#define FW_VERSION_DEBUG    6
+// This is a development build. A development build is either built from an unofficial git repository, 
+// or from an unofficial branch, or it does not have a label set. Only the build server should set this build type.
+#define FW_VERSION_DEVEL    5
+// This is an alpha release. Only the build server should set this build type.
+#define FW_VERSION_ALPHA    4
+// This is a beta release. Only the build server should set this build type.
+#define FW_VERSION_BETA     3
+// This is a release candidate build. Only the build server should set this build type.
+#define FW_VERSION_RC       2
+// This is a final release. Only the build server should set this build type.
+#define FW_VERSION_GOLD     1
+// This is an unofficial build. The firmware should only be checked into github with this symbol,
+// the build server shall never produce builds with this build type.
+#define FW_VERSION_UNKNOWN  0
 
 #if FW_DEV_VERSION == FW_VERSION_DEBUG
 #define DEBUG_BUILD
@@ -79,25 +93,28 @@
 #define EEPROM_UVLO_FAN_SPEED			(EEPROM_UVLO_FEEDRATE - 1) 
 #define EEPROM_FAN_CHECK_ENABLED		(EEPROM_UVLO_FAN_SPEED - 1)
 #define EEPROM_UVLO_MESH_BED_LEVELING     (EEPROM_FAN_CHECK_ENABLED - 9*2)
+
 #define EEPROM_UVLO_Z_MICROSTEPS     (EEPROM_UVLO_MESH_BED_LEVELING - 2)
 #define EEPROM_UVLO_E_ABS            (EEPROM_UVLO_Z_MICROSTEPS - 1)
-#define EEPROM_UVLO_CURRENT_POSITION_E	(EEPROM_UVLO_E_ABS - 4) //float for current position in E
+#define EEPROM_UVLO_CURRENT_POSITION_E	(EEPROM_UVLO_E_ABS - 4)                 //float for current position in E
 
 // Crash detection mode EEPROM setting 
-#define EEPROM_CRASH_DET       (EEPROM_UVLO_MESH_BED_LEVELING-12) 
+#define EEPROM_CRASH_DET         (EEPROM_UVLO_CURRENT_POSITION_E - 5)           // float (orig EEPROM_UVLO_MESH_BED_LEVELING-12) 
+// Crash detection counter Y (last print)
+#define EEPROM_CRASH_COUNT_Y       (EEPROM_CRASH_DET - 1)                       // uint8 (orig EEPROM_UVLO_MESH_BED_LEVELING-15)
 // Filament sensor on/off EEPROM setting 
-#define EEPROM_FSENSOR       (EEPROM_UVLO_MESH_BED_LEVELING-14) 
-// Crash detection counter
-#define EEPROM_CRASH_COUNT       (EEPROM_UVLO_MESH_BED_LEVELING-15)
-// Filament runout/error coutner
-#define EEPROM_FERROR_COUNT      (EEPROM_UVLO_MESH_BED_LEVELING-16)
-// Power loss errors
-#define EEPROM_POWER_COUNT       (EEPROM_UVLO_MESH_BED_LEVELING-17)
-
-#define EEPROM_XYZ_CAL_SKEW (EEPROM_POWER_COUNT - 4) //float for skew backup
+#define EEPROM_FSENSOR           (EEPROM_CRASH_COUNT_Y - 1)                     // uint8 (orig EEPROM_UVLO_MESH_BED_LEVELING-14) 
+// Crash detection counter X (last print)
+#define EEPROM_CRASH_COUNT_X       (EEPROM_FSENSOR - 1)                         // uint8 (orig EEPROM_UVLO_MESH_BED_LEVELING-15)
+// Filament runout/error coutner (last print)
+#define EEPROM_FERROR_COUNT      (EEPROM_CRASH_COUNT_X - 1)                     // uint8 (orig EEPROM_UVLO_MESH_BED_LEVELING-16)
+// Power loss errors (last print)
+#define EEPROM_POWER_COUNT       (EEPROM_FERROR_COUNT - 1)                      // uint8 (orig EEPROM_UVLO_MESH_BED_LEVELING-17)
+
+#define EEPROM_XYZ_CAL_SKEW (EEPROM_POWER_COUNT - 4)                            // float for skew backup
 #define EEPROM_WIZARD_ACTIVE (EEPROM_XYZ_CAL_SKEW - 1)
-#define EEPROM_BELTSTATUS_X (EEPROM_WIZARD_ACTIVE - 2) //uint16
-#define EEPROM_BELTSTATUS_Y (EEPROM_BELTSTATUS_X - 2) //uint16
+#define EEPROM_BELTSTATUS_X (EEPROM_WIZARD_ACTIVE - 2)                          // uint16
+#define EEPROM_BELTSTATUS_Y (EEPROM_BELTSTATUS_X - 2)                           // uint16
 
 #define EEPROM_DIR_DEPTH        (EEPROM_BELTSTATUS_Y-1)
 #define EEPROM_DIRS  (EEPROM_DIR_DEPTH-80) //8 chars for each dir name, max 10 levels
@@ -106,6 +123,16 @@
 
 #define EEPROM_FSENS_AUTOLOAD_ENABLED (EEPROM_SECOND_SERIAL_ACTIVE - 1)
 
+// Crash detection counter X (total)
+#define EEPROM_CRASH_COUNT_X_TOT       (EEPROM_FSENS_AUTOLOAD_ENABLED - 2)     // uint16
+// Crash detection counter Y (total)
+#define EEPROM_CRASH_COUNT_Y_TOT       (EEPROM_CRASH_COUNT_X_TOT - 2)          // uint16
+// Filament runout/error coutner (total)
+#define EEPROM_FERROR_COUNT_TOT      (EEPROM_CRASH_COUNT_Y_TOT - 2)            // uint16
+// Power loss errors (total)
+#define EEPROM_POWER_COUNT_TOT       (EEPROM_FERROR_COUNT_TOT - 2)             // uint16
+
+
 //TMC2130 configuration
 #define EEPROM_TMC_AXIS_SIZE  //axis configuration block size
 #define EEPROM_TMC_X (EEPROM_TMC + 0 * EEPROM_TMC_AXIS_SIZE) //X axis configuration blok
@@ -557,8 +584,8 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 #define SDSUPPORT // Enable SD Card Support in Hardware Console
 //#define SDSLOW // Use slower SD transfer mode (not normally needed - uncomment if you're getting volume init error)
 #define SD_CHECK_AND_RETRY // Use CRC checks and retries on the SD communication
-#define ENCODER_PULSES_PER_STEP 2 // Increase if you have a high resolution encoder
-#define ENCODER_STEPS_PER_MENU_ITEM 2 // Set according to ENCODER_PULSES_PER_STEP or your liking
+#define ENCODER_PULSES_PER_STEP 4 // Increase if you have a high resolution encoder
+#define ENCODER_STEPS_PER_MENU_ITEM 1 // Set according to ENCODER_PULSES_PER_STEP or your liking
 //#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store.
 //#define ULTIPANEL  //the UltiPanel as on Thingiverse
 //#define LCD_FEEDBACK_FREQUENCY_HZ 1000	// this is the tone frequency the buzzer plays when on UI feedback. ie Screen Click

+ 11 - 2
Firmware/ConfigurationStore.cpp

@@ -47,7 +47,7 @@ void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size)
 // wrong data being written to the variables.
 // ALSO:  always make sure the variables in the Store and retrieve sections are in the same order.
 
-#define EEPROM_VERSION "V1"
+#define EEPROM_VERSION "V2"
 
 #ifdef EEPROM_SETTINGS
 void Config_StoreSettings(uint16_t offset, uint8_t level) 
@@ -285,9 +285,10 @@ void Config_PrintSettings(uint8_t level)
 
 
 #ifdef EEPROM_SETTINGS
-void Config_RetrieveSettings(uint16_t offset, uint8_t level)
+bool Config_RetrieveSettings(uint16_t offset, uint8_t level)
 {
     int i=offset;
+	bool previous_settings_retrieved = true;
     char stored_ver[4];
     char ver[4]=EEPROM_VERSION;
     EEPROM_READ_VAR(i,stored_ver); //read stored version
@@ -386,10 +387,18 @@ void Config_RetrieveSettings(uint16_t offset, uint8_t level)
     else
     {
         Config_ResetDefault();
+		//Return false to inform user that eeprom version was changed and firmware is using default hardcoded settings now.
+		//In case that storing to eeprom was not used yet, do not inform user that hardcoded settings are used.
+		if (eeprom_read_byte((uint8_t *)offset) != 0xFF ||
+			eeprom_read_byte((uint8_t *)offset + 1) != 0xFF ||
+			eeprom_read_byte((uint8_t *)offset + 2) != 0xFF) {
+			previous_settings_retrieved = false;
+		}
     }
     #ifdef EEPROM_CHITCHAT
       Config_PrintSettings();
     #endif
+	return previous_settings_retrieved;
 }
 #endif
 

+ 1 - 1
Firmware/ConfigurationStore.h

@@ -14,7 +14,7 @@ FORCE_INLINE void Config_PrintSettings() {}
 
 #ifdef EEPROM_SETTINGS
 void Config_StoreSettings(uint16_t offset, uint8_t level = 0);
-void Config_RetrieveSettings(uint16_t offset, uint8_t level = 0);
+bool Config_RetrieveSettings(uint16_t offset, uint8_t level = 0);
 #else
 FORCE_INLINE void Config_StoreSettings() {}
 FORCE_INLINE void Config_RetrieveSettings() { Config_ResetDefault(); Config_PrintSettings(); }

+ 26 - 13
Firmware/Configuration_prusa.h

@@ -32,8 +32,8 @@
 
 // Steps per unit {X,Y,Z,E}
 //#define DEFAULT_AXIS_STEPS_PER_UNIT   {100,100,3200/8,140}
-//#define DEFAULT_AXIS_STEPS_PER_UNIT   {100,100,3200/8,280}
-#define DEFAULT_AXIS_STEPS_PER_UNIT   {100,100,3200/8,560}
+#define DEFAULT_AXIS_STEPS_PER_UNIT   {100,100,3200/8,280}
+//#define DEFAULT_AXIS_STEPS_PER_UNIT   {100,100,3200/8,560}
 
 // Endstop inverting
 const bool X_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
@@ -104,7 +104,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 #define MINTEMP_MINAMBIENT      25
 #define MINTEMP_MINAMBIENT_RAW  978
 
-
+//#define DEBUG_BUILD
 #ifdef DEBUG_BUILD
 //#define _NO_ASM
 #define DEBUG_DCODES //D codes
@@ -130,7 +130,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 //#define DEBUG_BLINK_ACTIVE
 //#define DEBUG_DISABLE_FANCHECK     //disable fan check (no ISR INT7, check disabled)
 //#define DEBUG_DISABLE_FSENSORCHECK //disable fsensor check (no ISR INT7, check disabled)
-#define DEBUG_DUMP_TO_2ND_SERIAL   //dump received characters to 2nd serial line
+//#define DEBUG_DUMP_TO_2ND_SERIAL   //dump received characters to 2nd serial line
 #define DEBUG_STEPPER_TIMER_MISSED // Stop on stepper timer overflow, beep and display a message.
 #define PLANNER_DIAGNOSTICS // Show the planner queue status on printer display.
 #endif /* DEBUG_BUILD */
@@ -144,7 +144,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 
 #define TMC2130_USTEPS_XY   16        // microstep resolution for XY axes
 #define TMC2130_USTEPS_Z    16        // microstep resolution for Z axis
-#define TMC2130_USTEPS_E    64        // microstep resolution for E axis
+#define TMC2130_USTEPS_E    32        // microstep resolution for E axis
 #define TMC2130_INTPOL_XY   1         // extrapolate 256 for XY axes
 #define TMC2130_INTPOL_Z    1         // extrapolate 256 for Z axis
 #define TMC2130_INTPOL_E    1         // extrapolate 256 for E axis
@@ -159,16 +159,28 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 #define TMC2130_PWM_AUTO_Y  1         // PWMCONF
 #define TMC2130_PWM_FREQ_Y  2         // PWMCONF
 
-/* //not used
+#define TMC2130_PWM_GRAD_E  2         // PWMCONF
+#define TMC2130_PWM_AMPL_E  235       // PWMCONF
+#define TMC2130_PWM_AUTO_E  1         // PWMCONF
+#define TMC2130_PWM_FREQ_E  2         // PWMCONF
+
 #define TMC2130_PWM_GRAD_Z  4         // PWMCONF
 #define TMC2130_PWM_AMPL_Z  200       // PWMCONF
 #define TMC2130_PWM_AUTO_Z  1         // PWMCONF
 #define TMC2130_PWM_FREQ_Z  2         // PWMCONF
+
 #define TMC2130_PWM_GRAD_E  4         // PWMCONF
-#define TMC2130_PWM_AMPL_E  200       // PWMCONF
+#define TMC2130_PWM_AMPL_E  240       // PWMCONF
 #define TMC2130_PWM_AUTO_E  1         // PWMCONF
 #define TMC2130_PWM_FREQ_E  2         // PWMCONF
-*/
+
+#define TMC2130_TOFF_XYZ    3         // CHOPCONF // fchop = 27.778kHz
+#define TMC2130_TOFF_E      3         // CHOPCONF // fchop = 27.778kHz
+//#define TMC2130_TOFF_E      4         // CHOPCONF // fchop = 21.429kHz
+//#define TMC2130_TOFF_E      5         // CHOPCONF // fchop = 17.442kHz
+
+//#define TMC2130_STEALTH_E // Extruder stealthChop mode
+//#define TMC2130_CNSTOFF_E // Extruder constant-off-time mode (similar to MK2)
 
 //#define TMC2130_PWM_DIV   683         // PWM frequency divider (1024, 683, 512, 410)
 #define TMC2130_PWM_DIV   512         // PWM frequency divider (1024, 683, 512, 410)
@@ -193,6 +205,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 //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 {13, 20, 25, 35}  // default holding currents for all axes
 #define TMC2130_CURRENTS_R {13, 20, 25, 35}  // default running currents for all axes
+#define TMC2130_UNLOAD_CURRENT_R 12			 // lowe current for M600 to protect filament sensor 
 
 //#define TMC2130_DEBUG
 //#define TMC2130_DEBUG_WR
@@ -322,8 +335,8 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
  PAT9125 SETTINGS
  *------------------------------------*/
 
-#define PAT9125_XRES			200
-#define PAT9125_YRES			200
+#define PAT9125_XRES			0
+#define PAT9125_YRES			255
 
 /*------------------------------------
  BED SETTINGS
@@ -430,11 +443,11 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 #define PP_PREHEAT_HPB_TEMP 100
 #define PP_PREHEAT_FAN_SPEED 0
 
-#define PET_PREHEAT_HOTEND_TEMP 240
-#define PET_PREHEAT_HPB_TEMP 90
+#define PET_PREHEAT_HOTEND_TEMP 230
+#define PET_PREHEAT_HPB_TEMP 85
 #define PET_PREHEAT_FAN_SPEED 0
 
-#define FLEX_PREHEAT_HOTEND_TEMP 230
+#define FLEX_PREHEAT_HOTEND_TEMP 240
 #define FLEX_PREHEAT_HPB_TEMP 50
 #define FLEX_PREHEAT_FAN_SPEED 0
 

+ 5 - 2
Firmware/Dcodes.cpp

@@ -449,7 +449,7 @@ void dcode_10()
 void dcode_12()
 {//Reset Filament error, Power loss and crash counter ( Do it before every print and you can get stats for the print )
 	LOG("D12 - Reset failstat counters\n");
-    eeprom_update_byte((uint8_t*)EEPROM_CRASH_COUNT, 0x00);
+    eeprom_update_byte((uint8_t*)EEPROM_CRASH_COUNT_X, 0x00);
     eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, 0x00);
     eeprom_update_byte((uint8_t*)EEPROM_POWER_COUNT, 0x00);
 }
@@ -491,7 +491,8 @@ void dcode_9125()
 	LOG("D9125 - PAT9125\n");
 	if ((strchr_pointer[1+4] == '?') || (strchr_pointer[1+4] == 0))
 	{
-		printf("res_x=%d res_y=%d x=%d y=%d b=%d s=%d\n", pat9125_xres, pat9125_yres, pat9125_x, pat9125_y, pat9125_b, pat9125_s);
+//		printf("res_x=%d res_y=%d x=%d y=%d b=%d s=%d\n", pat9125_xres, pat9125_yres, pat9125_x, pat9125_y, pat9125_b, pat9125_s);
+		printf("x=%d y=%d b=%d s=%d\n", pat9125_x, pat9125_y, pat9125_b, pat9125_s);
 		return;
 	}
 	if (strchr_pointer[1+4] == '!')
@@ -500,11 +501,13 @@ void dcode_9125()
 		printf("x=%d y=%d b=%d s=%d\n", pat9125_x, pat9125_y, pat9125_b, pat9125_s);
 		return;
 	}
+/*
 	if (code_seen('R'))
 	{
 		unsigned char res = (int)code_value();
 		LOG("pat9125_init(xres=yres=%d)=%d\n", res, pat9125_init(res, res));
 	}
+*/
 	if (code_seen('X'))
 	{
 		pat9125_x = (int)code_value();

+ 0 - 7
Firmware/MarlinSerial.cpp

@@ -99,13 +99,6 @@ ISR(USART1_RX_vect)
 #endif
 #endif
 
-// Constructors ////////////////////////////////////////////////////////////////
-
-MarlinSerial::MarlinSerial()
-{
-
-}
-
 // Public Methods //////////////////////////////////////////////////////////////
 
 void MarlinSerial::begin(long baud)

+ 33 - 34
Firmware/MarlinSerial.h

@@ -90,14 +90,13 @@ class MarlinSerial //: public Stream
 {
 
   public:
-    MarlinSerial();
-    void begin(long);
-    void end();
-    int peek(void);
-    int read(void);
-    void flush(void);
+    static void begin(long);
+    static void end();
+    static int peek(void);
+    static int read(void);
+    static void flush(void);
     
-    FORCE_INLINE int available(void)
+    static FORCE_INLINE int available(void)
     {
       return (unsigned int)(RX_BUFFER_SIZE + rx_buffer.head - rx_buffer.tail) % RX_BUFFER_SIZE;
     }
@@ -110,7 +109,7 @@ class MarlinSerial //: public Stream
       M_UDRx = c;
     }
     */
-	void write(uint8_t c)
+	static void write(uint8_t c)
 	{
 		if (selectedSerialPort == 0)
 		{
@@ -124,7 +123,7 @@ class MarlinSerial //: public Stream
 		}
 	}
     
-    void checkRx(void)
+    static void checkRx(void)
     {
         if (selectedSerialPort == 0) {
             if((M_UCSRxA & (1<<M_RXCx)) != 0) {
@@ -150,7 +149,7 @@ class MarlinSerial //: public Stream
 #endif //DEBUG_DUMP_TO_2ND_SERIAL
                 }
             }
-        } else if(selectedSerialPort == 1) {
+        } else { // if(selectedSerialPort == 1) {
             if((UCSR1A & (1<<RXC1)) != 0) {
                 // Test for a framing error.
                 if (UCSR1A & (1<<FE1)) {
@@ -179,54 +178,54 @@ class MarlinSerial //: public Stream
     
     
     private:
-    void printNumber(unsigned long, uint8_t);
-    void printFloat(double, uint8_t);
+    static void printNumber(unsigned long, uint8_t);
+    static void printFloat(double, uint8_t);
     
     
   public:
     
-    FORCE_INLINE void write(const char *str)
+    static FORCE_INLINE void write(const char *str)
     {
       while (*str)
         write(*str++);
     }
 
 
-    FORCE_INLINE void write(const uint8_t *buffer, size_t size)
+    static FORCE_INLINE void write(const uint8_t *buffer, size_t size)
     {
       while (size--)
         write(*buffer++);
     }
 
-    FORCE_INLINE void print(const String &s)
+    static FORCE_INLINE void print(const String &s)
     {
       for (int i = 0; i < (int)s.length(); i++) {
         write(s[i]);
       }
     }
     
-    FORCE_INLINE void print(const char *str)
+    static FORCE_INLINE void print(const char *str)
     {
       write(str);
     }
-    void print(char, int = BYTE);
-    void print(unsigned char, int = BYTE);
-    void print(int, int = DEC);
-    void print(unsigned int, int = DEC);
-    void print(long, int = DEC);
-    void print(unsigned long, int = DEC);
-    void print(double, int = 2);
-
-    void println(const String &s);
-    void println(const char[]);
-    void println(char, int = BYTE);
-    void println(unsigned char, int = BYTE);
-    void println(int, int = DEC);
-    void println(unsigned int, int = DEC);
-    void println(long, int = DEC);
-    void println(unsigned long, int = DEC);
-    void println(double, int = 2);
-    void println(void);
+    static void print(char, int = BYTE);
+    static void print(unsigned char, int = BYTE);
+    static void print(int, int = DEC);
+    static void print(unsigned int, int = DEC);
+    static void print(long, int = DEC);
+    static void print(unsigned long, int = DEC);
+    static void print(double, int = 2);
+
+    static void println(const String &s);
+    static void println(const char[]);
+    static void println(char, int = BYTE);
+    static void println(unsigned char, int = BYTE);
+    static void println(int, int = DEC);
+    static void println(unsigned int, int = DEC);
+    static void println(long, int = DEC);
+    static void println(unsigned long, int = DEC);
+    static void println(double, int = 2);
+    static void println(void);
 };
 
 extern MarlinSerial MSerial;

+ 85 - 46
Firmware/Marlin_main.cpp

@@ -604,7 +604,7 @@ void crashdet_disable()
 {
 //	MYSERIAL.println("crashdet_disable"); 
 	tmc2130_sg_stop_on_crash = false;
-	tmc2130_sg_crash = false;
+	tmc2130_sg_crash = 0;
 	eeprom_update_byte((uint8_t*)EEPROM_CRASH_DET, 0x00); 
 	CrashDetectMenu = 0;
 }
@@ -633,7 +633,7 @@ void crashdet_stop_and_save_print2()
 	sei();
 }
 
-void crashdet_detected()
+void crashdet_detected(uint8_t mask)
 {
 //	printf("CRASH_DETECTED");
 /*	while (!is_buffer_empty())
@@ -646,11 +646,17 @@ void crashdet_detected()
 	lcd_update_enable(true);
 	lcd_implementation_clear();
 	lcd_update(2);
-    
-    // Increment crash counter
-    uint8_t crash_count = eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT);
-    crash_count++;
-    eeprom_update_byte((uint8_t*)EEPROM_CRASH_COUNT, crash_count);
+
+	if (mask & X_AXIS_MASK)
+	{
+		eeprom_update_byte((uint8_t*)EEPROM_CRASH_COUNT_X, eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_X) + 1);
+		eeprom_update_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT, eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT) + 1);
+	}
+	if (mask & Y_AXIS_MASK)
+	{
+		eeprom_update_byte((uint8_t*)EEPROM_CRASH_COUNT_Y, eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_Y) + 1);
+		eeprom_update_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT, eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT) + 1);
+	}
     
 #ifdef AUTOMATIC_RECOVERY_AFTER_CRASH
     bool yesno = true;
@@ -662,8 +668,7 @@ void crashdet_detected()
 	lcd_setstatuspgm(MSG_CRASH_DETECTED);
 	if (yesno)
 	{
-		enquecommand_P(PSTR("G28 X"));
-		enquecommand_P(PSTR("G28 Y"));
+		enquecommand_P(PSTR("G28 X Y"));
 		enquecommand_P(PSTR("CRASH_RECOVER"));
 	}
 	else
@@ -685,6 +690,13 @@ void crashdet_cancel()
 	tmc2130_sg_stop_on_crash = true;
 }
 
+void failstats_reset_print()
+{
+	eeprom_update_byte((uint8_t *)EEPROM_CRASH_COUNT_X, 0);
+	eeprom_update_byte((uint8_t *)EEPROM_CRASH_COUNT_Y, 0);
+	eeprom_update_byte((uint8_t *)EEPROM_FERROR_COUNT, 0);
+	eeprom_update_byte((uint8_t *)EEPROM_POWER_COUNT, 0);
+}
 
 
 #ifdef MESH_BED_LEVELING
@@ -720,10 +732,16 @@ void factory_reset(char level, bool quiet)
 			eeprom_update_dword((uint32_t *)EEPROM_TOTALTIME, 0);
 			eeprom_update_dword((uint32_t *)EEPROM_FILAMENTUSED, 0);
 
-			eeprom_update_byte((uint8_t *)EEPROM_POWER_COUNT, 0);
-			eeprom_update_byte((uint8_t *)EEPROM_CRASH_COUNT, 0);
+			eeprom_update_byte((uint8_t *)EEPROM_CRASH_COUNT_X, 0);
+			eeprom_update_byte((uint8_t *)EEPROM_CRASH_COUNT_Y, 0);
 			eeprom_update_byte((uint8_t *)EEPROM_FERROR_COUNT, 0);
-			
+			eeprom_update_byte((uint8_t *)EEPROM_POWER_COUNT, 0);
+
+			eeprom_update_word((uint16_t *)EEPROM_CRASH_COUNT_X_TOT, 0);
+			eeprom_update_word((uint16_t *)EEPROM_CRASH_COUNT_Y_TOT, 0);
+			eeprom_update_word((uint16_t *)EEPROM_FERROR_COUNT_TOT, 0);
+			eeprom_update_word((uint16_t *)EEPROM_POWER_COUNT_TOT, 0);
+
 			lcd_menu_statistics();
             
 			break;
@@ -891,21 +909,21 @@ void factory_reset()
 void show_fw_version_warnings() {
 	if (FW_DEV_VERSION == FW_VERSION_GOLD || FW_DEV_VERSION == FW_VERSION_RC) return;
 	switch (FW_DEV_VERSION) {
-	case(FW_VERSION_ALPHA): lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_ALPHA); break;
-	case(FW_VERSION_BETA): lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_BETA); break;
-	case(FW_VERSION_RC): lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_RC); break;
-	case(FW_VERSION_DEBUG): 
-#if 1
+	case(FW_VERSION_ALPHA):   lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_ALPHA);   break;
+	case(FW_VERSION_BETA):    lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_BETA);    break;
+  case(FW_VERSION_DEVEL):
+	case(FW_VERSION_DEBUG):
     lcd_update_enable(false);
     lcd_implementation_clear();
+  #if FW_DEV_VERSION == FW_VERSION_DEVEL
+    lcd_print_at_PGM(0, 0, PSTR("Development build !!"));
+  #else
     lcd_print_at_PGM(0, 0, PSTR("Debbugging build !!!"));
+  #endif
     lcd_print_at_PGM(0, 1, PSTR("May destroy printer!"));
     lcd_print_at_PGM(0, 2, PSTR("ver ")); lcd_printPGM(PSTR(FW_VERSION_FULL));
     lcd_print_at_PGM(0, 3, PSTR(FW_REPOSITORY));
     lcd_wait_for_click();
-#else
-    lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_DEBUG);
-#endif
     break;
 	default: lcd_show_fullscreen_message_and_wait_P(MSG_FW_VERSION_UNKNOWN); break;
 	}
@@ -992,7 +1010,7 @@ void setup()
 	SERIAL_ECHOLN((int)sizeof(block_t)*BLOCK_BUFFER_SIZE);
 	//lcd_update_enable(false); // why do we need this?? - andre
 	// loads data from EEPROM if available else uses defaults (and resets step acceleration rate)
-	Config_RetrieveSettings(EEPROM_OFFSET);
+	bool previous_settings_retrieved = Config_RetrieveSettings(EEPROM_OFFSET);
 	SdFatUtil::set_stack_guard(); //writes magic number at the end of static variables to protect against overwriting static memory by stack
 
 	tp_init();    // Initialize temperature loop
@@ -1092,12 +1110,14 @@ void setup()
 	// Force SD card update. Otherwise the SD card update is done from loop() on card.checkautostart(false), 
 	// but this times out if a blocking dialog is shown in setup().
 	card.initsd();
-	if (eeprom_read_byte((uint8_t*)EEPROM_POWER_COUNT) == 0xff)
-		eeprom_write_byte((uint8_t*)EEPROM_POWER_COUNT, 0);
-	if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT) == 0xff)
-		eeprom_write_byte((uint8_t*)EEPROM_CRASH_COUNT, 0);
-	if (eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) == 0xff)
-		eeprom_write_byte((uint8_t*)EEPROM_FERROR_COUNT, 0);
+	if (eeprom_read_byte((uint8_t*)EEPROM_POWER_COUNT) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_POWER_COUNT, 0);
+	if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_X) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_CRASH_COUNT_X, 0);
+	if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_Y) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_CRASH_COUNT_Y, 0);
+	if (eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) == 0xff) eeprom_write_byte((uint8_t*)EEPROM_FERROR_COUNT, 0);
+	if (eeprom_read_word((uint16_t*)EEPROM_POWER_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_POWER_COUNT_TOT, 0);
+	if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT, 0);
+	if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT, 0);
+	if (eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, 0);
 #ifdef SNMM
 	if (eeprom_read_dword((uint32_t*)EEPROM_BOWDEN_LENGTH) == 0x0ffffffff) { //bowden length used for SNMM
 	  int _z = BOWDEN_LENGTH;
@@ -1152,6 +1172,8 @@ void setup()
 
   show_fw_version_warnings();
 
+  if (!previous_settings_retrieved) lcd_show_fullscreen_message_and_wait_P(MSG_DEFAULT_SETTINGS_LOADED); //if EEPROM version was changed, inform user that default setting were loaded
+
   if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE) == 1) {
 	  lcd_wizard(0);
   }
@@ -1231,7 +1253,7 @@ void setup()
 
 #ifdef PAT9125
 void fsensor_init() {
-	int pat9125 = pat9125_init(PAT9125_XRES, PAT9125_YRES);
+	int pat9125 = pat9125_init();
 	printf_P(PSTR("PAT9125_init:%d\n"), pat9125);
 	uint8_t fsensor = eeprom_read_byte((uint8_t*)EEPROM_FSENSOR);
 	if (!pat9125)
@@ -1474,9 +1496,15 @@ void loop()
 	tmc2130_check_overtemp();
 	if (tmc2130_sg_crash)
 	{
-		tmc2130_sg_crash = false;
+		uint8_t crash = tmc2130_sg_crash;
+		tmc2130_sg_crash = 0;
 //		crashdet_stop_and_save_print();
-		enquecommand_P((PSTR("CRASH_DETECTED")));
+		switch (crash)
+		{
+		case 1: enquecommand_P((PSTR("CRASH_DETECTEDX"))); break;
+		case 2: enquecommand_P((PSTR("CRASH_DETECTEDY"))); break;
+		case 3: enquecommand_P((PSTR("CRASH_DETECTEDXY"))); break;
+		}
 	}
 #endif //TMC2130
 
@@ -2277,7 +2305,12 @@ void process_commands()
   }
 
   else if(code_seen("CRASH_DETECTED"))
-	  crashdet_detected();
+  {
+	  uint8_t mask = 0;
+	  if (code_seen("X")) mask |= X_AXIS_MASK;
+	  if (code_seen("Y")) mask |= Y_AXIS_MASK;
+	  crashdet_detected(mask);
+  }
   else if(code_seen("CRASH_RECOVER"))
 	  crashdet_recover();
   else if(code_seen("CRASH_CANCEL"))
@@ -3109,6 +3142,9 @@ void process_commands()
 #ifdef PINDA_THERMISTOR
 		if (true)
 		{
+			lcd_show_fullscreen_message_and_wait_P(MSG_TEMP_CAL_WARNING);
+			bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_STEEL_SHEET_CHECK, false, false);
+			if(result) lcd_show_fullscreen_message_and_wait_P(MSG_REMOVE_STEEL_SHEET);
 			if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) {
 				// We don't know where we are! HOME!
 				// Push the commands to the front of the message queue in the reverse order!
@@ -3852,13 +3888,8 @@ void process_commands()
 		eeprom_update_byte((unsigned char *)EEPROM_FARM_MODE, farm_mode);
 		lcd_update(2);
 		break;
-
-
-
-
-
-
-
+	default:
+		printf_P(PSTR("Unknown G code: %s \n"), cmdbuffer + bufindr + CMDHDRSIZE);
     }
   } // end if(code_seen('G'))
 
@@ -3869,7 +3900,8 @@ void process_commands()
 	   
 	 /*for (++strchr_pointer; *strchr_pointer == ' ' || *strchr_pointer == '\t'; ++strchr_pointer);*/
 	  if (*(strchr_pointer+index) < '0' || *(strchr_pointer+index) > '9') {
-		  SERIAL_ECHOLNPGM("Invalid M code");
+		  printf_P(PSTR("Invalid M code: %s \n"), cmdbuffer + bufindr + CMDHDRSIZE);
+
 	  } else
     switch((int)code_value())
     {
@@ -3963,6 +3995,8 @@ void process_commands()
       card.openFile(strchr_pointer + 4,true);
       break;
     case 24: //M24 - Start SD print
+	  if (!card.paused)
+		failstats_reset_print();
       card.startFileprint();
       starttime=millis();
 	  break;
@@ -5706,6 +5740,10 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 			//plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 3500 / 60, active_extruder);
             
             target[E_AXIS] -= FILAMENTCHANGE_FINALRETRACT;
+            st_synchronize();
+            uint8_t tmc2130_current_r_bckp = tmc2130_current_r[E_AXIS];
+            tmc2130_set_current_r(E_AXIS, TMC2130_UNLOAD_CURRENT_R);
+
             target[E_AXIS] -= 45;
             plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 5200 / 60, active_extruder);
             st_synchronize();
@@ -5716,6 +5754,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
             plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 1000 / 60, active_extruder);
             st_synchronize();
             
+            tmc2130_set_current_r(E_AXIS, tmc2130_current_r_bckp);
 #endif // SNMM
 
 
@@ -5741,7 +5780,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 			WRITE(BEEPER, LOW);
 
 			KEEPALIVE_STATE(PAUSED_FOR_USER);
-			lcd_change_fil_state = lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_UNLOAD_SUCCESSFULL, false, true);
+			lcd_change_fil_state = lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_UNLOAD_SUCCESSFUL, false, true);
 			if (lcd_change_fil_state == 0) lcd_show_fullscreen_message_and_wait_P(MSG_CHECK_IDLER);
 			//lcd_return_to_status();
 			lcd_update_enable(true);
@@ -5949,7 +5988,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 		if(lcd_commands_type == 0)	lcd_commands_type = LCD_COMMAND_LONG_PAUSE_RESUME;
 	}
 	break;
-            
+
 #ifdef LIN_ADVANCE
     case 900: // M900: Set LIN_ADVANCE options.
         gcode_M900();
@@ -6123,7 +6162,7 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 		lcd_setstatuspgm(MSG_UNLOADING_FILAMENT); 
 
 //		extr_unload2();
-
+		
 		current_position[E_AXIS] -= 45;
 		plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 5200 / 60, active_extruder);
         st_synchronize();
@@ -6170,7 +6209,8 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
       gcode_LastN = Stopped_gcode_LastN;
       FlushSerialRequestResend();
     break;
-	default: SERIAL_ECHOLNPGM("Invalid M code.");
+	default: 
+		printf_P(PSTR("Unknown M code: %s \n"), cmdbuffer + bufindr + CMDHDRSIZE);
     }
 	
   } // end if(code_seen('M')) (end of M codes)
@@ -7531,9 +7571,8 @@ void uvlo_()
     disable_z();
     
     // Increment power failure counter
-    uint8_t power_count = eeprom_read_byte((uint8_t*)EEPROM_POWER_COUNT);
-    power_count++;
-    eeprom_update_byte((uint8_t*)EEPROM_POWER_COUNT, power_count);
+	eeprom_update_byte((uint8_t*)EEPROM_POWER_COUNT, eeprom_read_byte((uint8_t*)EEPROM_POWER_COUNT) + 1);
+	eeprom_update_word((uint16_t*)EEPROM_POWER_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_POWER_COUNT_TOT) + 1);
     
 		SERIAL_ECHOLNPGM("UVLO - end");
 		MYSERIAL.println(millis() - time_start);

+ 4 - 0
Firmware/cardreader.cpp

@@ -25,6 +25,7 @@ CardReader::CardReader()
    sdpos = 0;
    sdprinting = false;
    cardOK = false;
+   paused = false;
    saving = false;
    logging = false;
    autostart_atmillis=0;
@@ -240,6 +241,7 @@ void CardReader::startFileprint()
   if(cardOK)
   {
     sdprinting = true;
+	paused = false;
 	#ifdef SDCARD_SORT_ALPHA
 		//flush_presort();
 	#endif
@@ -251,6 +253,7 @@ void CardReader::pauseSDPrint()
   if(sdprinting)
   {
     sdprinting = false;
+	paused = true;
   }
 }
 
@@ -333,6 +336,7 @@ void CardReader::openFile(char* name,bool read, bool replace_current/*=true*/)
     SERIAL_ECHOLN(name);
   }
   sdprinting = false;
+  paused = false;
   
  
   SdFile myDir;

+ 1 - 0
Firmware/cardreader.h

@@ -75,6 +75,7 @@ public:
   bool logging;
   bool sdprinting ;  
   bool cardOK ;
+  bool paused ;
   char filename[13];
   uint16_t creationTime, creationDate;
   uint32_t cluster, position;

+ 26 - 12
Firmware/fsensor.cpp

@@ -4,8 +4,10 @@
 
 #include "fsensor.h"
 #include "pat9125.h"
+#include "stepper.h"
 #include "planner.h"
 #include "fastio.h"
+#include "cmdqueue.h"
 
 //#include "LiquidCrystal.h"
 //extern LiquidCrystal lcd;
@@ -14,7 +16,7 @@
 #define FSENSOR_ERR_MAX          5  //filament sensor max error count
 #define FSENSOR_INT_PIN         63  //filament sensor interrupt pin PK1
 #define FSENSOR_INT_PIN_MSK   0x02  //filament sensor interrupt pin mask (bit1)
-#define FSENSOR_CHUNK_LEN      560  //filament sensor chunk length in steps
+#define FSENSOR_CHUNK_LEN      280  //filament sensor chunk length in steps
 
 extern void stop_and_save_print_to_ram(float z_move, float e_move);
 extern void restore_print_from_ram_and_continue(float e_move);
@@ -60,7 +62,7 @@ void fsensor_unblock() {
 bool fsensor_enable()
 {
 //	puts_P(PSTR("fsensor_enable\n"));
-	int pat9125 = pat9125_init(PAT9125_XRES, PAT9125_YRES);
+	int pat9125 = pat9125_init();
 //    printf_P(PSTR("PAT9125_init:%d\n"), pat9125);
 	if (pat9125)
 		fsensor_not_responding = false;
@@ -168,7 +170,9 @@ ISR(PCINT2_vect)
 	*digitalPinToPCMSK(fsensor_int_pin) |= bit(digitalPinToPCMSKbit(fsensor_int_pin));*/
 	if (!pat9125_update_y())
 	{
-//		puts_P(PSTR("pat9125 not responding.\n"));
+#ifdef DEBUG_FSENSOR_LOG
+		puts_P(PSTR("pat9125 not responding.\n"));
+#endif //DEBUG_FSENSOR_LOG
 		fsensor_disable();
 		fsensor_not_responding = true;
 	}
@@ -255,18 +259,28 @@ void fsensor_update()
 	if (!fsensor_enabled) return;
 	if (fsensor_err_cnt > FSENSOR_ERR_MAX)
 	{
-//		MYSERIAL.println("fsensor_update (fsensor_err_cnt > FSENSOR_ERR_MAX)");
-/*		if (fsensor_ignore_error)
+		fsensor_stop_and_save_print();
+
+		fsensor_err_cnt = 0;
+
+		enquecommand_front_P((PSTR("G1 E-3 F200")));
+		process_commands();
+	    cmdqueue_pop_front();
+		st_synchronize();
+
+		enquecommand_front_P((PSTR("G1 E3 F200")));
+		process_commands();
+	    cmdqueue_pop_front();
+		st_synchronize();
+
+		if (fsensor_err_cnt == 0)
 		{
-			MYSERIAL.println("fsensor_update - error ignored)");
-			fsensor_ignore_error = false;
+			fsensor_restore_print_and_continue();
 		}
-		else*/
+		else
 		{
-			fsensor_stop_and_save_print();
-			uint8_t ferror_count = eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT);
-			ferror_count++;
-			eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, ferror_count);
+			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")));
 			fsensor_M600 = true;
 			fsensor_enabled = false;

+ 16 - 16
Firmware/language_all.cpp

@@ -479,8 +479,10 @@ const char * const MSG_DATE_LANG_TABLE[LANG_NUM] PROGMEM = {
 };
 
 const char MSG_DEFAULT_SETTINGS_LOADED_EN[] PROGMEM = "Default settings loaded";
-const char * const MSG_DEFAULT_SETTINGS_LOADED_LANG_TABLE[1] PROGMEM = {
-	MSG_DEFAULT_SETTINGS_LOADED_EN
+const char MSG_DEFAULT_SETTINGS_LOADED_CZ[] PROGMEM = "Nahrano vychozi nastaveni";
+const char * const MSG_DEFAULT_SETTINGS_LOADED_LANG_TABLE[LANG_NUM] PROGMEM = {
+	MSG_DEFAULT_SETTINGS_LOADED_EN,
+	MSG_DEFAULT_SETTINGS_LOADED_CZ
 };
 
 const char MSG_DISABLE_STEPPERS_EN[] PROGMEM = "Disable steppers";
@@ -845,13 +847,6 @@ const char * const MSG_FW_VERSION_BETA_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_FW_VERSION_BETA_CZ
 };
 
-const char MSG_FW_VERSION_DEBUG_EN[] PROGMEM = "This is development firmware version which contains additional debugging features. Using this version may cause printer damage.";
-const char MSG_FW_VERSION_DEBUG_CZ[] PROGMEM = "Toto je vyvojova verze firmwaru obsahujici funkce pro debugging. Pouziti teto verze muze poskodit Vasi tiskarnu.";
-const char * const MSG_FW_VERSION_DEBUG_LANG_TABLE[LANG_NUM] PROGMEM = {
-	MSG_FW_VERSION_DEBUG_EN,
-	MSG_FW_VERSION_DEBUG_CZ
-};
-
 const char MSG_FW_VERSION_RC_EN[] PROGMEM = "This firmware version is release candidate. Some of the features may not work properly.";
 const char MSG_FW_VERSION_RC_CZ[] PROGMEM = "Tato verze firmware je release candidate. Nektere z funkci nemusi pracovat spolehlive.";
 const char * const MSG_FW_VERSION_RC_LANG_TABLE[LANG_NUM] PROGMEM = {
@@ -859,8 +854,8 @@ const char * const MSG_FW_VERSION_RC_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_FW_VERSION_RC_CZ
 };
 
-const char MSG_FW_VERSION_UNKNOWN_EN[] PROGMEM = "WARNING: Unknown firmware version";
-const char MSG_FW_VERSION_UNKNOWN_CZ[] PROGMEM = "VAROVANI: Neznama verze firmware";
+const char MSG_FW_VERSION_UNKNOWN_EN[] PROGMEM = "WARNING: This is an unofficial, unsupported build. Use at your own risk!";
+const char MSG_FW_VERSION_UNKNOWN_CZ[] PROGMEM = "VAROVANI: Neznama, nepodporovana verze firmware. Pouziti na vlastni nebezpeci!";
 const char * const MSG_FW_VERSION_UNKNOWN_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_FW_VERSION_UNKNOWN_EN,
 	MSG_FW_VERSION_UNKNOWN_CZ
@@ -2164,6 +2159,11 @@ const char * const MSG_TEMP_CALIBRATION_ON_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_TEMP_CALIBRATION_ON_CZ
 };
 
+const char MSG_TEMP_CAL_WARNING_EN[] PROGMEM = "Stable ambient temperature 21-26C is needed a rigid stand is required.";
+const char * const MSG_TEMP_CAL_WARNING_LANG_TABLE[1] PROGMEM = {
+	MSG_TEMP_CAL_WARNING_EN
+};
+
 const char MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF_EN[] PROGMEM = "SD card  [normal]";
 const char * const MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF_LANG_TABLE[1] PROGMEM = {
 	MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF_EN
@@ -2235,11 +2235,11 @@ const char * const MSG_UNLOAD_FILAMENT_4_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_UNLOAD_FILAMENT_4_CZ
 };
 
-const char MSG_UNLOAD_SUCCESSFULL_EN[] PROGMEM = "Was filament unload successfull?";
-const char MSG_UNLOAD_SUCCESSFULL_CZ[] PROGMEM = "Bylo vysunuti filamentu uspesne?";
-const char * const MSG_UNLOAD_SUCCESSFULL_LANG_TABLE[LANG_NUM] PROGMEM = {
-	MSG_UNLOAD_SUCCESSFULL_EN,
-	MSG_UNLOAD_SUCCESSFULL_CZ
+const char MSG_UNLOAD_SUCCESSFUL_EN[] PROGMEM = "Was filament unload successful?";
+const char MSG_UNLOAD_SUCCESSFUL_CZ[] PROGMEM = "Bylo vysunuti filamentu uspesne?";
+const char * const MSG_UNLOAD_SUCCESSFUL_LANG_TABLE[LANG_NUM] PROGMEM = {
+	MSG_UNLOAD_SUCCESSFUL_EN,
+	MSG_UNLOAD_SUCCESSFUL_CZ
 };
 
 const char MSG_USB_PRINTING_EN[] PROGMEM = "USB printing  ";

+ 6 - 6
Firmware/language_all.h

@@ -168,8 +168,8 @@ extern const char* const MSG_CURRENT_LANG_TABLE[LANG_NUM];
 #define MSG_CURRENT LANG_TABLE_SELECT(MSG_CURRENT_LANG_TABLE)
 extern const char* const MSG_DATE_LANG_TABLE[LANG_NUM];
 #define MSG_DATE LANG_TABLE_SELECT(MSG_DATE_LANG_TABLE)
-extern const char* const MSG_DEFAULT_SETTINGS_LOADED_LANG_TABLE[1];
-#define MSG_DEFAULT_SETTINGS_LOADED LANG_TABLE_SELECT_EXPLICIT(MSG_DEFAULT_SETTINGS_LOADED_LANG_TABLE, 0)
+extern const char* const MSG_DEFAULT_SETTINGS_LOADED_LANG_TABLE[LANG_NUM];
+#define MSG_DEFAULT_SETTINGS_LOADED LANG_TABLE_SELECT(MSG_DEFAULT_SETTINGS_LOADED_LANG_TABLE)
 extern const char* const MSG_DISABLE_STEPPERS_LANG_TABLE[LANG_NUM];
 #define MSG_DISABLE_STEPPERS LANG_TABLE_SELECT(MSG_DISABLE_STEPPERS_LANG_TABLE)
 extern const char* const MSG_DWELL_LANG_TABLE[1];
@@ -290,8 +290,6 @@ extern const char* const MSG_FW_VERSION_ALPHA_LANG_TABLE[LANG_NUM];
 #define MSG_FW_VERSION_ALPHA LANG_TABLE_SELECT(MSG_FW_VERSION_ALPHA_LANG_TABLE)
 extern const char* const MSG_FW_VERSION_BETA_LANG_TABLE[LANG_NUM];
 #define MSG_FW_VERSION_BETA LANG_TABLE_SELECT(MSG_FW_VERSION_BETA_LANG_TABLE)
-extern const char* const MSG_FW_VERSION_DEBUG_LANG_TABLE[LANG_NUM];
-#define MSG_FW_VERSION_DEBUG LANG_TABLE_SELECT(MSG_FW_VERSION_DEBUG_LANG_TABLE)
 extern const char* const MSG_FW_VERSION_RC_LANG_TABLE[LANG_NUM];
 #define MSG_FW_VERSION_RC LANG_TABLE_SELECT(MSG_FW_VERSION_RC_LANG_TABLE)
 extern const char* const MSG_FW_VERSION_UNKNOWN_LANG_TABLE[LANG_NUM];
@@ -710,6 +708,8 @@ extern const char* const MSG_TEMP_CALIBRATION_OFF_LANG_TABLE[LANG_NUM];
 #define MSG_TEMP_CALIBRATION_OFF LANG_TABLE_SELECT(MSG_TEMP_CALIBRATION_OFF_LANG_TABLE)
 extern const char* const MSG_TEMP_CALIBRATION_ON_LANG_TABLE[LANG_NUM];
 #define MSG_TEMP_CALIBRATION_ON LANG_TABLE_SELECT(MSG_TEMP_CALIBRATION_ON_LANG_TABLE)
+extern const char* const MSG_TEMP_CAL_WARNING_LANG_TABLE[1];
+#define MSG_TEMP_CAL_WARNING LANG_TABLE_SELECT_EXPLICIT(MSG_TEMP_CAL_WARNING_LANG_TABLE, 0)
 extern const char* const MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF_LANG_TABLE[1];
 #define MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF LANG_TABLE_SELECT_EXPLICIT(MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF_LANG_TABLE, 0)
 extern const char* const MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON_LANG_TABLE[1];
@@ -732,8 +732,8 @@ extern const char* const MSG_UNLOAD_FILAMENT_3_LANG_TABLE[LANG_NUM];
 #define MSG_UNLOAD_FILAMENT_3 LANG_TABLE_SELECT(MSG_UNLOAD_FILAMENT_3_LANG_TABLE)
 extern const char* const MSG_UNLOAD_FILAMENT_4_LANG_TABLE[LANG_NUM];
 #define MSG_UNLOAD_FILAMENT_4 LANG_TABLE_SELECT(MSG_UNLOAD_FILAMENT_4_LANG_TABLE)
-extern const char* const MSG_UNLOAD_SUCCESSFULL_LANG_TABLE[LANG_NUM];
-#define MSG_UNLOAD_SUCCESSFULL LANG_TABLE_SELECT(MSG_UNLOAD_SUCCESSFULL_LANG_TABLE)
+extern const char* const MSG_UNLOAD_SUCCESSFUL_LANG_TABLE[LANG_NUM];
+#define MSG_UNLOAD_SUCCESSFUL LANG_TABLE_SELECT(MSG_UNLOAD_SUCCESSFUL_LANG_TABLE)
 extern const char* const MSG_USB_PRINTING_LANG_TABLE[LANG_NUM];
 #define MSG_USB_PRINTING LANG_TABLE_SELECT(MSG_USB_PRINTING_LANG_TABLE)
 extern const char* const MSG_USED_LANG_TABLE[LANG_NUM];

+ 3 - 3
Firmware/language_cz.h

@@ -369,12 +369,13 @@
 #define MSG_PLACE_STEEL_SHEET				"Umistete prosim tiskovy plat na heatbed"
 #define MSG_RECOVER_PRINT					"Detekovan vypadek proudu.Obnovit tisk?"
 #define MSG_PRESS_TO_UNLOAD					"Pro vysunuti filamentu stisknete prosim tlacitko"	
-#define MSG_UNLOAD_SUCCESSFULL				"Bylo vysunuti filamentu uspesne?"
+#define MSG_UNLOAD_SUCCESSFUL				"Bylo vysunuti filamentu uspesne?"
 #define MSG_PRESS_TO_PREHEAT				"Pro nahrati trysky a pokracovani stisknete tlacitko."
 #define MSG_PULL_OUT_FILAMENT				"Prosim vyjmete urychlene filament"
 #define MSG_CHECK_IDLER						"Prosim otevrete idler a manualne odstrante filament."
 #define MSG_FILE_INCOMPLETE					"Soubor nekompletni. Pokracovat?"
 #define MSG_FILE_CNT						"Nektere soubory nebudou setrideny. Maximalni pocet souboru pro setrideni je 100."
+#define MSG_DEFAULT_SETTINGS_LOADED			"Nahrano vychozi nastaveni"
 #define MSG_SORT_TIME						"Trideni     [Cas]"
 #define MSG_SORT_ALPHA						"Trideni [Abeceda]"
 #define MSG_SORT_NONE						"Trideni   [Zadne]"
@@ -401,8 +402,7 @@
 
 #define MSG_FSENS_NOT_RESPONDING     "CHYBA: Filament senzor nereaguje, zkontrolujte zapojeni."
 
-#define MSG_FW_VERSION_UNKNOWN		 "VAROVANI: Neznama verze firmware"
+#define MSG_FW_VERSION_UNKNOWN		 "VAROVANI: Neznama, nepodporovana verze firmware. Pouziti na vlastni nebezpeci!"
 #define MSG_FW_VERSION_ALPHA		 "Pouzivate alpha verzi firmwaru. Jedna se o vyvojovou verzi. Pouzivani teto verze firmware neni doporuceno a muze zpusobit poskozeni tiskarny." 
 #define MSG_FW_VERSION_BETA			 "Pouzivate beta verzi firmwaru. Jedna se o vyvojovou verzi. Pouzivani teto verze firmware neni doporuceno a muze zpusobit poskozeni tiskarny."
 #define MSG_FW_VERSION_RC			 "Tato verze firmware je release candidate. Nektere z funkci nemusi pracovat spolehlive."
-#define MSG_FW_VERSION_DEBUG		 "Toto je vyvojova verze firmwaru obsahujici funkce pro debugging. Pouziti teto verze muze poskodit Vasi tiskarnu."

+ 3 - 3
Firmware/language_en.h

@@ -361,6 +361,7 @@
 #define(length=20, lines=4) MSG_REMOVE_STEEL_SHEET				"Please remove steel sheet from heatbed."
 #define(length=20, lines=2) MSG_CALIBRATE_Z_AUTO				"Calibrating Z"
 #define(length=20, lines=2) MSG_STEEL_SHEET_CHECK				"Is steel sheet on heatbed?"
+#define(length=20, lines=4) MSG_TEMP_CAL_WARNING				"Stable ambient temperature 21-26C is needed a rigid stand is required."
 
 #define MSG_SELFTEST_AXIS					"Axis"
 #define MSG_SELFTEST_AXIS_LENGTH			"Axis length"
@@ -386,7 +387,7 @@
 #define(length=17, lines=1) MSG_FSENS_AUTOLOAD_NA                "F. autoload [N/A]"
 #define(length=20, lines=4) MSG_PRESS_TO_UNLOAD					"Please press the knob to unload filament"
 #define(length=20, lines=4) MSG_PRESS_TO_PREHEAT				"Press knob to preheat nozzle and continue."
-#define(length=20, lines=2) MSG_UNLOAD_SUCCESSFULL				"Was filament unload successfull?"
+#define(length=20, lines=2) MSG_UNLOAD_SUCCESSFUL				"Was filament unload successful?"
 #define(length=20, lines=4) MSG_CHECK_IDLER						"Please open idler and remove filament manually."
 #define(length=20, lines=4) MSG_PULL_OUT_FILAMENT				"Please pull out filament immediately"
 #define(length=20, lines=2) MSG_FILE_INCOMPLETE					"File incomplete. Continue anyway?"
@@ -407,8 +408,7 @@
 #define(length=20, lines=4) MSG_AUTOLOADING_ONLY_IF_FSENS_ON     "Autoloading filament available only when filament sensor is turned on..."
 
 #define(length=20, lines=4) MSG_FSENS_NOT_RESPONDING     "ERROR: Filament sensor is not responding, please check connection."
-#define(length=20, lines=8) MSG_FW_VERSION_UNKNOWN		 "WARNING: Unknown firmware version"
+#define(length=20, lines=8) MSG_FW_VERSION_UNKNOWN		 "WARNING: This is an unofficial, unsupported build. Use at your own risk!"
 #define(length=20, lines=8) MSG_FW_VERSION_ALPHA		 "You are using firmware alpha version. This is development version. Using this version is not recommended and may cause printer damage." 
 #define(length=20, lines=8) MSG_FW_VERSION_BETA			 "You are using firmware beta version. This is development version. Using this version is not recommended and may cause printer damage."
 #define(length=20, lines=8) MSG_FW_VERSION_RC			 "This firmware version is release candidate. Some of the features may not work properly."
-#define(length=20, lines=8) MSG_FW_VERSION_DEBUG		 "This is development firmware version which contains additional debugging features. Using this version may cause printer damage."

+ 99 - 10
Firmware/pat9125.cpp

@@ -17,14 +17,64 @@
 
 unsigned char pat9125_PID1 = 0;
 unsigned char pat9125_PID2 = 0;
-unsigned char pat9125_xres = 0;
-unsigned char pat9125_yres = 0;
 int pat9125_x = 0;
 int pat9125_y = 0;
 unsigned char pat9125_b = 0;
 unsigned char pat9125_s = 0;
 
-int pat9125_init(unsigned char xres, unsigned char yres)
+// Init sequence, address & value.
+const PROGMEM unsigned char pat9125_init_seq1[] = {
+	// Disable write protect.
+	PAT9125_WP, 0x5a,
+	// Set the X resolution to zero to let the sensor know that it could safely ignore movement in the X axis.
+    PAT9125_RES_X, PAT9125_XRES,
+    // Set the Y resolution to a maximum (or nearly a maximum).
+    PAT9125_RES_Y, PAT9125_YRES,
+    // Set 12-bit X/Y data format.
+    PAT9125_ORIENTATION, 0x04,
+//	PAT9125_ORIENTATION, 0x04 | (xinv?0x08:0) | (yinv?0x10:0), //!? direction switching does not work
+    // Now continues the magic sequence from the PAT912EL Application Note: Firmware Guides for Tracking Optimization.
+    0x5e, 0x08,
+    0x20, 0x64,
+    0x2b, 0x6d,
+    0x32, 0x2f,
+    // stopper
+    0x0ff
+};
+
+// Init sequence, address & value.
+const PROGMEM unsigned char pat9125_init_seq2[] = {
+	// Magic sequence to enforce full frame rate of the sensor.
+	0x06, 0x028,
+	0x33, 0x0d0,
+	0x36, 0x0c2,
+	0x3e, 0x001,
+	0x3f, 0x015,
+	0x41, 0x032,
+	0x42, 0x03b,
+	0x43, 0x0f2,
+	0x44, 0x03b,
+	0x45, 0x0f2,
+	0x46, 0x022,
+	0x47, 0x03b,
+	0x48, 0x0f2,
+	0x49, 0x03b,
+	0x4a, 0x0f0,
+	0x58, 0x098,
+	0x59, 0x00c,
+	0x5a, 0x008,
+	0x5b, 0x00c,
+	0x5c, 0x008,
+	0x61, 0x010,
+	0x67, 0x09b,
+	0x6e, 0x022,
+	0x71, 0x007,
+	0x72, 0x008,
+	// stopper
+    0x0ff
+};
+
+int pat9125_init()
 {
 #ifdef PAT9125_SWSPI
 	swspi_init();
@@ -35,8 +85,7 @@ int pat9125_init(unsigned char xres, unsigned char yres)
 #ifdef PAT9125_HWI2C
 	Wire.begin();
 #endif //PAT9125_HWI2C
-	pat9125_xres = xres;
-	pat9125_yres = yres;
+	// Verify that the sensor responds with its correct product ID.
 	pat9125_PID1 = pat9125_rd_reg(PAT9125_PID1);
 	pat9125_PID2 = pat9125_rd_reg(PAT9125_PID2);
 //	pat9125_PID1 = 0x31;
@@ -45,9 +94,44 @@ int pat9125_init(unsigned char xres, unsigned char yres)
 	{
 		return 0;
 	}
-    pat9125_wr_reg(PAT9125_RES_X, pat9125_xres);
-    pat9125_wr_reg(PAT9125_RES_Y, pat9125_yres);
-//	pat9125_wr_reg(PAT9125_ORIENTATION, 0x04 | (xinv?0x08:0) | (yinv?0x10:0)); //!? direction switching does not work
+	// Switch to bank0, not allowed to perform OTS_RegWriteRead.
+	pat9125_wr_reg(PAT9125_BANK_SELECTION, 0);
+	// Software reset (i.e. set bit7 to 1). It will reset to 0 automatically.
+	// After the reset, OTS_RegWriteRead is not allowed.
+	pat9125_wr_reg(PAT9125_CONFIG, 0x97);
+	// Wait until the sensor reboots.
+	// Delay 1ms.
+	delayMicroseconds(1000);
+	{
+		const unsigned char *ptr = pat9125_init_seq1;
+		for (;;) {
+			const unsigned char addr = pgm_read_byte_near(ptr ++);
+			if (addr == 0x0ff)
+				break;
+			if (! pat9125_wr_reg_verify(addr, pgm_read_byte_near(ptr ++)))
+				// Verification of the register write failed.
+				return 0;
+		}
+	}
+	// Delay 10ms.
+	delayMicroseconds(10000);
+	// Switch to bank1, not allowed to perform OTS_RegWrite.
+	pat9125_wr_reg(PAT9125_BANK_SELECTION, 0x01);
+	{
+		const unsigned char *ptr = pat9125_init_seq2;
+		for (;;) {
+			const unsigned char addr = pgm_read_byte_near(ptr ++);
+			if (addr == 0x0ff)
+				break;
+			if (! pat9125_wr_reg_verify(addr, pgm_read_byte_near(ptr ++)))
+				// Verification of the register write failed.
+				return 0;
+		}
+	}
+	// Switch to bank0, not allowed to perform OTS_RegWriteRead.
+	pat9125_wr_reg(PAT9125_BANK_SELECTION, 0x00);
+	// Enable write protect.
+	pat9125_wr_reg(PAT9125_WP, 0x00);
 	return 1;
 }
 
@@ -69,8 +153,8 @@ int pat9125_update()
 			if (iDY & 0x800) iDY -= 4096;
 			pat9125_x += iDX;
 			pat9125_y -= iDY; //negative number, because direction switching does not work
-			return 1;
 		}
+		return 1;
 	}
 	return 0;
 }
@@ -87,8 +171,8 @@ int pat9125_update_y()
 			int iDY = ucYL | ((ucXYH << 8) & 0xf00);
 			if (iDY & 0x800) iDY -= 4096;
 			pat9125_y -= iDY; //negative number, because direction switching does not work
-			return 1;
 		}
+		return 1;
 	}
 	return 0;
 }
@@ -133,7 +217,12 @@ void pat9125_wr_reg(unsigned char addr, unsigned char data)
 	Wire.write(data);
 	Wire.endTransmission();
 #endif //PAT9125_HWI2C
+}
 
+bool pat9125_wr_reg_verify(unsigned char addr, unsigned char data)
+{
+	pat9125_wr_reg(addr, data);
+	return pat9125_rd_reg(addr) == data;
 }
 
 #endif //PAT9125

+ 3 - 4
Firmware/pat9125.h

@@ -23,24 +23,23 @@
 #define PAT9125_SHUTTER			0x14
 #define PAT9125_FRAME			0x17
 #define PAT9125_ORIENTATION		0x19
+#define PAT9125_BANK_SELECTION	0x7f
 
 extern unsigned char pat9125_PID1;
 extern unsigned char pat9125_PID2;
 
-extern unsigned char pat9125_xres;
-extern unsigned char pat9125_yres;
-
 extern int pat9125_x;
 extern int pat9125_y;
 extern unsigned char pat9125_b;
 extern unsigned char pat9125_s;
 
-extern int pat9125_init(unsigned char xres, unsigned char yres);
+extern int pat9125_init();
 extern int pat9125_update();
 extern int pat9125_update_y();
 
 extern unsigned char pat9125_rd_reg(unsigned char addr);
 extern void pat9125_wr_reg(unsigned char addr, unsigned char data);
+extern bool pat9125_wr_reg_verify(unsigned char addr, unsigned char data);
 
 
 #endif //PAT9125_H

+ 21 - 8
Firmware/pins_Einy_0_4.h

@@ -142,11 +142,24 @@
 #define LOGIC_ANALYZER_CH6		17				// PH1 (TXD2)
 #define LOGIC_ANALYZER_CH7 		76				// PJ5
 
-#define LOGIC_ANALYZER_CH0_ENABLE SET_OUTPUT(LOGIC_ANALYZER_CH0)
-#define LOGIC_ANALYZER_CH1_ENABLE SET_OUTPUT(LOGIC_ANALYZER_CH1)
-#define LOGIC_ANALYZER_CH2_ENABLE SET_OUTPUT(LOGIC_ANALYZER_CH2)
-#define LOGIC_ANALYZER_CH3_ENABLE SET_OUTPUT(LOGIC_ANALYZER_CH3)
-#define LOGIC_ANALYZER_CH4_ENABLE do { DDRK |= 1 << 0; } while (0)
-#define LOGIC_ANALYZER_CH5_ENABLE do { cbi(UCSR2B, TXEN2); cbi(UCSR2B, RXEN2); cbi(UCSR2B, RXCIE2); SET_OUTPUT(LOGIC_ANALYZER_CH5); } while (0)
-#define LOGIC_ANALYZER_CH6_ENABLE do { cbi(UCSR2B, TXEN2); cbi(UCSR2B, RXEN2); cbi(UCSR2B, RXCIE2); SET_OUTPUT(LOGIC_ANALYZER_CH6); } while (0)
-#define LOGIC_ANALYZER_CH7_ENABLE SET_OUTPUT(LOGIC_ANALYZER_CH7)
+#define LOGIC_ANALYZER_CH0_ENABLE do { SET_OUTPUT(LOGIC_ANALYZER_CH0); WRITE(LOGIC_ANALYZER_CH0, false); } while (0)
+#define LOGIC_ANALYZER_CH1_ENABLE do { SET_OUTPUT(LOGIC_ANALYZER_CH1); WRITE(LOGIC_ANALYZER_CH1, false); } while (0)
+#define LOGIC_ANALYZER_CH2_ENABLE do { SET_OUTPUT(LOGIC_ANALYZER_CH2); WRITE(LOGIC_ANALYZER_CH2, false); } while (0)
+#define LOGIC_ANALYZER_CH3_ENABLE do { SET_OUTPUT(LOGIC_ANALYZER_CH3); WRITE(LOGIC_ANALYZER_CH3, false); } while (0)
+#define LOGIC_ANALYZER_CH4_ENABLE do { DDRK |= 1 << 0; WRITE_LOGIC_ANALYZER_CH4(false); } while (0)
+#define LOGIC_ANALYZER_CH5_ENABLE do { cbi(UCSR2B, TXEN2); cbi(UCSR2B, RXEN2); cbi(UCSR2B, RXCIE2); SET_OUTPUT(LOGIC_ANALYZER_CH5); WRITE(LOGIC_ANALYZER_CH5, false); } while (0)
+#define LOGIC_ANALYZER_CH6_ENABLE do { cbi(UCSR2B, TXEN2); cbi(UCSR2B, RXEN2); cbi(UCSR2B, RXCIE2); SET_OUTPUT(LOGIC_ANALYZER_CH6); WRITE(LOGIC_ANALYZER_CH6, false); } while (0)
+#define LOGIC_ANALYZER_CH7_ENABLE do { SET_OUTPUT(LOGIC_ANALYZER_CH7); WRITE(LOGIC_ANALYZER_CH7, false); } while (0)
+
+// Async output on channel 5 of the logical analyzer.
+// Baud rate 2MBit, 9 bits, 1 stop bit.
+#define LOGIC_ANALYZER_SERIAL_TX_ENABLE do { UBRR2H = 0; UBRR2L = 0; UCSR2B = (1 << TXEN2) | (1 << UCSZ02); UCSR2C = 0x06; } while (0)
+// Non-checked (quicker) variant. Use it if you are sure that the transmit buffer is already empty.
+#define LOGIC_ANALYZER_SERIAL_TX_WRITE_NC(C) do { if (C & 0x100) UCSR2B |= 1; else UCSR2B &= ~1; UDR2 = C; } while (0)
+#define LOGIC_ANALYZER_SERIAL_TX_WRITE(C) do { \
+	/* Wait for empty transmit buffer */ \
+	while (!(UCSR2A & (1<<UDRE2))); \
+	/* Put data into buffer, sends the data */ \
+	LOGIC_ANALYZER_SERIAL_TX_WRITE_NC(C); \
+} while (0)
+

+ 4 - 0
Firmware/planner.cpp

@@ -186,12 +186,16 @@ FORCE_INLINE float intersection_distance(float initial_rate, float final_rate, f
   }
 }
 
+// Minimum stepper rate 120Hz.
 #define MINIMAL_STEP_RATE 120
 
 // Calculates trapezoid parameters so that the entry- and exit-speed is compensated by the provided factors.
 void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit_speed) 
 {
   // These two lines are the only floating point calculations performed in this routine.
+  // initial_rate, final_rate in Hz.
+  // Minimum stepper rate 120Hz, maximum 40kHz. If the stepper rate goes above 10kHz,
+  // the stepper interrupt routine groups the pulses by 2 or 4 pulses per interrupt tick.
   uint32_t initial_rate = ceil(entry_speed * block->speed_factor); // (step/min)
   uint32_t final_rate   = ceil(exit_speed  * block->speed_factor); // (step/min)
 

+ 6 - 6
Firmware/temperature.cpp

@@ -362,10 +362,10 @@ unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
       int p;
       if (extruder<0){
         p=soft_pwm_bed;       
-        SERIAL_PROTOCOLPGM("ok B:");
+        SERIAL_PROTOCOLPGM("B:");
       }else{
         p=soft_pwm[extruder];       
-        SERIAL_PROTOCOLPGM("ok T:");
+        SERIAL_PROTOCOLPGM("T:");
       }
 			
       SERIAL_PROTOCOL(input);   
@@ -500,12 +500,12 @@ void fanSpeedError(unsigned char _fan) {
 		}
 	}
 	else {
-		setTargetHotend0(0);
+			setTargetHotend0(0);
+			SERIAL_ECHOLNPGM("// action:pause"); //for octoprint
 	}
-	SERIAL_ERROR_START;
 	switch (_fan) {
 	case 0:
-			SERIAL_ERRORLNPGM("ERROR: Extruder fan speed is lower then expected");
+			SERIAL_ECHOLNPGM("Extruder fan speed is lower then expected");
 			if (get_message_level() == 0) {
 				WRITE(BEEPER, HIGH);
 				delayMicroseconds(200);
@@ -515,7 +515,7 @@ void fanSpeedError(unsigned char _fan) {
 			}
 		break;
 	case 1:
-			SERIAL_ERRORLNPGM("ERROR: Print fan speed is lower then expected");
+			SERIAL_ECHOLNPGM("Print fan speed is lower then expected");
 			if (get_message_level() == 0) {
 				WRITE(BEEPER, HIGH);
 				delayMicroseconds(200);

+ 39 - 12
Firmware/tmc2130.cpp

@@ -34,13 +34,13 @@ uint8_t tmc2130_current_r_home[4] = {10, 10, 20, 10};
 
 
 //pwm_ampl
-uint8_t tmc2130_pwm_ampl[2] = {TMC2130_PWM_AMPL_X, TMC2130_PWM_AMPL_Y};
+uint8_t tmc2130_pwm_ampl[4] = {TMC2130_PWM_AMPL_X, TMC2130_PWM_AMPL_Y, TMC2130_PWM_AMPL_Z, TMC2130_PWM_AMPL_E};
 //pwm_grad
-uint8_t tmc2130_pwm_grad[2] = {TMC2130_PWM_GRAD_X, TMC2130_PWM_GRAD_Y};
+uint8_t tmc2130_pwm_grad[4] = {TMC2130_PWM_GRAD_X, TMC2130_PWM_GRAD_Y, TMC2130_PWM_GRAD_Z, TMC2130_PWM_GRAD_E};
 //pwm_auto
-uint8_t tmc2130_pwm_auto[2] = {TMC2130_PWM_AUTO_X, TMC2130_PWM_AUTO_Y};
+uint8_t tmc2130_pwm_auto[4] = {TMC2130_PWM_AUTO_X, TMC2130_PWM_AUTO_Y, TMC2130_PWM_AUTO_Z, TMC2130_PWM_AUTO_E};
 //pwm_freq
-uint8_t tmc2130_pwm_freq[2] = {TMC2130_PWM_FREQ_X, TMC2130_PWM_FREQ_Y};
+uint8_t tmc2130_pwm_freq[4] = {TMC2130_PWM_FREQ_X, TMC2130_PWM_FREQ_Y, TMC2130_PWM_FREQ_Z, TMC2130_PWM_FREQ_E};
 
 uint8_t tmc2130_mres[4] = {0, 0, 0, 0}; //will be filed at begin of init
 
@@ -58,7 +58,7 @@ uint32_t tmc2130_sg_meassure_val = 0;
 
 bool tmc2130_sg_stop_on_crash = true;
 uint8_t tmc2130_sg_diag_mask = 0x00;
-bool tmc2130_sg_crash = false;
+uint8_t tmc2130_sg_crash = 0;
 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;
@@ -198,7 +198,15 @@ void tmc2130_init()
 //		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);
+#ifndef TMC2130_STEALTH_E
 		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
+#else //TMC2130_STEALTH_E
+		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16));
+		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_TCOOLTHRS, 0);
+		tmc2130_wr(tmc2130_cs[axis], TMC2130_REG_GCONF, TMC2130_GCONF_SILENT);
+		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);
+#endif //TMC2130_STEALTH_E
 	}
 
 	tmc2130_sg_err[0] = 0;
@@ -226,7 +234,7 @@ extern bool is_usb_printing;
 void tmc2130_st_isr(uint8_t last_step_mask)
 {
 	if (tmc2130_mode == TMC2130_MODE_SILENT || tmc2130_sg_stop_on_crash == false) return;
-	bool crash = false;
+	uint8_t crash = 0;
 	uint8_t diag_mask = tmc2130_sample_diag();
 //	for (uint8_t axis = X_AXIS; axis <= E_AXIS; axis++)
 	for (uint8_t axis = X_AXIS; axis <= Z_AXIS; axis++)
@@ -239,12 +247,12 @@ void tmc2130_st_isr(uint8_t last_step_mask)
 		{
 			tmc2130_sg_cnt[axis] = tmc2130_sg_err[axis];
 			tmc2130_sg_change = true;
-			uint8_t sg_thr = 48;
-			if (axis == Y_AXIS) sg_thr = 64;
+			uint8_t sg_thr = 64;
+//			if (axis == Y_AXIS) sg_thr = 64;
 			if (tmc2130_sg_err[axis] >= sg_thr)
 			{
 				tmc2130_sg_err[axis] = 0;
-				crash = true;
+				crash |= mask;
 			}
 		}
 	}
@@ -259,7 +267,7 @@ void tmc2130_st_isr(uint8_t last_step_mask)
 		}*/
 		if (/*!is_usb_printing && */tmc2130_sg_stop_on_crash && crash)
 		{
-			tmc2130_sg_crash = true;
+			tmc2130_sg_crash = crash;
 			tmc2130_sg_stop_on_crash = false;
 			crashdet_stop_and_save_print();
 		}
@@ -414,14 +422,33 @@ void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_
 {
 	uint8_t cs = tmc2130_cs[axis];
 	uint8_t intpol = 1;
+	uint8_t toff = TMC2130_TOFF_XYZ; // toff = 3 (fchop = 27.778kHz)
+	uint8_t hstrt = 5; //initial 4, modified to 5
+	uint8_t hend = 1;
+	uint8_t fd3 = 0;
+	uint8_t rndtf = 0; //random off time
+	uint8_t chm = 0; //spreadCycle
+	uint8_t tbl = 2; //blanking time
+	if (axis == E_AXIS)
+	{
+#ifdef TMC2130_CNSTOFF_E
+		// fd = 0 (slow decay only)
+		hstrt = 0; //fd0..2
+		fd3 = 0; //fd3
+		hend = 0; //sine wave offset
+		chm = 1; // constant off time mod
+#endif //TMC2130_CNSTOFF_E
+		toff = TMC2130_TOFF_E; // toff = 3-5
+//		rndtf = 1;
+	}
 	if (current_r <= 31)
 	{
-		tmc2130_wr_CHOPCONF(cs, 3, 5, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, mres, intpol, 0, 0);
+		tmc2130_wr_CHOPCONF(cs, toff, hstrt, hend, fd3, 0, rndtf, chm, tbl, 1, 0, 0, 0, mres, intpol, 0, 0);
 		tmc2130_wr(cs, TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((current_r & 0x1f) << 8) | (current_h & 0x1f));
 	}
 	else
 	{
-		tmc2130_wr_CHOPCONF(cs, 3, 5, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, mres, intpol, 0, 0);
+		tmc2130_wr_CHOPCONF(cs, toff, hstrt, hend, fd3, 0, 0, 0, tbl, 0, 0, 0, 0, mres, intpol, 0, 0);
 		tmc2130_wr(cs, TMC2130_REG_IHOLD_IRUN, 0x000f0000 | (((current_r >> 1) & 0x1f) << 8) | ((current_h >> 1) & 0x1f));
 	}
 }

+ 1 - 1
Firmware/tmc2130.h

@@ -13,7 +13,7 @@ extern uint8_t tmc2130_current_r[4];
 extern uint8_t tmc2130_sg_thr[4];
 
 extern bool tmc2130_sg_stop_on_crash;
-extern bool tmc2130_sg_crash;
+extern uint8_t tmc2130_sg_crash; //crash mask
 
 extern uint8_t tmc2130_sg_meassure;
 extern uint16_t tmc2130_sg_meassure_cnt;

+ 65 - 46
Firmware/ultralcd.cpp

@@ -576,12 +576,17 @@ void lcd_commands()
 	if (lcd_commands_type == LCD_COMMAND_LONG_PAUSE)
 	{
 		if(lcd_commands_step == 0) {
-			card.pauseSDPrint();
-			lcd_setstatuspgm(MSG_FINISHING_MOVEMENTS);
-			lcdDrawUpdate = 3;
-			lcd_commands_step = 1;
+			if (card.sdprinting) {
+				card.pauseSDPrint();
+				lcd_setstatuspgm(MSG_FINISHING_MOVEMENTS);
+				lcdDrawUpdate = 3;
+				lcd_commands_step = 1;
+			}
+			else {
+				lcd_commands_type = 0;
+			}
 		}
-		if (lcd_commands_step == 1 && !blocks_queued()) {
+		if (lcd_commands_step == 1 && !blocks_queued() && !homing_flag) {
 			lcd_setstatuspgm(MSG_PRINT_PAUSED);
 			isPrintPaused = true;
 			long_pause();
@@ -598,7 +603,7 @@ void lcd_commands()
 			lcdDrawUpdate = 3;
 			lcd_commands_step = 4;
 		}
-		if (lcd_commands_step == 1 && !blocks_queued()) {	//recover feedmultiply
+		if (lcd_commands_step == 1 && !blocks_queued() && cmd_buffer_empty()) {	//recover feedmultiply; cmd_buffer_empty() ensures that card.sdprinting is synchronized with buffered commands and thus print cant be paused until resume is finished
 			
 			sprintf_P(cmd1, PSTR("M220 S%d"), saved_feedmultiply);
 			enquecommand(cmd1);
@@ -668,10 +673,10 @@ void lcd_commands()
 		if (lcd_commands_step == 10 && !blocks_queued() && cmd_buffer_empty())
 		{
 			enquecommand_P(PSTR("M107"));
-			enquecommand_P(PSTR("M104 S210"));
-			enquecommand_P(PSTR("M140 S55"));
-			enquecommand_P(PSTR("M190 S55"));
-			enquecommand_P(PSTR("M109 S210"));
+			enquecommand_P(PSTR("M104 S" STRINGIFY(PLA_PREHEAT_HOTEND_TEMP)));
+			enquecommand_P(PSTR("M140 S" STRINGIFY(PLA_PREHEAT_HPB_TEMP)));
+			enquecommand_P(PSTR("M190 S" STRINGIFY(PLA_PREHEAT_HPB_TEMP)));
+			enquecommand_P(PSTR("M109 S" STRINGIFY(PLA_PREHEAT_HOTEND_TEMP)));
 			enquecommand_P(PSTR("T0"));
 			enquecommand_P(MSG_M117_V2_CALIBRATION);
 			enquecommand_P(PSTR("G87")); //sets calibration status
@@ -932,10 +937,10 @@ void lcd_commands()
 		if (lcd_commands_step == 9 && !blocks_queued() && cmd_buffer_empty())
 		{
 			enquecommand_P(PSTR("M107"));
-			enquecommand_P(PSTR("M104 S210"));
-			enquecommand_P(PSTR("M140 S55"));
-			enquecommand_P(PSTR("M190 S55"));
-			enquecommand_P(PSTR("M109 S210"));
+			enquecommand_P(PSTR("M104 S" STRINGIFY(PLA_PREHEAT_HOTEND_TEMP)));
+			enquecommand_P(PSTR("M140 S" STRINGIFY(PLA_PREHEAT_HPB_TEMP)));
+			enquecommand_P(PSTR("M190 S" STRINGIFY(PLA_PREHEAT_HPB_TEMP)));
+			enquecommand_P(PSTR("M109 S" STRINGIFY(PLA_PREHEAT_HOTEND_TEMP)));
 			enquecommand_P(MSG_M117_V2_CALIBRATION);
 			enquecommand_P(PSTR("G87")); //sets calibration status
 			enquecommand_P(PSTR("G28"));
@@ -1524,45 +1529,58 @@ static void lcd_menu_extruder_info()
     }
 }
 
-static void lcd_menu_fails_stats()
+static void lcd_menu_fails_stats_total()
 {
-    
-    // Display screen info
-    
-    lcd.setCursor(0, 0);
-    lcd.print("Failure stats       ");
-    
-    // Display power failures
-    uint8_t power_count = eeprom_read_byte((uint8_t*)EEPROM_POWER_COUNT);
-    lcd.setCursor(0, 1);
-    lcd.print(" Power failures:    ");
-    lcd.setCursor(17, 1);
-    lcd.print(itostr3((int)power_count));
-
-    
-    // Display Crash detected
-    uint8_t crash_count = eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT);
-    lcd.setCursor(0, 2);
-    lcd.print(" Crash detected:    ");
-    lcd.setCursor(17, 2);
-    lcd.print(itostr3((int)crash_count));
-    
-    
-    // Display filament failures
-    uint8_t ferror_count = eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT);
-    lcd.setCursor(0, 3);
-    lcd.print(" Filament fails:    ");
-    lcd.setCursor(17, 3);
-    lcd.print(itostr3((int)ferror_count));
-
+//01234567890123456789
+//Total failures
+// Power failures  000
+// Filam. runouts  000
+// Crash  X 000  Y 000
+//////////////////////
+    uint16_t power = eeprom_read_word((uint16_t*)EEPROM_POWER_COUNT_TOT);
+    uint16_t filam = eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT);
+    uint16_t crashX = eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT);
+    uint16_t crashY = eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT);
+	fprintf_P(lcdout, PSTR(ESC_H(0,0)"Total failures"ESC_H(1,1)"Power failures  %-3d"ESC_H(1,2)"Filam. runouts  %-3d"ESC_H(1,3)"Crash  X %-3d  Y %-3d"), power, filam, crashX, crashY);
 	if (lcd_clicked())
     {
         lcd_quick_feedback();
-        lcd_return_to_status();
+        //lcd_return_to_status();
+		lcd_goto_menu(lcd_menu_fails_stats, 4);
     }
-    
 }
 
+static void lcd_menu_fails_stats_print()
+{
+//01234567890123456789
+//Last print failures
+// Power failures  000
+// Filam. runouts  000
+// Crash  X 000  Y 000
+//////////////////////
+    uint8_t power = eeprom_read_byte((uint8_t*)EEPROM_POWER_COUNT);
+    uint8_t filam = eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT);
+    uint8_t crashX = eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_X);
+    uint8_t crashY = eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_Y);
+	fprintf_P(lcdout, PSTR(ESC_H(0,0)"Last print failures"ESC_H(1,1)"Power failures  %-3d"ESC_H(1,2)"Filam. runouts  %-3d"ESC_H(1,3)"Crash  X %-3d  Y %-3d"), power, filam, crashX, crashY);
+	if (lcd_clicked())
+    {
+        lcd_quick_feedback();
+        //lcd_return_to_status();
+		lcd_goto_menu(lcd_menu_fails_stats, 2);
+    }    
+}
+
+static void lcd_menu_fails_stats()
+{
+	START_MENU();
+	MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
+	MENU_ITEM(submenu, PSTR("Last print"), lcd_menu_fails_stats_print);
+	MENU_ITEM(submenu, PSTR("Total"), lcd_menu_fails_stats_total);
+	END_MENU();
+}
+
+
 #ifdef DEBUG_BUILD
 extern uint16_t SP_min;
 extern char* __malloc_heap_start;
@@ -3496,6 +3514,7 @@ void lcd_second_serial_set() {
 	if(selectedSerialPort == 1) selectedSerialPort = 0;
 	else selectedSerialPort = 1;
 	eeprom_update_byte((unsigned char *)EEPROM_SECOND_SERIAL_ACTIVE, selectedSerialPort);
+	MYSERIAL.begin(BAUDRATE);
 	lcd_goto_menu(lcd_settings_menu, 11);
 }
 

+ 17 - 7
Firmware/util.cpp

@@ -86,7 +86,7 @@ inline bool parse_version(const char *str, uint16_t version[4])
             version[3] = FIRMWARE_REVISION_ALPHA;
         else if (n == strlen_P(STR_REVISION_BETA) && strncmp_P(p, STR_REVISION_BETA, n) == 0)
             version[3] = FIRMWARE_REVISION_BETA;
-        else if ((n == 2 || n == 3) && p[0] == 'r' && p[1] == 'c') {
+        else if ((n == 2 || n == 3) && (p[0] == 'r' || p[0] == 'R') && (p[1] == 'c' || p[1] == 'C')) {
             if (n == 2)
                 version[3] = FIRMWARE_REVISION_RC;
             else {
@@ -116,12 +116,22 @@ inline bool parse_version(const char *str, uint16_t version[4])
 inline bool strncmp_PP(const char *p1, const char *p2, uint8_t n)
 {
     for (; n > 0; -- n, ++ p1, ++ p2) {
-        if (pgm_read_byte(p1) < pgm_read_byte(p2))
-            return -1;
-        if (pgm_read_byte(p1) > pgm_read_byte(p2))
-            return 1;
-        if (pgm_read_byte(p1) == 0)
-            return 0;
+		if (pgm_read_byte(p1) >= 65 && pgm_read_byte(p1) <= 92) //p1 is upper case (p2 is always lowercase)
+		{
+			if ((pgm_read_byte(p1)+32) < pgm_read_byte(p2))
+				return -1;
+			if ((pgm_read_byte(p1)+32) > pgm_read_byte(p2))
+				return 1;
+		}
+		else if (pgm_read_byte(p1) == 0) {
+			return 0;
+		}
+		else { //p1 is lowercase
+			if (pgm_read_byte(p1) < pgm_read_byte(p2))
+				return -1;
+			if (pgm_read_byte(p1) > pgm_read_byte(p2))
+				return 1;
+		}            
     }
     return 0;
 }