Pin state reporting of all pins. Flash optimization.

- New pin state realtime reporting feature. Instead of `Lim:000` for
limit state reports, the new feature shows `Pin:000|0|0000`, or
something similar. The `|` delimited fields indicate xyz limits, probe,
and control pin states, where 0 is always not triggered, and 1 is
triggered. Invert masks ARE accounted for.
  Each field may be enabled or disabled via the `$10` status report
setting. The probe and control pin flags are bits 5 and 6, respectively.

- Remove the now deprecated `REPORT_CONTROL_PIN_STATE` option in
config.h

- The old limit pin reports `Lim:000` may be re-enabled by commenting
out `REPORT_ALL_PIN_STATES` in config.h.

- Incremented the version letter (v1.0c) to indicate the change in
reporting style.

- Replaced all bit_true_atomic and bit_false_atomic macros with
function calls. This saved a couple hundred bytes of flash.
This commit is contained in:
Sonny Jeon 2015-11-09 21:54:26 -07:00
parent b9c3461932
commit 5eee10845b
16 changed files with 182 additions and 63 deletions

View File

@ -31,9 +31,11 @@ Grbl includes full acceleration management with look ahead. That means the contr
*** ***
##Update Summary for v1.0b ##Update Summary for v1.0c
- **IMPORTANT:** Your EEPROM will be wiped and restored with new settings. This is due to the addition of two new spindle speed '$' settings. - **IMPORTANT:** Your EEPROM will be wiped and restored with new settings. This is due to the addition of two new spindle speed '$' settings.
- Altered limit pin status reports from `Lim:000` to `Pin:000|0|0000`, where the `|` delimiters separate the new probe state and control pin states. Each new field may be disabled by the `$10` Grbl setting. NOTE: Commenting `REPORT_ALL_PIN_STATES` in config.h reverts to old `Lim:` reports, if needed.
- New safety door parking motion as a compile-option. Grbl will retract, disable the spindle/coolant, and park near Z max. When resumed, it will perform these task in reverse order and continue the program. Highly configurable. See config.h for details. - New safety door parking motion as a compile-option. Grbl will retract, disable the spindle/coolant, and park near Z max. When resumed, it will perform these task in reverse order and continue the program. Highly configurable. See config.h for details.
- New '$' Grbl settings for max and min spindle rpm. Allows for tweaking the PWM output to more closely match true spindle rpm. When max rpm is set to zero or less than min rpm, the PWM pin D11 will act like a simple enable on/off output. - New '$' Grbl settings for max and min spindle rpm. Allows for tweaking the PWM output to more closely match true spindle rpm. When max rpm is set to zero or less than min rpm, the PWM pin D11 will act like a simple enable on/off output.

View File

@ -1,3 +1,39 @@
----------------
Date: 2015-09-30
Author: Sonny Jeon
Subject: Bug fixes.
- G38.x was not printing correctly in the $G g-code state reports. Now
fixed.
- When investigating the above issue, it was noticed that G38.x
wouldnt show at all, but instead a G0 would be printed. This was
unlike the v0.9j master build. It turned out volatile variables do not
like to be defined inside a C struct. These are undefined on how to be
handled. Once pulled out, all weird issues went away.
- Also changed two sizeof() statements in the mc_probe() and
probe_state_monitor() functions to be more robust later on.
- Updated the commit logs to individual files for each minor release.
Forgot to update the generating script to account for this.
----------------
Date: 2015-09-30
Author: Sonny Jeon
Subject: Minor bug fixes.
- G38.x was not printing correctly in the $G g-code state reports. Now
fixed.
- Potential bug regarding volatile variables inside a struct. It has
never been a problem in v0.9, but ran into this during v1.0
development. Just to be safe, the fixes are applied here.
- Updated pre-built firmwares with these two bug fixes.
---------------- ----------------
Date: 2015-09-24 Date: 2015-09-24
Author: Sonny Jeon Author: Sonny Jeon

View File

@ -164,11 +164,12 @@
// uncomment the config option USE_SPINDLE_DIR_AS_ENABLE_PIN below. // uncomment the config option USE_SPINDLE_DIR_AS_ENABLE_PIN below.
// #define INVERT_SPINDLE_ENABLE_PIN // Default disabled. Uncomment to enable. // #define INVERT_SPINDLE_ENABLE_PIN // Default disabled. Uncomment to enable.
// Enable control pin states feedback in status reports. The data is presented as simple binary of // Enable all pin states feedback in status reports. Configurable with Grbl settings to print only
// the control pin port (0 (low) or 1(high)), masked to show only the input pins. Non-control pins on the // the desired data, which is presented as simple binary reading of each pin as (0 (low) or 1(high)).
// port will always show a 0 value. See cpu_map.h for the pin bitmap. As with the limit pin reporting, // The fields are printed in a particular order and settings groups are separated by '|' characters.
// we do not recommend keeping this option enabled. Try to only use this for setting up a new CNC. // NOTE: This option is here for backward compatibility of the old style of pin state reports, i.e.
// #define REPORT_CONTROL_PIN_STATE // Default disabled. Uncomment to enable. // `Lim:000`. This new `Pin:` report will be the standard going forward.
#define REPORT_ALL_PIN_STATES // Default enabled. Comment to disable.
// When Grbl powers-cycles or is hard reset with the Arduino reset button, Grbl boots up with no ALARM // When Grbl powers-cycles or is hard reset with the Arduino reset button, Grbl boots up with no ALARM
// by default. This is to make it as simple as possible for new users to start using Grbl. When homing // by default. This is to make it as simple as possible for new users to start using Grbl. When homing

View File

@ -1044,7 +1044,7 @@ uint8_t gc_execute_line(char *line)
protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on. protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on.
if (gc_state.modal.program_flow == PROGRAM_FLOW_PAUSED) { if (gc_state.modal.program_flow == PROGRAM_FLOW_PAUSED) {
if (sys.state != STATE_CHECK_MODE) { if (sys.state != STATE_CHECK_MODE) {
bit_true_atomic(sys_rt_exec_state, EXEC_FEED_HOLD); // Use feed hold for program pause. system_set_exec_state_flag(EXEC_FEED_HOLD); // Use feed hold for program pause.
protocol_execute_realtime(); // Execute suspend. protocol_execute_realtime(); // Execute suspend.
} }
} else { // == PROGRAM_FLOW_COMPLETED } else { // == PROGRAM_FLOW_COMPLETED

View File

@ -22,8 +22,8 @@
#define grbl_h #define grbl_h
// Grbl versioning system // Grbl versioning system
#define GRBL_VERSION "1.0b" #define GRBL_VERSION "1.0c"
#define GRBL_VERSION_BUILD "20150930" #define GRBL_VERSION_BUILD "20151109"
// Define standard libraries used by Grbl. // Define standard libraries used by Grbl.
#include <avr/io.h> #include <avr/io.h>

View File

@ -106,11 +106,11 @@ uint8_t limits_get_state()
// Check limit pin state. // Check limit pin state.
if (limits_get_state()) { if (limits_get_state()) {
mc_reset(); // Initiate system kill. mc_reset(); // Initiate system kill.
bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event system_set_exec_alarm_flag((EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event
} }
#else #else
mc_reset(); // Initiate system kill. mc_reset(); // Initiate system kill.
bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event system_set_exec_alarm_flag((EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event
#endif #endif
} }
} }
@ -126,7 +126,7 @@ uint8_t limits_get_state()
// Check limit pin state. // Check limit pin state.
if (limits_get_state()) { if (limits_get_state()) {
mc_reset(); // Initiate system kill. mc_reset(); // Initiate system kill.
bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event system_set_exec_alarm_flag((EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event
} }
} }
} }
@ -235,7 +235,7 @@ void limits_go_home(uint8_t cycle_mask)
return; return;
} else { } else {
// Pull-off motion complete. Disable CYCLE_STOP from executing. // Pull-off motion complete. Disable CYCLE_STOP from executing.
bit_false_atomic(sys_rt_exec_state,EXEC_CYCLE_STOP); system_clear_exec_state_flag(EXEC_CYCLE_STOP);
break; break;
} }
} }
@ -335,7 +335,7 @@ void limits_soft_check(float *target)
// workspace volume so just come to a controlled stop so position is not lost. When complete // workspace volume so just come to a controlled stop so position is not lost. When complete
// enter alarm mode. // enter alarm mode.
if (sys.state == STATE_CYCLE) { if (sys.state == STATE_CYCLE) {
bit_true_atomic(sys_rt_exec_state, EXEC_FEED_HOLD); system_set_exec_state_flag(EXEC_FEED_HOLD);
do { do {
protocol_execute_realtime(); protocol_execute_realtime();
if (sys.abort) { return; } if (sys.abort) { return; }
@ -343,7 +343,7 @@ void limits_soft_check(float *target)
} }
mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown.
bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_SOFT_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate soft limit critical event system_set_exec_alarm_flag((EXEC_ALARM_SOFT_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate soft limit critical event
protocol_execute_realtime(); // Execute to enter critical event loop and system abort protocol_execute_realtime(); // Execute to enter critical event loop and system abort
return; return;
} }

View File

@ -220,7 +220,7 @@ void mc_homing_cycle()
#ifdef LIMITS_TWO_SWITCHES_ON_AXES #ifdef LIMITS_TWO_SWITCHES_ON_AXES
if (limits_get_state()) { if (limits_get_state()) {
mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown.
bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); system_set_exec_alarm_flag((EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT));
return; return;
} }
#endif #endif
@ -276,7 +276,7 @@ void mc_homing_cycle()
// After syncing, check if probe is already triggered. If so, halt and issue alarm. // After syncing, check if probe is already triggered. If so, halt and issue alarm.
// NOTE: This probe initialization error applies to all probing cycles. // NOTE: This probe initialization error applies to all probing cycles.
if ( probe_get_state() ) { // Check probe pin state. if ( probe_get_state() ) { // Check probe pin state.
bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); system_set_exec_alarm_flag(EXEC_ALARM_PROBE_FAIL);
protocol_execute_realtime(); protocol_execute_realtime();
} }
if (sys.abort) { return; } // Return if system reset has been issued. if (sys.abort) { return; } // Return if system reset has been issued.
@ -292,7 +292,7 @@ void mc_homing_cycle()
sys_probe_state = PROBE_ACTIVE; sys_probe_state = PROBE_ACTIVE;
// Perform probing cycle. Wait here until probe is triggered or motion completes. // Perform probing cycle. Wait here until probe is triggered or motion completes.
bit_true_atomic(sys_rt_exec_state, EXEC_CYCLE_START); system_set_exec_state_flag(EXEC_CYCLE_START);
do { do {
protocol_execute_realtime(); protocol_execute_realtime();
if (sys.abort) { return; } // Check for system abort if (sys.abort) { return; } // Check for system abort
@ -303,7 +303,7 @@ void mc_homing_cycle()
// Set state variables and error out, if the probe failed and cycle with error is enabled. // Set state variables and error out, if the probe failed and cycle with error is enabled.
if (sys_probe_state == PROBE_ACTIVE) { if (sys_probe_state == PROBE_ACTIVE) {
if (is_no_error) { memcpy(sys.probe_position, sys.position, sizeof(sys.position)); } if (is_no_error) { memcpy(sys.probe_position, sys.position, sizeof(sys.position)); }
else { bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); } else { system_set_exec_alarm_flag(EXEC_ALARM_PROBE_FAIL); }
} else { } else {
sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully. sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully.
} }
@ -366,7 +366,7 @@ void mc_reset()
{ {
// Only this function can set the system reset. Helps prevent multiple kill calls. // Only this function can set the system reset. Helps prevent multiple kill calls.
if (bit_isfalse(sys_rt_exec_state, EXEC_RESET)) { if (bit_isfalse(sys_rt_exec_state, EXEC_RESET)) {
bit_true_atomic(sys_rt_exec_state, EXEC_RESET); system_set_exec_state_flag(EXEC_RESET);
// Kill spindle and coolant. // Kill spindle and coolant.
spindle_stop(); spindle_stop();
@ -378,8 +378,8 @@ void mc_reset()
// violated, by which, all bets are off. // violated, by which, all bets are off.
if ((sys.state & (STATE_CYCLE | STATE_HOMING)) || if ((sys.state & (STATE_CYCLE | STATE_HOMING)) ||
(sys.step_control & (STEP_CONTROL_EXECUTE_HOLD | STEP_CONTROL_EXECUTE_PARK))) { (sys.step_control & (STEP_CONTROL_EXECUTE_HOLD | STEP_CONTROL_EXECUTE_PARK))) {
if (sys.state == STATE_HOMING) { bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_HOMING_FAIL); } if (sys.state == STATE_HOMING) { system_set_exec_alarm_flag(EXEC_ALARM_HOMING_FAIL); }
else { bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_ABORT_CYCLE); } else { system_set_exec_alarm_flag(EXEC_ALARM_ABORT_CYCLE); }
st_go_idle(); // Force kill steppers. Position has likely been lost. st_go_idle(); // Force kill steppers. Position has likely been lost.
} }
} }

View File

@ -56,9 +56,6 @@
// Bit field and masking macros // Bit field and masking macros
#define bit(n) (1 << n) #define bit(n) (1 << n)
#define bit_true_atomic(x,mask) {uint8_t sreg = SREG; cli(); (x) |= (mask); SREG = sreg; }
#define bit_false_atomic(x,mask) {uint8_t sreg = SREG; cli(); (x) &= ~(mask); SREG = sreg; }
#define bit_toggle_atomic(x,mask) {uint8_t sreg = SREG; cli(); (x) ^= (mask); SREG = sreg; }
#define bit_true(x,mask) (x) |= (mask) #define bit_true(x,mask) (x) |= (mask)
#define bit_false(x,mask) (x) &= ~(mask) #define bit_false(x,mask) (x) &= ~(mask)
#define bit_istrue(x,mask) ((x & mask) != 0) #define bit_istrue(x,mask) ((x & mask) != 0)

View File

@ -34,7 +34,7 @@ void probe_init()
#else #else
PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation. PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation.
#endif #endif
// probe_configure_invert_mask(false); // Initialize invert mask. Not required. Updated when in-use. probe_configure_invert_mask(false); // Initialize invert mask. Re-updated during use.
} }

View File

@ -190,7 +190,7 @@ void protocol_buffer_synchronize()
// when one of these conditions exist respectively: There are no more blocks sent (i.e. streaming // when one of these conditions exist respectively: There are no more blocks sent (i.e. streaming
// is finished, single commands), a command that needs to wait for the motions in the buffer to // is finished, single commands), a command that needs to wait for the motions in the buffer to
// execute calls a buffer sync, or the planner buffer is full and ready to go. // execute calls a buffer sync, or the planner buffer is full and ready to go.
void protocol_auto_cycle_start() { bit_true_atomic(sys_rt_exec_state, EXEC_CYCLE_START); } void protocol_auto_cycle_start() { system_set_exec_state_flag(EXEC_CYCLE_START); }
// This function is the general interface to Grbl's real-time command execution system. It is called // This function is the general interface to Grbl's real-time command execution system. It is called
@ -237,7 +237,7 @@ void protocol_exec_rt_system()
// Halt everything upon a critical event flag. Currently hard and soft limits flag this. // Halt everything upon a critical event flag. Currently hard and soft limits flag this.
if (rt_exec & EXEC_CRITICAL_EVENT) { if (rt_exec & EXEC_CRITICAL_EVENT) {
report_feedback_message(MESSAGE_CRITICAL_EVENT); report_feedback_message(MESSAGE_CRITICAL_EVENT);
bit_false_atomic(sys_rt_exec_state,EXEC_RESET); // Disable any existing reset system_clear_exec_state_flag(EXEC_RESET); // Disable any existing reset
do { do {
// Block everything, except reset and status reports, until user issues reset or power // Block everything, except reset and status reports, until user issues reset or power
// cycles. Hard limits typically occur while unattended or not paying attention. Gives // cycles. Hard limits typically occur while unattended or not paying attention. Gives
@ -248,12 +248,12 @@ void protocol_exec_rt_system()
// TODO: Allow status reports during a critical alarm. Still need to think about implications of this. // TODO: Allow status reports during a critical alarm. Still need to think about implications of this.
// if (sys_rt_exec_state & EXEC_STATUS_REPORT) { // if (sys_rt_exec_state & EXEC_STATUS_REPORT) {
// report_realtime_status(); // report_realtime_status();
// bit_false_atomic(sys_rt_exec_state,EXEC_STATUS_REPORT); // system_clear_exec_state_flag(EXEC_STATUS_REPORT);
// } // }
} while (bit_isfalse(sys_rt_exec_state,EXEC_RESET)); } while (bit_isfalse(sys_rt_exec_state,EXEC_RESET));
} }
bit_false_atomic(sys_rt_exec_alarm,0xFF); // Clear all alarm flags system_clear_exec_alarm_flag(0xFF); // Clear all alarm flags
} }
rt_exec = sys_rt_exec_state; // Copy volatile sys_rt_exec_state. rt_exec = sys_rt_exec_state; // Copy volatile sys_rt_exec_state.
@ -268,7 +268,7 @@ void protocol_exec_rt_system()
// Execute and serial print status // Execute and serial print status
if (rt_exec & EXEC_STATUS_REPORT) { if (rt_exec & EXEC_STATUS_REPORT) {
report_realtime_status(); report_realtime_status();
bit_false_atomic(sys_rt_exec_state,EXEC_STATUS_REPORT); system_clear_exec_state_flag(EXEC_STATUS_REPORT);
} }
// NOTE: The math involved to calculate the hold should be low enough for most, if not all, // NOTE: The math involved to calculate the hold should be low enough for most, if not all,
@ -340,7 +340,7 @@ void protocol_exec_rt_system()
} }
bit_false_atomic(sys_rt_exec_state,(EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR)); system_clear_exec_state_flag((EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR));
} }
// Execute a cycle start by starting the stepper interrupt to begin executing the blocks in queue. // Execute a cycle start by starting the stepper interrupt to begin executing the blocks in queue.
@ -380,7 +380,7 @@ void protocol_exec_rt_system()
} }
} }
} }
bit_false_atomic(sys_rt_exec_state,EXEC_CYCLE_START); system_clear_exec_state_flag(EXEC_CYCLE_START);
} }
if (rt_exec & EXEC_CYCLE_STOP) { if (rt_exec & EXEC_CYCLE_STOP) {
@ -399,7 +399,7 @@ void protocol_exec_rt_system()
sys.suspend = SUSPEND_DISABLE; sys.suspend = SUSPEND_DISABLE;
sys.state = STATE_IDLE; sys.state = STATE_IDLE;
} }
bit_false_atomic(sys_rt_exec_state,EXEC_CYCLE_STOP); system_clear_exec_state_flag(EXEC_CYCLE_STOP);
} }
} }
@ -544,7 +544,7 @@ static void protocol_exec_rt_suspend()
if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) { if (bit_isfalse(sys.suspend,SUSPEND_RESTART_RETRACT)) {
sys.suspend |= SUSPEND_RESTORE_COMPLETE; sys.suspend |= SUSPEND_RESTORE_COMPLETE;
bit_true_atomic(sys_rt_exec_state,EXEC_CYCLE_START); // Set to resume program. system_set_exec_state_flag(EXEC_CYCLE_START); // Set to resume program.
} }
} }

View File

@ -502,14 +502,28 @@ void report_realtime_status()
printFloat_RateValue(st_get_realtime_rate()); printFloat_RateValue(st_get_realtime_rate());
#endif #endif
#ifdef REPORT_ALL_PIN_STATES
if (bit_istrue(settings.status_report_mask,
( BITFLAG_RT_STATUS_LIMIT_PINS| BITFLAG_RT_STATUS_PROBE_PIN | BITFLAG_RT_STATUS_CONTROL_PINS ))) {
printPgmString(PSTR(",Pin:"));
if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_LIMIT_PINS)) {
print_unsigned_int8(limits_get_state(),2,N_AXIS);
}
printPgmString(PSTR("|"));
if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_PROBE_PIN)) {
if (probe_get_state()) { printPgmString(PSTR("1")); }
else { printPgmString(PSTR("0")); }
}
printPgmString(PSTR("|"));
if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_CONTROL_PINS)) {
print_unsigned_int8(system_control_get_state(),2,N_CONTROL_PIN);
}
}
#else
if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_LIMIT_PINS)) { if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_LIMIT_PINS)) {
printPgmString(PSTR(",Lim:")); printPgmString(PSTR(",Lim:"));
print_unsigned_int8(limits_get_state(),2,N_AXIS); print_unsigned_int8(limits_get_state(),2,N_AXIS);
} }
#ifdef REPORT_CONTROL_PIN_STATE
printPgmString(PSTR(",Ctl:"));
print_uint8_base2(CONTROL_PIN & CONTROL_MASK);
#endif #endif
printPgmString(PSTR(">\r\n")); printPgmString(PSTR(">\r\n"));

View File

@ -164,10 +164,10 @@ ISR(SERIAL_RX)
// Pick off realtime command characters directly from the serial stream. These characters are // Pick off realtime command characters directly from the serial stream. These characters are
// not passed into the buffer, but these set system state flag bits for realtime execution. // not passed into the buffer, but these set system state flag bits for realtime execution.
switch (data) { switch (data) {
case CMD_STATUS_REPORT: bit_true_atomic(sys_rt_exec_state, EXEC_STATUS_REPORT); break; // Set as true case CMD_STATUS_REPORT: system_set_exec_state_flag(EXEC_STATUS_REPORT); break; // Set as true
case CMD_CYCLE_START: bit_true_atomic(sys_rt_exec_state, EXEC_CYCLE_START); break; // Set as true case CMD_CYCLE_START: system_set_exec_state_flag(EXEC_CYCLE_START); break; // Set as true
case CMD_FEED_HOLD: bit_true_atomic(sys_rt_exec_state, EXEC_FEED_HOLD); break; // Set as true case CMD_FEED_HOLD: system_set_exec_state_flag(EXEC_FEED_HOLD); break; // Set as true
case CMD_SAFETY_DOOR: bit_true_atomic(sys_rt_exec_state, EXEC_SAFETY_DOOR); break; // Set as true case CMD_SAFETY_DOOR: system_set_exec_state_flag(EXEC_SAFETY_DOOR); break; // Set as true
case CMD_RESET: mc_reset(); break; // Call motion control reset routine. case CMD_RESET: mc_reset(); break; // Call motion control reset routine.
default: // Write character to buffer default: // Write character to buffer
next_head = serial_rx_buffer_head + 1; next_head = serial_rx_buffer_head + 1;

View File

@ -45,6 +45,8 @@
#define BITFLAG_RT_STATUS_PLANNER_BUFFER bit(2) #define BITFLAG_RT_STATUS_PLANNER_BUFFER bit(2)
#define BITFLAG_RT_STATUS_SERIAL_RX bit(3) #define BITFLAG_RT_STATUS_SERIAL_RX bit(3)
#define BITFLAG_RT_STATUS_LIMIT_PINS bit(4) #define BITFLAG_RT_STATUS_LIMIT_PINS bit(4)
#define BITFLAG_RT_STATUS_PROBE_PIN bit(5)
#define BITFLAG_RT_STATUS_CONTROL_PINS bit(6)
// Define settings restore bitflags. // Define settings restore bitflags.
#define SETTINGS_RESTORE_ALL 0xFF // All bitflags #define SETTINGS_RESTORE_ALL 0xFF // All bitflags

View File

@ -349,7 +349,7 @@ ISR(TIMER1_COMPA_vect)
} else { } else {
// Segment buffer empty. Shutdown. // Segment buffer empty. Shutdown.
st_go_idle(); st_go_idle();
bit_true_atomic(sys_rt_exec_state,EXEC_CYCLE_STOP); // Flag main program for cycle end system_set_exec_state_flag(EXEC_CYCLE_STOP); // Flag main program for cycle end
return; // Nothing to do but exit. return; // Nothing to do but exit.
} }
} }

View File

@ -34,27 +34,45 @@ void system_init()
} }
// Returns control pin state as a uint8 bitfield. Each bit indicates the input pin state, where
// triggered is 1 and not triggered is 0. Invert mask is applied. Bitfield organization is
// defined by the CONTROL_PIN_INDEX in the header file.
uint8_t system_control_get_state()
{
uint8_t control_state = 0;
uint8_t pin = (CONTROL_PIN & CONTROL_MASK);
#ifndef INVERT_ALL_CONTROL_PINS
pin ^= CONTROL_INVERT_MASK;
#endif
if (pin) {
#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
if (bit_istrue(pin,(1<<SAFETY_DOOR_BIT))) { control_state |= CONTROL_PIN_INDEX_SAFETY_DOOR; }
#endif
if (bit_istrue(pin,(1<<RESET_BIT))) { control_state |= CONTROL_PIN_INDEX_RESET; }
if (bit_istrue(pin,(1<<FEED_HOLD_BIT))) { control_state |= CONTROL_PIN_INDEX_FEED_HOLD; }
if (bit_istrue(pin,(1<<CYCLE_START_BIT))) { control_state |= CONTROL_PIN_INDEX_CYCLE_START; }
}
return(control_state);
}
// Pin change interrupt for pin-out commands, i.e. cycle start, feed hold, and reset. Sets // Pin change interrupt for pin-out commands, i.e. cycle start, feed hold, and reset. Sets
// only the realtime command execute variable to have the main program execute these when // only the realtime command execute variable to have the main program execute these when
// its ready. This works exactly like the character-based realtime commands when picked off // its ready. This works exactly like the character-based realtime commands when picked off
// directly from the incoming serial data stream. // directly from the incoming serial data stream.
ISR(CONTROL_INT_vect) ISR(CONTROL_INT_vect)
{ {
uint8_t pin = (CONTROL_PIN & CONTROL_MASK); uint8_t pin = system_control_get_state();
#ifndef INVERT_ALL_CONTROL_PINS
pin ^= CONTROL_INVERT_MASK;
#endif
// Enter only if any CONTROL pin is detected as active.
if (pin) { if (pin) {
if (bit_istrue(pin,bit(RESET_BIT))) { if (bit_istrue(pin,CONTROL_PIN_INDEX_RESET)) {
mc_reset(); mc_reset();
} else if (bit_istrue(pin,bit(CYCLE_START_BIT))) { } else if (bit_istrue(pin,CONTROL_PIN_INDEX_CYCLE_START)) {
bit_true(sys_rt_exec_state, EXEC_CYCLE_START); bit_true(sys_rt_exec_state, EXEC_CYCLE_START);
#ifndef ENABLE_SAFETY_DOOR_INPUT_PIN #ifndef ENABLE_SAFETY_DOOR_INPUT_PIN
} else if (bit_istrue(pin,bit(FEED_HOLD_BIT))) { } else if (bit_istrue(pin,CONTROL_PIN_INDEX_FEED_HOLD)) {
bit_true(sys_rt_exec_state, EXEC_FEED_HOLD); bit_true(sys_rt_exec_state, EXEC_FEED_HOLD);
#else #else
} else if (bit_istrue(pin,bit(SAFETY_DOOR_BIT))) { } else if (bit_istrue(pin,CONTROL_PIN_INDEX_SAFETY_DOOR)) {
bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR); bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR);
#endif #endif
} }
@ -66,11 +84,7 @@ ISR(CONTROL_INT_vect)
uint8_t system_check_safety_door_ajar() uint8_t system_check_safety_door_ajar()
{ {
#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
#ifdef INVERT_CONTROL_PIN return(system_control_get_state() & CONTROL_PIN_INDEX_SAFETY_DOOR);
return(bit_istrue(CONTROL_PIN,bit(SAFETY_DOOR_BIT)));
#else
return(bit_isfalse(CONTROL_PIN,bit(SAFETY_DOOR_BIT)));
#endif
#else #else
return(false); // Input pin not enabled, so just return that it's closed. return(false); // Input pin not enabled, so just return that it's closed.
#endif #endif
@ -275,3 +289,33 @@ void system_convert_array_steps_to_mpos(float *position, int32_t *steps)
} }
return; return;
} }
// Special handlers for setting and clearing Grbl's real-time execution flags.
void system_set_exec_state_flag(uint8_t mask) {
uint8_t sreg = SREG;
cli();
sys_rt_exec_state |= (mask);
SREG = sreg;
}
void system_clear_exec_state_flag(uint8_t mask) {
uint8_t sreg = SREG;
cli();
sys_rt_exec_state &= ~(mask);
SREG = sreg;
}
void system_set_exec_alarm_flag(uint8_t mask) {
uint8_t sreg = SREG;
cli();
sys_rt_exec_alarm |= (mask);
SREG = sreg;
}
void system_clear_exec_alarm_flag(uint8_t mask) {
uint8_t sreg = SREG;
cli();
sys_rt_exec_alarm &= ~(mask);
SREG = sreg;
}

View File

@ -69,13 +69,26 @@
#define SUSPEND_SAFETY_DOOR_AJAR bit(5) // Indicates suspend was initiated by a safety door state. #define SUSPEND_SAFETY_DOOR_AJAR bit(5) // Indicates suspend was initiated by a safety door state.
#define SUSPEND_MOTION_CANCEL bit(6) // Indicates a canceled resume motion. Currently used by probing routine. #define SUSPEND_MOTION_CANCEL bit(6) // Indicates a canceled resume motion. Currently used by probing routine.
// Define step segment generator state flags.
#define STEP_CONTROL_NORMAL_OP 0 #define STEP_CONTROL_NORMAL_OP 0
// #define STEP_CONTROL_RECOMPUTE_ACTIVE_BLOCK bit(0) // #define STEP_CONTROL_RECOMPUTE_ACTIVE_BLOCK bit(0)
#define STEP_CONTROL_END_MOTION bit(1) #define STEP_CONTROL_END_MOTION bit(1)
#define STEP_CONTROL_EXECUTE_HOLD bit(2) #define STEP_CONTROL_EXECUTE_HOLD bit(2)
#define STEP_CONTROL_EXECUTE_PARK bit(3) #define STEP_CONTROL_EXECUTE_PARK bit(3)
// Define control pin index for Grbl internal use. Pin maps may change, but these values don't.
#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
#define N_CONTROL_PIN 4
#define CONTROL_PIN_INDEX_SAFETY_DOOR bit(0)
#define CONTROL_PIN_INDEX_RESET bit(1)
#define CONTROL_PIN_INDEX_FEED_HOLD bit(2)
#define CONTROL_PIN_INDEX_CYCLE_START bit(3)
#else
#define N_CONTROL_PIN 3
#define CONTROL_PIN_INDEX_RESET bit(0)
#define CONTROL_PIN_INDEX_FEED_HOLD bit(1)
#define CONTROL_PIN_INDEX_CYCLE_START bit(2)
#endif
// Define global system variables // Define global system variables
@ -102,6 +115,9 @@ volatile uint8_t sys_rt_exec_alarm; // Global realtime executor bitflag variabl
// Initialize the serial protocol // Initialize the serial protocol
void system_init(); void system_init();
// Returns bitfield of control pin states, organized by CONTROL_PIN_INDEX. (1=triggered, 0=not triggered).
uint8_t system_control_get_state();
// Returns if safety door is open or closed, based on pin state. // Returns if safety door is open or closed, based on pin state.
uint8_t system_check_safety_door_ajar(); uint8_t system_check_safety_door_ajar();
@ -117,4 +133,11 @@ float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx);
// Updates a machine 'position' array based on the 'step' array sent. // Updates a machine 'position' array based on the 'step' array sent.
void system_convert_array_steps_to_mpos(float *position, int32_t *steps); void system_convert_array_steps_to_mpos(float *position, int32_t *steps);
// Special handlers for setting and clearing Grbl's real-time execution flags.
void system_set_exec_state_flag(uint8_t mask);
void system_clear_exec_state_flag(uint8_t mask);
void system_set_exec_alarm_flag(uint8_t mask);
void system_clear_exec_alarm_flag(uint8_t mask);
#endif #endif