From 832e8819556dd482772e48bd9db9a3e0563a9455 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Wed, 10 Mar 2021 17:46:19 +0100 Subject: [PATCH 01/26] Disable M120 M121 --- Firmware/Marlin_main.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 547f4e21..fd2a6e39 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -6967,19 +6967,21 @@ Sigma_Exit: lcd_setstatus(strchr_pointer + 5); break;*/ +#if 0 //Disable these for the time being /*! - ### M120 - Enable endstops M120: Enable endstop detection + ### M120 - Enable endstops M120: Enable endstop detection */ case 120: enable_endstops(true) ; break; /*! - ### M121 - Disable endstops M121: Disable endstop detection + ### M121 - Disable endstops M121: Disable endstop detection */ case 121: enable_endstops(false) ; break; +#endif //0 /*! ### M119 - Get endstop states M119: Get Endstop Status From 6355458052f2be41e6e4ae038695920dae302192 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Thu, 11 Mar 2021 15:00:49 +0100 Subject: [PATCH 02/26] Add def `M120_M121_ENABLED` to `Configuration_adv.h` --- Firmware/Configuration_adv.h | 6 ++++++ Firmware/Marlin_main.cpp | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 75ac0be9..59590b6f 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -387,6 +387,12 @@ const unsigned int dropsegments=5; //everything with less than this number of st */ #define EXTENDED_CAPABILITIES_REPORT +/** + * Enable M120/M121 G-code commands + * + */ +//#define M120_M121_ENABLED //Be careful enabling and using these G-code commands. + //=========================================================================== //============================= Define Defines ============================ //=========================================================================== diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index fd2a6e39..fb61b872 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -6967,7 +6967,7 @@ Sigma_Exit: lcd_setstatus(strchr_pointer + 5); break;*/ -#if 0 //Disable these for the time being +#ifdef M120_M121_ENABLED /*! ### M120 - Enable endstops M120: Enable endstop detection */ @@ -6981,7 +6981,7 @@ Sigma_Exit: case 121: enable_endstops(false) ; break; -#endif //0 +#endif //M120_M121_ENABLED /*! ### M119 - Get endstop states M119: Get Endstop Status From 99206884b5e46a098b3b65a1414416eb35fd58b4 Mon Sep 17 00:00:00 2001 From: espr14 Date: Fri, 12 Mar 2021 05:04:49 +0100 Subject: [PATCH 03/26] Calibration: detect biased PINDA and retry calibration PFW-1223 --- Firmware/mesh_bed_calibration.cpp | 43 ++++++++++++++++++++------- Firmware/mesh_bed_calibration.h | 17 +++++------ Firmware/xyzcal.cpp | 48 +++++++++++++++++++++++++------ Firmware/xyzcal.h | 13 ++------- 4 files changed, 84 insertions(+), 37 deletions(-) diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp index b4490e93..22a8d7b9 100644 --- a/Firmware/mesh_bed_calibration.cpp +++ b/Firmware/mesh_bed_calibration.cpp @@ -1,4 +1,3 @@ -#include "Marlin.h" #include "Configuration.h" #include "ConfigurationStore.h" #include "language.h" @@ -1065,7 +1064,7 @@ error: } #ifdef NEW_XYZCAL -bool xyzcal_find_bed_induction_sensor_point_xy(); +BedSkewOffsetDetectionResultType xyzcal_find_bed_induction_sensor_point_xy(); #endif //NEW_XYZCAL // Search around the current_position[X,Y], // look for the induction sensor response. @@ -1081,7 +1080,7 @@ bool xyzcal_find_bed_induction_sensor_point_xy(); #endif //HEATBED_V2 #ifdef HEATBED_V2 -bool find_bed_induction_sensor_point_xy(int +BedSkewOffsetDetectionResultType find_bed_induction_sensor_point_xy(int #if !defined (NEW_XYZCAL) && defined (SUPPORT_VERBOSITY) verbosity_level #endif @@ -1137,7 +1136,7 @@ bool find_bed_induction_sensor_point_xy(int // go_xyz(current_position[X_AXIS], current_position[Y_AXIS], MESH_HOME_Z_SEARCH, homing_feedrate[Z_AXIS]/60); go_xyz(x0, y0, current_position[Z_AXIS], feedrate); - // Continously lower the Z axis. + // Continuously lower the Z axis. endstops_hit_on_purpose(); enable_z_endstop(true); bool direction = false; @@ -1335,7 +1334,7 @@ bool find_bed_induction_sensor_point_xy(int #endif //NEW_XYZCAL } #else //HEATBED_V2 -bool find_bed_induction_sensor_point_xy(int verbosity_level) +BedSkewOffsetDetectionResultType find_bed_induction_sensor_point_xy(int verbosity_level) { #ifdef NEW_XYZCAL return xyzcal_find_bed_induction_sensor_point_xy(); @@ -1531,7 +1530,9 @@ bool find_bed_induction_sensor_point_xy(int verbosity_level) } enable_z_endstop(false); - return found; + if (found) + return BED_SKEW_OFFSET_DETECTION_POINT_FOUND; + return BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND; #endif //NEW_XYZCAL } @@ -2238,9 +2239,15 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level // Collect the rear 2x3 points. current_position[Z_AXIS] = MESH_HOME_Z_SEARCH + FIND_BED_INDUCTION_SENSOR_POINT_Z_STEP * iteration * 0.3; - for (int k = 0; k < 4; ++k) { - // Don't let the manage_inactivity() function remove power from the motors. - refresh_cmd_timeout(); + + /// Retry point scanning if a point with bad data appears. + /// Bad data could be cause by "cold" sensor. + /// This behavior vanishes after few point scans so retry will help. + for (int retries = 0; retries <= 1; ++retries) { + bool retry = false; + for (int k = 0; k < 4; ++k) { + // Don't let the manage_inactivity() function remove power from the motors. + refresh_cmd_timeout(); #ifdef MESH_BED_CALIBRATION_SHOW_LCD lcd_set_cursor(0, next_line); lcd_print(k + 1); @@ -2304,8 +2311,19 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level if (verbosity_level >= 10) delay_keep_alive(3000); #endif // SUPPORT_VERBOSITY - if (!find_bed_induction_sensor_point_xy(verbosity_level)) - return BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND; + + BedSkewOffsetDetectionResultType result; + result = find_bed_induction_sensor_point_xy(verbosity_level); + switch(result){ + case BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND: + return BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND; + case BED_SKEW_OFFSET_DETECTION_POINT_SCAN_FAILED: + retry = true; + break; + default: + break; + } + #ifndef NEW_XYZCAL #ifndef HEATBED_V2 @@ -2380,6 +2398,9 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level } #endif // SUPPORT_VERBOSITY } + if (!retry) + break; + } DBG(_n("All 4 calibration points found.\n")); delay_keep_alive(0); //manage_heater, reset watchdog, manage inactivity diff --git a/Firmware/mesh_bed_calibration.h b/Firmware/mesh_bed_calibration.h index 7ca93c95..c539d4b5 100644 --- a/Firmware/mesh_bed_calibration.h +++ b/Firmware/mesh_bed_calibration.h @@ -1,5 +1,6 @@ -#ifndef MESH_BED_CALIBRATION_H -#define MESH_BED_CALIBRATION_H +#pragma once + +#include "Marlin.h" #define BED_ZERO_REF_X (- 22.f + X_PROBE_OFFSET_FROM_EXTRUDER) // -22 + 23 = 1 #define BED_ZERO_REF_Y (- 0.6f + Y_PROBE_OFFSET_FROM_EXTRUDER + 4.f) // -0.6 + 5 + 4 = 8.4 @@ -145,11 +146,6 @@ inline bool world2machine_clamp(float &x, float &y) machine2world(tmpx, tmpy, x, y); return clamped; } - -bool find_bed_induction_sensor_point_z(float minimum_z = -10.f, uint8_t n_iter = 3, int verbosity_level = 0); -bool find_bed_induction_sensor_point_xy(int verbosity_level = 0); -void go_home_with_z_lift(); - /** * @brief Bed skew and offest detection result * @@ -159,8 +155,10 @@ void go_home_with_z_lift(); enum BedSkewOffsetDetectionResultType { // Detection failed, some point was not found. + BED_SKEW_OFFSET_DETECTION_POINT_FOUND = 0, //!< Point found BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND = -1, //!< Point not found. BED_SKEW_OFFSET_DETECTION_FITTING_FAILED = -2, //!< Fitting failed + BED_SKEW_OFFSET_DETECTION_POINT_SCAN_FAILED = -3, //!< Point scan failed, try again // Detection finished with success. BED_SKEW_OFFSET_DETECTION_PERFECT = 0, //!< Perfect. @@ -168,6 +166,10 @@ enum BedSkewOffsetDetectionResultType { BED_SKEW_OFFSET_DETECTION_SKEW_EXTREME = 2 //!< Extremely skewed. }; +bool find_bed_induction_sensor_point_z(float minimum_z = -10.f, uint8_t n_iter = 3, int verbosity_level = 0); +BedSkewOffsetDetectionResultType find_bed_induction_sensor_point_xy(int verbosity_level = 0); +void go_home_with_z_lift(); + extern BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level, uint8_t &too_far_mask); #ifndef NEW_XYZCAL extern BedSkewOffsetDetectionResultType improve_bed_offset_and_skew(int8_t method, int8_t verbosity_level, uint8_t &too_far_mask); @@ -213,4 +215,3 @@ extern void mbl_settings_init(); extern bool mbl_point_measurement_valid(uint8_t ix, uint8_t iy, uint8_t meas_points, bool zigzag); extern void mbl_interpolation(uint8_t meas_points); -#endif /* MESH_BED_CALIBRATION_H */ diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index 9293c2e8..e738c353 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -837,7 +837,7 @@ void dynamic_circle(uint8_t *matrix_32x32, float &x, float &y, float &r, uint8_t for (int8_t i = iterations; i > 0; --i){ //@size=128B - DBG(_n(" [%f, %f][%f] circle\n"), x, y, r); + // DBG(_n(" [%f, %f][%f] circle\n"), x, y, r); /// read points on the circle for (uint8_t p = 0; p < num_points; ++p){ @@ -904,12 +904,42 @@ uint8_t find_patterns(uint8_t *matrix32, uint16_t *pattern08, uint16_t *pattern1 return match10; } +/// Scan should include normal data. +/// If it's too extreme (00, FF) it could be caused by biased sensor. +/// \return true if data looks normal +bool check_scan(uint8_t *matrix32){ + /// magic constants that define normality + const int16_t threshold_total = 900; + const int threshold_extreme = 50; + + int16_t mins = 0; + int16_t maxs = 0; + + for (int16_t i = 0; i < 32*32;++i){ + if (matrix32[i] == 0) { + ++mins; + } else { + ++maxs; + } + } + const int16_t rest = 1024 - mins - maxs; + + if (mins + maxs > threshold_total + && mins > threshold_extreme + && maxs > threshold_extreme + && mins > rest + && maxs > rest) + return false; + + return true; +} + /// scans area around the current head location and /// searches for the center of the calibration pin -bool xyzcal_scan_and_process(void){ +BedSkewOffsetDetectionResultType xyzcal_scan_and_process(){ //@size=44 - DBG(_n("sizeof(block_buffer)=%d\n"), sizeof(block_t)*BLOCK_BUFFER_SIZE); - bool ret = false; + // DBG(_n("sizeof(block_buffer)=%d\n"), sizeof(block_t)*BLOCK_BUFFER_SIZE); + BedSkewOffsetDetectionResultType ret = BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND; int16_t x = _X; int16_t y = _Y; const int16_t z = _Z; @@ -925,6 +955,8 @@ bool xyzcal_scan_and_process(void){ xyzcal_scan_pixels_32x32_Zhop(x, y, z, 2400, 200, matrix32); print_image(matrix32); + if (!check_scan(matrix32)) + return BED_SKEW_OFFSET_DETECTION_POINT_SCAN_FAILED; /// SEARCH FOR BINARY CIRCLE uint8_t uc = 0; @@ -955,7 +987,7 @@ bool xyzcal_scan_and_process(void){ x = round_to_i16(xf); y = round_to_i16(yf); xyzcal_lineXYZ_to(x, y, z, 200, 0); - ret = true; + ret = BED_SKEW_OFFSET_DETECTION_POINT_FOUND; } /// wipe buffer @@ -964,11 +996,11 @@ bool xyzcal_scan_and_process(void){ return ret; } -bool xyzcal_find_bed_induction_sensor_point_xy(void){ - bool ret = false; +BedSkewOffsetDetectionResultType xyzcal_find_bed_induction_sensor_point_xy(void){ + BedSkewOffsetDetectionResultType ret = BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND; //@size=258 - DBG(_n("xyzcal_find_bed_induction_sensor_point_xy x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]); + // DBG(_n("xyzcal_find_bed_induction_sensor_point_xy x=%ld y=%ld z=%ld\n"), count_position[X_AXIS], count_position[Y_AXIS], count_position[Z_AXIS]); st_synchronize(); xyzcal_meassure_enter(); diff --git a/Firmware/xyzcal.h b/Firmware/xyzcal.h index 348ff3ce..8f908bbe 100644 --- a/Firmware/xyzcal.h +++ b/Firmware/xyzcal.h @@ -1,9 +1,9 @@ //xyzcal.h - xyz calibration with image processing -#ifndef _XYZCAL_H -#define _XYZCAL_H +#pragma once #include +#include "mesh_bed_calibration.h" extern void xyzcal_meassure_enter(void); @@ -17,11 +17,4 @@ extern bool xyzcal_spiral8(int16_t cx, int16_t cy, int16_t z0, int16_t dz, int16 //extern int8_t xyzcal_meassure_pinda_hysterezis(int16_t min_z, int16_t max_z, uint16_t delay_us, uint8_t samples); -extern bool xyzcal_searchZ(void); - -extern bool xyzcal_scan_and_process(void); - -extern bool xyzcal_find_bed_induction_sensor_point_xy(void); - - -#endif //_XYZCAL_H +extern BedSkewOffsetDetectionResultType xyzcal_find_bed_induction_sensor_point_xy(); From f31189e5be11e8fac7ddf3d8cf707d540d6a7ef6 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 17 Mar 2021 12:30:54 +0100 Subject: [PATCH 04/26] Version changed (3.10.0-RC1 build 4078) --- Firmware/Configuration.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 62688ebe..d390283f 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -16,8 +16,8 @@ extern uint16_t nPrinterType; extern PGM_P sPrinterName; // Firmware version -#define FW_VERSION "3.9.3" -#define FW_COMMIT_NR 3556 +#define FW_VERSION "3.10.0-RC1" +#define FW_COMMIT_NR 4078 // 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 From 8ac1d5b95eb205a385063c4b5369bad69432f465 Mon Sep 17 00:00:00 2001 From: DRracer Date: Fri, 19 Mar 2021 10:18:28 +0100 Subject: [PATCH 05/26] Attempt to workaround the M73 C0|D0 visual issue (#3067) Attempt to workaround the M73 C0|D0 visual issue This is an attempt to enable alternation of time to print finish and time to color change even in the last minute of time to color change, i.e. be able to print "0:00C". The proposed solution leverages the capability of the current FW to read float values from the C|D parameter. This could have the raw benefit of being able still to alternate this time on the LCD as "0:00C" (or "<1min") if the slicer sends a non-zero but <1 time right before the color change. Co-authored-by: D.R.racer Co-authored-by: 3d-gussner <3d.gussner@gmail.com> --- Firmware/Marlin.h | 4 ++-- Firmware/Marlin_main.cpp | 23 ++++++++++++++--------- Firmware/ultralcd.cpp | 10 +++++----- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index cc2766b4..98e5102c 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -363,8 +363,8 @@ extern bool mmu_print_saved; //estimated time to end of the print extern uint8_t print_percent_done_normal; -extern uint16_t print_time_remaining_normal; extern uint8_t print_percent_done_silent; +extern uint16_t print_time_remaining_normal; extern uint16_t print_time_remaining_silent; extern uint16_t print_time_to_change_normal; extern uint16_t print_time_to_change_silent; @@ -376,7 +376,7 @@ extern uint16_t gcode_in_progress; extern LongTimer safetyTimer; -#define PRINT_PERCENT_DONE_INIT 0xff +#define PRINT_PERCENT_DONE_INIT 0xff #define PRINTER_ACTIVE (IS_SD_PRINTING || is_usb_printing || isPrintPaused || (custom_message_type == CustomMsg::TempCal) || saved_printing || (lcd_commands_type == LcdCommands::Layer1Cal) || mmu_print_saved || homing_flag || mesh_bed_leveling_flag) //! Beware - mcode_in_progress is set as soon as the command gets really processed, diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 547f4e21..9386e753 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -313,8 +313,8 @@ bool mmu_print_saved = false; // storing estimated time to end of print counted by slicer uint8_t print_percent_done_normal = PRINT_PERCENT_DONE_INIT; -uint16_t print_time_remaining_normal = PRINT_TIME_REMAINING_INIT; //estimated remaining print time in minutes uint8_t print_percent_done_silent = PRINT_PERCENT_DONE_INIT; +uint16_t print_time_remaining_normal = PRINT_TIME_REMAINING_INIT; //estimated remaining print time in minutes uint16_t print_time_remaining_silent = PRINT_TIME_REMAINING_INIT; //estimated remaining print time in minutes uint16_t print_time_to_change_normal = PRINT_TIME_REMAINING_INIT; //estimated remaining time to next change in minutes uint16_t print_time_to_change_silent = PRINT_TIME_REMAINING_INIT; //estimated remaining time to next change in minutes @@ -6389,14 +6389,19 @@ Sigma_Exit: if(code_seen('R')) print_time_remaining_normal = code_value(); if(code_seen('Q')) print_percent_done_silent = code_value(); if(code_seen('S')) print_time_remaining_silent = code_value(); - if(code_seen('C')) print_time_to_change_normal = code_value(); - if(code_seen('D')) print_time_to_change_silent = code_value(); - - { - const char* _msg_mode_done_remain = _N("%S MODE: Percent done: %d; print time remaining in mins: %d; Change in mins: %d\n"); - printf_P(_msg_mode_done_remain, _N("NORMAL"), int(print_percent_done_normal), print_time_remaining_normal, print_time_to_change_normal); - printf_P(_msg_mode_done_remain, _N("SILENT"), int(print_percent_done_silent), print_time_remaining_silent, print_time_to_change_silent); - } + if(code_seen('C')){ + float print_time_to_change_normal_f = code_value_float(); + print_time_to_change_normal = ( print_time_to_change_normal_f <= 0 ) ? PRINT_TIME_REMAINING_INIT : print_time_to_change_normal_f; + } + if(code_seen('D')){ + float print_time_to_change_silent_f = code_value_float(); + print_time_to_change_silent = ( print_time_to_change_silent_f <= 0 ) ? PRINT_TIME_REMAINING_INIT : print_time_to_change_silent_f; + } + { + const char* _msg_mode_done_remain = _N("%S MODE: Percent done: %hhd; print time remaining in mins: %d; Change in mins: %d\n"); + printf_P(_msg_mode_done_remain, _N("NORMAL"), int8_t(print_percent_done_normal), print_time_remaining_normal, print_time_to_change_normal); + printf_P(_msg_mode_done_remain, _N("SILENT"), int8_t(print_percent_done_silent), print_time_remaining_silent, print_time_to_change_silent); + } break; } /*! diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index e1d89c3f..5ac1a0cc 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -510,9 +510,9 @@ void lcdui_print_time(void) //if remaining print time estimation is available print it else print elapsed time int chars = 0; if (PRINTER_ACTIVE) { - uint16_t print_t = 0; - uint16_t print_tr = 0; - uint16_t print_tc = 0; + uint16_t print_t = PRINT_TIME_REMAINING_INIT; + uint16_t print_tr = PRINT_TIME_REMAINING_INIT; + uint16_t print_tc = PRINT_TIME_REMAINING_INIT; char suff = ' '; char suff_doubt = ' '; @@ -542,12 +542,12 @@ void lcdui_print_time(void) clock_interval++; - if (print_tc != 0 && clock_interval > CLOCK_INTERVAL_TIME) { + if (print_tc != PRINT_TIME_REMAINING_INIT && clock_interval > CLOCK_INTERVAL_TIME) { print_t = print_tc; suff = 'C'; } else //#endif //CLOCK_INTERVAL_TIME - if (print_tr != 0) { + if (print_tr != PRINT_TIME_REMAINING_INIT) { print_t = print_tr; suff = 'R'; } else From cdcc06f3769967857eeba263e748d021aa1a921b Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Mon, 29 Mar 2021 12:21:42 +0200 Subject: [PATCH 06/26] SDFile - fix errorneous offset computation ... my fault, I was originally too optimistic about the overflow Fixes #3077 PFW-1233 --- Firmware/SdFile.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Firmware/SdFile.cpp b/Firmware/SdFile.cpp index 1bad4319..e21144ee 100644 --- a/Firmware/SdFile.cpp +++ b/Firmware/SdFile.cpp @@ -178,14 +178,17 @@ eof_or_fail: } bool SdFile::gfEnsureBlock(){ - if ( vol_->cacheRawBlock(gfBlock, SdVolume::CACHE_FOR_READ)){ + // this comparison is heavy-weight, especially when there is another one inside cacheRawBlock + // but it is necessary to avoid computing of terminateOfs if not needed + if( gfBlock != vol_->cacheBlockNumber_ ){ + if ( ! vol_->cacheRawBlock(gfBlock, SdVolume::CACHE_FOR_READ)){ + return false; + } // terminate with a '\n' - const uint16_t terminateOfs = fileSize_ - gfOffset; + const uint32_t terminateOfs = fileSize_ - gfOffset; vol_->cache()->data[ terminateOfs < 512 ? terminateOfs : 512 ] = '\n'; - return true; - } else { - return false; } + return true; } bool SdFile::gfComputeNextFileBlock() { From 6a61c26955fb9d1bdf492789545fce45073c17f7 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 5 Apr 2021 20:04:50 +0200 Subject: [PATCH 07/26] Removed unused crashdet_stop_and_save_print2 --- Firmware/Marlin_main.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 547f4e21..982a93db 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -588,19 +588,6 @@ void crashdet_restore_print_and_continue() // babystep_apply(); } - -void crashdet_stop_and_save_print2() -{ - cli(); - planner_abort_hard(); //abort printing - cmdqueue_reset(); //empty cmdqueue - card.sdprinting = false; - card.closefile(); - // Reset and re-enable the stepper timer just before the global interrupts are enabled. - st_reset_timer(); - sei(); -} - void crashdet_detected(uint8_t mask) { st_synchronize(); From 3276320a062554b161df9e060dbbc1fcb70c4eaf Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 5 Apr 2021 20:07:03 +0200 Subject: [PATCH 08/26] Hide tmc2130_sg_change behind DEBUG_CRASHDET_COUNTERS tmc2130_sg_change is only used for debugging purposes. Hide definition and usage behind the required define. --- Firmware/tmc2130.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Firmware/tmc2130.cpp b/Firmware/tmc2130.cpp index 3f682690..480efb2b 100755 --- a/Firmware/tmc2130.cpp +++ b/Firmware/tmc2130.cpp @@ -68,8 +68,9 @@ uint8_t tmc2130_sg_diag_mask = 0x00; 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}; +#ifdef DEBUG_CRASHDET_COUNTERS bool tmc2130_sg_change = false; - +#endif bool skip_debug_msg = false; @@ -255,7 +256,9 @@ void tmc2130_st_isr() if (tmc2130_sg_cnt[axis] < tmc2130_sg_err[axis]) { tmc2130_sg_cnt[axis] = tmc2130_sg_err[axis]; +#ifdef DEBUG_CRASHDET_COUNTERS tmc2130_sg_change = true; +#endif uint8_t sg_thr = 64; // if (axis == Y_AXIS) sg_thr = 64; if (tmc2130_sg_err[axis] >= sg_thr) @@ -409,7 +412,9 @@ void tmc2130_check_overtemp() } checktime = _millis(); +#ifdef DEBUG_CRASHDET_COUNTERS tmc2130_sg_change = true; +#endif } #ifdef DEBUG_CRASHDET_COUNTERS if (tmc2130_sg_change) From d2be40491b62ea2169c431a734a48319ff0940f7 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 5 Apr 2021 22:11:06 +0200 Subject: [PATCH 09/26] PP recovery: clamp initial position to software endstops As done when initializing the printer from a cold start, we need to clamp the starting position to software endstops before setting the planner position since 0,0 is frequently out-of-bounds. This avoids an useless move during recovery that can cause a crash: - Initial X is set to be 0 - G1 performed by homing will clamp X>=0, resulting in a positive shift - If X is already at max X (extruder being parked due to PP), this will slam at X+, causing an immediate crash. --- Firmware/Marlin_main.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 982a93db..56da2276 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -11169,11 +11169,6 @@ bool recover_machine_state_after_power_panic() // Recover last E axis position current_position[E_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E)); - memcpy(destination, current_position, sizeof(destination)); - - SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial "); - print_world_coordinates(); - // 3) Initialize the logical to physical coordinate system transformation. world2machine_initialize(); // SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial "); @@ -11185,7 +11180,11 @@ bool recover_machine_state_after_power_panic() // 5) Set the physical positions from the logical positions using the world2machine transformation // This is only done to inizialize Z/E axes with physical locations, since X/Y are unknown. + clamp_to_software_endstops(current_position); + memcpy(destination, current_position, sizeof(destination)); plan_set_position_curposXYZE(); + SERIAL_ECHOPGM("recover_machine_state_after_power_panic, initial "); + print_world_coordinates(); // 6) Power up the Z motors, mark their positions as known. axis_known_position[Z_AXIS] = true; From ce2e35d14d4365318b2a51b491623449fc4776f7 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 5 Apr 2021 23:35:17 +0200 Subject: [PATCH 10/26] Move G80 into it's own function No actual changes done in the function in this, besides break->return. In G28, simply call the new function instead of using goto, making the code more readable. Also remove the senseless comments in G28 about command queuing (dating back to when G80 was queued instead of being executed). --- Firmware/Marlin_main.cpp | 798 ++++++++++++++++++++------------------- 1 file changed, 400 insertions(+), 398 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 56da2276..451363c9 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -2941,6 +2941,403 @@ static void gcode_G28(bool home_x_axis, bool home_y_axis, bool home_z_axis) #endif //TMC2130 } + +// G80 - Automatic mesh bed leveling +static void gcode_G80() +{ + mesh_bed_leveling_flag = true; +#ifndef PINDA_THERMISTOR + static bool run = false; // thermistor-less PINDA temperature compensation is running +#endif // ndef PINDA_THERMISTOR + +#ifdef SUPPORT_VERBOSITY + int8_t verbosity_level = 0; + if (code_seen('V')) { + // Just 'V' without a number counts as V1. + char c = strchr_pointer[1]; + verbosity_level = (c == ' ' || c == '\t' || c == 0) ? 1 : code_value_short(); + } +#endif //SUPPORT_VERBOSITY + // Firstly check if we know where we are + 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! + // There shall be always enough space reserved for these commands. + repeatcommand_front(); // repeat G80 with all its parameters + enquecommand_front_P(G28W0); + return; + } + + uint8_t nMeasPoints = MESH_MEAS_NUM_X_POINTS; + if (code_seen('N')) { + nMeasPoints = code_value_uint8(); + if (nMeasPoints != 7) { + nMeasPoints = 3; + } + } + else { + nMeasPoints = eeprom_read_byte((uint8_t*)EEPROM_MBL_POINTS_NR); + } + + uint8_t nProbeRetry = 3; + if (code_seen('R')) { + nProbeRetry = code_value_uint8(); + if (nProbeRetry > 10) { + nProbeRetry = 10; + } + } + else { + nProbeRetry = eeprom_read_byte((uint8_t*)EEPROM_MBL_PROBE_NR); + } + bool magnet_elimination = (eeprom_read_byte((uint8_t*)EEPROM_MBL_MAGNET_ELIMINATION) > 0); + +#ifndef PINDA_THERMISTOR + if (run == false && temp_cal_active == true && calibration_status_pinda() == true && target_temperature_bed >= 50) + { + temp_compensation_start(); + run = true; + repeatcommand_front(); // repeat G80 with all its parameters + enquecommand_front_P(G28W0); + break; + } + run = false; +#endif //PINDA_THERMISTOR + // Save custom message state, set a new custom message state to display: Calibrating point 9. + CustomMsg custom_message_type_old = custom_message_type; + unsigned int custom_message_state_old = custom_message_state; + custom_message_type = CustomMsg::MeshBedLeveling; + custom_message_state = (nMeasPoints * nMeasPoints) + 10; + lcd_update(1); + + mbl.reset(); //reset mesh bed leveling + + // Reset baby stepping to zero, if the babystepping has already been loaded before. + babystep_undo(); + + // Cycle through all points and probe them + // First move up. During this first movement, the babystepping will be reverted. + current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; + plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60); + // The move to the first calibration point. + current_position[X_AXIS] = BED_X0; + current_position[Y_AXIS] = BED_Y0; + +#ifdef SUPPORT_VERBOSITY + if (verbosity_level >= 1) + { + bool clamped = world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); + clamped ? SERIAL_PROTOCOLPGM("First calibration point clamped.\n") : SERIAL_PROTOCOLPGM("No clamping for first calibration point.\n"); + } +#else //SUPPORT_VERBOSITY + world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); +#endif //SUPPORT_VERBOSITY + + plan_buffer_line_curposXYZE(homing_feedrate[X_AXIS] / 30); + // Wait until the move is finished. + st_synchronize(); + + uint8_t mesh_point = 0; //index number of calibration point + + int XY_AXIS_FEEDRATE = homing_feedrate[X_AXIS] / 20; + int Z_LIFT_FEEDRATE = homing_feedrate[Z_AXIS] / 40; + bool has_z = is_bed_z_jitter_data_valid(); //checks if we have data from Z calibration (offsets of the Z heiths of the 8 calibration points from the first point) +#ifdef SUPPORT_VERBOSITY + if (verbosity_level >= 1) { + has_z ? SERIAL_PROTOCOLPGM("Z jitter data from Z cal. valid.\n") : SERIAL_PROTOCOLPGM("Z jitter data from Z cal. not valid.\n"); + } +#endif // SUPPORT_VERBOSITY + int l_feedmultiply = setup_for_endstop_move(false); //save feedrate and feedmultiply, sets feedmultiply to 100 + while (mesh_point != nMeasPoints * nMeasPoints) { + // Get coords of a measuring point. + uint8_t ix = mesh_point % nMeasPoints; // from 0 to MESH_NUM_X_POINTS - 1 + uint8_t iy = mesh_point / nMeasPoints; + /*if (!mbl_point_measurement_valid(ix, iy, nMeasPoints, true)) { + printf_P(PSTR("Skipping point [%d;%d] \n"), ix, iy); + custom_message_state--; + mesh_point++; + continue; //skip + }*/ + if (iy & 1) ix = (nMeasPoints - 1) - ix; // Zig zag + if (nMeasPoints == 7) //if we have 7x7 mesh, compare with Z-calibration for points which are in 3x3 mesh + { + has_z = ((ix % 3 == 0) && (iy % 3 == 0)) && is_bed_z_jitter_data_valid(); + } + float z0 = 0.f; + if (has_z && (mesh_point > 0)) { + uint16_t z_offset_u = 0; + if (nMeasPoints == 7) { + z_offset_u = eeprom_read_word((uint16_t*)(EEPROM_BED_CALIBRATION_Z_JITTER + 2 * ((ix/3) + iy - 1))); + } + else { + z_offset_u = eeprom_read_word((uint16_t*)(EEPROM_BED_CALIBRATION_Z_JITTER + 2 * (ix + iy * 3 - 1))); + } + z0 = mbl.z_values[0][0] + *reinterpret_cast(&z_offset_u) * 0.01; +#ifdef SUPPORT_VERBOSITY + if (verbosity_level >= 1) { + printf_P(PSTR("Bed leveling, point: %d, calibration Z stored in eeprom: %d, calibration z: %f \n"), mesh_point, z_offset_u, z0); + } +#endif // SUPPORT_VERBOSITY + } + + // Move Z up to MESH_HOME_Z_SEARCH. + if((ix == 0) && (iy == 0)) current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; + else current_position[Z_AXIS] += 2.f / nMeasPoints; //use relative movement from Z coordinate where PINDa triggered on previous point. This makes calibration faster. + float init_z_bckp = current_position[Z_AXIS]; + plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE); + st_synchronize(); + + // Move to XY position of the sensor point. + current_position[X_AXIS] = BED_X(ix, nMeasPoints); + current_position[Y_AXIS] = BED_Y(iy, nMeasPoints); + + //printf_P(PSTR("[%f;%f]\n"), current_position[X_AXIS], current_position[Y_AXIS]); + + +#ifdef SUPPORT_VERBOSITY + if (verbosity_level >= 1) { + bool clamped = world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); + SERIAL_PROTOCOL(mesh_point); + clamped ? SERIAL_PROTOCOLPGM(": xy clamped.\n") : SERIAL_PROTOCOLPGM(": no xy clamping\n"); + } +#else //SUPPORT_VERBOSITY + world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); +#endif // SUPPORT_VERBOSITY + + //printf_P(PSTR("after clamping: [%f;%f]\n"), current_position[X_AXIS], current_position[Y_AXIS]); + plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE); + st_synchronize(); + + // Go down until endstop is hit + const float Z_CALIBRATION_THRESHOLD = 1.f; + if (!find_bed_induction_sensor_point_z((has_z && mesh_point > 0) ? z0 - Z_CALIBRATION_THRESHOLD : -10.f, nProbeRetry)) { //if we have data from z calibration max allowed difference is 1mm for each point, if we dont have data max difference is 10mm from initial point + printf_P(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); + break; + } + if (init_z_bckp - current_position[Z_AXIS] < 0.1f) { //broken cable or initial Z coordinate too low. Go to MESH_HOME_Z_SEARCH and repeat last step (z-probe) again to distinguish between these two cases. + //printf_P(PSTR("Another attempt! Current Z position: %f\n"), current_position[Z_AXIS]); + current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; + plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE); + st_synchronize(); + + if (!find_bed_induction_sensor_point_z((has_z && mesh_point > 0) ? z0 - Z_CALIBRATION_THRESHOLD : -10.f, nProbeRetry)) { //if we have data from z calibration max allowed difference is 1mm for each point, if we dont have data max difference is 10mm from initial point + printf_P(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); + break; + } + if (MESH_HOME_Z_SEARCH - current_position[Z_AXIS] < 0.1f) { + puts_P(PSTR("Bed leveling failed. Sensor disconnected or cable broken.")); + break; + } + } + if (has_z && fabs(z0 - current_position[Z_AXIS]) > Z_CALIBRATION_THRESHOLD) { //if we have data from z calibration, max. allowed difference is 1mm for each point + puts_P(PSTR("Bed leveling failed. Sensor triggered too high.")); + break; + } +#ifdef SUPPORT_VERBOSITY + if (verbosity_level >= 10) { + SERIAL_ECHOPGM("X: "); + MYSERIAL.print(current_position[X_AXIS], 5); + SERIAL_ECHOLNPGM(""); + SERIAL_ECHOPGM("Y: "); + MYSERIAL.print(current_position[Y_AXIS], 5); + SERIAL_PROTOCOLPGM("\n"); + } +#endif // SUPPORT_VERBOSITY + float offset_z = 0; + +#ifdef PINDA_THERMISTOR + offset_z = temp_compensation_pinda_thermistor_offset(current_temperature_pinda); +#endif //PINDA_THERMISTOR + // #ifdef SUPPORT_VERBOSITY + /* if (verbosity_level >= 1) + { + SERIAL_ECHOPGM("mesh bed leveling: "); + MYSERIAL.print(current_position[Z_AXIS], 5); + SERIAL_ECHOPGM(" offset: "); + MYSERIAL.print(offset_z, 5); + SERIAL_ECHOLNPGM(""); + }*/ + // #endif // SUPPORT_VERBOSITY + mbl.set_z(ix, iy, current_position[Z_AXIS] - offset_z); //store measured z values z_values[iy][ix] = z - offset_z; + + custom_message_state--; + mesh_point++; + lcd_update(1); + } + current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; +#ifdef SUPPORT_VERBOSITY + if (verbosity_level >= 20) { + SERIAL_ECHOLNPGM("Mesh bed leveling while loop finished."); + SERIAL_ECHOLNPGM("MESH_HOME_Z_SEARCH: "); + MYSERIAL.print(current_position[Z_AXIS], 5); + } +#endif // SUPPORT_VERBOSITY + plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE); + st_synchronize(); + if (mesh_point != nMeasPoints * nMeasPoints) { + Sound_MakeSound(e_SOUND_TYPE_StandardAlert); + bool bState; + do { // repeat until Z-leveling o.k. + lcd_display_message_fullscreen_P(_i("Some problem encountered, Z-leveling enforced ...")); +#ifdef TMC2130 + lcd_wait_for_click_delay(MSG_BED_LEVELING_FAILED_TIMEOUT); + calibrate_z_auto(); // Z-leveling (X-assembly stay up!!!) +#else // TMC2130 + lcd_wait_for_click_delay(0); // ~ no timeout + lcd_calibrate_z_end_stop_manual(true); // Z-leveling (X-assembly stay up!!!) +#endif // TMC2130 + // ~ Z-homing (can not be used "G28", because X & Y-homing would have been done before (Z-homing)) + bState=enable_z_endstop(false); + current_position[Z_AXIS] -= 1; + plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40); + st_synchronize(); + enable_z_endstop(true); +#ifdef TMC2130 + tmc2130_home_enter(Z_AXIS_MASK); +#endif // TMC2130 + current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; + plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40); + st_synchronize(); +#ifdef TMC2130 + tmc2130_home_exit(); +#endif // TMC2130 + enable_z_endstop(bState); + } while (st_get_position_mm(Z_AXIS) > MESH_HOME_Z_SEARCH); // i.e. Z-leveling not o.k. + // plan_set_z_position(MESH_HOME_Z_SEARCH); // is not necessary ('do-while' loop always ends at the expected Z-position) + custom_message_type=CustomMsg::Status; // display / status-line recovery + lcd_update_enable(true); // display / status-line recovery + gcode_G28(true, true, true); // X & Y & Z-homing (must be after individual Z-homing (problem with spool-holder)!) + repeatcommand_front(); // re-run (i.e. of "G80") + return; + } + clean_up_after_endstop_move(l_feedmultiply); + // SERIAL_ECHOLNPGM("clean up finished "); + +#ifndef PINDA_THERMISTOR + if(temp_cal_active == true && calibration_status_pinda() == true) temp_compensation_apply(); //apply PINDA temperature compensation +#endif + babystep_apply(); // Apply Z height correction aka baby stepping before mesh bed leveing gets activated. + // SERIAL_ECHOLNPGM("babystep applied"); + bool eeprom_bed_correction_valid = eeprom_read_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID) == 1; +#ifdef SUPPORT_VERBOSITY + if (verbosity_level >= 1) { + eeprom_bed_correction_valid ? SERIAL_PROTOCOLPGM("Bed correction data valid\n") : SERIAL_PROTOCOLPGM("Bed correction data not valid\n"); + } +#endif // SUPPORT_VERBOSITY + + for (uint8_t i = 0; i < 4; ++i) { + unsigned char codes[4] = { 'L', 'R', 'F', 'B' }; + long correction = 0; + if (code_seen(codes[i])) + correction = code_value_long(); + else if (eeprom_bed_correction_valid) { + unsigned char *addr = (i < 2) ? + ((i == 0) ? (unsigned char*)EEPROM_BED_CORRECTION_LEFT : (unsigned char*)EEPROM_BED_CORRECTION_RIGHT) : + ((i == 2) ? (unsigned char*)EEPROM_BED_CORRECTION_FRONT : (unsigned char*)EEPROM_BED_CORRECTION_REAR); + correction = eeprom_read_int8(addr); + } + if (correction == 0) + continue; + + if (labs(correction) > BED_ADJUSTMENT_UM_MAX) { + SERIAL_ERROR_START; + SERIAL_ECHOPGM("Excessive bed leveling correction: "); + SERIAL_ECHO(correction); + SERIAL_ECHOLNPGM(" microns"); + } + else { + float offset = float(correction) * 0.001f; + switch (i) { + case 0: + for (uint8_t row = 0; row < nMeasPoints; ++row) { + for (uint8_t col = 0; col < nMeasPoints - 1; ++col) { + mbl.z_values[row][col] += offset * (nMeasPoints - 1 - col) / (nMeasPoints - 1); + } + } + break; + case 1: + for (uint8_t row = 0; row < nMeasPoints; ++row) { + for (uint8_t col = 1; col < nMeasPoints; ++col) { + mbl.z_values[row][col] += offset * col / (nMeasPoints - 1); + } + } + break; + case 2: + for (uint8_t col = 0; col < nMeasPoints; ++col) { + for (uint8_t row = 0; row < nMeasPoints; ++row) { + mbl.z_values[row][col] += offset * (nMeasPoints - 1 - row) / (nMeasPoints - 1); + } + } + break; + case 3: + for (uint8_t col = 0; col < nMeasPoints; ++col) { + for (uint8_t row = 1; row < nMeasPoints; ++row) { + mbl.z_values[row][col] += offset * row / (nMeasPoints - 1); + } + } + break; + } + } + } + // SERIAL_ECHOLNPGM("Bed leveling correction finished"); + if (nMeasPoints == 3) { + mbl.upsample_3x3(); //interpolation from 3x3 to 7x7 points using largrangian polynomials while using the same array z_values[iy][ix] for storing (just coppying measured data to new destination and interpolating between them) + } + /* + SERIAL_PROTOCOLPGM("Num X,Y: "); + SERIAL_PROTOCOL(MESH_NUM_X_POINTS); + SERIAL_PROTOCOLPGM(","); + SERIAL_PROTOCOL(MESH_NUM_Y_POINTS); + SERIAL_PROTOCOLPGM("\nZ search height: "); + SERIAL_PROTOCOL(MESH_HOME_Z_SEARCH); + SERIAL_PROTOCOLLNPGM("\nMeasured points:"); + for (int y = MESH_NUM_Y_POINTS-1; y >= 0; y--) { + for (int x = 0; x < MESH_NUM_X_POINTS; x++) { + SERIAL_PROTOCOLPGM(" "); + SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5); + } + SERIAL_PROTOCOLPGM("\n"); + } + */ + if (nMeasPoints == 7 && magnet_elimination) { + mbl_interpolation(nMeasPoints); + } + /* + SERIAL_PROTOCOLPGM("Num X,Y: "); + SERIAL_PROTOCOL(MESH_NUM_X_POINTS); + SERIAL_PROTOCOLPGM(","); + SERIAL_PROTOCOL(MESH_NUM_Y_POINTS); + SERIAL_PROTOCOLPGM("\nZ search height: "); + SERIAL_PROTOCOL(MESH_HOME_Z_SEARCH); + SERIAL_PROTOCOLLNPGM("\nMeasured points:"); + for (int y = MESH_NUM_Y_POINTS-1; y >= 0; y--) { + for (int x = 0; x < MESH_NUM_X_POINTS; x++) { + SERIAL_PROTOCOLPGM(" "); + SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5); + } + SERIAL_PROTOCOLPGM("\n"); + } + */ + // SERIAL_ECHOLNPGM("Upsample finished"); + mbl.active = 1; //activate mesh bed leveling + // SERIAL_ECHOLNPGM("Mesh bed leveling activated"); + go_home_with_z_lift(); + // SERIAL_ECHOLNPGM("Go home finished"); + //unretract (after PINDA preheat retraction) + if ((degHotend(active_extruder) > EXTRUDE_MINTEMP) && eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE) && calibration_status_pinda() && (target_temperature_bed >= 50)) { + current_position[E_AXIS] += default_retraction; + plan_buffer_line_curposXYZE(400); + } + KEEPALIVE_STATE(NOT_BUSY); + // Restore custom message state + lcd_setstatuspgm(_T(WELCOME_MSG)); + custom_message_type = custom_message_type_old; + custom_message_state = custom_message_state_old; + mesh_bed_leveling_flag = false; + mesh_bed_run_from_menu = false; + lcd_update(2); +} + + void adjust_bed_reset() { eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID, 1); @@ -4517,9 +4914,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) gcode_G28(home_x, home_x_value, home_y, home_y_value, home_z, home_z_value, without_mbl); #endif //TMC2130 if ((home_x || home_y || without_mbl || home_z) == false) { - // Push the commands to the front of the message queue in the reverse order! - // There shall be always enough space reserved for these commands. - goto case_G80; + gcode_G80(); } break; } @@ -5071,404 +5466,11 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) * v Y-axis */ - case 80: - + case 80: { #ifdef MK1BP break; #endif //MK1BP - case_G80: - { - mesh_bed_leveling_flag = true; -#ifndef PINDA_THERMISTOR - static bool run = false; // thermistor-less PINDA temperature compensation is running -#endif // ndef PINDA_THERMISTOR - -#ifdef SUPPORT_VERBOSITY - int8_t verbosity_level = 0; - if (code_seen('V')) { - // Just 'V' without a number counts as V1. - char c = strchr_pointer[1]; - verbosity_level = (c == ' ' || c == '\t' || c == 0) ? 1 : code_value_short(); - } -#endif //SUPPORT_VERBOSITY - // Firstly check if we know where we are - 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! - // There shall be always enough space reserved for these commands. - repeatcommand_front(); // repeat G80 with all its parameters - enquecommand_front_P(G28W0); - break; - } - - uint8_t nMeasPoints = MESH_MEAS_NUM_X_POINTS; - if (code_seen('N')) { - nMeasPoints = code_value_uint8(); - if (nMeasPoints != 7) { - nMeasPoints = 3; - } - } - else { - nMeasPoints = eeprom_read_byte((uint8_t*)EEPROM_MBL_POINTS_NR); - } - - uint8_t nProbeRetry = 3; - if (code_seen('R')) { - nProbeRetry = code_value_uint8(); - if (nProbeRetry > 10) { - nProbeRetry = 10; - } - } - else { - nProbeRetry = eeprom_read_byte((uint8_t*)EEPROM_MBL_PROBE_NR); - } - bool magnet_elimination = (eeprom_read_byte((uint8_t*)EEPROM_MBL_MAGNET_ELIMINATION) > 0); - -#ifndef PINDA_THERMISTOR - if (run == false && temp_cal_active == true && calibration_status_pinda() == true && target_temperature_bed >= 50) - { - temp_compensation_start(); - run = true; - repeatcommand_front(); // repeat G80 with all its parameters - enquecommand_front_P(G28W0); - break; - } - run = false; -#endif //PINDA_THERMISTOR - // Save custom message state, set a new custom message state to display: Calibrating point 9. - CustomMsg custom_message_type_old = custom_message_type; - unsigned int custom_message_state_old = custom_message_state; - custom_message_type = CustomMsg::MeshBedLeveling; - custom_message_state = (nMeasPoints * nMeasPoints) + 10; - lcd_update(1); - - mbl.reset(); //reset mesh bed leveling - - // Reset baby stepping to zero, if the babystepping has already been loaded before. - babystep_undo(); - - // Cycle through all points and probe them - // First move up. During this first movement, the babystepping will be reverted. - current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60); - // The move to the first calibration point. - current_position[X_AXIS] = BED_X0; - current_position[Y_AXIS] = BED_Y0; - - #ifdef SUPPORT_VERBOSITY - if (verbosity_level >= 1) - { - bool clamped = world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); - clamped ? SERIAL_PROTOCOLPGM("First calibration point clamped.\n") : SERIAL_PROTOCOLPGM("No clamping for first calibration point.\n"); - } - #else //SUPPORT_VERBOSITY - world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); - #endif //SUPPORT_VERBOSITY - - plan_buffer_line_curposXYZE(homing_feedrate[X_AXIS] / 30); - // Wait until the move is finished. - st_synchronize(); - - uint8_t mesh_point = 0; //index number of calibration point - - int XY_AXIS_FEEDRATE = homing_feedrate[X_AXIS] / 20; - int Z_LIFT_FEEDRATE = homing_feedrate[Z_AXIS] / 40; - bool has_z = is_bed_z_jitter_data_valid(); //checks if we have data from Z calibration (offsets of the Z heiths of the 8 calibration points from the first point) - #ifdef SUPPORT_VERBOSITY - if (verbosity_level >= 1) { - has_z ? SERIAL_PROTOCOLPGM("Z jitter data from Z cal. valid.\n") : SERIAL_PROTOCOLPGM("Z jitter data from Z cal. not valid.\n"); - } - #endif // SUPPORT_VERBOSITY - int l_feedmultiply = setup_for_endstop_move(false); //save feedrate and feedmultiply, sets feedmultiply to 100 - while (mesh_point != nMeasPoints * nMeasPoints) { - // Get coords of a measuring point. - uint8_t ix = mesh_point % nMeasPoints; // from 0 to MESH_NUM_X_POINTS - 1 - uint8_t iy = mesh_point / nMeasPoints; - /*if (!mbl_point_measurement_valid(ix, iy, nMeasPoints, true)) { - printf_P(PSTR("Skipping point [%d;%d] \n"), ix, iy); - custom_message_state--; - mesh_point++; - continue; //skip - }*/ - if (iy & 1) ix = (nMeasPoints - 1) - ix; // Zig zag - if (nMeasPoints == 7) //if we have 7x7 mesh, compare with Z-calibration for points which are in 3x3 mesh - { - has_z = ((ix % 3 == 0) && (iy % 3 == 0)) && is_bed_z_jitter_data_valid(); - } - float z0 = 0.f; - if (has_z && (mesh_point > 0)) { - uint16_t z_offset_u = 0; - if (nMeasPoints == 7) { - z_offset_u = eeprom_read_word((uint16_t*)(EEPROM_BED_CALIBRATION_Z_JITTER + 2 * ((ix/3) + iy - 1))); - } - else { - z_offset_u = eeprom_read_word((uint16_t*)(EEPROM_BED_CALIBRATION_Z_JITTER + 2 * (ix + iy * 3 - 1))); - } - z0 = mbl.z_values[0][0] + *reinterpret_cast(&z_offset_u) * 0.01; - #ifdef SUPPORT_VERBOSITY - if (verbosity_level >= 1) { - printf_P(PSTR("Bed leveling, point: %d, calibration Z stored in eeprom: %d, calibration z: %f \n"), mesh_point, z_offset_u, z0); - } - #endif // SUPPORT_VERBOSITY - } - - // Move Z up to MESH_HOME_Z_SEARCH. - if((ix == 0) && (iy == 0)) current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - else current_position[Z_AXIS] += 2.f / nMeasPoints; //use relative movement from Z coordinate where PINDa triggered on previous point. This makes calibration faster. - float init_z_bckp = current_position[Z_AXIS]; - plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE); - st_synchronize(); - - // Move to XY position of the sensor point. - current_position[X_AXIS] = BED_X(ix, nMeasPoints); - current_position[Y_AXIS] = BED_Y(iy, nMeasPoints); - - //printf_P(PSTR("[%f;%f]\n"), current_position[X_AXIS], current_position[Y_AXIS]); - - - #ifdef SUPPORT_VERBOSITY - if (verbosity_level >= 1) { - bool clamped = world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); - SERIAL_PROTOCOL(mesh_point); - clamped ? SERIAL_PROTOCOLPGM(": xy clamped.\n") : SERIAL_PROTOCOLPGM(": no xy clamping\n"); - } - #else //SUPPORT_VERBOSITY - world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); - #endif // SUPPORT_VERBOSITY - - //printf_P(PSTR("after clamping: [%f;%f]\n"), current_position[X_AXIS], current_position[Y_AXIS]); - plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE); - st_synchronize(); - - // Go down until endstop is hit - const float Z_CALIBRATION_THRESHOLD = 1.f; - if (!find_bed_induction_sensor_point_z((has_z && mesh_point > 0) ? z0 - Z_CALIBRATION_THRESHOLD : -10.f, nProbeRetry)) { //if we have data from z calibration max allowed difference is 1mm for each point, if we dont have data max difference is 10mm from initial point - printf_P(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); - break; - } - if (init_z_bckp - current_position[Z_AXIS] < 0.1f) { //broken cable or initial Z coordinate too low. Go to MESH_HOME_Z_SEARCH and repeat last step (z-probe) again to distinguish between these two cases. - //printf_P(PSTR("Another attempt! Current Z position: %f\n"), current_position[Z_AXIS]); - current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE); - st_synchronize(); - - if (!find_bed_induction_sensor_point_z((has_z && mesh_point > 0) ? z0 - Z_CALIBRATION_THRESHOLD : -10.f, nProbeRetry)) { //if we have data from z calibration max allowed difference is 1mm for each point, if we dont have data max difference is 10mm from initial point - printf_P(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); - break; - } - if (MESH_HOME_Z_SEARCH - current_position[Z_AXIS] < 0.1f) { - puts_P(PSTR("Bed leveling failed. Sensor disconnected or cable broken.")); - break; - } - } - if (has_z && fabs(z0 - current_position[Z_AXIS]) > Z_CALIBRATION_THRESHOLD) { //if we have data from z calibration, max. allowed difference is 1mm for each point - puts_P(PSTR("Bed leveling failed. Sensor triggered too high.")); - break; - } - #ifdef SUPPORT_VERBOSITY - if (verbosity_level >= 10) { - SERIAL_ECHOPGM("X: "); - MYSERIAL.print(current_position[X_AXIS], 5); - SERIAL_ECHOLNPGM(""); - SERIAL_ECHOPGM("Y: "); - MYSERIAL.print(current_position[Y_AXIS], 5); - SERIAL_PROTOCOLPGM("\n"); - } - #endif // SUPPORT_VERBOSITY - float offset_z = 0; - -#ifdef PINDA_THERMISTOR - offset_z = temp_compensation_pinda_thermistor_offset(current_temperature_pinda); -#endif //PINDA_THERMISTOR -// #ifdef SUPPORT_VERBOSITY -/* if (verbosity_level >= 1) - { - SERIAL_ECHOPGM("mesh bed leveling: "); - MYSERIAL.print(current_position[Z_AXIS], 5); - SERIAL_ECHOPGM(" offset: "); - MYSERIAL.print(offset_z, 5); - SERIAL_ECHOLNPGM(""); - }*/ -// #endif // SUPPORT_VERBOSITY - mbl.set_z(ix, iy, current_position[Z_AXIS] - offset_z); //store measured z values z_values[iy][ix] = z - offset_z; - - custom_message_state--; - mesh_point++; - lcd_update(1); - } - current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - #ifdef SUPPORT_VERBOSITY - if (verbosity_level >= 20) { - SERIAL_ECHOLNPGM("Mesh bed leveling while loop finished."); - SERIAL_ECHOLNPGM("MESH_HOME_Z_SEARCH: "); - MYSERIAL.print(current_position[Z_AXIS], 5); - } - #endif // SUPPORT_VERBOSITY - plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE); - st_synchronize(); - if (mesh_point != nMeasPoints * nMeasPoints) { - Sound_MakeSound(e_SOUND_TYPE_StandardAlert); - bool bState; - do { // repeat until Z-leveling o.k. - lcd_display_message_fullscreen_P(_i("Some problem encountered, Z-leveling enforced ...")); -#ifdef TMC2130 - lcd_wait_for_click_delay(MSG_BED_LEVELING_FAILED_TIMEOUT); - calibrate_z_auto(); // Z-leveling (X-assembly stay up!!!) -#else // TMC2130 - lcd_wait_for_click_delay(0); // ~ no timeout - lcd_calibrate_z_end_stop_manual(true); // Z-leveling (X-assembly stay up!!!) -#endif // TMC2130 - // ~ Z-homing (can not be used "G28", because X & Y-homing would have been done before (Z-homing)) - bState=enable_z_endstop(false); - current_position[Z_AXIS] -= 1; - plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40); - st_synchronize(); - enable_z_endstop(true); -#ifdef TMC2130 - tmc2130_home_enter(Z_AXIS_MASK); -#endif // TMC2130 - current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40); - st_synchronize(); -#ifdef TMC2130 - tmc2130_home_exit(); -#endif // TMC2130 - enable_z_endstop(bState); - } while (st_get_position_mm(Z_AXIS) > MESH_HOME_Z_SEARCH); // i.e. Z-leveling not o.k. -// plan_set_z_position(MESH_HOME_Z_SEARCH); // is not necessary ('do-while' loop always ends at the expected Z-position) - custom_message_type=CustomMsg::Status; // display / status-line recovery - lcd_update_enable(true); // display / status-line recovery - gcode_G28(true, true, true); // X & Y & Z-homing (must be after individual Z-homing (problem with spool-holder)!) - repeatcommand_front(); // re-run (i.e. of "G80") - break; - } - clean_up_after_endstop_move(l_feedmultiply); -// SERIAL_ECHOLNPGM("clean up finished "); - -#ifndef PINDA_THERMISTOR - if(temp_cal_active == true && calibration_status_pinda() == true) temp_compensation_apply(); //apply PINDA temperature compensation -#endif - babystep_apply(); // Apply Z height correction aka baby stepping before mesh bed leveing gets activated. -// SERIAL_ECHOLNPGM("babystep applied"); - bool eeprom_bed_correction_valid = eeprom_read_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID) == 1; - #ifdef SUPPORT_VERBOSITY - if (verbosity_level >= 1) { - eeprom_bed_correction_valid ? SERIAL_PROTOCOLPGM("Bed correction data valid\n") : SERIAL_PROTOCOLPGM("Bed correction data not valid\n"); - } - #endif // SUPPORT_VERBOSITY - - for (uint8_t i = 0; i < 4; ++i) { - unsigned char codes[4] = { 'L', 'R', 'F', 'B' }; - long correction = 0; - if (code_seen(codes[i])) - correction = code_value_long(); - else if (eeprom_bed_correction_valid) { - unsigned char *addr = (i < 2) ? - ((i == 0) ? (unsigned char*)EEPROM_BED_CORRECTION_LEFT : (unsigned char*)EEPROM_BED_CORRECTION_RIGHT) : - ((i == 2) ? (unsigned char*)EEPROM_BED_CORRECTION_FRONT : (unsigned char*)EEPROM_BED_CORRECTION_REAR); - correction = eeprom_read_int8(addr); - } - if (correction == 0) - continue; - - if (labs(correction) > BED_ADJUSTMENT_UM_MAX) { - SERIAL_ERROR_START; - SERIAL_ECHOPGM("Excessive bed leveling correction: "); - SERIAL_ECHO(correction); - SERIAL_ECHOLNPGM(" microns"); - } - else { - float offset = float(correction) * 0.001f; - switch (i) { - case 0: - for (uint8_t row = 0; row < nMeasPoints; ++row) { - for (uint8_t col = 0; col < nMeasPoints - 1; ++col) { - mbl.z_values[row][col] += offset * (nMeasPoints - 1 - col) / (nMeasPoints - 1); - } - } - break; - case 1: - for (uint8_t row = 0; row < nMeasPoints; ++row) { - for (uint8_t col = 1; col < nMeasPoints; ++col) { - mbl.z_values[row][col] += offset * col / (nMeasPoints - 1); - } - } - break; - case 2: - for (uint8_t col = 0; col < nMeasPoints; ++col) { - for (uint8_t row = 0; row < nMeasPoints; ++row) { - mbl.z_values[row][col] += offset * (nMeasPoints - 1 - row) / (nMeasPoints - 1); - } - } - break; - case 3: - for (uint8_t col = 0; col < nMeasPoints; ++col) { - for (uint8_t row = 1; row < nMeasPoints; ++row) { - mbl.z_values[row][col] += offset * row / (nMeasPoints - 1); - } - } - break; - } - } - } -// SERIAL_ECHOLNPGM("Bed leveling correction finished"); - if (nMeasPoints == 3) { - mbl.upsample_3x3(); //interpolation from 3x3 to 7x7 points using largrangian polynomials while using the same array z_values[iy][ix] for storing (just coppying measured data to new destination and interpolating between them) - } -/* - SERIAL_PROTOCOLPGM("Num X,Y: "); - SERIAL_PROTOCOL(MESH_NUM_X_POINTS); - SERIAL_PROTOCOLPGM(","); - SERIAL_PROTOCOL(MESH_NUM_Y_POINTS); - SERIAL_PROTOCOLPGM("\nZ search height: "); - SERIAL_PROTOCOL(MESH_HOME_Z_SEARCH); - SERIAL_PROTOCOLLNPGM("\nMeasured points:"); - for (int y = MESH_NUM_Y_POINTS-1; y >= 0; y--) { - for (int x = 0; x < MESH_NUM_X_POINTS; x++) { - SERIAL_PROTOCOLPGM(" "); - SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5); - } - SERIAL_PROTOCOLPGM("\n"); - } -*/ - if (nMeasPoints == 7 && magnet_elimination) { - mbl_interpolation(nMeasPoints); - } -/* - SERIAL_PROTOCOLPGM("Num X,Y: "); - SERIAL_PROTOCOL(MESH_NUM_X_POINTS); - SERIAL_PROTOCOLPGM(","); - SERIAL_PROTOCOL(MESH_NUM_Y_POINTS); - SERIAL_PROTOCOLPGM("\nZ search height: "); - SERIAL_PROTOCOL(MESH_HOME_Z_SEARCH); - SERIAL_PROTOCOLLNPGM("\nMeasured points:"); - for (int y = MESH_NUM_Y_POINTS-1; y >= 0; y--) { - for (int x = 0; x < MESH_NUM_X_POINTS; x++) { - SERIAL_PROTOCOLPGM(" "); - SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5); - } - SERIAL_PROTOCOLPGM("\n"); - } -*/ -// SERIAL_ECHOLNPGM("Upsample finished"); - mbl.active = 1; //activate mesh bed leveling -// SERIAL_ECHOLNPGM("Mesh bed leveling activated"); - go_home_with_z_lift(); -// SERIAL_ECHOLNPGM("Go home finished"); - //unretract (after PINDA preheat retraction) - if ((degHotend(active_extruder) > EXTRUDE_MINTEMP) && eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE) && calibration_status_pinda() && (target_temperature_bed >= 50)) { - current_position[E_AXIS] += default_retraction; - plan_buffer_line_curposXYZE(400); - } - KEEPALIVE_STATE(NOT_BUSY); - // Restore custom message state - lcd_setstatuspgm(_T(WELCOME_MSG)); - custom_message_type = custom_message_type_old; - custom_message_state = custom_message_state_old; - mesh_bed_leveling_flag = false; - mesh_bed_run_from_menu = false; - lcd_update(2); - + gcode_G80(); } break; From 5da39df968954e9798f42e0b39a2eb2748eb82fa Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Tue, 6 Apr 2021 00:10:33 +0200 Subject: [PATCH 11/26] G80: Use consistent XY axis feedrate --- Firmware/Marlin_main.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 451363c9..b024c3ce 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3032,13 +3032,12 @@ static void gcode_G80() world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); #endif //SUPPORT_VERBOSITY - plan_buffer_line_curposXYZE(homing_feedrate[X_AXIS] / 30); + int XY_AXIS_FEEDRATE = homing_feedrate[X_AXIS] / 20; + plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE); // Wait until the move is finished. st_synchronize(); uint8_t mesh_point = 0; //index number of calibration point - - int XY_AXIS_FEEDRATE = homing_feedrate[X_AXIS] / 20; int Z_LIFT_FEEDRATE = homing_feedrate[Z_AXIS] / 40; bool has_z = is_bed_z_jitter_data_valid(); //checks if we have data from Z calibration (offsets of the Z heiths of the 8 calibration points from the first point) #ifdef SUPPORT_VERBOSITY From 5923276a86984452a5269809e383396d9ef6332c Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Tue, 6 Apr 2021 00:12:01 +0200 Subject: [PATCH 12/26] G80: correctly abort during crash detection Crash detection is handled at a higher level (which automatically repeats the current command), however we still need to abort the current command correctly. Handle XY crashes by checking the planner status after st_synchronize(). --- Firmware/Marlin_main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index b024c3ce..3cd28077 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3036,6 +3036,8 @@ static void gcode_G80() plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE); // Wait until the move is finished. st_synchronize(); + if (waiting_inside_plan_buffer_line_print_aborted) + return; uint8_t mesh_point = 0; //index number of calibration point int Z_LIFT_FEEDRATE = homing_feedrate[Z_AXIS] / 40; @@ -3105,6 +3107,8 @@ static void gcode_G80() //printf_P(PSTR("after clamping: [%f;%f]\n"), current_position[X_AXIS], current_position[Y_AXIS]); plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE); st_synchronize(); + if (waiting_inside_plan_buffer_line_print_aborted) + return; // Go down until endstop is hit const float Z_CALIBRATION_THRESHOLD = 1.f; From a5530593fa9f70eab675c773915745ec2c1df227 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Tue, 6 Apr 2021 00:31:56 +0200 Subject: [PATCH 13/26] G80: preserve lcd status and message when aborting Restore the old status just before returning, so that the subsequent G80 can restore the first (initial) message correctly. --- Firmware/Marlin_main.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 3cd28077..90512837 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3037,7 +3037,11 @@ static void gcode_G80() // Wait until the move is finished. st_synchronize(); if (waiting_inside_plan_buffer_line_print_aborted) + { + custom_message_type = custom_message_type_old; + custom_message_state = custom_message_state_old; return; + } uint8_t mesh_point = 0; //index number of calibration point int Z_LIFT_FEEDRATE = homing_feedrate[Z_AXIS] / 40; @@ -3108,7 +3112,11 @@ static void gcode_G80() plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE); st_synchronize(); if (waiting_inside_plan_buffer_line_print_aborted) + { + custom_message_type = custom_message_type_old; + custom_message_state = custom_message_state_old; return; + } // Go down until endstop is hit const float Z_CALIBRATION_THRESHOLD = 1.f; @@ -3206,7 +3214,9 @@ static void gcode_G80() enable_z_endstop(bState); } while (st_get_position_mm(Z_AXIS) > MESH_HOME_Z_SEARCH); // i.e. Z-leveling not o.k. // plan_set_z_position(MESH_HOME_Z_SEARCH); // is not necessary ('do-while' loop always ends at the expected Z-position) - custom_message_type=CustomMsg::Status; // display / status-line recovery + + custom_message_type = custom_message_type_old; + custom_message_state = custom_message_state_old; lcd_update_enable(true); // display / status-line recovery gcode_G28(true, true, true); // X & Y & Z-homing (must be after individual Z-homing (problem with spool-holder)!) repeatcommand_front(); // re-run (i.e. of "G80") From b46a52ffa8786e51b9efc349b8ece5e850e47cd8 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Tue, 6 Apr 2021 01:52:00 +0200 Subject: [PATCH 14/26] G80: Handle crash detection At a higher level, crash detection will repeat the last gcode command. Some commands such as G28 or G80 need to be repeated in full and require special handling. In such cases, do not store the saved target coordinate (which is fake in such cases) and invalidate the saved position. This fixes the last coordinate of the first G1 move after recovery. We also avoid moving from the origin when the saved position is invalidated, which is not strictly necessary, but saves some time. --- Firmware/Marlin_main.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 90512837..dfc92a4b 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -219,7 +219,7 @@ unsigned int heating_status; unsigned int heating_status_counter; bool loading_flag = false; - +#define XY_NO_RESTORE_FLAG (mesh_bed_leveling_flag || homing_flag) char snmm_filaments_used = 0; @@ -305,7 +305,12 @@ bool no_response = false; uint8_t important_status; uint8_t saved_filament_type; -#define SAVED_TARGET_UNSET (X_MIN_POS-1) +// Define some coordinates outside the clamp limits (making them invalid past the parsing stage) so +// that they can be used later for various logical checks +#define X_COORD_INVALID (X_MIN_POS-1) +#define Y_COORD_INVALID (Y_MIN_POS-1) + +#define SAVED_TARGET_UNSET X_COORD_INVALID float saved_target[NUM_AXIS] = {SAVED_TARGET_UNSET, 0, 0, 0}; // save/restore printing in case that mmu was not responding @@ -375,7 +380,7 @@ boolean chdkActive = false; bool saved_printing = false; //!< Print is paused and saved in RAM static uint32_t saved_sdpos = 0; //!< SD card position, or line number in case of USB printing uint8_t saved_printing_type = PRINTING_TYPE_SD; -static float saved_pos[4] = { 0, 0, 0, 0 }; +static float saved_pos[4] = { X_COORD_INVALID, 0, 0, 0 }; static uint16_t saved_feedrate2 = 0; //!< Default feedrate (truncated from float) static int saved_feedmultiply2 = 0; static uint8_t saved_active_extruder = 0; @@ -11460,7 +11465,8 @@ void stop_and_save_print_to_ram(float z_move, float e_move) #endif // save the global state at planning time - if (current_block) + bool pos_invalid = XY_NO_RESTORE_FLAG; + if (current_block && !pos_invalid) { memcpy(saved_target, current_block->gcode_target, sizeof(saved_target)); saved_feedrate2 = current_block->gcode_feedrate; @@ -11472,7 +11478,10 @@ void stop_and_save_print_to_ram(float z_move, float e_move) } planner_abort_hard(); //abort printing + memcpy(saved_pos, current_position, sizeof(saved_pos)); + if (pos_invalid) saved_pos[X_AXIS] = X_COORD_INVALID; + saved_feedmultiply2 = feedmultiply; //save feedmultiply saved_active_extruder = active_extruder; //save active_extruder saved_extruder_temperature = degTargetHotend(active_extruder); @@ -11566,6 +11575,13 @@ void restore_print_from_ram_and_continue(float e_move) fans_check_enabled = false; #endif + // do not restore XY for commands that do not require that + if (saved_pos[X_AXIS] == X_COORD_INVALID) + { + saved_pos[X_AXIS] = current_position[X_AXIS]; + saved_pos[Y_AXIS] = current_position[Y_AXIS]; + } + //first move print head in XY to the saved position: plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], current_position[Z_AXIS], saved_pos[E_AXIS] - e_move, homing_feedrate[Z_AXIS]/13, active_extruder); //then move Z From 449d1819714cce5b8c59c08b46e50f907468e0be Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Tue, 6 Apr 2021 02:20:00 +0200 Subject: [PATCH 15/26] G80: handle power panic This is handled in the same way crash detection is handled: homing/mbl invalidates saved_target _and_ current position. Fixes PP recovery during MBL and homing. --- Firmware/Marlin_main.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index dfc92a4b..72e1e9ca 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -10851,8 +10851,9 @@ void uvlo_() } // save the global state at planning time + bool pos_invalid = XY_NO_RESTORE_FLAG; uint16_t feedrate_bckp; - if (current_block) + if (current_block && !pos_invalid) { memcpy(saved_target, current_block->gcode_target, sizeof(saved_target)); feedrate_bckp = current_block->gcode_feedrate; @@ -10930,8 +10931,13 @@ void uvlo_() 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]); + if (pos_invalid) + eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0), X_COORD_INVALID); + else + { + 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]); + } // Store the current feed rate, temperatures, fan speed and extruder multipliers (flow rates) eeprom_update_word((uint16_t*)EEPROM_UVLO_FEEDRATE, feedrate_bckp); @@ -11282,10 +11288,13 @@ void restore_print_from_eeprom(bool mbl_was_active) { // Move to the XY print position in logical coordinates, where the print has been killed, but // without shifting Z along the way. This requires performing the move without mbl. - sprintf_P(cmd, PSTR("G1 X%f Y%f F3000"), - eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0)), - eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4))); - enquecommand(cmd); + float pos_x = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 0)); + float pos_y = eeprom_read_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4)); + if (pos_x != X_COORD_INVALID) + { + sprintf_P(cmd, PSTR("G1 X%f Y%f F3000"), pos_x, pos_y); + enquecommand(cmd); + } // Enable MBL and switch to logical positioning if (mbl_was_active) From 9454f9d8ece0e25c4c9b5eeff02ea3eaf658c020 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 5 Mar 2021 09:51:23 +0200 Subject: [PATCH 16/26] Rename w25x20cl to xflash --- Firmware/Marlin_main.cpp | 62 +++++++++---------- Firmware/config.h | 8 --- Firmware/language.c | 42 ++++++------- Firmware/optiboot_w25x20cl.h | 6 -- ...iboot_w25x20cl.cpp => optiboot_xflash.cpp} | 44 ++++++------- Firmware/optiboot_xflash.h | 6 ++ Firmware/pins_Einsy_1_0.h | 4 +- Firmware/ultralcd.cpp | 26 ++++---- .../variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 2 +- .../variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 2 +- Firmware/w25x20cl.h | 44 ------------- Firmware/{w25x20cl.c => xflash.c} | 62 ++++++++++--------- Firmware/xflash.h | 50 +++++++++++++++ 13 files changed, 180 insertions(+), 178 deletions(-) delete mode 100644 Firmware/optiboot_w25x20cl.h rename Firmware/{optiboot_w25x20cl.cpp => optiboot_xflash.cpp} (93%) create mode 100644 Firmware/optiboot_xflash.h delete mode 100644 Firmware/w25x20cl.h rename Firmware/{w25x20cl.c => xflash.c} (73%) create mode 100644 Firmware/xflash.h diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 09e1dc49..ebaf3f14 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -103,10 +103,10 @@ #include "tmc2130.h" #endif //TMC2130 -#ifdef W25X20CL -#include "w25x20cl.h" -#include "optiboot_w25x20cl.h" -#endif //W25X20CL +#ifdef XFLASH +#include "xflash.h" +#include "optiboot_xflash.h" +#endif //XFLASH #ifdef BLINKM #include "BlinkM.h" @@ -910,7 +910,7 @@ uint8_t check_printer_version() #if (LANG_MODE != 0) //secondary language support -#ifdef W25X20CL +#ifdef XFLASH // language update from external flash @@ -936,7 +936,7 @@ void update_sec_lang_from_external_flash() cli(); uint16_t size = header.size - state * LANGBOOT_BLOCKSIZE; if (size > LANGBOOT_BLOCKSIZE) size = LANGBOOT_BLOCKSIZE; - w25x20cl_rd_data(src_addr + state * LANGBOOT_BLOCKSIZE, (uint8_t*)LANGBOOT_RAMBUFFER, size); + xflash_rd_data(src_addr + state * LANGBOOT_BLOCKSIZE, (uint8_t*)LANGBOOT_RAMBUFFER, size); if (state == 0) { //TODO - check header integrity @@ -954,7 +954,7 @@ void update_sec_lang_from_external_flash() } -#ifdef DEBUG_W25X20CL +#ifdef DEBUG_XFLASH uint8_t lang_xflash_enum_codes(uint16_t* codes) { @@ -964,7 +964,7 @@ uint8_t lang_xflash_enum_codes(uint16_t* codes) while (1) { printf_P(_n("LANGTABLE%d:"), count); - w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); + xflash_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); if (header.magic != LANG_MAGIC) { puts_P(_n("NG!")); @@ -992,17 +992,17 @@ void list_sec_lang_from_external_flash() printf_P(_n("XFlash lang count = %hhd\n"), count); } -#endif //DEBUG_W25X20CL +#endif //DEBUG_XFLASH -#endif //W25X20CL +#endif //XFLASH #endif //(LANG_MODE != 0) -static void w25x20cl_err_msg() +static void xflash_err_msg() { lcd_clear(); - lcd_puts_P(_n("External SPI flash\nW25X20CL is not res-\nponding. Language\nswitch unavailable.")); + lcd_puts_P(_n("External SPI flash\nXFLASH is not res-\nponding. Language\nswitch unavailable.")); } // "Setup" function is called by the Arduino framework on startup. @@ -1028,23 +1028,23 @@ void setup() fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream stdout = uartout; -#ifdef W25X20CL - bool w25x20cl_success = w25x20cl_init(); +#ifdef XFLASH + bool xflash_success = xflash_init(); uint8_t optiboot_status = 1; - if (w25x20cl_success) + if (xflash_success) { - optiboot_status = optiboot_w25x20cl_enter(); + optiboot_status = optiboot_xflash_enter(); #if (LANG_MODE != 0) //secondary language support update_sec_lang_from_external_flash(); #endif //(LANG_MODE != 0) } else { - w25x20cl_err_msg(); + xflash_err_msg(); } #else - const bool w25x20cl_success = true; -#endif //W25X20CL + const bool xflash_success = true; +#endif //XFLASH setup_killpin(); @@ -1091,7 +1091,7 @@ void setup() } -#ifndef W25X20CL +#ifndef XFLASH SERIAL_PROTOCOLLNPGM("start"); #else if ((optiboot_status != 0) || (selectedSerialPort != 0)) @@ -1172,7 +1172,7 @@ void setup() #undef LT_PRINT_TEST #if 0 - w25x20cl_rd_data(0x25ba, (uint8_t*)&block_buffer, 1024); + xflash_rd_data(0x25ba, (uint8_t*)&block_buffer, 1024); for (uint16_t i = 0; i < 1024; i++) { if ((i % 16) == 0) printf_P(_n("%04x:"), 0x25ba+i); @@ -1269,11 +1269,11 @@ void setup() tp_init(); // Initialize temperature loop - if (w25x20cl_success) lcd_splash(); // we need to do this again, because tp_init() kills lcd + if (xflash_success) lcd_splash(); // we need to do this again, because tp_init() kills lcd else { - w25x20cl_err_msg(); - puts_P(_n("W25X20CL not responding.")); + xflash_err_msg(); + puts_P(_n("XFLASH not responding.")); } #ifdef EXTRUDER_ALTFAN_DETECT SERIAL_ECHORPGM(_n("Extruder fan type: ")); @@ -1458,16 +1458,16 @@ void setup() #if (LANG_MODE != 0) //secondary language support -#ifdef DEBUG_W25X20CL - W25X20CL_SPI_ENTER(); +#ifdef DEBUG_XFLASH + XFLASH_SPI_ENTER(); uint8_t uid[8]; // 64bit unique id - w25x20cl_rd_uid(uid); - puts_P(_n("W25X20CL UID=")); + xflash_rd_uid(uid); + puts_P(_n("XFLASH UID=")); for (uint8_t i = 0; i < 8; i ++) printf_P(PSTR("%02hhx"), uid[i]); putchar('\n'); list_sec_lang_from_external_flash(); -#endif //DEBUG_W25X20CL +#endif //DEBUG_XFLASH // lang_reset(); if (!lang_select(eeprom_read_byte((uint8_t*)EEPROM_LANG))) @@ -4013,10 +4013,10 @@ void process_commands() } else if (code_seen_P(PSTR("RESET"))) { // PRUSA RESET #ifdef WATCHDOG -#if defined(W25X20CL) && defined(BOOTAPP) +#if defined(XFLASH) && defined(BOOTAPP) boot_app_magic = BOOT_APP_MAGIC; boot_app_flags = BOOT_APP_FLG_RUN; -#endif //defined(W25X20CL) && defined(BOOTAPP) +#endif //defined(XFLASH) && defined(BOOTAPP) softReset(); #elif defined(BOOTAPP) //this is a safety precaution. This is because the new bootloader turns off the heaters, but the old one doesn't. The watchdog should be used most of the time. asm volatile("jmp 0x3E000"); diff --git a/Firmware/config.h b/Firmware/config.h index 87599b64..2ec2077e 100644 --- a/Firmware/config.h +++ b/Firmware/config.h @@ -54,14 +54,6 @@ #define TMC2130_SPCR SPI_SPCR(TMC2130_SPI_RATE, 1, 1, 1, 0) #define TMC2130_SPSR SPI_SPSR(TMC2130_SPI_RATE) -//W25X20CL configuration -//pinout: -#define W25X20CL_PIN_CS 32 -//spi: -#define W25X20CL_SPI_RATE 0 // fosc/4 = 4MHz -#define W25X20CL_SPCR SPI_SPCR(W25X20CL_SPI_RATE, 1, 1, 1, 0) -#define W25X20CL_SPSR SPI_SPSR(W25X20CL_SPI_RATE) - //LANG - Multi-language support //#define LANG_MODE 0 // primary language only #define LANG_MODE 1 // sec. language support diff --git a/Firmware/language.c b/Firmware/language.c index 368997cf..01a39652 100644 --- a/Firmware/language.c +++ b/Firmware/language.c @@ -7,9 +7,9 @@ #include "Configuration.h" #include "pins.h" -#ifdef W25X20CL -#include "w25x20cl.h" -#endif //W25X20CL +#ifdef XFLASH +#include "xflash.h" +#endif //XFLASH // Currently active language selection. uint8_t lang_selected = 0; @@ -54,7 +54,7 @@ uint8_t lang_select(uint8_t lang) lang_table = 0; lang_selected = lang; } -#ifdef W25X20CL +#ifdef XFLASH if (lang_get_code(lang) == lang_get_code(LANG_ID_SEC)) lang = LANG_ID_SEC; if (lang == LANG_ID_SEC) //current secondary language { @@ -68,7 +68,7 @@ uint8_t lang_select(uint8_t lang) } } } -#else //W25X20CL +#else //XFLASH if (lang == LANG_ID_SEC) { uint16_t table = _SEC_LANG_TABLE; @@ -82,7 +82,7 @@ uint8_t lang_select(uint8_t lang) } } } -#endif //W25X20CL +#endif //XFLASH if (lang_selected == lang) { eeprom_update_byte((unsigned char*)EEPROM_LANG, lang_selected); @@ -107,19 +107,19 @@ uint8_t lang_get_count() { if (pgm_read_dword(((uint32_t*)(_PRI_LANG_SIGNATURE))) == 0xffffffff) return 1; //signature not set - only primary language will be available -#ifdef W25X20CL - W25X20CL_SPI_ENTER(); +#ifdef XFLASH + XFLASH_SPI_ENTER(); uint8_t count = 2; //count = 1+n (primary + secondary + all in xflash) uint32_t addr = 0x00000; //start of xflash lang_table_header_t header; //table header structure while (1) { - w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash + xflash_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash if (header.magic != LANG_MAGIC) break; //break if magic not valid addr += header.size; //calc address of next table count++; //inc counter } -#else //W25X20CL +#else //XFLASH uint16_t table = _SEC_LANG_TABLE; uint8_t count = 1; //count = 1 (primary) while (pgm_read_dword(((uint32_t*)table)) == LANG_MAGIC) //magic valid @@ -127,14 +127,14 @@ uint8_t lang_get_count() table += pgm_read_word((uint16_t*)(table + 4)); count++; } -#endif //W25X20CL +#endif //XFLASH return count; } uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* offset) { if (lang == LANG_ID_PRI) return 0; //primary lang not supported for this function -#ifdef W25X20CL +#ifdef XFLASH if (lang == LANG_ID_SEC) { uint16_t ui = _SEC_LANG_TABLE; //table pointer @@ -142,18 +142,18 @@ uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* off if (offset) *offset = ui; return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid } - W25X20CL_SPI_ENTER(); + XFLASH_SPI_ENTER(); uint32_t addr = 0x00000; //start of xflash lang--; while (1) { - w25x20cl_rd_data(addr, (uint8_t*)(header), sizeof(lang_table_header_t)); //read table header from xflash + xflash_rd_data(addr, (uint8_t*)(header), sizeof(lang_table_header_t)); //read table header from xflash if (header->magic != LANG_MAGIC) break; //break if not valid if (offset) *offset = addr; if (--lang == 0) return 1; addr += header->size; //calc address of next table } -#else //W25X20CL +#else //XFLASH if (lang == LANG_ID_SEC) { uint16_t ui = _SEC_LANG_TABLE; //table pointer @@ -161,32 +161,32 @@ uint8_t lang_get_header(uint8_t lang, lang_table_header_t* header, uint32_t* off if (offset) *offset = ui; return (header->magic == LANG_MAGIC)?1:0; //return 1 if magic valid } -#endif //W25X20CL +#endif //XFLASH return 0; } uint16_t lang_get_code(uint8_t lang) { if (lang == LANG_ID_PRI) return LANG_CODE_EN; //primary lang = EN -#ifdef W25X20CL +#ifdef XFLASH if (lang == LANG_ID_SEC) { uint16_t ui = _SEC_LANG_TABLE; //table pointer if (pgm_read_dword(((uint32_t*)(ui + 0))) != LANG_MAGIC) return LANG_CODE_XX; //magic not valid return pgm_read_word(((uint32_t*)(ui + 10))); //return lang code from progmem } - W25X20CL_SPI_ENTER(); + XFLASH_SPI_ENTER(); uint32_t addr = 0x00000; //start of xflash lang_table_header_t header; //table header structure lang--; while (1) { - w25x20cl_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash + xflash_rd_data(addr, (uint8_t*)&header, sizeof(lang_table_header_t)); //read table header from xflash if (header.magic != LANG_MAGIC) break; //break if not valid if (--lang == 0) return header.code; addr += header.size; //calc address of next table } -#else //W25X20CL +#else //XFLASH uint16_t table = _SEC_LANG_TABLE; uint8_t count = 1; //count = 1 (primary) while (pgm_read_dword((uint32_t*)table) == LANG_MAGIC) //magic valid @@ -195,7 +195,7 @@ uint16_t lang_get_code(uint8_t lang) table += pgm_read_word((uint16_t*)(table + 4)); count++; } -#endif //W25X20CL +#endif //XFLASH return LANG_CODE_XX; } diff --git a/Firmware/optiboot_w25x20cl.h b/Firmware/optiboot_w25x20cl.h deleted file mode 100644 index 95c6465f..00000000 --- a/Firmware/optiboot_w25x20cl.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef OPTIBOOT_W25X20CL_H -#define OPTIBOOT_W25X20CL_H - -extern uint8_t optiboot_w25x20cl_enter(); - -#endif /* OPTIBOOT_W25X20CL_H */ diff --git a/Firmware/optiboot_w25x20cl.cpp b/Firmware/optiboot_xflash.cpp similarity index 93% rename from Firmware/optiboot_w25x20cl.cpp rename to Firmware/optiboot_xflash.cpp index ed38b299..fb1f8075 100644 --- a/Firmware/optiboot_w25x20cl.cpp +++ b/Firmware/optiboot_xflash.cpp @@ -4,7 +4,7 @@ // Licence GLP 2 or later. #include "Marlin.h" -#include "w25x20cl.h" +#include "xflash.h" #include "stk500.h" #include "bootapp.h" #include @@ -16,14 +16,14 @@ static unsigned const int __attribute__((section(".version"))) optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER; #if 0 -#define W25X20CL_SIGNATURE_0 9 -#define W25X20CL_SIGNATURE_1 8 -#define W25X20CL_SIGNATURE_2 7 +#define XFLASH_SIGNATURE_0 9 +#define XFLASH_SIGNATURE_1 8 +#define XFLASH_SIGNATURE_2 7 #else //FIXME this is a signature of ATmega2560! -#define W25X20CL_SIGNATURE_0 0x1E -#define W25X20CL_SIGNATURE_1 0x98 -#define W25X20CL_SIGNATURE_2 0x01 +#define XFLASH_SIGNATURE_0 0x1E +#define XFLASH_SIGNATURE_1 0x98 +#define XFLASH_SIGNATURE_2 0x01 #endif #define RECV_READY ((UCSR0A & _BV(RXC0)) != 0) @@ -78,7 +78,7 @@ extern struct block_t *block_buffer; //! @brief Enter an STK500 compatible Optiboot boot loader waiting for flashing the languages to an external flash memory. //! @return 1 if "start\n" was not sent. Optiboot was skipped //! @return 0 if "start\n" was sent. Optiboot ran normally. No need to send "start\n" in setup() -uint8_t optiboot_w25x20cl_enter() +uint8_t optiboot_xflash_enter() { // Make sure to check boot_app_magic as well. Since these bootapp flags are located right in the middle of the stack, // they can be unintentionally changed. As a workaround to the language upload problem, do not only check for one bit if it's set, @@ -154,7 +154,7 @@ uint8_t optiboot_w25x20cl_enter() } spi_init(); - w25x20cl_init(); + xflash_init(); wdt_disable(); /* Forever loop: exits by causing WDT reset */ @@ -254,16 +254,16 @@ uint8_t optiboot_w25x20cl_enter() // During a single bootloader run, only erase a 64kB block once. // An 8bit bitmask 'pages_erased' covers 512kB of FLASH memory. if ((address == 0) && (pages_erased & (1 << (addr >> 16))) == 0) { - w25x20cl_wait_busy(); - w25x20cl_enable_wr(); - w25x20cl_block64_erase(addr); + xflash_wait_busy(); + xflash_enable_wr(); + xflash_block64_erase(addr); pages_erased |= (1 << (addr >> 16)); } - w25x20cl_wait_busy(); - w25x20cl_enable_wr(); - w25x20cl_page_program(addr, buff, savelength); - w25x20cl_wait_busy(); - w25x20cl_disable_wr(); + xflash_wait_busy(); + xflash_enable_wr(); + xflash_page_program(addr, buff, savelength); + xflash_wait_busy(); + xflash_disable_wr(); } } /* Read memory block mode, length is big endian. */ @@ -279,8 +279,8 @@ uint8_t optiboot_w25x20cl_enter() // Read the destination type. It should always be 'F' as flash. It is not checked. (void)getch(); verifySpace(); - w25x20cl_wait_busy(); - w25x20cl_rd_data(addr, buff, length); + xflash_wait_busy(); + xflash_rd_data(addr, buff, length); for (i = 0; i < length; ++ i) putch(buff[i]); } @@ -288,9 +288,9 @@ uint8_t optiboot_w25x20cl_enter() else if(ch == STK_READ_SIGN) { // READ SIGN - return what Avrdude wants to hear verifySpace(); - putch(W25X20CL_SIGNATURE_0); - putch(W25X20CL_SIGNATURE_1); - putch(W25X20CL_SIGNATURE_2); + putch(XFLASH_SIGNATURE_0); + putch(XFLASH_SIGNATURE_1); + putch(XFLASH_SIGNATURE_2); } else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */ // Adaboot no-wait mod diff --git a/Firmware/optiboot_xflash.h b/Firmware/optiboot_xflash.h new file mode 100644 index 00000000..453c9e00 --- /dev/null +++ b/Firmware/optiboot_xflash.h @@ -0,0 +1,6 @@ +#ifndef OPTIBOOT_XFLASH_H +#define OPTIBOOT_XFLASH_H + +extern uint8_t optiboot_xflash_enter(); + +#endif /* OPTIBOOT_XFLASH_H */ diff --git a/Firmware/pins_Einsy_1_0.h b/Firmware/pins_Einsy_1_0.h index 70660bca..b3841a59 100755 --- a/Firmware/pins_Einsy_1_0.h +++ b/Firmware/pins_Einsy_1_0.h @@ -15,9 +15,11 @@ #define AMBIENT_THERMISTOR #define PINDA_THERMISTOR -#define W25X20CL // external 256kB flash +#define XFLASH // external 256kB flash #define BOOTAPP // bootloader support +#define XFLASH_PIN_CS 32 + #define X_TMC2130_CS 41 #define X_TMC2130_DIAG 64 // !!! changed from 40 (EINY03) #define X_STEP_PIN 37 diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 5ac1a0cc..3e765a5c 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -4361,7 +4361,7 @@ void menu_setlang(unsigned char lang) } #ifdef COMMUNITY_LANG_SUPPORT -#ifdef W25X20CL +#ifdef XFLASH static void lcd_community_language_menu() { MENU_BEGIN(); @@ -4375,7 +4375,7 @@ static void lcd_community_language_menu() } MENU_END(); } -#endif //W25X20CL +#endif //XFLASH #endif //COMMUNITY_LANG_SUPPORT && W52X20CL @@ -4390,7 +4390,7 @@ static void lcd_language_menu() return; } uint8_t cnt = lang_get_count(); -#ifdef W25X20CL +#ifdef XFLASH if (cnt == 2) //display secondary language in case of clear xflash { if (menu_item_text_P(lang_get_name_by_code(lang_get_code(1)))) @@ -4401,9 +4401,9 @@ static void lcd_language_menu() } else for (int i = 2; i < 8; i++) //skip seconday language - solved in lang_select (MK3) 'i < 8' for 7 official languages -#else //W25X20CL +#else //XFLASH for (int i = 1; i < cnt; i++) //all seconday languages (MK2/25) -#endif //W25X20CL +#endif //XFLASH if (menu_item_text_P(lang_get_name_by_code(lang_get_code(i)))) { menu_setlang(i); @@ -4411,9 +4411,9 @@ static void lcd_language_menu() } #ifdef COMMUNITY_LANG_SUPPORT -#ifdef W25X20CL +#ifdef XFLASH MENU_ITEM_SUBMENU_P(_T(MSG_COMMUNITY_MADE), lcd_community_language_menu); ////MSG_COMMUNITY_MADE c=18 -#endif //W25X20CL +#endif //XFLASH #endif //COMMUNITY_LANG_SUPPORT && W52X20CL MENU_END(); @@ -6323,15 +6323,15 @@ unsigned char lcd_choose_color() { } -#include "w25x20cl.h" +#include "xflash.h" #ifdef LCD_TEST static void lcd_test_menu() { - W25X20CL_SPI_ENTER(); - w25x20cl_enable_wr(); - w25x20cl_chip_erase(); - w25x20cl_disable_wr(); + XFLASH_SPI_ENTER(); + xflash_enable_wr(); + xflash_chip_erase(); + xflash_disable_wr(); } #endif //LCD_TEST @@ -6672,7 +6672,7 @@ static void lcd_main_menu() } MENU_ITEM_SUBMENU_P(_i("Support"), lcd_support_menu);////MSG_SUPPORT #ifdef LCD_TEST - MENU_ITEM_SUBMENU_P(_i("W25x20CL init"), lcd_test_menu);////MSG_SUPPORT + MENU_ITEM_SUBMENU_P(_i("XFLASH init"), lcd_test_menu);////MSG_SUPPORT #endif //LCD_TEST MENU_END(); diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index 2c62f2fd..8caaeb32 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -159,7 +159,7 @@ //#define DEBUG_BUILD //#define DEBUG_SEC_LANG //secondary language debug output at startup -//#define DEBUG_W25X20CL //debug external spi flash +//#define DEBUG_XFLASH //debug external spi flash #ifdef DEBUG_BUILD //#define _NO_ASM #define DEBUG_DCODES //D codes diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index d74d75d5..e9619afc 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -161,7 +161,7 @@ //#define DEBUG_BUILD //#define DEBUG_SEC_LANG //secondary language debug output at startup -//#define DEBUG_W25X20CL //debug external spi flash +//#define DEBUG_XFLASH //debug external spi flash #ifdef DEBUG_BUILD //#define _NO_ASM #define DEBUG_DCODES //D codes diff --git a/Firmware/w25x20cl.h b/Firmware/w25x20cl.h deleted file mode 100644 index 10aaaf2c..00000000 --- a/Firmware/w25x20cl.h +++ /dev/null @@ -1,44 +0,0 @@ -//w25x20cl.h -#ifndef _W25X20CL_H -#define _W25X20CL_H - -#include -#include "config.h" -#include "spi.h" - - - -#define W25X20CL_STATUS_BUSY 0x01 -#define W25X20CL_STATUS_WEL 0x02 -#define W25X20CL_STATUS_BP0 0x04 -#define W25X20CL_STATUS_BP1 0x08 -#define W25X20CL_STATUS_TB 0x20 -#define W25X20CL_STATUS_SRP 0x80 - -#define W25X20CL_SPI_ENTER() spi_setup(W25X20CL_SPCR, W25X20CL_SPSR) - -#if defined(__cplusplus) -extern "C" { -#endif //defined(__cplusplus) - - -extern int8_t w25x20cl_init(void); -extern void w25x20cl_enable_wr(void); -extern void w25x20cl_disable_wr(void); -extern uint8_t w25x20cl_rd_status_reg(void); -extern void w25x20cl_wr_status_reg(uint8_t val); -extern void w25x20cl_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt); -extern void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt); -extern void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt); -extern void w25x20cl_sector_erase(uint32_t addr); -extern void w25x20cl_block32_erase(uint32_t addr); -extern void w25x20cl_block64_erase(uint32_t addr); -extern void w25x20cl_chip_erase(void); -extern void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt); -extern void w25x20cl_rd_uid(uint8_t* uid); -extern void w25x20cl_wait_busy(void); - -#if defined(__cplusplus) -} -#endif //defined(__cplusplus) -#endif //_W25X20CL_H diff --git a/Firmware/w25x20cl.c b/Firmware/xflash.c similarity index 73% rename from Firmware/w25x20cl.c rename to Firmware/xflash.c index 40d183f1..3c5d6f96 100644 --- a/Firmware/w25x20cl.c +++ b/Firmware/xflash.c @@ -1,6 +1,6 @@ -//w25x20cl.c +//xflash.c -#include "w25x20cl.h" +#include "xflash.h" #include #include #include "spi.h" @@ -31,8 +31,8 @@ #define _CMD_JEDEC_ID 0x9f #define _CMD_RD_UID 0x4b -#define _CS_LOW() WRITE(W25X20CL_PIN_CS, 0) -#define _CS_HIGH() WRITE(W25X20CL_PIN_CS, 1) +#define _CS_LOW() WRITE(XFLASH_PIN_CS, 0) +#define _CS_HIGH() WRITE(XFLASH_PIN_CS, 1) //#define _SPI_TX swspi_tx //#define _SPI_RX swspi_rx @@ -40,33 +40,33 @@ #define _SPI_RX() spi_txrx(0xff) -int w25x20cl_mfrid_devid(void); +int xflash_mfrid_devid(void); -int8_t w25x20cl_init(void) +int8_t xflash_init(void) { _CS_HIGH(); - SET_OUTPUT(W25X20CL_PIN_CS); - W25X20CL_SPI_ENTER(); - if (!w25x20cl_mfrid_devid()) return 0; + SET_OUTPUT(XFLASH_PIN_CS); + XFLASH_SPI_ENTER(); + if (!xflash_mfrid_devid()) return 0; return 1; } -void w25x20cl_enable_wr(void) +void xflash_enable_wr(void) { _CS_LOW(); _SPI_TX(_CMD_ENABLE_WR); // send command 0x06 _CS_HIGH(); } -void w25x20cl_disable_wr(void) +void xflash_disable_wr(void) { _CS_LOW(); _SPI_TX(_CMD_DISABLE_WR); // send command 0x04 _CS_HIGH(); } -uint8_t w25x20cl_rd_status_reg(void) +uint8_t xflash_rd_status_reg(void) { _CS_LOW(); _SPI_TX(_CMD_RD_STATUS_REG); // send command 0x90 @@ -75,6 +75,7 @@ uint8_t w25x20cl_rd_status_reg(void) return val; } +#if 0 void w25x20cl_wr_status_reg(uint8_t val) { _CS_LOW(); @@ -82,8 +83,9 @@ void w25x20cl_wr_status_reg(uint8_t val) _SPI_TX(val); // send value _CS_HIGH(); } +#endif -void w25x20cl_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt) +void xflash_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt) { _CS_LOW(); _SPI_TX(_CMD_RD_DATA); // send command 0x03 @@ -95,7 +97,7 @@ void w25x20cl_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt) _CS_HIGH(); } -void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt) +void xflash_page_program(uint32_t addr, uint8_t* data, uint16_t cnt) { _CS_LOW(); _SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02 @@ -107,7 +109,7 @@ void w25x20cl_page_program(uint32_t addr, uint8_t* data, uint16_t cnt) _CS_HIGH(); } -void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt) +void xflash_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt) { _CS_LOW(); _SPI_TX(_CMD_PAGE_PROGRAM); // send command 0x02 @@ -119,7 +121,7 @@ void w25x20cl_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt) _CS_HIGH(); } -void w25x20cl_erase(uint8_t cmd, uint32_t addr) +void xflash_erase(uint8_t cmd, uint32_t addr) { _CS_LOW(); _SPI_TX(cmd); // send command 0x20 @@ -129,22 +131,22 @@ void w25x20cl_erase(uint8_t cmd, uint32_t addr) _CS_HIGH(); } -void w25x20cl_sector_erase(uint32_t addr) +void xflash_sector_erase(uint32_t addr) { - return w25x20cl_erase(_CMD_SECTOR_ERASE, addr); + return xflash_erase(_CMD_SECTOR_ERASE, addr); } -void w25x20cl_block32_erase(uint32_t addr) +void xflash_block32_erase(uint32_t addr) { - return w25x20cl_erase(_CMD_BLOCK32_ERASE, addr); + return xflash_erase(_CMD_BLOCK32_ERASE, addr); } -void w25x20cl_block64_erase(uint32_t addr) +void xflash_block64_erase(uint32_t addr) { - return w25x20cl_erase(_CMD_BLOCK64_ERASE, addr); + return xflash_erase(_CMD_BLOCK64_ERASE, addr); } -void w25x20cl_chip_erase(void) +void xflash_chip_erase(void) { _CS_LOW(); _SPI_TX(_CMD_CHIP_ERASE); // send command 0xc7 @@ -152,7 +154,7 @@ void w25x20cl_chip_erase(void) } -void w25x20cl_rd_uid(uint8_t* uid) +void xflash_rd_uid(uint8_t* uid) { _CS_LOW(); _SPI_TX(_CMD_RD_UID); // send command 0x4b @@ -165,20 +167,20 @@ void w25x20cl_rd_uid(uint8_t* uid) _CS_HIGH(); } -int w25x20cl_mfrid_devid(void) +int xflash_mfrid_devid(void) { _CS_LOW(); _SPI_TX(_CMD_MFRID_DEVID); // send command 0x90 uint8_t cnt = 3; // 3 address bytes while (cnt--) // send address bytes _SPI_TX(0x00); - uint8_t w25x20cl_mfrid = _SPI_RX(); // receive mfrid - uint8_t w25x20cl_devid = _SPI_RX(); // receive devid + uint8_t xflash_mfrid = _SPI_RX(); // receive mfrid + uint8_t xflash_devid = _SPI_RX(); // receive devid _CS_HIGH(); - return ((w25x20cl_mfrid == _MFRID) && (w25x20cl_devid == _DEVID)); + return ((xflash_mfrid == _MFRID) && (xflash_devid == _DEVID)); } -void w25x20cl_wait_busy(void) +void xflash_wait_busy(void) { - while (w25x20cl_rd_status_reg() & W25X20CL_STATUS_BUSY) ; + while (xflash_rd_status_reg() & XFLASH_STATUS_BUSY) ; } diff --git a/Firmware/xflash.h b/Firmware/xflash.h new file mode 100644 index 00000000..c9ad5275 --- /dev/null +++ b/Firmware/xflash.h @@ -0,0 +1,50 @@ +//xflash.h +#ifndef _XFLASH_H +#define _XFLASH_H + +#include +#include "config.h" +#include "spi.h" + + + +#define XFLASH_STATUS_BUSY 0x01 +#define XFLASH_STATUS_WEL 0x02 +#define XFLASH_STATUS_BP0 0x04 +#define XFLASH_STATUS_BP1 0x08 +#define XFLASH_STATUS_TB 0x20 +#define XFLASH_STATUS_SRP 0x80 + +#define XFLASH_SPI_RATE 0 // fosc/4 = 4MHz +#define XFLASH_SPCR SPI_SPCR(XFLASH_SPI_RATE, 1, 1, 1, 0) +#define XFLASH_SPSR SPI_SPSR(XFLASH_SPI_RATE) + +#define XFLASH_SPI_ENTER() spi_setup(XFLASH_SPCR, XFLASH_SPSR) + +#if defined(__cplusplus) +extern "C" { +#endif //defined(__cplusplus) + + +extern int8_t xflash_init(void); +extern void xflash_enable_wr(void); +extern void xflash_disable_wr(void); +extern uint8_t xflash_rd_status_reg(void); +#if 0 +extern void w25x20cl_wr_status_reg(uint8_t val); +#endif +extern void xflash_rd_data(uint32_t addr, uint8_t* data, uint16_t cnt); +extern void xflash_page_program(uint32_t addr, uint8_t* data, uint16_t cnt); +extern void xflash_page_program_P(uint32_t addr, uint8_t* data, uint16_t cnt); +extern void xflash_sector_erase(uint32_t addr); +extern void xflash_block32_erase(uint32_t addr); +extern void xflash_block64_erase(uint32_t addr); +extern void xflash_chip_erase(void); +extern void xflash_page_program(uint32_t addr, uint8_t* data, uint16_t cnt); +extern void xflash_rd_uid(uint8_t* uid); +extern void xflash_wait_busy(void); + +#if defined(__cplusplus) +} +#endif //defined(__cplusplus) +#endif //_XFLASH_H From 07bf4bbe4841c42602c8f6659ba30dbb32a87741 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 5 Mar 2021 09:54:52 +0200 Subject: [PATCH 17/26] Fix gd25120c rd_uid command --- Firmware/xflash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/xflash.c b/Firmware/xflash.c index 3c5d6f96..bc266605 100644 --- a/Firmware/xflash.c +++ b/Firmware/xflash.c @@ -159,8 +159,8 @@ void xflash_rd_uid(uint8_t* uid) _CS_LOW(); _SPI_TX(_CMD_RD_UID); // send command 0x4b uint8_t cnt = 4; // 4 dummy bytes - while (cnt--) // receive dummy bytes - _SPI_RX(); + while (cnt--) // transmit dummy bytes + _SPI_TX(0x00); cnt = 8; // 8 bytes UID while (cnt--) // receive UID uid[7 - cnt] = _SPI_RX(); From 56948157d0fdeb7727b8acdb49ec385162609cc2 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 5 Mar 2021 13:48:25 +0200 Subject: [PATCH 18/26] GD25Q40C xflash support --- Firmware/xflash.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Firmware/xflash.c b/Firmware/xflash.c index bc266605..a39908cd 100644 --- a/Firmware/xflash.c +++ b/Firmware/xflash.c @@ -6,8 +6,11 @@ #include "spi.h" #include "fastio.h" -#define _MFRID 0xEF -#define _DEVID 0x11 +#define _MFRID_W25X20CL 0xEF +#define _DEVID_W25X20CL 0x11 + +#define _MFRID_GD25Q20C 0xEF +#define _DEVID_GD25Q20C 0x11 #define _CMD_ENABLE_WR 0x06 #define _CMD_ENABLE_WR_VSR 0x50 @@ -177,7 +180,9 @@ int xflash_mfrid_devid(void) uint8_t xflash_mfrid = _SPI_RX(); // receive mfrid uint8_t xflash_devid = _SPI_RX(); // receive devid _CS_HIGH(); - return ((xflash_mfrid == _MFRID) && (xflash_devid == _DEVID)); + return + ((xflash_mfrid == _MFRID_W25X20CL) && (xflash_devid == _DEVID_W25X20CL)) || + ((xflash_mfrid == _MFRID_GD25Q20C) && (xflash_devid == _DEVID_GD25Q20C)); } void xflash_wait_busy(void) From 94c1e65d83277745593cf1678d52b9074fbfe23b Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 5 Mar 2021 13:53:37 +0200 Subject: [PATCH 19/26] Fix MK2.x builds --- Firmware/xflash.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Firmware/xflash.c b/Firmware/xflash.c index a39908cd..2b9520fa 100644 --- a/Firmware/xflash.c +++ b/Firmware/xflash.c @@ -6,6 +6,8 @@ #include "spi.h" #include "fastio.h" +#ifdef XFLASH + #define _MFRID_W25X20CL 0xEF #define _DEVID_W25X20CL 0x11 @@ -189,3 +191,5 @@ void xflash_wait_busy(void) { while (xflash_rd_status_reg() & XFLASH_STATUS_BUSY) ; } + +#endif //XFLASH From d31601dcb817aa78d0014c8407d384ce7929389a Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 9 Mar 2021 17:19:44 +0200 Subject: [PATCH 20/26] Use correct mfrid for gd25q20c --- Firmware/xflash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/xflash.c b/Firmware/xflash.c index 2b9520fa..e9d894a5 100644 --- a/Firmware/xflash.c +++ b/Firmware/xflash.c @@ -11,7 +11,7 @@ #define _MFRID_W25X20CL 0xEF #define _DEVID_W25X20CL 0x11 -#define _MFRID_GD25Q20C 0xEF +#define _MFRID_GD25Q20C 0xC8 #define _DEVID_GD25Q20C 0x11 #define _CMD_ENABLE_WR 0x06 From 61faa49cbb6ec1f4e7607d2c022b5d7de9547733 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Wed, 7 Apr 2021 15:57:50 +0200 Subject: [PATCH 21/26] Fix buffer overflow in buf Fix cmd overflow introduced in 186ce0f. With a precision of %f being .6 and assuming a maximum (theoretical) acceleration of 99999 we need 47 bytes including terminating byte. Round it to 48 --- Firmware/Marlin_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 72e1e9ca..ad54ddea 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -11247,7 +11247,7 @@ void restore_print_from_eeprom(bool mbl_was_active) { int feedrate_rec; int feedmultiply_rec; uint8_t fan_speed_rec; - char cmd[30]; + char cmd[48]; char filename[13]; uint8_t depth = 0; char dir_name[9]; From 7356cd0811b7e06f7bcc628bd8fe4b73da242d3c Mon Sep 17 00:00:00 2001 From: Voinea Dragos Date: Thu, 1 Apr 2021 20:37:07 +0300 Subject: [PATCH 22/26] EEPROM_JOB_ID --- Firmware/eeprom.cpp | 3 +++ Firmware/eeprom.h | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Firmware/eeprom.cpp b/Firmware/eeprom.cpp index 4f519cae..d24e11b7 100644 --- a/Firmware/eeprom.cpp +++ b/Firmware/eeprom.cpp @@ -97,6 +97,9 @@ void eeprom_init() #ifdef PINDA_TEMP_COMP if (eeprom_read_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_PINDA_TEMP_COMPENSATION, 0); #endif //PINDA_TEMP_COMP + + if (eeprom_read_dword((uint32_t*)EEPROM_JOB_ID) == EEPROM_EMPTY_VALUE32) + eeprom_update_dword((uint32_t*)EEPROM_JOB_ID, 0); } //! @brief Get default sheet name for index diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index 2590d0f2..df91e2b6 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -324,6 +324,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP | 0x0D11 3345 | float | EEPROM_UVLO_ACCELL | ??? | ff ff ff ffh | Power panic saved normal acceleration | ??? | D3 Ax0d11 C4 | 0x0D0D 3341 | float | EEPROM_UVLO_RETRACT_ACCELL | ??? | ff ff ff ffh | Power panic saved retract acceleration | ??? | D3 Ax0d0d C4 | 0x0D09 3337 | float | EEPROM_UVLO_TRAVEL_ACCELL | ??? | ff ff ff ffh | Power panic saved travel acceleration | ??? | D3 Ax0d09 C4 +| 0x0D05 3333 | uint32_t | EEPROM_JOB_ID | ??? | 00 00 00 00h | Job ID used by host software | D3 only | D3 Ax0d05 C4 | Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--: @@ -337,6 +338,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP #define EEPROM_EMPTY_VALUE 0xFF #define EEPROM_EMPTY_VALUE16 0xFFFF +#define EEPROM_EMPTY_VALUE32 0xFFFFFFFFl // The total size of the EEPROM is // 4096 for the Atmega2560 #define EEPROM_TOP 4096 @@ -534,8 +536,10 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE); #define EEPROM_UVLO_RETRACT_ACCELL (EEPROM_UVLO_ACCELL-4) // float #define EEPROM_UVLO_TRAVEL_ACCELL (EEPROM_UVLO_RETRACT_ACCELL-4) // float +#define EEPROM_JOB_ID (EEPROM_UVLO_TRAVEL_ACCELL-4) //uint32_t + //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items. -#define EEPROM_LAST_ITEM EEPROM_UVLO_TRAVEL_ACCELL +#define EEPROM_LAST_ITEM EEPROM_JOB_ID // !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! // !!!!! From 5a91e1de4d305d39ad9933c620444c45af757a14 Mon Sep 17 00:00:00 2001 From: "DESKTOP-AFI832L\\admin" Date: Tue, 13 Apr 2021 15:18:56 +0200 Subject: [PATCH 23/26] Calibration: fix checking of scan of calibration points PFW-1223 --- Firmware/xyzcal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/xyzcal.cpp b/Firmware/xyzcal.cpp index e738c353..ea92359c 100644 --- a/Firmware/xyzcal.cpp +++ b/Firmware/xyzcal.cpp @@ -918,7 +918,7 @@ bool check_scan(uint8_t *matrix32){ for (int16_t i = 0; i < 32*32;++i){ if (matrix32[i] == 0) { ++mins; - } else { + } else if (matrix32[i] == 0xFF){ ++maxs; } } From c43688a5498f000bdc8e09c4f812e03f9cc373b3 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Fri, 16 Apr 2021 13:52:36 +0200 Subject: [PATCH 24/26] Version changed (3.10.0-RC2 build 4104) --- Firmware/Configuration.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index d390283f..a6c89c88 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -16,8 +16,8 @@ extern uint16_t nPrinterType; extern PGM_P sPrinterName; // Firmware version -#define FW_VERSION "3.10.0-RC1" -#define FW_COMMIT_NR 4078 +#define FW_VERSION "3.10.0-RC2" +#define FW_COMMIT_NR 4104 // 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 From 23c75da727c913dbf745dcb4d736c2b4c35f66ba Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 18 Apr 2021 00:06:56 +0200 Subject: [PATCH 25/26] Fix Crash/PP recovery position on instructions with comments PR #2967 altered the way ``sdpos_atomic`` was set, causing issues in the crashdetect/powerpanic recovery offset if the instruction being recovered happens to contain a comment. Previously ``sdpos`` was assumed to be a single byte prior to the last read character. sdpos+1 would thus position the index to the next instruction. With gcode-filtering in place, sdpos is left just before the comment, while the actual read position is at the newline. This causes to parser to resume in the middle of the comment. Change the value returned by cardreader::get_sdpos() to always return the last read position, as everybody expects (!!). This avoids the +1, and correctly sets the resume position to the next valid instruction without overhead. --- Firmware/cardreader.h | 9 ++++++--- Firmware/cmdqueue.cpp | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 715d82fa..47343e23 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -59,9 +59,12 @@ public: FORCE_INLINE bool isFileOpen() { return file.isOpen(); } bool eof() { return sdpos>=filesize; } - // There may be a potential performance problem - when the comment reading fails, sdpos points to the last correctly read character. - // However, repeated reading (e.g. after power panic) the comment will be read again - it should survive correctly, it will just take a few moments to skip - FORCE_INLINE int16_t getFilteredGcodeChar() { sdpos = file.curPosition();return (int16_t)file.readFilteredGcode();}; + FORCE_INLINE int16_t getFilteredGcodeChar() + { + int16_t c = (int16_t)file.readFilteredGcode(); + sdpos = file.curPosition(); + return c; + }; void setIndex(long index) {sdpos = index;file.seekSetFilteredGcode(index);}; FORCE_INLINE uint8_t percentDone(){if(!isFileOpen()) return 0; if(filesize) return sdpos/((filesize+99)/100); else return 0;}; FORCE_INLINE char* getWorkDirName(){workDir.getFilename(filename);return filename;}; diff --git a/Firmware/cmdqueue.cpp b/Firmware/cmdqueue.cpp index a400a4e1..3bde3336 100755 --- a/Firmware/cmdqueue.cpp +++ b/Firmware/cmdqueue.cpp @@ -600,7 +600,7 @@ void get_command() } // The new command buffer could be updated non-atomically, because it is not yet considered // to be inside the active queue. - sd_count.value = (card.get_sdpos()+1) - sdpos_atomic; + sd_count.value = card.get_sdpos() - sdpos_atomic; cmdbuffer[bufindw] = CMDBUFFER_CURRENT_TYPE_SDCARD; cmdbuffer[bufindw+1] = sd_count.lohi.lo; cmdbuffer[bufindw+2] = sd_count.lohi.hi; @@ -625,7 +625,7 @@ void get_command() // or a 115200 Bd serial line receive interrupt, which will not trigger faster than 12kHz. ++ buflen; bufindw += len; - sdpos_atomic = card.get_sdpos()+1; + sdpos_atomic = card.get_sdpos(); if (bufindw == sizeof(cmdbuffer)) bufindw = 0; sei(); From a5e4df390d4cdb7b4fe41a2bf8e4205e966cc43e Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sat, 17 Apr 2021 23:35:26 +0200 Subject: [PATCH 26/26] Sync before/after setting mesh_bed_leveling_flag/homing_flag mesh_bed_leveling_flag and homing_flag should be set only when the planner is empty as a consequence of #3100, since any operation executed *while* the mbl/homing flag is set is considered part of the compound instruction that generated it (G80, G28, G30, G76). Failure in doing so can result in instructions just prior being lost, since they're incorrectly discarded (assumed to be redone). G1 ; lost .. G80 ; .. if PP happens here --- Firmware/Marlin_main.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 1a9d33a0..68933093 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -2660,16 +2660,15 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, long home_y_value, bool home_z_axis, long home_z_value, bool without_mbl) #endif //TMC2130 { + // Flag for the display update routine and to disable the print cancelation during homing. st_synchronize(); + homing_flag = true; #if 0 SERIAL_ECHOPGM("G28, initial "); print_world_coordinates(); SERIAL_ECHOPGM("G28, initial "); print_physical_coordinates(); #endif - // Flag for the display update routine and to disable the print cancelation during homing. - homing_flag = true; - // Which axes should be homed? bool home_x = home_x_axis; bool home_y = home_y_axis; @@ -2912,24 +2911,21 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon #if (defined(MESH_BED_LEVELING) && !defined(MK1BP)) if (home_x_axis || home_y_axis || without_mbl || home_z_axis) - { + { if (! home_z && mbl_was_active) { // Re-enable the mesh bed leveling if only the X and Y axes were re-homed. mbl.active = true; // and re-adjust the current logical Z axis with the bed leveling offset applicable at the current XY position. current_position[Z_AXIS] -= mbl.get_z(st_get_position_mm(X_AXIS), st_get_position_mm(Y_AXIS)); } - } - else - { - st_synchronize(); - homing_flag = false; - } + } #endif if (farm_mode) { prusa_statistics(20); }; + st_synchronize(); homing_flag = false; + #if 0 SERIAL_ECHOPGM("G28, final "); print_world_coordinates(); SERIAL_ECHOPGM("G28, final "); print_physical_coordinates(); @@ -2950,6 +2946,10 @@ static void gcode_G28(bool home_x_axis, bool home_y_axis, bool home_z_axis) // G80 - Automatic mesh bed leveling static void gcode_G80() { + st_synchronize(); + if (waiting_inside_plan_buffer_line_print_aborted) + return; + mesh_bed_leveling_flag = true; #ifndef PINDA_THERMISTOR static bool run = false; // thermistor-less PINDA temperature compensation is running @@ -3350,9 +3350,11 @@ static void gcode_G80() lcd_setstatuspgm(_T(WELCOME_MSG)); custom_message_type = custom_message_type_old; custom_message_state = custom_message_state_old; - mesh_bed_leveling_flag = false; mesh_bed_run_from_menu = false; lcd_update(2); + + st_synchronize(); + mesh_bed_leveling_flag = false; } @@ -5145,8 +5147,9 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) */ case 30: { - homing_flag = true; st_synchronize(); + homing_flag = true; + // TODO: make sure the bed_level_rotation_matrix is identity or the planner will get set incorectly int l_feedmultiply = setup_for_endstop_move(); @@ -5249,7 +5252,9 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) } } + st_synchronize(); homing_flag = true; // keep homing on to avoid babystepping while the LCD is enabled + lcd_update_enable(true); KEEPALIVE_STATE(NOT_BUSY); //no need to print busy messages as we print current temperatures periodicaly SERIAL_ECHOLNPGM("PINDA probe calibration start");