From e9c870e7a069ca22964d828853f64a2ea59fba08 Mon Sep 17 00:00:00 2001 From: NotaRobotexe Date: Wed, 29 May 2019 20:33:22 +0200 Subject: [PATCH 1/2] fix of fixof power panic --- Firmware/Marlin_main.cpp | 49 +++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 0bbe6a4e1..9f25fdb61 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1007,10 +1007,6 @@ static void w25x20cl_err_msg() void setup() { mmu_init(); - - #ifdef UVLO_SUPPORT - setup_uvlo_interrupt(); - #endif //UVLO_SUPPORT ultralcd_init(); @@ -1300,6 +1296,10 @@ void setup() #endif //TMC2130 + #ifdef UVLO_SUPPORT + setup_uvlo_interrupt(); + #endif //UVLO_SUPPORT + st_init(); // Initialize stepper, this enables interrupts! #ifdef TMC2130 @@ -3132,7 +3132,6 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float custom_message_type = CUSTOM_MSG_TYPE_STATUS; } - //! @brief Rise Z if too low to avoid blob/jam before filament loading //! //! It doesn't plan_buffer_line(), as it expects plan_buffer_line() to be called after @@ -8689,7 +8688,7 @@ void serialecho_temperatures() { extern uint32_t sdpos_atomic; #ifdef UVLO_SUPPORT -void uvlo_() +void uvlo_() { unsigned long time_start = _millis(); bool sd_print = card.sdprinting; @@ -8740,8 +8739,7 @@ void uvlo_() // Clean the input command queue. cmdqueue_reset(); card.sdprinting = false; -// card.closefile(); - +// 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, @@ -8764,6 +8762,15 @@ void uvlo_() current_position[E_AXIS] - default_retraction, 40, active_extruder); st_synchronize(); + + 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) / cs.axis_steps_per_unit[Z_AXIS], + current_position[E_AXIS] - default_retraction, + 40, active_extruder); + st_synchronize(); + disable_e0(); disable_z(); // Move Z up to the next 0th full step. @@ -8781,9 +8788,10 @@ void uvlo_() // 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]); + eeprom_update_float((float*)EEPROM_UVLO_CURRENT_POSITION_Z , current_position[Z_AXIS] + UVLO_Z_AXIS_SHIFT + float((1024 - z_microsteps + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS]); // Store the current feed rate, temperatures, fan speed and extruder multipliers (flow rates) EEPROM_save_B(EEPROM_UVLO_FEEDRATE, &feedrate_bckp); eeprom_update_byte((uint8_t*)EEPROM_UVLO_TARGET_HOTEND, target_temperature[active_extruder]); @@ -8817,7 +8825,6 @@ void uvlo_() plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 500, active_extruder); st_synchronize(); #endif - wdt_enable(WDTO_500MS); WRITE(BEEPER,HIGH); while(1) @@ -8851,8 +8858,13 @@ disable_z(); //if(sd_print) if(eeprom_read_byte((uint8_t*)EEPROM_UVLO)==1){ eeprom_update_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z), current_position[Z_AXIS]); - eeprom_update_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS),z_microsteps); + eeprom_update_word((uint16_t*)(EEPROM_UVLO_TINY_Z_MICROSTEPS),z_microsteps); } + +if(eeprom_read_float((float*)EEPROM_UVLO_TINY_CURRENT_POSITION_Z) < 0.001f){ + eeprom_update_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z), eeprom_read_float((float*)EEPROM_UVLO_CURRENT_POSITION_Z)); +} + eeprom_update_byte((uint8_t*)EEPROM_UVLO,2); // Increment power failure counter @@ -8920,7 +8932,7 @@ void setup_uvlo_interrupt() { ISR(INT4_vect) { EIMSK &= ~(1 << 4); //disable INT4 interrupt to make sure that this code will be executed just once SERIAL_ECHOLNPGM("INT4"); - if(IS_SD_PRINTING && (!(eeprom_read_byte((uint8_t*)EEPROM_UVLO))) ) uvlo_(); + if((IS_SD_PRINTING || (eeprom_read_byte((uint8_t*)EEPROM_UVLO)!=2)) && (!(eeprom_read_byte((uint8_t*)EEPROM_UVLO)))) uvlo_(); if(eeprom_read_byte((uint8_t*)EEPROM_UVLO)) uvlo_tiny(); } @@ -8966,11 +8978,13 @@ void recover_machine_state_after_power_panic(bool bTiny) // 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. if(bTiny){ - current_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z)) + float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS)) + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS]; + current_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z)); + + float tinyDelta = 1.25*(mbl.get_z(0, 0) - mbl.get_z(current_position[X_AXIS], current_position[Y_AXIS])); + current_position[Z_AXIS] += tinyDelta; // compensate z-level } else{ - 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)) + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS]; + current_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z)); } if (eeprom_read_byte((uint8_t*)EEPROM_UVLO_E_ABS)) { current_position[E_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E)); @@ -8986,7 +9000,6 @@ void recover_machine_state_after_power_panic(bool bTiny) // 2) Initialize the logical to physical coordinate system transformation. world2machine_initialize(); - // 3) Restore the mesh bed leveling offsets. This is 2*7*7=98 bytes, which takes 98*3.4us=333us in worst case. mbl.active = false; for (int8_t mesh_point = 0; mesh_point < MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS; ++ mesh_point) { @@ -9079,8 +9092,8 @@ void restore_print_from_eeprom() { strcat_P(cmd, PSTR(" F2000")); enquecommand(cmd); // Move the Z axis down to the print, in logical coordinates. - strcpy_P(cmd, PSTR("G1 Z")); strcat(cmd, ftostr32( eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z)) - (UVLO_Z_AXIS_SHIFT + - float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS)) + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS]))); + strcpy_P(cmd, PSTR("G1 Z")); strcat(cmd, ftostr32( eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z)) + - (UVLO_Z_AXIS_SHIFT + float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS)) + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS]))); enquecommand(cmd); // Unretract. enquecommand_P(PSTR("G1 E" STRINGIFY(2*default_retraction)" F480")); From 2c4e98dc272a86f8269f7e3168653f2db461b886 Mon Sep 17 00:00:00 2001 From: NotaRobotexe Date: Wed, 5 Jun 2019 13:12:08 +0200 Subject: [PATCH 2/2] power panic improvement --- Firmware/Marlin_main.cpp | 76 ++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 9f25fdb61..676b67135 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1296,12 +1296,12 @@ void setup() #endif //TMC2130 - #ifdef UVLO_SUPPORT - setup_uvlo_interrupt(); - #endif //UVLO_SUPPORT - st_init(); // Initialize stepper, this enables interrupts! +#ifdef UVLO_SUPPORT + setup_uvlo_interrupt(); +#endif //UVLO_SUPPORT + #ifdef TMC2130 tmc2130_mode = silentMode?TMC2130_MODE_SILENT:TMC2130_MODE_NORMAL; update_mode_profile(); @@ -8690,6 +8690,7 @@ extern uint32_t sdpos_atomic; void uvlo_() { + printf_P(_N("******* UVLo 0 Current pos Z_AXIS:%.3f\nCurrent pos Z_AXIS:%.3f\n pos Z_AXIS:%.3f\n"), current_position[Z_AXIS], eeprom_read_float((float*)EEPROM_UVLO_TINY_CURRENT_POSITION_Z),eeprom_read_float((float*)EEPROM_UVLO_CURRENT_POSITION_Z)); unsigned long time_start = _millis(); bool sd_print = card.sdprinting; // Conserve power as soon as possible. @@ -8735,7 +8736,6 @@ void uvlo_() // Store the current extruder position. eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E), st_get_position_mm(E_AXIS)); eeprom_update_byte((uint8_t*)EEPROM_UVLO_E_ABS, axis_relative_modes[3]?0:1); - // Clean the input command queue. cmdqueue_reset(); card.sdprinting = false; @@ -8762,7 +8762,8 @@ void uvlo_() current_position[E_AXIS] - default_retraction, 40, active_extruder); st_synchronize(); - + disable_e0(); + plan_buffer_line( current_position[X_AXIS], current_position[Y_AXIS], @@ -8791,7 +8792,7 @@ void uvlo_() 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] + UVLO_Z_AXIS_SHIFT + float((1024 - z_microsteps + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS]); + eeprom_update_float((float*)EEPROM_UVLO_CURRENT_POSITION_Z , current_position[Z_AXIS]); // Store the current feed rate, temperatures, fan speed and extruder multipliers (flow rates) EEPROM_save_B(EEPROM_UVLO_FEEDRATE, &feedrate_bckp); eeprom_update_byte((uint8_t*)EEPROM_UVLO_TARGET_HOTEND, target_temperature[active_extruder]); @@ -8850,19 +8851,19 @@ tmc2130_set_current_r(Z_AXIS, 20); #ifdef TMC2130 z_microsteps=tmc2130_rd_MSCNT(Z_TMC2130_CS); #endif //TMC2130 - planner_abort_hard(); disable_z(); // Finaly store the "power outage" flag. //if(sd_print) -if(eeprom_read_byte((uint8_t*)EEPROM_UVLO)==1){ +if(eeprom_read_byte((uint8_t*)EEPROM_UVLO)!=2){ eeprom_update_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z), current_position[Z_AXIS]); eeprom_update_word((uint16_t*)(EEPROM_UVLO_TINY_Z_MICROSTEPS),z_microsteps); } if(eeprom_read_float((float*)EEPROM_UVLO_TINY_CURRENT_POSITION_Z) < 0.001f){ eeprom_update_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z), eeprom_read_float((float*)EEPROM_UVLO_CURRENT_POSITION_Z)); + eeprom_update_word((uint16_t*)(EEPROM_UVLO_TINY_Z_MICROSTEPS), eeprom_read_word((uint16_t*)EEPROM_UVLO_Z_MICROSTEPS)); } eeprom_update_byte((uint8_t*)EEPROM_UVLO,2); @@ -8870,7 +8871,6 @@ eeprom_update_byte((uint8_t*)EEPROM_UVLO,2); // Increment power failure counter 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); - wdt_enable(WDTO_500MS); WRITE(BEEPER,HIGH); while(1) @@ -8932,7 +8932,7 @@ void setup_uvlo_interrupt() { ISR(INT4_vect) { EIMSK &= ~(1 << 4); //disable INT4 interrupt to make sure that this code will be executed just once SERIAL_ECHOLNPGM("INT4"); - if((IS_SD_PRINTING || (eeprom_read_byte((uint8_t*)EEPROM_UVLO)!=2)) && (!(eeprom_read_byte((uint8_t*)EEPROM_UVLO)))) uvlo_(); + if((IS_SD_PRINTING ) || (!(eeprom_read_byte((uint8_t*)EEPROM_UVLO)))) uvlo_(); if(eeprom_read_byte((uint8_t*)EEPROM_UVLO)) uvlo_tiny(); } @@ -8941,11 +8941,13 @@ void recover_print(uint8_t automatic) { lcd_update_enable(true); lcd_update(2); lcd_setstatuspgm(_i("Recovering print "));////MSG_RECOVERING_PRINT c=20 r=1 - bool bTiny=(eeprom_read_byte((uint8_t*)EEPROM_UVLO)==2); - recover_machine_state_after_power_panic(bTiny); //recover position, temperatures and extrude_multipliers + + bool bTiny=(eeprom_read_byte((uint8_t*)EEPROM_UVLO)==2); + recover_machine_state_after_power_panic(bTiny); //recover position, temperatures and extrude_multipliers // Lift the print head, so one may remove the excess priming material. - if(!bTiny&&(current_position[Z_AXIS]<25)) + if(!bTiny&&(current_position[Z_AXIS]<25)) enquecommand_P(PSTR("G1 Z25 F800")); + // Home X and Y axes. Homing just X and Y shall not touch the babystep and the world2machine transformation status. enquecommand_P(PSTR("G28 X Y")); // Set the target bed and nozzle temperatures and wait. @@ -8975,16 +8977,32 @@ void recover_machine_state_after_power_panic(bool bTiny) // The logical XY coordinates are needed to recover the machine Z coordinate corrected by the mesh bed leveling. current_position[X_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0)); current_position[Y_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4)); + + // 2) Restore the mesh bed leveling offsets. This is 2*7*7=98 bytes, which takes 98*3.4us=333us in worst case. + mbl.active = false; + for (int8_t mesh_point = 0; mesh_point < MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS; ++ mesh_point) { + uint8_t ix = mesh_point % MESH_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1 + uint8_t iy = mesh_point / MESH_NUM_X_POINTS; + // Scale the z value to 10u resolution. + int16_t v; + eeprom_read_block(&v, (void*)(EEPROM_UVLO_MESH_BED_LEVELING_FULL+2*mesh_point), 2); + if (v != 0) + mbl.active = true; + mbl.z_values[iy][ix] = float(v) * 0.001f; + } + // 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. - if(bTiny){ - current_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z)); - - float tinyDelta = 1.25*(mbl.get_z(0, 0) - mbl.get_z(current_position[X_AXIS], current_position[Y_AXIS])); - current_position[Z_AXIS] += tinyDelta; // compensate z-level + if(bTiny){ + current_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_TINY_CURRENT_POSITION_Z)) + + float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_TINY_Z_MICROSTEPS)) + + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS]; + current_position[Z_AXIS] -= 0.4*mbl.get_z(current_position[X_AXIS], current_position[Y_AXIS]); } else{ - 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)) + + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS]; } if (eeprom_read_byte((uint8_t*)EEPROM_UVLO_E_ABS)) { current_position[E_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E)); @@ -8998,20 +9016,8 @@ void recover_machine_state_after_power_panic(bool bTiny) SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial "); print_world_coordinates(); - // 2) Initialize the logical to physical coordinate system transformation. + // 3) Initialize the logical to physical coordinate system transformation. world2machine_initialize(); - // 3) Restore the mesh bed leveling offsets. This is 2*7*7=98 bytes, which takes 98*3.4us=333us in worst case. - mbl.active = false; - for (int8_t mesh_point = 0; mesh_point < MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS; ++ mesh_point) { - uint8_t ix = mesh_point % MESH_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1 - uint8_t iy = mesh_point / MESH_NUM_X_POINTS; - // Scale the z value to 10u resolution. - int16_t v; - eeprom_read_block(&v, (void*)(EEPROM_UVLO_MESH_BED_LEVELING_FULL+2*mesh_point), 2); - if (v != 0) - mbl.active = true; - mbl.z_values[iy][ix] = float(v) * 0.001f; - } // SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial "); // print_mesh_bed_leveling_table(); @@ -9092,8 +9098,8 @@ void restore_print_from_eeprom() { strcat_P(cmd, PSTR(" F2000")); enquecommand(cmd); // Move the Z axis down to the print, in logical coordinates. - strcpy_P(cmd, PSTR("G1 Z")); strcat(cmd, ftostr32( eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z)) - - (UVLO_Z_AXIS_SHIFT + float((1024 - eeprom_read_word((uint16_t*)(EEPROM_UVLO_Z_MICROSTEPS)) + 7) >> 4) / cs.axis_steps_per_unit[Z_AXIS]))); + eeprom_update_byte((uint8_t*)EEPROM_UVLO,1); + strcpy_P(cmd, PSTR("G1 Z")); strcat(cmd, ftostr32(eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_Z)))); enquecommand(cmd); // Unretract. enquecommand_P(PSTR("G1 E" STRINGIFY(2*default_retraction)" F480"));