From e7db065c80eb34f13ea9367ee26547138db21b43 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 4 Mar 2017 14:26:38 -0500 Subject: [PATCH] Checkpoint job kill code --- g2core/alarm.cpp | 13 ++--- g2core/canonical_machine.h | 4 +- g2core/cycle_feedhold.cpp | 105 ++++++++++++++++++++++++++----------- 3 files changed, 83 insertions(+), 39 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index dc9c0e0f..7e4fd2e5 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -256,11 +256,12 @@ stat_t cm_panic(const stat_t status, const char *msg) void cm_job_kill() { - cm->job_kill_requested = true; + cm1.hold_abort_requested = true; + cm_program_end(); - if (cm->machine_state == MACHINE_ALARM) { - cm->machine_state = MACHINE_PROGRAM_STOP; - } else if (cm->machine_state == MACHINE_SHUTDOWN) { - cm->machine_state = MACHINE_READY; - } +// if (cm->machine_state == MACHINE_ALARM) { +// cm->machine_state = MACHINE_PROGRAM_STOP; +// } else if (cm->machine_state == MACHINE_SHUTDOWN) { +// cm->machine_state = MACHINE_READY; +// } } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index db353a83..08b630a7 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -259,8 +259,8 @@ typedef struct cmMachine { // struct to manage canonical machin uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) uint8_t shutdown_requested; // set non-zero to request shutdown in support of external estop (value is input number) bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them - bool hold_exit_requested; // request exit from feedhold - bool job_kill_requested; // ^d job kill received + bool hold_exit_requested; // request normal exit from feedhold + bool hold_abort_requested; // request emergency exit from feedhold (typically ^d job kill) bool return_flags[AXES]; // flags for recording which axes moved - used in feedhold exit move cmHomingState homing_state; // home: homing cycle sub-state machine diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index bdae316d..39767fd8 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -42,10 +42,10 @@ static stat_t _run_p1_hold_entry_actions(void); static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); 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); +static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); +static void _feedhold_p1_exit(void); +static void _feedhold_p2_exit(void); +static void _feedhold_abort(void); /**************************************************************************************** @@ -219,7 +219,8 @@ stat_t cm_feedhold_sequencing_callback() } } if (cm2.hold_state == FEEDHOLD_P2_EXIT) { - return(_finalize_p2_hold_exit()); + _feedhold_p2_exit(); + return (STAT_OK); } // queue flush won't run until the hold is complete and all (subsequent) motion has stopped @@ -230,12 +231,11 @@ 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()); + // special handling for feedhold abort - M2/M30, job kill, alarms + if (cm1.hold_abort_requested) { + _feedhold_abort(); } - + // exit_hold runs for both ~ and % feedhold ends if (cm1.hold_exit_requested) { @@ -249,7 +249,7 @@ stat_t cm_feedhold_sequencing_callback() } } if (cm1.hold_state == FEEDHOLD_P1_EXIT) { - return(_finalize_p1_hold_exit()); // run multiple times until actions are complete + _feedhold_p1_exit(); // run multiple times until actions are complete } return (STAT_OK); } @@ -291,9 +291,9 @@ static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) // Com static stat_t _run_p1_hold_entry_actions() // Execute Case (5) { - // do not perform entry actions if in alarm state - if (cm_is_alarmed()) { - cm1.hold_state = FEEDHOLD_HOLD; + // do not perform entry actions if feedhold abort in progress + if (cm1.hold_abort_requested) { + cm1.hold_state = FEEDHOLD_OFF; return (STAT_OK); } @@ -346,7 +346,7 @@ static stat_t _run_p1_hold_entry_actions() // Execute Case (5) /**************************************************************************************** * _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 + * _feedhold_p1_exit() - callback to finsh return once moves are done * * These functions assume that the feedhold sequencing callback has resolved all * state and timing issues and it's OK to call this now. Do not call this function @@ -356,8 +356,17 @@ static stat_t _run_p1_hold_entry_actions() // Execute Case (5) * the sync runs from an interrupt. Finalization needs to run from the main loop. */ -static stat_t _run_p1_hold_exit_actions() // Execute Cases (6) and (7) +static stat_t _run_p1_hold_exit_actions() // Execute Cases (6) and (7) { + // do not perform exit actions if feedhold abort in progress + if (cm1.hold_abort_requested) { + cm = &cm1; // reset to p1 planner + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + cm1.hold_state = FEEDHOLD_OFF; + return (STAT_OK); + } + // perform end-hold actions --- while still in secondary machine coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused @@ -379,11 +388,11 @@ static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _finalize_p1_hold_exit() +static void _feedhold_p1_exit() { // skip out if not ready to finalize the exit if (cm1.hold_state != FEEDHOLD_P1_EXIT) { - return (STAT_NOOP); // ??? return (STAT_EAGAIN); + return; } // return to primary planner (p1) @@ -408,14 +417,15 @@ static stat_t _finalize_p1_hold_exit() cm_cycle_end(); } cm1.hold_state = FEEDHOLD_OFF; - return (STAT_OK); } /**************************************************************************************** - * _finalize_p2_hold_exit() + * _feedhold_p2_exit() - exit from a feedhold in feedhold (from p2) + * + * Assumes planner is in p2 on entry */ -static stat_t _finalize_p2_hold_exit() +static void _feedhold_p2_exit() { float position[AXES]; copy_vector(position, mr2.position); // save the final position @@ -427,27 +437,60 @@ static stat_t _finalize_p2_hold_exit() cm_set_motion_state(MOTION_STOP); cm_cycle_end(); sr_request_status_report(SR_REQUEST_IMMEDIATE); - return (STAT_OK); } /**************************************************************************************** - * _feedhold_alarm_exit() + * _feedhold_abort() - used to exit a feedhold without completing exit actions + * + * Valid entry states (all must be handled): + * Case (1) Not in a feedhold (FEEDHOLD_OFF). Ignore the request + * + * Case (2) In a feedhold but have not yet hit the hold point. + * Leave the abort request pending to be picked up by p2 entry actions, + * which are not allowed to proceed. + * + * Case (3) In a feedhold and currently executing P2 entry actions + * Case (4) In a feedhold and currently idle in P2 + * Case (5) In a feedhold and currently moving in P2 + * Case (6) In a feedhold and currently executing P2 exit actions */ -static stat_t _feedhold_alarm_exit() +static void _feedhold_abort() { - cm = &cm1; // return to primary planner (p1) + // Exit if not in a feedhold + if (cm1.hold_state == FEEDHOLD_OFF) { + cm1.hold_abort_requested = false; + return; + } + + // No action if waiting for HOLD point - let P2_START run the abort + if ((cm1.hold_state > FEEDHOLD_OFF) && (cm1.hold_state < FEEDHOLD_P2_START)) { + return; + } + + // If in p2 perform the p2 exit first + if (cm == &cm2) { + _feedhold_p2_exit(); + } + + // perform a complete exit from p1 + cm = &cm1; // return to p1 if not already here 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 + + // execute this block if a queue flush was performed + // adjust p1 planner positions to runtime positions + if (cm1.flush_state == FLUSH_WAS_RUN) { 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); -} + + // end cycle + cm_set_motion_state(MOTION_STOP); +// cm_cycle_end(); + cm1.hold_state = FEEDHOLD_OFF; + cm1.hold_abort_requested = false; +} /**************************************************************************************** * Queue Flush operations