Add HOST_PROMPT_SUPPORT (#13039)

This commit is contained in:
InsanityAutomation
2019-02-12 16:55:47 -05:00
committed by Scott Lahteine
parent 0feeef2604
commit 7f1b69b0c8
189 changed files with 2076 additions and 3479 deletions

View File

@ -34,6 +34,10 @@
bool EmergencyParser::killed_by_M112, // = false
EmergencyParser::enabled;
#if ENABLED(HOST_PROMPT_SUPPORT)
uint8_t EmergencyParser::M876_reason; // = 0
#endif
// Global instance
EmergencyParser emergency_parser;

View File

@ -27,15 +27,20 @@
#define FORCE_INLINE __attribute__((always_inline)) inline
#if ENABLED(HOST_PROMPT_SUPPORT)
#include "host_actions.h"
#endif
// External references
extern volatile bool wait_for_user, wait_for_heatup;
void quickstop_stepper();
void host_response_handler(const uint8_t response);
class EmergencyParser {
public:
// Currently looking for: M108, M112, M410
// Currently looking for: M108, M112, M410, M876
enum State : char {
EP_RESET,
EP_N,
@ -48,11 +53,22 @@ public:
EP_M4,
EP_M41,
EP_M410,
#if ENABLED(HOST_PROMPT_SUPPORT)
EP_M8,
EP_M87,
EP_M876,
EP_M876S,
EP_M876SN,
#endif
EP_IGNORE // to '\n'
};
static bool killed_by_M112;
#if ENABLED(HOST_PROMPT_SUPPORT)
static uint8_t M876_reason;
#endif
EmergencyParser() { enable(); }
FORCE_INLINE static void enable() { enabled = true; }
@ -86,6 +102,9 @@ public:
case ' ': break;
case '1': state = EP_M1; break;
case '4': state = EP_M4; break;
#if ENABLED(HOST_PROMPT_SUPPORT)
case '8': state = EP_M8; break;
#endif
default: state = EP_IGNORE;
}
break;
@ -114,6 +133,37 @@ public:
state = (c == '0') ? EP_M410 : EP_IGNORE;
break;
#if ENABLED(HOST_PROMPT_SUPPORT)
case EP_M8:
state = (c == '7') ? EP_M87 : EP_IGNORE;
break;
case EP_M87:
state = (c == '6') ? EP_M876 : EP_IGNORE;
break;
case EP_M876:
switch(c) {
case ' ': break;
case 'S': state = EP_M876S; break;
default: state = EP_IGNORE; break;
}
break;
case EP_M876S:
switch (c) {
case ' ': break;
case '0': case '1': case '2':
case '3': case '4': case '5':
case '6': case '7': case '8':
case '9':
state = EP_M876SN;
M876_reason = (uint8_t)(c - '0');
break;
}
break;
#endif
case EP_IGNORE:
if (c == '\n') state = EP_RESET;
break;
@ -124,6 +174,9 @@ public:
case EP_M108: wait_for_user = wait_for_heatup = false; break;
case EP_M112: killed_by_M112 = true; break;
case EP_M410: quickstop_stepper(); break;
#if ENABLED(HOST_PROMPT_SUPPORT)
case EP_M876SN: host_response_handler(M876_reason); break;
#endif
default: break;
}
state = EP_RESET;

View File

@ -0,0 +1,157 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "../inc/MarlinConfig.h"
#if ENABLED(HOST_ACTION_COMMANDS)
#include "host_actions.h"
//#define DEBUG_HOST_ACTIONS
#if ENABLED(ADVANCED_PAUSE_FEATURE)
#include "pause.h"
#include "../gcode/queue.h"
#endif
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
#include "runout.h"
#endif
extern volatile bool wait_for_user;
void host_action(const char * const pstr, const bool eol) {
SERIAL_ECHOPGM("//action:");
serialprintPGM(pstr);
if (eol) SERIAL_EOL();
}
#ifdef ACTION_ON_KILL
void host_action_kill() { host_action(PSTR(ACTION_ON_KILL)); }
#endif
#ifdef ACTION_ON_PAUSE
void host_action_pause(const bool eol/*=true*/) { host_action(PSTR(ACTION_ON_PAUSE), eol); }
#endif
#ifdef ACTION_ON_PAUSED
void host_action_paused(const bool eol/*=true*/) { host_action(PSTR(ACTION_ON_PAUSED), eol); }
#endif
#ifdef ACTION_ON_RESUME
void host_action_resume() { host_action(PSTR(ACTION_ON_RESUME)); }
#endif
#ifdef ACTION_ON_RESUMED
void host_action_resumed() { host_action(PSTR(ACTION_ON_RESUMED)); }
#endif
#ifdef ACTION_ON_CANCEL
void host_action_cancel() { host_action(PSTR(ACTION_ON_CANCEL)); }
#endif
#if ENABLED(HOST_PROMPT_SUPPORT)
PromptReason host_prompt_reason = PROMPT_NOT_DEFINED;
void host_action_prompt(const char * const ptype, const bool eol=true) {
host_action(PSTR("prompt_"), false);
serialprintPGM(ptype);
if (eol) SERIAL_EOL();
}
void host_action_prompt_plus(const char * const ptype, const char * const pstr, const bool eol=true) {
host_action_prompt(ptype, false);
SERIAL_CHAR(' ');
serialprintPGM(pstr);
if (eol) SERIAL_EOL();
}
void host_action_prompt_begin(const char * const pstr, const bool eol/*=true*/) { host_action_prompt_plus(PSTR("begin"), pstr, eol); }
void host_action_prompt_button(const char * const pstr) { host_action_prompt_plus(PSTR("button"), pstr); }
void host_action_prompt_end() { host_action_prompt(PSTR("end")); }
void host_action_prompt_show() { host_action_prompt(PSTR("show")); }
void host_prompt_do(const PromptReason reason, const char * const pstr, const char * const pbtn/*=NULL*/) {
host_prompt_reason = reason;
host_action_prompt_end();
host_action_prompt_begin(pstr);
if (pbtn) host_action_prompt_button(pbtn);
host_action_prompt_show();
}
inline void say_m876_response(const char * const pstr) {
SERIAL_ECHOPGM("M876 Responding PROMPT_");
serialprintPGM(pstr);
SERIAL_EOL();
}
void host_response_handler(const uint8_t response) {
#ifdef DEBUG_HOST_ACTIONS
SERIAL_ECHOLNPAIR("M86 Handle Reason: ", host_prompt_reason);
SERIAL_ECHOLNPAIR("M86 Handle Response: ", response);
#endif
const char *msg = PSTR("UNKNOWN STATE");
const PromptReason hpr = host_prompt_reason;
host_prompt_reason = PROMPT_NOT_DEFINED;
switch (hpr) {
case PROMPT_FILAMENT_RUNOUT:
msg = PSTR("FILAMENT_RUNOUT");
if (response == 0) {
advanced_pause_menu_response = ADVANCED_PAUSE_RESPONSE_EXTRUDE_MORE;
host_action_prompt_end(); // Close current prompt
host_action_prompt_begin(PSTR("Paused"));
host_action_prompt_button(PSTR("Purge More"));
if (false
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|| runout.filament_ran_out
#endif
)
host_action_prompt_button(PSTR("DisableRunout"));
else {
host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
host_action_prompt_button(PSTR("Continue"));
}
host_action_prompt_show();
}
else if (response == 1) {
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
if (runout.filament_ran_out) {
runout.enabled = false;
runout.reset();
}
#endif
advanced_pause_menu_response = ADVANCED_PAUSE_RESPONSE_RESUME_PRINT;
}
break;
case PROMPT_USER_CONTINUE:
msg = PSTR("FILAMENT_RUNOUT_CONTINUE");
wait_for_user = false;
break;
case PROMPT_PAUSE_RESUME:
msg = PSTR("LCD_PAUSE_RESUME");
enqueue_and_echo_commands_P(PSTR("M24"));
break;
case PROMPT_INFO:
msg = PSTR("GCODE_INFO");
break;
default: break;
}
say_m876_response(msg);
}
#endif // HOST_PROMPT_SUPPORT
#endif // HOST_ACTION_COMMANDS

View File

@ -0,0 +1,70 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../inc/MarlinConfig.h"
void host_action(const char * const pstr, const bool eol=true);
#ifdef ACTION_ON_KILL
void host_action_kill();
#endif
#ifdef ACTION_ON_PAUSE
void host_action_pause(const bool eol=true);
#endif
#ifdef ACTION_ON_PAUSED
void host_action_paused(const bool eol=true);
#endif
#ifdef ACTION_ON_RESUME
void host_action_resume();
#endif
#ifdef ACTION_ON_RESUMED
void host_action_resumed();
#endif
#ifdef ACTION_ON_CANCEL
void host_action_cancel();
#endif
#if ENABLED(HOST_PROMPT_SUPPORT)
enum PromptReason : uint8_t {
PROMPT_NOT_DEFINED,
PROMPT_FILAMENT_RUNOUT,
PROMPT_USER_CONTINUE,
PROMPT_FILAMENT_RUNOUT_REHEAT,
PROMPT_PAUSE_RESUME,
PROMPT_INFO
};
extern PromptReason host_prompt_reason;
void host_response_handler(const uint8_t response);
void host_action_prompt_begin(const char * const pstr, const bool eol=true);
void host_action_prompt_button(const char * const pstr);
void host_action_prompt_end();
void host_action_prompt_show();
void host_prompt_do(const PromptReason type, const char * const pstr, const char * const pbtn=NULL);
inline void host_prompt_open(const PromptReason reason, const char * const pstr, const char * const pbtn=NULL) {
if (host_prompt_reason == PROMPT_NOT_DEFINED) host_prompt_do(reason, pstr, pbtn);
}
#endif

View File

@ -45,6 +45,10 @@
#include "runout.h"
#endif
#if ENABLED(HOST_ACTION_COMMANDS)
#include "host_actions.h"
#endif
#include "../lcd/ultralcd.h"
#include "../libs/buzzer.h"
#include "../libs/nozzle.h"
@ -154,6 +158,20 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
KEEPALIVE_STATE(PAUSED_FOR_USER);
wait_for_user = true; // LCD click or M108 will clear this
#if ENABLED(HOST_PROMPT_SUPPORT)
const char tool = '0'
#if NUM_RUNOUT_SENSORS > 1
+ active_extruder
#endif
;
host_prompt_reason = PROMPT_USER_CONTINUE;
host_action_prompt_end();
host_action_prompt_begin(PSTR("Load Filament T"), false);
SERIAL_CHAR(tool);
SERIAL_EOL();
host_action_prompt_button(PSTR("Continue"));
host_action_prompt_show();
#endif
while (wait_for_user) {
#if HAS_BUZZER
filament_change_beep(max_beep_count);
@ -206,6 +224,9 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
#endif
wait_for_user = true;
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Continuous Purge Running..."), PSTR("Continue"));
#endif
for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count)
do_pause_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE);
wait_for_user = false;
@ -224,6 +245,24 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
}
// Show "Purge More" / "Resume" menu and wait for reply
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
host_action_prompt_end(); // Close current prompt
host_action_prompt_begin(PSTR("Paused"));
host_action_prompt_button(PSTR("PurgeMore"));
if (false
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|| runout.filament_ran_out
#endif
)
host_action_prompt_button(PSTR("DisableRunout"));
else {
host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
host_action_prompt_button(PSTR("Continue"));
}
host_action_prompt_show();
#endif
#if HAS_LCD_MENU
if (show_lcd) {
KEEPALIVE_STATE(PAUSED_FOR_USER);
@ -324,10 +363,15 @@ bool pause_print(const float &retract, const point_t &park_point, const float &u
if (did_pause_print) return false; // already paused
#ifdef ACTION_ON_PAUSED
host_action_paused();
#elif defined(ACTION_ON_PAUSE)
host_action_pause();
#if ENABLED(HOST_ACTION_COMMANDS)
#ifdef ACTION_ON_PAUSED
host_action_paused();
#elif defined(ACTION_ON_PAUSE)
host_action_pause();
#endif
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_open(PROMPT_INFO, PSTR("Pause"));
#endif
#endif
if (!DEBUGGING(DRYRUN) && unload_length && thermalManager.targetTooColdToExtrude(active_extruder)) {
@ -445,7 +489,9 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
// Wait for filament insert by user and press button
KEEPALIVE_STATE(PAUSED_FOR_USER);
wait_for_user = true; // LCD click or M108 will clear this
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Nozzle Parked"), PSTR("Continue"));
#endif
while (wait_for_user) {
#if HAS_BUZZER
filament_change_beep(max_beep_count);
@ -463,9 +509,17 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
#endif
SERIAL_ECHO_MSG(_PMSG(MSG_FILAMENT_CHANGE_HEAT));
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("HeaterTimeout"), PSTR("Reheat"));
#endif
// Wait for LCD click or M108
while (wait_for_user) idle(true);
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Reheating"));
#endif
// Re-enable the heaters if they timed out
HOTEND_LOOP() thermalManager.reset_heater_idle_timer(e);
@ -480,7 +534,9 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
HOTEND_LOOP()
thermalManager.start_heater_idle_timer(e, nozzle_timeout);
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Reheat Done"), PSTR("Continue"));
#endif
wait_for_user = true;
nozzle_timed_out = false;
@ -578,6 +634,10 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
--did_pause_print;
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_open(PROMPT_INFO, PSTR("Resume"));
#endif
#if ENABLED(SDSUPPORT)
if (did_pause_print) {
card.startFileprint();

View File

@ -38,6 +38,10 @@ MMU2 mmu2;
#include "../../module/stepper_indirection.h"
#include "../../Marlin.h"
#if ENABLED(HOST_PROMPT_SUPPORT)
#include "../../feature/host_actions.h"
#endif
#define MMU_TODELAY 100
#define MMU_TIMEOUT 10
#define MMU_CMD_TIMEOUT 60000ul //5min timeout for mmu commands (except P0)
@ -791,6 +795,9 @@ void MMU2::filamentRunout() {
LCD_MESSAGEPGM(MSG_MMU2_EJECT_RECOVER);
BUZZ(200, 404);
wait_for_user = true;
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), PSTR("Continue"));
#endif
while (wait_for_user) idle();
BUZZ(200, 404);
BUZZ(200, 404);

View File

@ -33,7 +33,11 @@
FilamentMonitor runout;
bool FilamentMonitorBase::enabled = true,
FilamentMonitorBase::filament_ran_out; // = false
FilamentMonitorBase::filament_ran_out; // = false
#if ENABLED(HOST_ACTION_COMMANDS)
bool FilamentMonitorBase::host_handling; // = false
#endif
/**
* Called by FilamentSensorSwitch::run when filament is detected.

View File

@ -36,12 +36,21 @@
#include "../lcd/extensible_ui/ui_api.h"
#endif
#if ENABLED(ADVANCED_PAUSE_FEATURE)
#include "pause.h"
#endif
//#define FILAMENT_RUNOUT_SENSOR_DEBUG
class FilamentMonitorBase {
public:
static bool enabled;
static bool filament_ran_out;
static bool enabled, filament_ran_out;
#if ENABLED(HOST_ACTION_COMMANDS)
static bool host_handling;
#else
constexpr static bool host_handling = false;
#endif
};
template<class RESPONSE_T, class SENSOR_T>
@ -80,7 +89,7 @@ class TFilamentMonitor : public FilamentMonitorBase {
// Give the response a chance to update its counter.
static inline void run() {
if (enabled && !filament_ran_out && (IS_SD_PRINTING() || print_job_timer.isRunning())) {
if (enabled && !filament_ran_out && (IS_SD_PRINTING() || print_job_timer.isRunning() || did_pause_print)) {
#if FILAMENT_RUNOUT_DISTANCE_MM > 0
cli(); // Prevent RunoutResponseDelayed::block_completed from accumulating here
#endif
@ -92,24 +101,7 @@ class TFilamentMonitor : public FilamentMonitorBase {
#endif
if (ran_out) {
filament_ran_out = true;
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onFilamentRunout(ExtUI::getActiveTool());
#endif
#ifdef ACTION_ON_FILAMENT_RUNOUT
#if NUM_RUNOUT_SENSORS > 1
host_action_filament_runout(false);
SERIAL_CHAR(' ');
SERIAL_ECHOLN(int(active_extruder));
#else
host_action_filament_runout();
#endif
if (!IS_SD_PRINTING())
reset();
else
#endif
{
enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
}
event_filament_runout();
planner.synchronize();
}
}
@ -317,7 +309,11 @@ class FilamentSensorBase {
}
static inline void block_completed(const block_t* const b) {
if (b->steps[X_AXIS] || b->steps[Y_AXIS] || b->steps[Z_AXIS]) {
if (b->steps[X_AXIS] || b->steps[Y_AXIS] || b->steps[Z_AXIS]
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|| did_pause_print // Allow pause purge move to re-trigger runout state
#endif
) {
// Only trigger on extrusion with XYZ movement to allow filament change and retract/recover.
const uint8_t e = b->extruder;
const int32_t steps = b->steps[E_AXIS];