Browse Source

Soft Reset via Serial or post-kill button click (#21652)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
fedetony 3 years ago
parent
commit
d3a2c6a0b4
No account linked to committer's email address

+ 6
- 0
Marlin/Configuration_adv.h View File

@@ -3976,3 +3976,9 @@
3976 3976
  * a crash from a remote location. Requires ~400 bytes of SRAM and 5Kb of flash.
3977 3977
  */
3978 3978
 //#define POSTMORTEM_DEBUGGING
3979
+
3980
+/**
3981
+ * Software Reset options
3982
+ */
3983
+//#define SOFT_RESET_VIA_SERIAL         // 'KILL' and '^X' commands will soft-reset the controller
3984
+//#define SOFT_RESET_ON_KILL            // Use a digital button to soft-reset the controller after KILL

+ 9
- 0
Marlin/src/HAL/AVR/HAL.cpp View File

@@ -58,6 +58,15 @@ void HAL_init() {
58 58
   #endif
59 59
 }
60 60
 
61
+void HAL_reboot() {
62
+  #if ENABLED(USE_WATCHDOG)
63
+    while (1) { /* run out the watchdog */ }
64
+  #else
65
+    void (*resetFunc)() = 0;  // Declare resetFunc() at address 0
66
+    resetFunc();              // Jump to address 0
67
+  #endif
68
+}
69
+
61 70
 #if ENABLED(SDSUPPORT)
62 71
 
63 72
   #include "../../sd/SdFatUtil.h"

+ 1
- 1
Marlin/src/HAL/AVR/HAL.h View File

@@ -135,7 +135,7 @@ void HAL_init();
135 135
 inline void HAL_clear_reset_source() { MCUSR = 0; }
136 136
 inline uint8_t HAL_get_reset_source() { return MCUSR; }
137 137
 
138
-inline void HAL_reboot() {}  // reboot the board or restart the bootloader
138
+void HAL_reboot();
139 139
 
140 140
 #if GCC_VERSION <= 50000
141 141
   #pragma GCC diagnostic push

+ 2
- 0
Marlin/src/HAL/DUE/HAL.cpp View File

@@ -77,6 +77,8 @@ uint8_t HAL_get_reset_source() {
77 77
   }
78 78
 }
79 79
 
80
+void HAL_reboot() { rstc_start_software_reset(RSTC); }
81
+
80 82
 void _delay_ms(const int delay_ms) {
81 83
   // Todo: port for Due?
82 84
   delay(delay_ms);

+ 1
- 1
Marlin/src/HAL/DUE/HAL.h View File

@@ -113,7 +113,7 @@ void sei();                     // Enable interrupts
113 113
 void HAL_clear_reset_source();  // clear reset reason
114 114
 uint8_t HAL_get_reset_source(); // get reset reason
115 115
 
116
-inline void HAL_reboot() {}  // reboot the board or restart the bootloader
116
+void HAL_reboot();
117 117
 
118 118
 //
119 119
 // ADC

+ 2
- 0
Marlin/src/HAL/ESP32/HAL.cpp View File

@@ -141,6 +141,8 @@ void HAL_clear_reset_source() { }
141 141
 
142 142
 uint8_t HAL_get_reset_source() { return rtc_get_reset_reason(1); }
143 143
 
144
+void HAL_reboot() { ESP.restart(); }
145
+
144 146
 void _delay_ms(int delay_ms) { delay(delay_ms); }
145 147
 
146 148
 // return free memory between end of heap (or end bss) and whatever is current

+ 1
- 1
Marlin/src/HAL/ESP32/HAL.h View File

@@ -101,7 +101,7 @@ void HAL_clear_reset_source();
101 101
 // reset reason
102 102
 uint8_t HAL_get_reset_source();
103 103
 
104
-inline void HAL_reboot() {}  // reboot the board or restart the bootloader
104
+void HAL_reboot();
105 105
 
106 106
 void _delay_ms(int delay);
107 107
 

+ 2
- 0
Marlin/src/HAL/LINUX/HAL.cpp View File

@@ -73,4 +73,6 @@ void HAL_pwm_init() {
73 73
 
74 74
 }
75 75
 
76
+void HAL_reboot() { /* Reset the application state and GPIO */ }
77
+
76 78
 #endif // __PLAT_LINUX__

+ 1
- 1
Marlin/src/HAL/LINUX/HAL.h View File

@@ -107,7 +107,7 @@ uint16_t HAL_adc_get_result();
107 107
 inline void HAL_clear_reset_source(void) {}
108 108
 inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
109 109
 
110
-inline void HAL_reboot() {}  // reboot the board or restart the bootloader
110
+void HAL_reboot(); // Reset the application state and GPIO
111 111
 
112 112
 /* ---------------- Delay in cycles */
113 113
 FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {

+ 3
- 1
Marlin/src/HAL/LPC1768/HAL.cpp View File

@@ -67,7 +67,7 @@ void flashFirmware(const int16_t) {
67 67
   delay(500);          // Give OS time to disconnect
68 68
   USB_Connect(false);  // USB clear connection
69 69
   delay(1000);         // Give OS time to notice
70
-  NVIC_SystemReset();
70
+  HAL_reboot();
71 71
 }
72 72
 
73 73
 void HAL_clear_reset_source(void) {
@@ -81,4 +81,6 @@ uint8_t HAL_get_reset_source(void) {
81 81
   return RST_POWER_ON;
82 82
 }
83 83
 
84
+void HAL_reboot() { NVIC_SystemReset(); }
85
+
84 86
 #endif // TARGET_LPC1768

+ 1
- 1
Marlin/src/HAL/LPC1768/HAL.h View File

@@ -218,4 +218,4 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255,
218 218
 void HAL_clear_reset_source(void);
219 219
 uint8_t HAL_get_reset_source(void);
220 220
 
221
-inline void HAL_reboot() {}  // reboot the board or restart the bootloader
221
+void HAL_reboot();

+ 2
- 0
Marlin/src/HAL/SAMD51/HAL.cpp View File

@@ -436,6 +436,8 @@ uint8_t HAL_get_reset_source() {
436 436
 }
437 437
 #pragma pop_macro("WDT")
438 438
 
439
+void HAL_reboot() { NVIC_SystemReset(); }
440
+
439 441
 extern "C" {
440 442
   void * _sbrk(int incr);
441 443
 

+ 1
- 1
Marlin/src/HAL/SAMD51/HAL.h View File

@@ -109,7 +109,7 @@ typedef int8_t pin_t;
109 109
 void HAL_clear_reset_source();  // clear reset reason
110 110
 uint8_t HAL_get_reset_source(); // get reset reason
111 111
 
112
-inline void HAL_reboot() {}  // reboot the board or restart the bootloader
112
+void HAL_reboot();
113 113
 
114 114
 //
115 115
 // ADC

+ 4
- 2
Marlin/src/HAL/STM32/HAL.cpp View File

@@ -133,6 +133,8 @@ uint8_t HAL_get_reset_source() {
133 133
   ;
134 134
 }
135 135
 
136
+void HAL_reboot() { NVIC_SystemReset(); }
137
+
136 138
 void _delay_ms(const int delay_ms) { delay(delay_ms); }
137 139
 
138 140
 extern "C" {
@@ -147,8 +149,8 @@ extern "C" {
147 149
 void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRead(adc_pin); }
148 150
 uint16_t HAL_adc_get_result() { return HAL_adc_result; }
149 151
 
150
-// Reset the system (to initiate a firmware flash)
151
-void flashFirmware(const int16_t) { NVIC_SystemReset(); }
152
+// Reset the system to initiate a firmware flash
153
+void flashFirmware(const int16_t) { HAL_reboot(); }
152 154
 
153 155
 // Maple Compatibility
154 156
 volatile uint32_t systick_uptime_millis = 0;

+ 1
- 1
Marlin/src/HAL/STM32/HAL.h View File

@@ -144,7 +144,7 @@ void HAL_clear_reset_source();
144 144
 // Reset reason
145 145
 uint8_t HAL_get_reset_source();
146 146
 
147
-inline void HAL_reboot() {}  // reboot the board or restart the bootloader
147
+void HAL_reboot();
148 148
 
149 149
 void _delay_ms(const int delay);
150 150
 

+ 3
- 1
Marlin/src/HAL/STM32F1/HAL.cpp View File

@@ -453,6 +453,8 @@ void analogWrite(pin_t pin, int pwm_val8) {
453 453
     analogWrite(uint8_t(pin), pwm_val8);
454 454
 }
455 455
 
456
-void flashFirmware(const int16_t) { nvic_sys_reset(); }
456
+void HAL_reboot() { nvic_sys_reset(); }
457
+
458
+void flashFirmware(const int16_t) { HAL_reboot(); }
457 459
 
458 460
 #endif // __STM32F1__

+ 1
- 1
Marlin/src/HAL/STM32F1/HAL.h View File

@@ -207,7 +207,7 @@ void HAL_clear_reset_source();
207 207
 // Reset reason
208 208
 uint8_t HAL_get_reset_source();
209 209
 
210
-inline void HAL_reboot() {}  // reboot the board or restart the bootloader
210
+void HAL_reboot();
211 211
 
212 212
 void _delay_ms(const int delay);
213 213
 

+ 2
- 0
Marlin/src/HAL/TEENSY31_32/HAL.cpp View File

@@ -78,6 +78,8 @@ uint8_t HAL_get_reset_source() {
78 78
   return 0;
79 79
 }
80 80
 
81
+void HAL_reboot() { _reboot_Teensyduino_(); }
82
+
81 83
 extern "C" {
82 84
   extern char __bss_end;
83 85
   extern char __heap_start;

+ 1
- 2
Marlin/src/HAL/TEENSY31_32/HAL.h View File

@@ -34,7 +34,6 @@
34 34
 #include "fastio.h"
35 35
 #include "watchdog.h"
36 36
 
37
-
38 37
 #include <stdint.h>
39 38
 
40 39
 #define ST7920_DELAY_1 DELAY_NS(600)
@@ -93,7 +92,7 @@ void HAL_clear_reset_source();
93 92
 // Get the reason for the reset
94 93
 uint8_t HAL_get_reset_source();
95 94
 
96
-inline void HAL_reboot() {}  // reboot the board or restart the bootloader
95
+void HAL_reboot();
97 96
 
98 97
 FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
99 98
 

+ 2
- 0
Marlin/src/HAL/TEENSY35_36/HAL.cpp View File

@@ -86,6 +86,8 @@ uint8_t HAL_get_reset_source() {
86 86
   return 0;
87 87
 }
88 88
 
89
+void HAL_reboot() { _reboot_Teensyduino_(); }
90
+
89 91
 extern "C" {
90 92
   extern char __bss_end;
91 93
   extern char __heap_start;

+ 1
- 1
Marlin/src/HAL/TEENSY35_36/HAL.h View File

@@ -101,7 +101,7 @@ void HAL_clear_reset_source();
101 101
 // Reset reason
102 102
 uint8_t HAL_get_reset_source();
103 103
 
104
-inline void HAL_reboot() {}  // reboot the board or restart the bootloader
104
+void HAL_reboot();
105 105
 
106 106
 FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
107 107
 

+ 2
- 0
Marlin/src/HAL/TEENSY40_41/HAL.cpp View File

@@ -120,6 +120,8 @@ uint8_t HAL_get_reset_source() {
120 120
   return 0;
121 121
 }
122 122
 
123
+void HAL_reboot() { _reboot_Teensyduino_(); }
124
+
123 125
 #define __bss_end _ebss
124 126
 
125 127
 extern "C" {

+ 2
- 0
Marlin/src/HAL/TEENSY40_41/HAL.h View File

@@ -121,6 +121,8 @@ void HAL_clear_reset_source();
121 121
 // Reset reason
122 122
 uint8_t HAL_get_reset_source();
123 123
 
124
+void HAL_reboot();
125
+
124 126
 FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
125 127
 
126 128
 #if GCC_VERSION <= 50000

+ 10
- 8
Marlin/src/MarlinCore.cpp View File

@@ -863,20 +863,22 @@ void minkill(const bool steppers_off/*=false*/) {
863 863
 
864 864
   TERN_(HAS_SUICIDE, suicide());
865 865
 
866
-  #if HAS_KILL
866
+  #if EITHER(HAS_KILL, SOFT_RESET_ON_KILL)
867 867
 
868
-    // Wait for kill to be released
869
-    while (kill_state()) watchdog_refresh();
868
+    // Wait for both KILL and ENC to be released
869
+    while (TERN0(HAS_KILL, !kill_state()) || TERN0(SOFT_RESET_ON_KILL, !ui.button_pressed()))
870
+      watchdog_refresh();
870 871
 
871
-    // Wait for kill to be pressed
872
-    while (!kill_state()) watchdog_refresh();
872
+    // Wait for either KILL or ENC press
873
+    while (TERN1(HAS_KILL, kill_state()) && TERN1(SOFT_RESET_ON_KILL, ui.button_pressed()))
874
+      watchdog_refresh();
873 875
 
874
-    void (*resetFunc)() = 0;      // Declare resetFunc() at address 0
875
-    resetFunc();                  // Jump to address 0
876
+    // Reboot the board
877
+    HAL_reboot();
876 878
 
877 879
   #else
878 880
 
879
-    for (;;) watchdog_refresh();  // Wait for reset
881
+    for (;;) watchdog_refresh();  // Wait for RESET button or power-cycle
880 882
 
881 883
   #endif
882 884
 }

+ 20
- 0
Marlin/src/feature/e_parser.h View File

@@ -41,6 +41,8 @@ extern bool wait_for_user, wait_for_heatup;
41 41
   void quickresume_stepper();
42 42
 #endif
43 43
 
44
+void HAL_reboot();
45
+
44 46
 class EmergencyParser {
45 47
 
46 48
 public:
@@ -62,6 +64,10 @@ public:
62 64
       EP_R, EP_R0, EP_R00, EP_GRBL_RESUME,
63 65
       EP_P, EP_P0, EP_P00, EP_GRBL_PAUSE,
64 66
     #endif
67
+    #if ENABLED(SOFT_RESET_VIA_SERIAL)
68
+      EP_ctrl,
69
+      EP_K, EP_KI, EP_KIL, EP_KILL,
70
+    #endif
65 71
     EP_IGNORE // to '\n'
66 72
   };
67 73
 
@@ -89,6 +95,10 @@ public:
89 95
             case 'P': state = EP_P; break;
90 96
             case 'R': state = EP_R; break;
91 97
           #endif
98
+          #if ENABLED(SOFT_RESET_VIA_SERIAL)
99
+            case '^': state = EP_ctrl; break;
100
+            case 'K': state = EP_K; break;
101
+          #endif
92 102
           default: state = EP_IGNORE;
93 103
         }
94 104
         break;
@@ -121,6 +131,13 @@ public:
121 131
         case EP_P00: state = (c == '0') ? EP_GRBL_PAUSE  : EP_IGNORE; break;
122 132
       #endif
123 133
 
134
+      #if ENABLED(SOFT_RESET_VIA_SERIAL)
135
+        case EP_ctrl: state = (c == 'X') ? EP_KILL : EP_IGNORE; break;
136
+        case EP_K:    state = (c == 'I') ? EP_KI   : EP_IGNORE; break;
137
+        case EP_KI:   state = (c == 'L') ? EP_KIL  : EP_IGNORE; break;
138
+        case EP_KIL:  state = (c == 'L') ? EP_KILL : EP_IGNORE; break;
139
+      #endif
140
+
124 141
       case EP_M:
125 142
         switch (c) {
126 143
           case ' ': break;
@@ -189,6 +206,9 @@ public:
189 206
               case EP_GRBL_PAUSE: quickpause_stepper(); break;
190 207
               case EP_GRBL_RESUME: quickresume_stepper(); break;
191 208
             #endif
209
+            #if ENABLED(SOFT_RESET_VIA_SERIAL)
210
+              case EP_KILL: HAL_reboot(); break;
211
+            #endif
192 212
             default: break;
193 213
           }
194 214
           state = EP_RESET;

+ 6
- 1
Marlin/src/gcode/gcode_d.cpp View File

@@ -30,6 +30,7 @@
30 30
   #include "../HAL/shared/eeprom_if.h"
31 31
   #include "../HAL/shared/Delay.h"
32 32
   #include "../sd/cardreader.h"
33
+  #include "../MarlinCore.h" // for kill
33 34
 
34 35
   extern void dump_delay_accuracy_check();
35 36
 
@@ -44,12 +45,16 @@
44 45
     switch (dcode) {
45 46
 
46 47
       case -1:
47
-        for (;;); // forever
48
+        for (;;) { /* loop forever (watchdog reset) */ }
48 49
 
49 50
       case 0:
50 51
         HAL_reboot();
51 52
         break;
52 53
 
54
+      case 10:
55
+        kill(PSTR("D10"), PSTR("KILL TEST"), parser.seen('P'));
56
+        break;
57
+
53 58
       case 1: {
54 59
         // Zero or pattern-fill the EEPROM data
55 60
         #if ENABLED(EEPROM_SETTINGS)

+ 8
- 1
Marlin/src/inc/SanityCheck.h View File

@@ -2208,13 +2208,20 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
2208 2208
 #endif
2209 2209
 
2210 2210
 /**
2211
- * emergency-command parser
2211
+ * Emergency Command Parser
2212 2212
  */
2213 2213
 #if ENABLED(EMERGENCY_PARSER) && defined(__AVR__) && defined(USBCON)
2214 2214
   #error "EMERGENCY_PARSER does not work on boards with AT90USB processors (USBCON)."
2215 2215
 #endif
2216 2216
 
2217 2217
 /**
2218
+ * Software Reset on Kill option
2219
+ */
2220
+#if ENABLED(SOFT_RESET_ON_KILL) && !BUTTON_EXISTS(ENC)
2221
+  #error "An encoder button is required or SOFT_RESET_ON_KILL will reset the printer without notice!"
2222
+#endif
2223
+
2224
+/**
2218 2225
  * I2C bus
2219 2226
  */
2220 2227
 #if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0

+ 1
- 1
Marlin/src/lcd/marlinui.h View File

@@ -39,7 +39,7 @@
39 39
   #include "tft_io/touch_calibration.h"
40 40
 #endif
41 41
 
42
-#if EITHER(HAS_LCD_MENU, ULTIPANEL_FEEDMULTIPLY)
42
+#if ANY(HAS_LCD_MENU, ULTIPANEL_FEEDMULTIPLY, SOFT_RESET_ON_KILL)
43 43
   #define HAS_ENCODER_ACTION 1
44 44
 #endif
45 45
 

+ 1
- 1
buildroot/tests/LPC1768 View File

@@ -45,7 +45,7 @@ opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER ADAPTIVE_FAN_SLOWING NO
45 45
            Z_SAFE_HOMING ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE \
46 46
            HOST_KEEPALIVE_FEATURE HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT \
47 47
            LCD_INFO_MENU ARC_SUPPORT BEZIER_CURVE_SUPPORT EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES \
48
-           SDSUPPORT SDCARD_SORT_ALPHA AUTO_REPORT_SD_STATUS EMERGENCY_PARSER
48
+           SDSUPPORT SDCARD_SORT_ALPHA AUTO_REPORT_SD_STATUS EMERGENCY_PARSER SOFT_RESET_ON_KILL SOFT_RESET_VIA_SERIAL
49 49
 exec_test $1 $2 "Re-ARM with NOZZLE_AS_PROBE and many features." "$3"
50 50
 
51 51
 # clean up

Loading…
Cancel
Save