diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index e2da88a4..99345a21 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -37,7 +37,7 @@ #include "temperature.h" #include "util.h" -/******************************************************************************** +/**************************************************************************************** * ALARM, SHUTDOWN, and PANIC are nested dolls. * * cm_alrm() - invoke alarm from command @@ -71,7 +71,7 @@ stat_t cm_clr(nvObj_t *nv) // clear alarm or shutdown from comman return (STAT_OK); } -/* +/**************************************************************************************** * cm_clear() - clear ALARM and SHUTDOWN states * cm_parse_clear() - parse incoming gcode for M30 or M2 clears if in ALARM state * @@ -99,7 +99,7 @@ void cm_parse_clear(const char *s) } } -/* +/**************************************************************************************** * cm_is_alarmed() - return alarm status code or OK if no alarms */ @@ -111,7 +111,7 @@ stat_t cm_is_alarmed() return (STAT_OK); } -/* +/**************************************************************************************** * cm_halt_all() - stop, spindle and coolant immediately * cm_halt_motion() - stop motion immediately. Does not affect spindle, coolant, or other IO * @@ -136,7 +136,7 @@ void cm_halt_motion(void) cm->hold_state = FEEDHOLD_OFF; } -/* +/**************************************************************************************** * cm_alarm() - enter ALARM state * * An ALARM sets the ALARM machine state, starts a feedhold to stop motion, stops the @@ -165,7 +165,8 @@ stat_t cm_alarm(const stat_t status, const char *msg) (cm->machine_state == MACHINE_PANIC)) { return (STAT_OK); // don't alarm if already in an alarm state } - cm->machine_state = MACHINE_ALARM; + cm1.machine_state = MACHINE_ALARM; // alarm both machines + cm2.machine_state = MACHINE_ALARM; cm_request_feedhold(); // stop motion cm_request_queue_flush(); // do a queue flush once runtime is not busy @@ -180,7 +181,8 @@ stat_t cm_alarm(const stat_t status, const char *msg) sr_request_status_report(SR_REQUEST_TIMED); return (status); } -/* + +/**************************************************************************************** * cm_shutdown() - enter shutdown state * * SHUTDOWN stops all motion, spindle and coolant immediately, sets a SHUTDOWN machine @@ -213,12 +215,13 @@ stat_t cm_shutdown(const stat_t status, const char *msg) } cm->homing_state = HOMING_NOT_HOMED; - cm->machine_state = MACHINE_SHUTDOWN; // do this after all other activity + cm1.machine_state = MACHINE_SHUTDOWN; // shut down both machines... + cm2.machine_state = MACHINE_SHUTDOWN; //...do this after all other activity rpt_exception(status, msg); // send exception report return (status); } -/* +/**************************************************************************************** * cm_panic() - enter panic state * * PANIC occurs if the firmware has detected an unrecoverable internal error @@ -241,7 +244,8 @@ stat_t cm_panic(const stat_t status, const char *msg) temperature_reset(); // turn off heaters and fans cm_queue_flush(&cm1); // flush all queues and reset positions - cm->machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable + cm1.machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable + cm2.machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable rpt_exception(status, msg); // send panic report return (status); } diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 45c42227..f202cb93 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -45,10 +45,12 @@ static stat_t _run_p1_hold_exit_actions(void); static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); static stat_t _finalize_p1_hold_exit(void); static stat_t _finalize_p2_hold_exit(void); +static stat_t _feedhold_alarm_exit(void); -/*********************************************************************************** - **** Feedholds ******************************************************************** - ***********************************************************************************/ + +/**************************************************************************************** + **** Feedholds ************************************************************************* + ****************************************************************************************/ /* * Feedholds, queue flushes and end_holds are all related and are performed in this * file and in plan_exec.cpp. Feedholds are implemented as a state machine @@ -105,7 +107,7 @@ static stat_t _finalize_p2_hold_exit(void); * (7) - Removing the hold state and there is no queued motion - see cycle_feedhold.cpp */ -/*********************************************************************************** +/**************************************************************************************** * cm_has_hold() - return true if a hold condition exists (or a pending hold request) */ bool cm_has_hold() @@ -113,7 +115,7 @@ bool cm_has_hold() return (cm1.hold_state != FEEDHOLD_OFF); } -/*********************************************************************************** +/**************************************************************************************** * cm_request_feedhold() * cm_request_exit_hold() * cm_request_queue_flush() @@ -179,7 +181,7 @@ void cm_start_hold() } } -/*********************************************************************************** +/**************************************************************************************** * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests * * Expected behaviors: (no-hold means machine is not in hold, etc) @@ -228,6 +230,12 @@ stat_t cm_feedhold_sequencing_callback() qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available } + // special handling for alarms and job kill + if ((cm1.hold_state == FEEDHOLD_HOLD) && (cm_is_alarmed())) { + cm1.hold_exit_requested = false; + return(_feedhold_alarm_exit()); + } + // exit_hold runs for both ~ and % feedhold ends if (cm1.hold_exit_requested) { @@ -246,7 +254,7 @@ stat_t cm_feedhold_sequencing_callback() return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * cm_feedhold_command_blocker() - prevents new Gcode commands from queueing to p2 planner */ @@ -257,8 +265,8 @@ stat_t cm_feedhold_command_blocker() } return (STAT_OK); } - -/*********************************************************************************** + +/**************************************************************************************** * _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold * _sync_to_p1_hold_entry_actions_done() - final state change occurs here * @@ -274,6 +282,7 @@ stat_t cm_feedhold_command_blocker() * not run actions, so this function is never called for p2 feedholds. It's called * from an interrupt, so it only sets a flag. */ + static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_HOLD; @@ -281,11 +290,15 @@ static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) } static stat_t _run_p1_hold_entry_actions() -{ +{ + // do not perform entry actions if in alarm state + if (cm_is_alarmed()) { + cm1.hold_state = FEEDHOLD_HOLD; + return (STAT_OK); + } + cm->hold_state = FEEDHOLD_ACTIONS_WAIT; // penultimate state before transitioning to HOLD - - debug_trap_if_true(st_runtime_isbusy(), "_run_p1_hold_entry_actions() - runtime is busy"); - + // copy the primary canonical machine to the secondary, // fix the planner pointer, and reset the secondary planner memcpy(&cm2, &cm1, sizeof(cmMachine_t)); @@ -330,7 +343,7 @@ static stat_t _run_p1_hold_entry_actions() return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * _run_p1_hold_exit_actions() - initiate return from feedhold planner * _sync_to_p1_hold_exit_actions_done() - callback to sync to end of planner operations * _finalize_p1_hold_exit() - callback to finsh return once moves are done @@ -399,7 +412,7 @@ static stat_t _finalize_p1_hold_exit() return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * _finalize_p2_hold_exit() */ @@ -418,7 +431,26 @@ static stat_t _finalize_p2_hold_exit() return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** + * _feedhold_alarm_exit() + */ + +static stat_t _feedhold_alarm_exit() +{ + cm = &cm1; // return to primary planner (p1) + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + + if (cm1.flush_state == FLUSH_WAS_RUN) { // adjust p1 planner positions to runtime positions + cm_reset_position_to_absolute_position(cm); + cm1.flush_state = FLUSH_OFF; + } + cm->cycle_state = CYCLE_OFF; + cm->hold_state = FEEDHOLD_OFF; + return (STAT_OK); +} + +/**************************************************************************************** * Queue Flush operations * * This one's complicated. See here first: