// Executes run-time commands, when required. This is called from various check points in the main // program, primarily where there may be a while loop waiting for a buffer to clear space or any // point where the execution time from the last check point may be more than a fraction of a second. // This is a way to execute runtime commands asynchronously (aka multitasking) with grbl's g-code // parsing and planning functions. This function also serves as an interface for the interrupts to // set the system runtime flags, where only the main program to handles them, removing the need to // define more computationally-expensive volatile variables. // NOTE: The sys.execute variable flags are set by the serial read subprogram, except where noted. void protocol_execute_runtime() { // evaluate emergency stop -cm if (!(AUX_PIN & (1<<AUX_STOP_BIT))) { if (!(sys.execute & EXEC_RESET)) { // Force stop only first time. st_go_idle(); spindle_stop(); sys.execute |= EXEC_RESET; // Set as true } } if (sys.execute) { // Enter only if any bit flag is true uint8_t rt_exec = sys.execute; // Avoid calling volatile multiple times // System abort. Steppers have already been force stopped. if (rt_exec & EXEC_RESET) { sys.abort = true; return; // Nothing else to do but exit. } // Execute and serial print status if (rt_exec & EXEC_STATUS_REPORT) { protocol_status_report(); bit_false(sys.execute,EXEC_STATUS_REPORT); } // Execute and serial print switches if (rt_exec & EXEC_SWITCH_REPORT) { protocol_switch_report(); bit_false(sys.execute,EXEC_SWITCH_REPORT); } // Initiate stepper feed hold if (rt_exec & EXEC_FEED_HOLD) { st_feed_hold(); // Initiate feed hold. bit_false(sys.execute,EXEC_FEED_HOLD); } // Reinitializes the stepper module running flags and re-plans the buffer after a feed hold. // NOTE: EXEC_CYCLE_STOP is set by the stepper subsystem when a cycle or feed hold completes. if (rt_exec & EXEC_CYCLE_STOP) { st_cycle_reinitialize(); bit_false(sys.execute,EXEC_CYCLE_STOP); } if (rt_exec & EXEC_CYCLE_START) { st_cycle_start(); // Issue cycle start command to stepper subsystem #ifdef CYCLE_AUTO_START sys.auto_start = true; // Re-enable auto start after feed hold. #endif bit_false(sys.execute,EXEC_CYCLE_START); } } }
// Executes run-time commands, when required. This is called from various check points in the main // program, primarily where there may be a while loop waiting for a buffer to clear space or any // point where the execution time from the last check point may be more than a fraction of a second. // This is a way to execute runtime commands asynchronously (aka multitasking) with grbl's g-code // parsing and planning functions. This function also serves as an interface for the interrupts to // set the system runtime flags, where only the main program handles them, removing the need to // define more computationally-expensive volatile variables. This also provides a controlled way to // execute certain tasks without having two or more instances of the same task, such as the planner // recalculating the buffer upon a feedhold or override. // NOTE: The sys.execute variable flags are set by any process, step or serial interrupts, pinouts, // limit switches, or the main program. void protocol_execute_runtime() { if (sys.execute) { // Enter only if any bit flag is true uint8_t rt_exec = sys.execute; // Avoid calling volatile multiple times // System alarm. Everything has shutdown by something that has gone severely wrong. Report // the source of the error to the user. If critical, Grbl disables by entering an infinite // loop until system reset/abort. if (rt_exec & (EXEC_ALARM | EXEC_CRIT_EVENT)) { sys.state = STATE_ALARM; // Set system alarm state // Critical event. Only hard limit qualifies. Update this as new critical events surface. if (rt_exec & EXEC_CRIT_EVENT) { report_alarm_message(ALARM_HARD_LIMIT); report_feedback_message(MESSAGE_CRITICAL_EVENT); bit_false(sys.execute,EXEC_RESET); // Disable any existing reset do { // Nothing. Block EVERYTHING until user issues reset or power cycles. Hard limits // typically occur while unattended or not paying attention. Gives the user time // to do what is needed before resetting, like killing the incoming stream. } while (bit_isfalse(sys.execute,EXEC_RESET)); // Standard alarm event. Only abort during motion qualifies. } else { // Runtime abort command issued during a cycle, feed hold, or homing cycle. Message the // user that position may have been lost and set alarm state to enable the alarm lockout // to indicate the possible severity of the problem. report_alarm_message(ALARM_ABORT_CYCLE); } bit_false(sys.execute,(EXEC_ALARM | EXEC_CRIT_EVENT)); } // Execute system abort. if (rt_exec & EXEC_RESET) { sys.abort = true; // Only place this is set true. return; // Nothing else to do but exit. } // Execute and serial print status if (rt_exec & EXEC_STATUS_REPORT) { report_realtime_status(); bit_false(sys.execute,EXEC_STATUS_REPORT); } // Initiate stepper feed hold if (rt_exec & EXEC_FEED_HOLD) { st_feed_hold(); // Initiate feed hold. bit_false(sys.execute,EXEC_FEED_HOLD); } // Reinitializes the stepper module running state and, if a feed hold, re-plans the buffer. // NOTE: EXEC_CYCLE_STOP is set by the stepper subsystem when a cycle or feed hold completes. if (rt_exec & EXEC_CYCLE_STOP) { st_cycle_reinitialize(); bit_false(sys.execute,EXEC_CYCLE_STOP); } if (rt_exec & EXEC_CYCLE_START) { st_cycle_start(); // Issue cycle start command to stepper subsystem if (bit_istrue(settings.flags,BITFLAG_AUTO_START)) { sys.auto_start = true; // Re-enable auto start after feed hold. } bit_false(sys.execute,EXEC_CYCLE_START); } } // Overrides flag byte (sys.override) and execution should be installed here, since they // are runtime and require a direct and controlled interface to the main stepper program. }
void protocol_execute_runtime() { uint8_t aux_bits; aux_bits = AUX_PIN ^ AUX_INVMASK; // apply invert mask if (!(aux_bits & (1<<AUX_STOP_BIT))) { if (!(emerg_stop)) { st_go_idle(); spindle_stop(); sys.abort = true; emerg_stop = true; } } else { emerg_stop = false; } AUX_PORT ^= (1<<AUX_WDOG_BIT); // Chargepump-Bit invertieren if (sys.execute) { // Enter only if any bit flag is true uint8_t rt_exec = sys.execute; // Avoid calling volatile multiple times // System abort. Steppers have already been force stopped. if (rt_exec & EXEC_RESET) { sys.abort = true; return; // Nothing else to do but exit. } // Execute and serial print status if (rt_exec & EXEC_STATUS_REPORT) { protocol_status_report(); bit_false(sys.execute,EXEC_STATUS_REPORT); } // Execute and serial print switches if (rt_exec & EXEC_SWITCH_REPORT) { protocol_switch_report(); bit_false(sys.execute,EXEC_SWITCH_REPORT); } // Initiate stepper feed hold if (rt_exec & EXEC_FEED_HOLD) { st_feed_hold(); // Initiate feed hold. bit_false(sys.execute,EXEC_FEED_HOLD); } // Reinitializes the stepper module running flags and re-plans the buffer after a feed hold. // NOTE: EXEC_CYCLE_STOP is set by the stepper subsystem when a cycle or feed hold completes. if (rt_exec & EXEC_CYCLE_STOP) { st_cycle_reinitialize(); bit_false(sys.execute,EXEC_CYCLE_STOP); } if (rt_exec & EXEC_CYCLE_START) { st_cycle_start(); // Issue cycle start command to stepper subsystem #ifdef CYCLE_AUTO_START sys.auto_start = true; // Re-enable auto start after feed hold. #endif bit_false(sys.execute,EXEC_CYCLE_START); } } }