From 04588ee5cba673979737c9317e86e7082c318f73 Mon Sep 17 00:00:00 2001 From: Thelvaen Date: Wed, 12 Feb 2020 13:25:16 +0100 Subject: [PATCH 1/9] removing sudo for normal build --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 54070dce2..9d62d9ae3 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ - For MK3 --> skip to step 3. - If you have a different printer model, follow step [2.b](#2b) from Windows build -3. Run `sudo ./build.sh` +3. Run `./build.sh` - Output hex file is at `"PrusaFirmware/lang/firmware.hex"` . In the same folder you can hex files for other languages as well. 4. Connect your printer and flash with PrusaSlicer ( Configuration --> Flash printer firmware ) or Slic3r PE. From 7179151d3f4a430c300fdcf21478fcdd2babe005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?val=C3=A8re=20didon?= Date: Sun, 29 Mar 2020 17:26:56 +0200 Subject: [PATCH 2/9] feutre -> furtif Translation error of Stealth --- lang/lang_en_fr.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/lang_en_fr.txt b/lang/lang_en_fr.txt index f6add9480..51ddf1596 100755 --- a/lang/lang_en_fr.txt +++ b/lang/lang_en_fr.txt @@ -20,7 +20,7 @@ #MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4 "WARNING:\x0aCrash detection\x0adisabled in\x0aStealth mode" -"ATTENTION:\x0aDetection de crash\x0adesactivee en\x0amode feutre" +"ATTENTION:\x0aDetection de crash\x0adesactivee en\x0amode furtif" # ">Cancel" @@ -550,7 +550,7 @@ #MSG_SILENT "Silent" -"Feutre" +"Furtif" # "MMU needs user attention." From 6da401be564b2621be8d4c49e3f07ec2e4b77321 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Mon, 30 Mar 2020 16:53:58 +0200 Subject: [PATCH 3/9] Move few D-codes command from Marlin_main to Dcodes D80, D81 and D106 have been added to `Marlin_main.cpp` but all other D-codes moved to `Dcodes.cpp/.h` --- Firmware/Dcodes.cpp | 92 ++++++++++++++++++++++++++++++++++++++++ Firmware/Dcodes.h | 22 ++++++++-- Firmware/Marlin_main.cpp | 54 ++--------------------- 3 files changed, 113 insertions(+), 55 deletions(-) diff --git a/Firmware/Dcodes.cpp b/Firmware/Dcodes.cpp index 79695c9e7..7506e7fc1 100644 --- a/Firmware/Dcodes.cpp +++ b/Firmware/Dcodes.cpp @@ -635,6 +635,98 @@ void dcode_12() } +#ifdef HEATBED_ANALYSIS + /*! + ### D80 - Bed check D80: Bed check + This command will log data to SD card file "mesh.txt". + #### Usage + + D80 [ E | F | G | H | I | J ] + + #### Parameters + - `E` - Dimension X (default 40) + - `F` - Dimention Y (default 40) + - `G` - Points X (default 40) + - `H` - Points Y (default 40) + - `I` - Offset X (default 74) + - `J` - Offset Y (default 34) + */ +void dcode_80() +{ + float dimension_x = 40; + float dimension_y = 40; + int points_x = 40; + int points_y = 40; + float offset_x = 74; + float offset_y = 33; + + if (code_seen('E')) dimension_x = code_value(); + if (code_seen('F')) dimension_y = code_value(); + if (code_seen('G')) {points_x = code_value(); } + if (code_seen('H')) {points_y = code_value(); } + if (code_seen('I')) {offset_x = code_value(); } + if (code_seen('J')) {offset_y = code_value(); } + printf_P(PSTR("DIM X: %f\n"), dimension_x); + printf_P(PSTR("DIM Y: %f\n"), dimension_y); + printf_P(PSTR("POINTS X: %d\n"), points_x); + printf_P(PSTR("POINTS Y: %d\n"), points_y); + printf_P(PSTR("OFFSET X: %f\n"), offset_x); + printf_P(PSTR("OFFSET Y: %f\n"), offset_y); + bed_check(dimension_x,dimension_y,points_x,points_y,offset_x,offset_y); +} + + + /*! + ### D81 - Bed analysis D80: Bed analysis + This command will log data to SD card file "wldsd.txt". + #### Usage + + D81 [ E | F | G | H | I | J ] + + #### Parameters + - `E` - Dimension X (default 40) + - `F` - Dimention Y (default 40) + - `G` - Points X (default 40) + - `H` - Points Y (default 40) + - `I` - Offset X (default 74) + - `J` - Offset Y (default 34) + */ +void dcode_81() +{ + float dimension_x = 40; + float dimension_y = 40; + int points_x = 40; + int points_y = 40; + float offset_x = 74; + float offset_y = 33; + + if (code_seen('E')) dimension_x = code_value(); + if (code_seen('F')) dimension_y = code_value(); + if (code_seen("G")) { strchr_pointer+=1; points_x = code_value(); } + if (code_seen("H")) { strchr_pointer+=1; points_y = code_value(); } + if (code_seen("I")) { strchr_pointer+=1; offset_x = code_value(); } + if (code_seen("J")) { strchr_pointer+=1; offset_y = code_value(); } + + bed_analysis(dimension_x,dimension_y,points_x,points_y,offset_x,offset_y); + +} + +#endif //HEATBED_ANALYSIS + + /*! + ### D106 - Print measured fan speed for different pwm values D106: Print measured fan speed for different pwm values + */ +void dcode_106() +{ + for (int i = 255; i > 0; i = i - 5) { + fanSpeed = i; + //delay_keep_alive(2000); + for (int j = 0; j < 100; j++) { + delay_keep_alive(100); + } + printf_P(_N("%d: %d\n"), i, fan_speed[1]); + } +} #ifdef TMC2130 #include "planner.h" diff --git a/Firmware/Dcodes.h b/Firmware/Dcodes.h index eaf849edb..894cba527 100644 --- a/Firmware/Dcodes.h +++ b/Firmware/Dcodes.h @@ -2,26 +2,40 @@ #define DCODES_H extern void dcode__1(); //D-1 - Endless loop (to simulate deadlock) - extern void dcode_0(); //D0 - Reset extern void dcode_1(); //D1 - Clear EEPROM extern void dcode_2(); //D2 - Read/Write RAM + +#ifdef DEBUG_DCODE3 extern void dcode_3(); //D3 - Read/Write EEPROM +#endif //DEBUG_DCODE3 + extern void dcode_4(); //D4 - Read/Write PIN + +#ifdef DEBUG_DCODE5 extern void dcode_5(); //D5 - Read/Write FLASH +#endif //DEBUG_DCODE5 + extern void dcode_6(); //D6 - Read/Write external FLASH extern void dcode_7(); //D7 - Read/Write Bootloader extern void dcode_8(); //D8 - Read/Write PINDA extern void dcode_9(); //D9 - Read/Write ADC (Write=enable simulated, Read=disable simulated) - extern void dcode_10(); //D10 - XYZ calibration = OK +extern void dcode_12(); //D12 - Log time. Writes the current time in the log file. + +#ifdef HEATBED_ANALYSIS +extern void dcode_80(); //D80 - Bed check. This command will log data to SD card file "mesh.txt". +extern void dcode_81(); //D81 - Bed analysis. This command will log data to SD card file "wldsd.txt". +#endif //HEATBED_ANALYSIS + + extern void dcode_106(); //D106 - Print measured fan speed for different pwm values #ifdef TMC2130 -extern void dcode_2130(); //D2130 - TMC2130 + extern void dcode_2130(); //D2130 - TMC2130 #endif //TMC2130 #ifdef PAT9125 -extern void dcode_9125(); //D9125 - PAT9125 + extern void dcode_9125(); //D9125 - PAT9125 #endif //PAT9125 diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index e4e40cfb2..c4948a20e 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -8976,28 +8976,7 @@ Sigma_Exit: - `J` - Offset Y (default 34) */ case 80: - { - float dimension_x = 40; - float dimension_y = 40; - int points_x = 40; - int points_y = 40; - float offset_x = 74; - float offset_y = 33; - - if (code_seen('E')) dimension_x = code_value(); - if (code_seen('F')) dimension_y = code_value(); - if (code_seen('G')) {points_x = code_value(); } - if (code_seen('H')) {points_y = code_value(); } - if (code_seen('I')) {offset_x = code_value(); } - if (code_seen('J')) {offset_y = code_value(); } - printf_P(PSTR("DIM X: %f\n"), dimension_x); - printf_P(PSTR("DIM Y: %f\n"), dimension_y); - printf_P(PSTR("POINTS X: %d\n"), points_x); - printf_P(PSTR("POINTS Y: %d\n"), points_y); - printf_P(PSTR("OFFSET X: %f\n"), offset_x); - printf_P(PSTR("OFFSET Y: %f\n"), offset_y); - bed_check(dimension_x,dimension_y,points_x,points_y,offset_x,offset_y); - }break; + dcode_80(); break; /*! ### D81 - Bed analysis D80: Bed analysis @@ -9015,24 +8994,7 @@ Sigma_Exit: - `J` - Offset Y (default 34) */ case 81: - { - float dimension_x = 40; - float dimension_y = 40; - int points_x = 40; - int points_y = 40; - float offset_x = 74; - float offset_y = 33; - - if (code_seen('E')) dimension_x = code_value(); - if (code_seen('F')) dimension_y = code_value(); - if (code_seen("G")) { strchr_pointer+=1; points_x = code_value(); } - if (code_seen("H")) { strchr_pointer+=1; points_y = code_value(); } - if (code_seen("I")) { strchr_pointer+=1; offset_x = code_value(); } - if (code_seen("J")) { strchr_pointer+=1; offset_y = code_value(); } - - bed_analysis(dimension_x,dimension_y,points_x,points_y,offset_x,offset_y); - - } break; + dcode_81(); break; #endif //HEATBED_ANALYSIS #ifdef DEBUG_DCODES @@ -9041,17 +9003,7 @@ Sigma_Exit: ### D106 - Print measured fan speed for different pwm values D106: Print measured fan speed for different pwm values */ case 106: - { - for (int i = 255; i > 0; i = i - 5) { - fanSpeed = i; - //delay_keep_alive(2000); - for (int j = 0; j < 100; j++) { - delay_keep_alive(100); - - } - printf_P(_N("%d: %d\n"), i, fan_speed[1]); - } - }break; + dcode_106(); break; #ifdef TMC2130 /*! From b8896ad9c0dd53b8f2be5d2cf5ae80ab63511d88 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 1 Apr 2020 12:28:39 +0300 Subject: [PATCH 4/9] First attempt for Z probe checking during selftest on the MK3/S --- Firmware/ultralcd.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index daf9f0176..08e8d567f 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -168,10 +168,10 @@ static void reset_crash_det(unsigned char axis); static bool lcd_selfcheck_axis_sg(unsigned char axis); static bool lcd_selfcheck_axis(int _axis, int _travel); #else -static bool lcd_selfcheck_endstops(); static bool lcd_selfcheck_axis(int _axis, int _travel); static bool lcd_selfcheck_pulleys(int axis); #endif //TMC2130 +static bool lcd_selfcheck_endstops(); static bool lcd_selfcheck_check_heater(bool _isbed); enum class TestScreen : uint_least8_t @@ -7667,11 +7667,7 @@ bool lcd_selftest() if (_result) { _progress = lcd_selftest_screen(TestScreen::FansOk, _progress, 3, true, 2000); -#ifndef TMC2130 - _result = lcd_selfcheck_endstops(); -#else - _result = true; -#endif + _result = lcd_selfcheck_endstops(); //With TMC2130, only the Z probe is tested. } if (_result) @@ -8137,31 +8133,42 @@ static bool lcd_selfcheck_pulleys(int axis) } return(true); } +#endif //not defined TMC2130 static bool lcd_selfcheck_endstops() { bool _result = true; - if (((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) || + if ( + #ifndef TMC2130 + ((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) || ((READ(Y_MIN_PIN) ^ Y_MIN_ENDSTOP_INVERTING) == 1) || + #endif //!TMC2130 ((READ(Z_MIN_PIN) ^ Z_MIN_ENDSTOP_INVERTING) == 1)) { + #ifndef TMC2130 if ((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) current_position[0] += 10; if ((READ(Y_MIN_PIN) ^ Y_MIN_ENDSTOP_INVERTING) == 1) current_position[1] += 10; + #endif //!TMC2130 if ((READ(Z_MIN_PIN) ^ Z_MIN_ENDSTOP_INVERTING) == 1) current_position[2] += 10; } plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); - _delay(500); + st_synchronize(); - if (((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) || + if ( + #ifndef TMC2130 + ((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) || ((READ(Y_MIN_PIN) ^ Y_MIN_ENDSTOP_INVERTING) == 1) || + #endif //!TMC2130 ((READ(Z_MIN_PIN) ^ Z_MIN_ENDSTOP_INVERTING) == 1)) { _result = false; char _error[4] = ""; + #ifndef TMC2130 if ((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) strcat(_error, "X"); if ((READ(Y_MIN_PIN) ^ Y_MIN_ENDSTOP_INVERTING) == 1) strcat(_error, "Y"); + #endif //!TMC2130 if ((READ(Z_MIN_PIN) ^ Z_MIN_ENDSTOP_INVERTING) == 1) strcat(_error, "Z"); lcd_selftest_error(TestError::Endstops, _error, ""); } @@ -8169,7 +8176,6 @@ static bool lcd_selfcheck_endstops() manage_inactivity(true); return _result; } -#endif //not defined TMC2130 static bool lcd_selfcheck_check_heater(bool _isbed) { From 8b2b32c85bf04b8dc6b6333228ce069f66b761bb Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 1 Apr 2020 13:15:08 +0300 Subject: [PATCH 5/9] Raise on nozzle crash --- Firmware/Marlin_main.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index ad5a1a85c..0700514db 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -2314,9 +2314,15 @@ bool homeaxis(int axis, bool doError, uint8_t cnt) #ifdef TMC2130 if (READ(Z_TMC2130_DIAG) != 0) { //Z crash FORCE_HIGH_POWER_END; - if (doError) kill(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); - current_position[axis] = -5; //assume that nozzle crashed into bed - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + if (doError) + { + current_position[Z_AXIS] += MESH_HOME_Z_SEARCH; + plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder); + st_synchronize(); + kill(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); + } + current_position[axis] = -MESH_HOME_Z_SEARCH; //assume that nozzle crashed into bed + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); return 0; } #endif //TMC2130 @@ -2332,9 +2338,15 @@ bool homeaxis(int axis, bool doError, uint8_t cnt) #ifdef TMC2130 if (READ(Z_TMC2130_DIAG) != 0) { //Z crash FORCE_HIGH_POWER_END; - if (doError) kill(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); - current_position[axis] = -5; //assume that nozzle crashed into bed - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + if (doError) + { + current_position[Z_AXIS] += MESH_HOME_Z_SEARCH; + plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder); + st_synchronize(); + kill(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); + } + current_position[axis] = -MESH_HOME_Z_SEARCH; //assume that nozzle crashed into bed + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); return 0; } #endif //TMC2130 From 792bab9bbb0ad21ab1bd36cb36c77df7e7333914 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 1 Apr 2020 13:50:22 +0300 Subject: [PATCH 6/9] Fix go up --- Firmware/Marlin_main.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 0700514db..0a621aab3 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -2316,14 +2316,16 @@ bool homeaxis(int axis, bool doError, uint8_t cnt) FORCE_HIGH_POWER_END; if (doError) { + current_position[Z_AXIS] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); current_position[Z_AXIS] += MESH_HOME_Z_SEARCH; plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder); st_synchronize(); kill(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); } - current_position[axis] = -MESH_HOME_Z_SEARCH; //assume that nozzle crashed into bed + current_position[Z_AXIS] = -MESH_HOME_Z_SEARCH; //assume that nozzle crashed into bed plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - return 0; + return 0; } #endif //TMC2130 current_position[axis] = 0; @@ -2340,14 +2342,16 @@ bool homeaxis(int axis, bool doError, uint8_t cnt) FORCE_HIGH_POWER_END; if (doError) { + current_position[Z_AXIS] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); current_position[Z_AXIS] += MESH_HOME_Z_SEARCH; plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder); st_synchronize(); kill(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); } - current_position[axis] = -MESH_HOME_Z_SEARCH; //assume that nozzle crashed into bed + current_position[Z_AXIS] = -MESH_HOME_Z_SEARCH; //assume that nozzle crashed into bed plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - return 0; + return 0; } #endif //TMC2130 axis_is_at_home(axis); From fd1d05ab48c3885a0fbb5b613edaf8bbf3c05606 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 2 Apr 2020 14:44:44 +0300 Subject: [PATCH 7/9] :recycle:Code optimization --- Firmware/Marlin.h | 4 ++-- Firmware/Marlin_main.cpp | 52 +++++++++++++++------------------------- Firmware/tmc2130.cpp | 2 +- Firmware/ultralcd.cpp | 2 +- 4 files changed, 23 insertions(+), 37 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index fb70dfed7..363407e2e 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -310,9 +310,9 @@ extern int8_t lcd_change_fil_state; extern float default_retraction; #ifdef TMC2130 -bool homeaxis(int axis, bool doError = true, uint8_t cnt = 1, uint8_t* pstep = 0); +void homeaxis(int axis, uint8_t cnt = 1, uint8_t* pstep = 0); #else -bool homeaxis(int axis, bool doError = true, uint8_t cnt = 1); +void homeaxis(int axis, uint8_t cnt = 1); #endif //TMC2130 diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 0a621aab3..2ba941e1c 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -2197,9 +2197,24 @@ bool calibrate_z_auto() #endif //TMC2130 #ifdef TMC2130 -bool homeaxis(int axis, bool doError, uint8_t cnt, uint8_t* pstep) +static void check_Z_crash(void) +{ + if (READ(Z_TMC2130_DIAG) != 0) { //Z crash + FORCE_HIGH_POWER_END; + current_position[Z_AXIS] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + current_position[Z_AXIS] += MESH_HOME_Z_SEARCH; + plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder); + st_synchronize(); + kill(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); + } +} +#endif //TMC2130 + +#ifdef TMC2130 +void homeaxis(int axis, uint8_t cnt, uint8_t* pstep) #else -bool homeaxis(int axis, bool doError, uint8_t cnt) +void homeaxis(int axis, uint8_t cnt) #endif //TMC2130 { bool endstops_enabled = enable_endstops(true); //RP: endstops should be allways enabled durring homing @@ -2312,21 +2327,7 @@ bool homeaxis(int axis, bool doError, uint8_t cnt) plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); st_synchronize(); #ifdef TMC2130 - if (READ(Z_TMC2130_DIAG) != 0) { //Z crash - FORCE_HIGH_POWER_END; - if (doError) - { - current_position[Z_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - current_position[Z_AXIS] += MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder); - st_synchronize(); - kill(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); - } - current_position[Z_AXIS] = -MESH_HOME_Z_SEARCH; //assume that nozzle crashed into bed - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - return 0; - } + check_Z_crash(); #endif //TMC2130 current_position[axis] = 0; plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); @@ -2338,21 +2339,7 @@ bool homeaxis(int axis, bool doError, uint8_t cnt) plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); st_synchronize(); #ifdef TMC2130 - if (READ(Z_TMC2130_DIAG) != 0) { //Z crash - FORCE_HIGH_POWER_END; - if (doError) - { - current_position[Z_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - current_position[Z_AXIS] += MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder); - st_synchronize(); - kill(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); - } - current_position[Z_AXIS] = -MESH_HOME_Z_SEARCH; //assume that nozzle crashed into bed - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - return 0; - } + check_Z_crash(); #endif //TMC2130 axis_is_at_home(axis); destination[axis] = current_position[axis]; @@ -2364,7 +2351,6 @@ bool homeaxis(int axis, bool doError, uint8_t cnt) #endif } enable_endstops(endstops_enabled); - return 1; } /**/ diff --git a/Firmware/tmc2130.cpp b/Firmware/tmc2130.cpp index 3a4e5b51e..108d00b1d 100755 --- a/Firmware/tmc2130.cpp +++ b/Firmware/tmc2130.cpp @@ -994,7 +994,7 @@ bool tmc2130_home_calibrate(uint8_t axis) uint8_t step[16]; uint8_t cnt[16]; uint8_t val[16]; - homeaxis(axis, true, 16, step); + homeaxis(axis, 16, step); bubblesort_uint8(step, 16, 0); printf_P(PSTR("sorted samples:\n")); for (uint8_t i = 0; i < 16; i++) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 08e8d567f..62c410727 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7734,7 +7734,7 @@ bool lcd_selftest() set_destination_to_current(); _progress = lcd_selftest_screen(TestScreen::AxisZ, _progress, 3, true, 1500); #ifdef TMC2130 - _result = homeaxis(Z_AXIS, false); + homeaxis(Z_AXIS); //In case of failure, the code gets stuck in this function. #else _result = lcd_selfcheck_axis(Z_AXIS, Z_MAX_POS); #endif //TMC2130 From a1b8ee67b32dafa74cca86dc8805606ed2522228 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Thu, 2 Apr 2020 14:56:19 +0200 Subject: [PATCH 8/9] Fix missing (hex) in D5 code (#2560) * Fix missing (hex) in D5 code * Make ALL D-codes available for DEBUG mode until now D3 and D5 needed to be defined separately * Forgot to modify Marlin_main --- Firmware/Dcodes.cpp | 6 +++--- Firmware/Marlin_main.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Firmware/Dcodes.cpp b/Firmware/Dcodes.cpp index 67cf1eb80..f943b4a31 100644 --- a/Firmware/Dcodes.cpp +++ b/Firmware/Dcodes.cpp @@ -98,7 +98,7 @@ void print_mem(uint32_t address, uint16_t count, uint8_t type, uint8_t countperl } } -#ifdef DEBUG_DCODE3 +#if defined DEBUG_DCODE3 || defined DEBUG_DCODES #define EEPROM_SIZE 0x1000 /*! ### D3 - Read/Write EEPROM D3: Read/Write EEPROM @@ -360,7 +360,7 @@ void dcode_4() } #endif //DEBUG_DCODES -#ifdef DEBUG_DCODE5 +#if defined DEBUG_DCODE5 || defined DEBUG_DCODES /*! ### D5 - Read/Write FLASH D5: Read/Write Flash @@ -372,7 +372,7 @@ void dcode_4() #### Parameters - `A` - Address (x00000-x3ffff) - `C` - Count (1-8192) - - `X` - Data + - `X` - Data (hex) - `E` - Erase #### Notes diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index ad5a1a85c..a6becaa66 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -8835,7 +8835,7 @@ Sigma_Exit: case 2: dcode_2(); break; #endif //DEBUG_DCODES -#ifdef DEBUG_DCODE3 +#if defined DEBUG_DCODE3 || defined DEBUG_DCODES /*! ### D3 - Read/Write EEPROM D3: Read/Write EEPROM @@ -8876,7 +8876,7 @@ Sigma_Exit: case 4: dcode_4(); break; #endif //DEBUG_DCODES -#ifdef DEBUG_DCODE5 +#if defined DEBUG_DCODE5 || defined DEBUG_DCODES /*! ### D5 - Read/Write FLASH D5: Read/Write Flash @@ -8888,7 +8888,7 @@ Sigma_Exit: #### Parameters - `A` - Address (x00000-x3ffff) - `C` - Count (1-8192) - - `X` - Data + - `X` - Data (hex) - `E` - Erase #### Notes From 9b3f51008be76d86c25b3412f09fd91653a84ee3 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 2 Apr 2020 19:32:13 +0300 Subject: [PATCH 9/9] :art:Change CRLF line ending to LF --- Firmware/heatbed_pwm.cpp | 380 +++++++++++++++++++-------------------- 1 file changed, 190 insertions(+), 190 deletions(-) diff --git a/Firmware/heatbed_pwm.cpp b/Firmware/heatbed_pwm.cpp index e85515016..4cd0bf5e5 100755 --- a/Firmware/heatbed_pwm.cpp +++ b/Firmware/heatbed_pwm.cpp @@ -1,190 +1,190 @@ -#include -#include -#include "io_atmega2560.h" - -// All this is about silencing the heat bed, as it behaves like a loudspeaker. -// Basically, we want the PWM heating switched at 30Hz (or so) which is a well ballanced -// frequency for both power supply units (i.e. both PSUs are reasonably silent). -// The only trouble is the rising or falling edge of bed heating - that creates an audible click. -// This audible click may be suppressed by making the rising or falling edge NOT sharp. -// Of course, making non-sharp edges in digital technology is not easy, but there is a solution. -// It is possible to do a fast PWM sequence with duty starting from 0 to 255. -// Doing this at higher frequency than the bed "loudspeaker" can handle makes the click barely audible. -// Technically: -// timer0 is set to fast PWM mode at 62.5kHz (timer0 is linked to the bed heating pin) (zero prescaler) -// To keep the bed switching at 30Hz - we don't want the PWM running at 62kHz all the time -// since it would burn the heatbed's MOSFET: -// 16MHz/256 levels of PWM duty gives us 62.5kHz -// 62.5kHz/256 gives ~244Hz, that is still too fast - 244/8 gives ~30Hz, that's what we need -// So the automaton runs atop of inner 8 (or 16) cycles. -// The finite automaton is running in the ISR(TIMER0_OVF_vect) - -// 2019-08-14 update: the original algorithm worked very well, however there were 2 regressions: -// 1. 62kHz ISR requires considerable amount of processing power, -// USB transfer speed dropped by 20%, which was most notable when doing short G-code segments. -// 2. Some users reported TLed PSU started clicking when running at 120V/60Hz. -// This looks like the original algorithm didn't maintain base PWM 30Hz, but only 15Hz -// To address both issues, there is an improved approach based on the idea of leveraging -// different CLK prescalers in some automaton states - i.e. when holding LOW or HIGH on the output pin, -// we don't have to clock 62kHz, but we can increase the CLK prescaler for these states to 8 (or even 64). -// That shall result in the ISR not being called that much resulting in regained performance -// Theoretically this is relatively easy, however one must be very carefull handling the AVR's timer -// control registers correctly, especially setting them in a correct order. -// Some registers are double buffered, some changes are applied in next cycles etc. -// The biggest problem was with the CLK prescaler itself - this circuit is shared among almost all timers, -// we don't want to reset the prescaler counted value when transiting among automaton states. -// Resetting the prescaler would make the PWM more precise, right now there are temporal segments -// of variable period ranging from 0 to 7 62kHz ticks - that's logical, the timer must "sync" -// to the new slower CLK after setting the slower prescaler value. -// In our application, this isn't any significant problem and may be ignored. -// Doing changes in timer's registers non-correctly results in artefacts on the output pin -// - it can toggle unnoticed, which will result in bed clicking again. -// That's why there are special transition states ZERO_TO_RISE and ONE_TO_FALL, which enable the -// counter change its operation atomically and without artefacts on the output pin. -// The resulting signal on the output pin was checked with an osciloscope. -// If there are any change requirements in the future, the signal must be checked with an osciloscope again, -// ad-hoc changes may completely screw things up! - -// 2020-01-29 update: we are introducing a new option to the automaton that will allow us to force the output state -// to either full ON or OFF. This is so that interference during the MBL probing is minimal. -// To accomplish this goal we use bedPWMDisabled. It is only supposed to be used for brief periods of time as to -// not make the bed temperature too unstable. Also, careful consideration should be used when using this -// option as leaving this enabled will also keep the bed output in the state it stopped in. - -///! Definition off finite automaton states -enum class States : uint8_t { - ZERO_START = 0,///< entry point of the automaton - reads the soft_pwm_bed value for the next whole PWM cycle - ZERO, ///< steady 0 (OFF), no change for the whole period - ZERO_TO_RISE, ///< metastate allowing the timer change its state atomically without artefacts on the output pin - RISE, ///< 16 fast PWM cycles with increasing duty up to steady ON - RISE_TO_ONE, ///< metastate allowing the timer change its state atomically without artefacts on the output pin - ONE, ///< steady 1 (ON), no change for the whole period - ONE_TO_FALL, ///< metastate allowing the timer change its state atomically without artefacts on the output pin - FALL, ///< 16 fast PWM cycles with decreasing duty down to steady OFF - FALL_TO_ZERO ///< metastate allowing the timer change its state atomically without artefacts on the output pin -}; - -///! Inner states of the finite automaton -static States state = States::ZERO_START; - -bool bedPWMDisabled = 0; - -///! Fast PWM counter is used in the RISE and FALL states (62.5kHz) -static uint8_t slowCounter = 0; -///! Slow PWM counter is used in the ZERO and ONE states (62.5kHz/8 or 64) -static uint8_t fastCounter = 0; -///! PWM counter for the whole cycle - a cache for soft_pwm_bed -static uint8_t pwm = 0; - -///! The slow PWM duty for the next 30Hz cycle -///! Set in the whole firmware at various places -extern unsigned char soft_pwm_bed; - -/// fastMax - how many fast PWM steps to do in RISE and FALL states -/// 16 is a good compromise between silenced bed ("smooth" edges) -/// and not burning the switching MOSFET -static const uint8_t fastMax = 16; - -/// Scaler 16->256 for fast PWM -static const uint8_t fastShift = 4; - -/// Increment slow PWM counter by slowInc every ZERO or ONE state -/// This allows for fine-tuning the basic PWM switching frequency -/// A possible further optimization - use a 64 prescaler (instead of 8) -/// increment slowCounter by 1 -/// but use less bits of soft PWM - something like soft_pwm_bed >> 2 -/// that may further reduce the CPU cycles required by the bed heating automaton -/// Due to the nature of bed heating the reduced PID precision may not be a major issue, however doing 8x less ISR(timer0_ovf) may significantly improve the performance -static const uint8_t slowInc = 1; - -ISR(TIMER0_OVF_vect) // timer compare interrupt service routine -{ - switch(state){ - case States::ZERO_START: - if (bedPWMDisabled) return; // stay in the OFF state and do not change the output pin - pwm = soft_pwm_bed << 1;// expecting soft_pwm_bed to be 7bit! - if( pwm != 0 ){ - state = States::ZERO; // do nothing, let it tick once again after the 30Hz period - } - break; - case States::ZERO: // end of state ZERO - we'll either stay in ZERO or change to RISE - // In any case update our cache of pwm value for the next whole cycle from soft_pwm_bed - slowCounter += slowInc; // this does software timer_clk/256 or less (depends on slowInc) - if( slowCounter > pwm ){ - return; - } // otherwise moving towards RISE - state = States::ZERO_TO_RISE; // and finalize the change in a transitional state RISE0 - break; - // even though it may look like the ZERO state may be glued together with the ZERO_TO_RISE, don't do it - // the timer must tick once more in order to get rid of occasional output pin toggles. - case States::ZERO_TO_RISE: // special state for handling transition between prescalers and switching inverted->non-inverted fast-PWM without toggling the output pin. - // It must be done in consequent steps, otherwise the pin will get flipped up and down during one PWM cycle. - // Also beware of the correct sequence of the following timer control registers initialization - it really matters! - state = States::RISE; // prepare for standard RISE cycles - fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE - TCNT0 = 255; // force overflow on the next clock cycle - TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz - TCCR0A &= ~(1 << COM0B0); // Clear OC0B on Compare Match, set OC0B at BOTTOM (non-inverting mode) - break; - case States::RISE: - OCR0B = (fastMax - fastCounter) << fastShift; - if( fastCounter ){ - --fastCounter; - } else { // end of RISE cycles, changing into state ONE - state = States::RISE_TO_ONE; - OCR0B = 255; // full duty - TCNT0 = 254; // make the timer overflow in the next cycle - // @@TODO these constants are still subject to investigation - } - break; - case States::RISE_TO_ONE: - state = States::ONE; - OCR0B = 255; // full duty - TCNT0 = 255; // make the timer overflow in the next cycle - TCCR0B = (1 << CS01); // change prescaler to 8, i.e. 7.8kHz - break; - case States::ONE: // state ONE - we'll either stay in ONE or change to FALL - OCR0B = 255; - if (bedPWMDisabled) return; // stay in the ON state and do not change the output pin - slowCounter += slowInc; // this does software timer_clk/256 or less - if( slowCounter < pwm ){ - return; - } - if( (soft_pwm_bed << 1) >= (255 - slowInc - 1) ){ //@@TODO simplify & explain - // if slowInc==2, soft_pwm == 251 will be the first to do short drops to zero. 252 will keep full heating - return; // want full duty for the next ONE cycle again - so keep on heating and just wait for the next timer ovf - } - // otherwise moving towards FALL - // @@TODO it looks like ONE_TO_FALL isn't necessary, there are no artefacts at all - state = States::ONE;//_TO_FALL; -// TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz -// break; -// case States::ONE_TO_FALL: -// OCR0B = 255; // zero duty - state=States::FALL; - fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE - TCNT0 = 255; // force overflow on the next clock cycle - TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz - // must switch to inverting mode already here, because it takes a whole PWM cycle and it would make a "1" at the end of this pwm cycle - // COM0B1 remains set both in inverting and non-inverting mode - TCCR0A |= (1 << COM0B0); // inverting mode - break; - case States::FALL: - OCR0B = (fastMax - fastCounter) << fastShift; // this is the same as in RISE, because now we are setting the zero part of duty due to inverting mode - //TCCR0A |= (1 << COM0B0); // already set in ONE_TO_FALL - if( fastCounter ){ - --fastCounter; - } else { // end of FALL cycles, changing into state ZERO - state = States::FALL_TO_ZERO; - TCNT0 = 128; //@@TODO again - need to wait long enough to propagate the timer state changes - OCR0B = 255; - } - break; - case States::FALL_TO_ZERO: - state = States::ZERO_START; // go to read new soft_pwm_bed value for the next cycle - TCNT0 = 128; - OCR0B = 255; - TCCR0B = (1 << CS01); // change prescaler to 8, i.e. 7.8kHz - break; - } -} +#include +#include +#include "io_atmega2560.h" + +// All this is about silencing the heat bed, as it behaves like a loudspeaker. +// Basically, we want the PWM heating switched at 30Hz (or so) which is a well ballanced +// frequency for both power supply units (i.e. both PSUs are reasonably silent). +// The only trouble is the rising or falling edge of bed heating - that creates an audible click. +// This audible click may be suppressed by making the rising or falling edge NOT sharp. +// Of course, making non-sharp edges in digital technology is not easy, but there is a solution. +// It is possible to do a fast PWM sequence with duty starting from 0 to 255. +// Doing this at higher frequency than the bed "loudspeaker" can handle makes the click barely audible. +// Technically: +// timer0 is set to fast PWM mode at 62.5kHz (timer0 is linked to the bed heating pin) (zero prescaler) +// To keep the bed switching at 30Hz - we don't want the PWM running at 62kHz all the time +// since it would burn the heatbed's MOSFET: +// 16MHz/256 levels of PWM duty gives us 62.5kHz +// 62.5kHz/256 gives ~244Hz, that is still too fast - 244/8 gives ~30Hz, that's what we need +// So the automaton runs atop of inner 8 (or 16) cycles. +// The finite automaton is running in the ISR(TIMER0_OVF_vect) + +// 2019-08-14 update: the original algorithm worked very well, however there were 2 regressions: +// 1. 62kHz ISR requires considerable amount of processing power, +// USB transfer speed dropped by 20%, which was most notable when doing short G-code segments. +// 2. Some users reported TLed PSU started clicking when running at 120V/60Hz. +// This looks like the original algorithm didn't maintain base PWM 30Hz, but only 15Hz +// To address both issues, there is an improved approach based on the idea of leveraging +// different CLK prescalers in some automaton states - i.e. when holding LOW or HIGH on the output pin, +// we don't have to clock 62kHz, but we can increase the CLK prescaler for these states to 8 (or even 64). +// That shall result in the ISR not being called that much resulting in regained performance +// Theoretically this is relatively easy, however one must be very carefull handling the AVR's timer +// control registers correctly, especially setting them in a correct order. +// Some registers are double buffered, some changes are applied in next cycles etc. +// The biggest problem was with the CLK prescaler itself - this circuit is shared among almost all timers, +// we don't want to reset the prescaler counted value when transiting among automaton states. +// Resetting the prescaler would make the PWM more precise, right now there are temporal segments +// of variable period ranging from 0 to 7 62kHz ticks - that's logical, the timer must "sync" +// to the new slower CLK after setting the slower prescaler value. +// In our application, this isn't any significant problem and may be ignored. +// Doing changes in timer's registers non-correctly results in artefacts on the output pin +// - it can toggle unnoticed, which will result in bed clicking again. +// That's why there are special transition states ZERO_TO_RISE and ONE_TO_FALL, which enable the +// counter change its operation atomically and without artefacts on the output pin. +// The resulting signal on the output pin was checked with an osciloscope. +// If there are any change requirements in the future, the signal must be checked with an osciloscope again, +// ad-hoc changes may completely screw things up! + +// 2020-01-29 update: we are introducing a new option to the automaton that will allow us to force the output state +// to either full ON or OFF. This is so that interference during the MBL probing is minimal. +// To accomplish this goal we use bedPWMDisabled. It is only supposed to be used for brief periods of time as to +// not make the bed temperature too unstable. Also, careful consideration should be used when using this +// option as leaving this enabled will also keep the bed output in the state it stopped in. + +///! Definition off finite automaton states +enum class States : uint8_t { + ZERO_START = 0,///< entry point of the automaton - reads the soft_pwm_bed value for the next whole PWM cycle + ZERO, ///< steady 0 (OFF), no change for the whole period + ZERO_TO_RISE, ///< metastate allowing the timer change its state atomically without artefacts on the output pin + RISE, ///< 16 fast PWM cycles with increasing duty up to steady ON + RISE_TO_ONE, ///< metastate allowing the timer change its state atomically without artefacts on the output pin + ONE, ///< steady 1 (ON), no change for the whole period + ONE_TO_FALL, ///< metastate allowing the timer change its state atomically without artefacts on the output pin + FALL, ///< 16 fast PWM cycles with decreasing duty down to steady OFF + FALL_TO_ZERO ///< metastate allowing the timer change its state atomically without artefacts on the output pin +}; + +///! Inner states of the finite automaton +static States state = States::ZERO_START; + +bool bedPWMDisabled = 0; + +///! Fast PWM counter is used in the RISE and FALL states (62.5kHz) +static uint8_t slowCounter = 0; +///! Slow PWM counter is used in the ZERO and ONE states (62.5kHz/8 or 64) +static uint8_t fastCounter = 0; +///! PWM counter for the whole cycle - a cache for soft_pwm_bed +static uint8_t pwm = 0; + +///! The slow PWM duty for the next 30Hz cycle +///! Set in the whole firmware at various places +extern unsigned char soft_pwm_bed; + +/// fastMax - how many fast PWM steps to do in RISE and FALL states +/// 16 is a good compromise between silenced bed ("smooth" edges) +/// and not burning the switching MOSFET +static const uint8_t fastMax = 16; + +/// Scaler 16->256 for fast PWM +static const uint8_t fastShift = 4; + +/// Increment slow PWM counter by slowInc every ZERO or ONE state +/// This allows for fine-tuning the basic PWM switching frequency +/// A possible further optimization - use a 64 prescaler (instead of 8) +/// increment slowCounter by 1 +/// but use less bits of soft PWM - something like soft_pwm_bed >> 2 +/// that may further reduce the CPU cycles required by the bed heating automaton +/// Due to the nature of bed heating the reduced PID precision may not be a major issue, however doing 8x less ISR(timer0_ovf) may significantly improve the performance +static const uint8_t slowInc = 1; + +ISR(TIMER0_OVF_vect) // timer compare interrupt service routine +{ + switch(state){ + case States::ZERO_START: + if (bedPWMDisabled) return; // stay in the OFF state and do not change the output pin + pwm = soft_pwm_bed << 1;// expecting soft_pwm_bed to be 7bit! + if( pwm != 0 ){ + state = States::ZERO; // do nothing, let it tick once again after the 30Hz period + } + break; + case States::ZERO: // end of state ZERO - we'll either stay in ZERO or change to RISE + // In any case update our cache of pwm value for the next whole cycle from soft_pwm_bed + slowCounter += slowInc; // this does software timer_clk/256 or less (depends on slowInc) + if( slowCounter > pwm ){ + return; + } // otherwise moving towards RISE + state = States::ZERO_TO_RISE; // and finalize the change in a transitional state RISE0 + break; + // even though it may look like the ZERO state may be glued together with the ZERO_TO_RISE, don't do it + // the timer must tick once more in order to get rid of occasional output pin toggles. + case States::ZERO_TO_RISE: // special state for handling transition between prescalers and switching inverted->non-inverted fast-PWM without toggling the output pin. + // It must be done in consequent steps, otherwise the pin will get flipped up and down during one PWM cycle. + // Also beware of the correct sequence of the following timer control registers initialization - it really matters! + state = States::RISE; // prepare for standard RISE cycles + fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE + TCNT0 = 255; // force overflow on the next clock cycle + TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz + TCCR0A &= ~(1 << COM0B0); // Clear OC0B on Compare Match, set OC0B at BOTTOM (non-inverting mode) + break; + case States::RISE: + OCR0B = (fastMax - fastCounter) << fastShift; + if( fastCounter ){ + --fastCounter; + } else { // end of RISE cycles, changing into state ONE + state = States::RISE_TO_ONE; + OCR0B = 255; // full duty + TCNT0 = 254; // make the timer overflow in the next cycle + // @@TODO these constants are still subject to investigation + } + break; + case States::RISE_TO_ONE: + state = States::ONE; + OCR0B = 255; // full duty + TCNT0 = 255; // make the timer overflow in the next cycle + TCCR0B = (1 << CS01); // change prescaler to 8, i.e. 7.8kHz + break; + case States::ONE: // state ONE - we'll either stay in ONE or change to FALL + OCR0B = 255; + if (bedPWMDisabled) return; // stay in the ON state and do not change the output pin + slowCounter += slowInc; // this does software timer_clk/256 or less + if( slowCounter < pwm ){ + return; + } + if( (soft_pwm_bed << 1) >= (255 - slowInc - 1) ){ //@@TODO simplify & explain + // if slowInc==2, soft_pwm == 251 will be the first to do short drops to zero. 252 will keep full heating + return; // want full duty for the next ONE cycle again - so keep on heating and just wait for the next timer ovf + } + // otherwise moving towards FALL + // @@TODO it looks like ONE_TO_FALL isn't necessary, there are no artefacts at all + state = States::ONE;//_TO_FALL; +// TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz +// break; +// case States::ONE_TO_FALL: +// OCR0B = 255; // zero duty + state=States::FALL; + fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE + TCNT0 = 255; // force overflow on the next clock cycle + TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz + // must switch to inverting mode already here, because it takes a whole PWM cycle and it would make a "1" at the end of this pwm cycle + // COM0B1 remains set both in inverting and non-inverting mode + TCCR0A |= (1 << COM0B0); // inverting mode + break; + case States::FALL: + OCR0B = (fastMax - fastCounter) << fastShift; // this is the same as in RISE, because now we are setting the zero part of duty due to inverting mode + //TCCR0A |= (1 << COM0B0); // already set in ONE_TO_FALL + if( fastCounter ){ + --fastCounter; + } else { // end of FALL cycles, changing into state ZERO + state = States::FALL_TO_ZERO; + TCNT0 = 128; //@@TODO again - need to wait long enough to propagate the timer state changes + OCR0B = 255; + } + break; + case States::FALL_TO_ZERO: + state = States::ZERO_START; // go to read new soft_pwm_bed value for the next cycle + TCNT0 = 128; + OCR0B = 255; + TCCR0B = (1 << CS01); // change prescaler to 8, i.e. 7.8kHz + break; + } +}