v1.1b: Tweaked Bf reports, jogging doc, saved another 160 bytes, minor bug fixes

- Increment to v1.1b due to status report tweak.

- Tweaked the buffer state status reports to show bytes and blocks
available, rather than in use. This does not require knowing the buffer
sizes beforehand. It’s implicit.

- Also, since buffer states are not used by most devs (after
inquiries), it is no longer enabled by default and a status mask option
was added for this.

- Fixed some typos and updated for the report tweak in the
documentation.

- Wrote a joystick implementation concept in the jogging markdown
document. Outlines how to get a low-latency feel to a joystick (and
other input devices).

- Removed XON/XOFF support. It’s not used by anyone because of its
inherent problems. Remains in older versions for reference.

- Added a compile option on how to handle the probe position during a
check mode.

- Fixed a jogging bug. If G93 is the modal state before a jogging
motion, the feed rate did not get calculated correctly. Fixed the issue.

- Refactored some code to save another 160+ bytes. Included an improved
float vector comparison macro and reducing a few large and repetitive
function calls.

- Fixed a probing bug (existing in v0.9 too) where the target positions
were not set correct and error handling was improper.
This commit is contained in:
Sonny Jeon
2016-09-26 22:33:19 -06:00
parent b04faaf0d3
commit d21e06a201
18 changed files with 251 additions and 167 deletions

View File

@ -254,10 +254,10 @@
// NOTE: This feature is new and experimental. Make sure the GUI you are using supports this mode.
#define REPORT_GUI_MODE // Default enabled. Comment to disable.
// The status report change for Grbl v1.0 and after also removed the ability to disable/enable data fields
// from the report. This caused issues for GUI developers, who've had to manage several scenarios and
// configurations. The increased efficiency of the new reporting style allows for all data fields to be
// sent without potential performance issues.
// The status report change for Grbl v1.0 and after also removed the ability to disable/enable most data
// fields from the report. This caused issues for GUI developers, who've had to manage several scenarios
// and configurations. The increased efficiency of the new reporting style allows for all data fields to
// be sent without potential performance issues.
// NOTE: The options below are here only provide a way to disable certain data fields if a unique
// situation demands it, but be aware GUIs may depend on this data. If disabled, it may not be compatible.
#define REPORT_FIELD_BUFFER_STATE // Default enabled. Comment to disable.
@ -453,16 +453,6 @@
// #define RX_BUFFER_SIZE 128 // (1-254) Uncomment to override defaults in serial.h
// #define TX_BUFFER_SIZE 90 // (1-254)
// Toggles XON/XOFF software flow control for serial communications. Not officially supported
// due to problems involving the Atmega8U2 USB-to-serial chips on current Arduinos. The firmware
// on these chips do not support XON/XOFF flow control characters and the intermediate buffer
// in the chips cause latency and overflow problems with standard terminal programs. However,
// using specifically-programmed UI's to manage this latency problem has been confirmed to work.
// As well as, older FTDI FT232RL-based Arduinos(Duemilanove) are known to work with standard
// terminal programs since their firmware correctly manage these XON/XOFF characters. In any
// case, please report any successes to grbl administrators!
// #define ENABLE_XONXOFF // Default disabled. Uncomment to enable.
// A simple software debouncing feature for hard limit switches. When enabled, the interrupt
// monitoring the hard limit switch pins will enable the Arduino's watchdog timer to re-check
// the limit pin state after a delay of about 32msec. This can help with CNC machines with
@ -472,6 +462,10 @@
// work well and are cheap to find) and wire in a low-pass circuit into each limit pin.
// #define ENABLE_SOFTWARE_DEBOUNCE // Default disabled. Uncomment to enable.
// Configures the position after a probing cycle during Grbl's check mode. Disabled sets
// the position to the probe target, when enabled sets the position to the start position.
// #define SET_CHECK_MODE_PROBE_TO_START // Default disabled. Uncomment to enable.
// Force Grbl to check the state of the hard limit switches when the processor detects a pin
// change inside the hard limit ISR routine. By default, Grbl will trigger the hard limits
// alarm upon any pin change, since bouncing switches can cause a state check like this to

View File

@ -47,7 +47,7 @@
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK 0
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK 255 // All enabled
#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
#define DEFAULT_JUNCTION_DEVIATION 0.01 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false
@ -89,7 +89,7 @@
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS))
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK 255 // All enabled
#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
#define DEFAULT_JUNCTION_DEVIATION 0.01 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // true
@ -134,7 +134,7 @@
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS))
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK 255 // All enabled
#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false
@ -179,7 +179,7 @@
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Z_AXIS))
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK 255 // All enabled
#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false
@ -223,7 +223,7 @@
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Z_AXIS))
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK 255 // All enabled
#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.01 // mm
#define DEFAULT_REPORT_INCHES 0 // false
@ -268,7 +268,7 @@
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Y_AXIS))
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK 255 // All enabled
#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false
@ -313,7 +313,7 @@
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Y_AXIS))
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK 255 // All enabled
#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false
@ -356,7 +356,7 @@
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS))
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK 255 // All enabled
#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false
@ -395,7 +395,7 @@
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK 0
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK 255 // All enabled
#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false
@ -434,7 +434,7 @@
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK 0
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK 255 // All enabled
#define DEFAULT_STATUS_REPORT_MASK 1 // MPos enabled
#define DEFAULT_JUNCTION_DEVIATION 0.01 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false

View File

@ -57,15 +57,6 @@ void gc_sync_position()
}
static uint8_t gc_check_same_position(float *pos_a, float *pos_b)
{
uint8_t idx;
for (idx=0; idx<N_AXIS; idx++) {
if (pos_a[idx] != pos_b[idx]) { return(false); }
}
return(true);
}
// Executes one line of 0-terminated G-Code. The line is assumed to contain only uppercase
// characters and signed floating point values (no whitespace). Comments and block delete
// characters have been removed. In this function, all units and positions are converted and
@ -430,35 +421,40 @@ uint8_t gc_execute_line(char *line)
// [2. Set feed rate mode ]: G93 F word missing with G1,G2/3 active, implicitly or explicitly. Feed rate
// is not defined after switching to G94 from G93.
if (gc_block.modal.feed_rate == FEED_RATE_MODE_INVERSE_TIME) { // = G93
// NOTE: G38 can also operate in inverse time, but is undefined as an error. Missing F word check added here.
if (axis_command == AXIS_COMMAND_MOTION_MODE) {
if ((gc_block.modal.motion != MOTION_MODE_NONE) || (gc_block.modal.motion != MOTION_MODE_SEEK)) {
if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } // [F word missing]
// NOTE: For jogging, ignore prior feed rate mode. Enforce G94 and check for required F word.
if (is_jog_motion) {
if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); }
if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.f *= MM_PER_INCH; }
} else {
if (gc_block.modal.feed_rate == FEED_RATE_MODE_INVERSE_TIME) { // = G93
// NOTE: G38 can also operate in inverse time, but is undefined as an error. Missing F word check added here.
if (axis_command == AXIS_COMMAND_MOTION_MODE) {
if ((gc_block.modal.motion != MOTION_MODE_NONE) || (gc_block.modal.motion != MOTION_MODE_SEEK)) {
if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } // [F word missing]
}
}
}
// NOTE: It seems redundant to check for an F word to be passed after switching from G94 to G93. We would
// accomplish the exact same thing if the feed rate value is always reset to zero and undefined after each
// inverse time block, since the commands that use this value already perform undefined checks. This would
// also allow other commands, following this switch, to execute and not error out needlessly. This code is
// combined with the above feed rate mode and the below set feed rate error-checking.
// NOTE: It seems redundant to check for an F word to be passed after switching from G94 to G93. We would
// accomplish the exact same thing if the feed rate value is always reset to zero and undefined after each
// inverse time block, since the commands that use this value already perform undefined checks. This would
// also allow other commands, following this switch, to execute and not error out needlessly. This code is
// combined with the above feed rate mode and the below set feed rate error-checking.
// [3. Set feed rate ]: F is negative (done.)
// - In inverse time mode: Always implicitly zero the feed rate value before and after block completion.
// NOTE: If in G93 mode or switched into it from G94, just keep F value as initialized zero or passed F word
// value in the block. If no F word is passed with a motion command that requires a feed rate, this will error
// out in the motion modes error-checking. However, if no F word is passed with NO motion command that requires
// a feed rate, we simply move on and the state feed rate value gets updated to zero and remains undefined.
} else { // = G94
// - In units per mm mode: If F word passed, ensure value is in mm/min, otherwise push last state value.
if (gc_state.modal.feed_rate == FEED_RATE_MODE_UNITS_PER_MIN) { // Last state is also G94
if (bit_istrue(value_words,bit(WORD_F))) {
if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.f *= MM_PER_INCH; }
} else {
// NOTE: Jogging mode does not pass modal feed rate and requires unique values for each command.
if (!is_jog_motion) { gc_block.values.f = gc_state.feed_rate; } // Push last state feed rate
}
} // Else, switching to G94 from G93, so don't push last state feed rate. Its undefined or the passed F word value.
// [3. Set feed rate ]: F is negative (done.)
// - In inverse time mode: Always implicitly zero the feed rate value before and after block completion.
// NOTE: If in G93 mode or switched into it from G94, just keep F value as initialized zero or passed F word
// value in the block. If no F word is passed with a motion command that requires a feed rate, this will error
// out in the motion modes error-checking. However, if no F word is passed with NO motion command that requires
// a feed rate, we simply move on and the state feed rate value gets updated to zero and remains undefined.
} else { // = G94
// - In units per mm mode: If F word passed, ensure value is in mm/min, otherwise push last state value.
if (gc_state.modal.feed_rate == FEED_RATE_MODE_UNITS_PER_MIN) { // Last state is also G94
if (bit_istrue(value_words,bit(WORD_F))) {
if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.f *= MM_PER_INCH; }
} else {
gc_block.values.f = gc_state.feed_rate; // Push last state feed rate
}
} // Else, switching to G94 from G93, so don't push last state feed rate. Its undefined or the passed F word value.
}
}
// bit_false(value_words,bit(WORD_F)); // NOTE: Single-meaning value word. Set at end of error-checking.
@ -712,7 +708,7 @@ uint8_t gc_execute_line(char *line)
if (value_words & bit(WORD_R)) { // Arc Radius Mode
bit_false(value_words,bit(WORD_R));
if (gc_check_same_position(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target]
if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target]
// Convert radius value to proper units.
if (gc_block.modal.units == UNITS_MODE_INCHES) { gc_block.values.r *= MM_PER_INCH; }
@ -836,7 +832,7 @@ uint8_t gc_execute_line(char *line)
// an error, it issues an alarm to prevent further motion to the probe. It's also done there to
// allow the planner buffer to empty and move off the probe trigger before another probing cycle.
if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words]
if (gc_check_same_position(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target]
if (isequal_position_vector(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target]
break;
}
}
@ -1021,42 +1017,38 @@ uint8_t gc_execute_line(char *line)
gc_state.modal.motion = gc_block.modal.motion;
if (gc_state.modal.motion != MOTION_MODE_NONE) {
if (axis_command == AXIS_COMMAND_MOTION_MODE) {
switch (gc_state.modal.motion) {
case MOTION_MODE_SEEK:
pl_data->condition |= PL_COND_FLAG_RAPID_MOTION; // Set rapid motion condition flag.
mc_line(gc_block.values.xyz, pl_data);
break;
case MOTION_MODE_LINEAR:
mc_line(gc_block.values.xyz, pl_data);
break;
case MOTION_MODE_CW_ARC:
mc_arc(gc_block.values.xyz, pl_data, gc_state.position, gc_block.values.ijk, gc_block.values.r,
axis_0, axis_1, axis_linear, true);
break;
case MOTION_MODE_CCW_ARC:
mc_arc(gc_block.values.xyz, pl_data, gc_state.position, gc_block.values.ijk, gc_block.values.r,
axis_0, axis_1, axis_linear, false);
break;
case MOTION_MODE_PROBE_TOWARD:
// NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So
// upon a successful probing cycle, the machine position and the returned value should be the same.
mc_probe_cycle(gc_block.values.xyz, pl_data, false, false);
break;
case MOTION_MODE_PROBE_TOWARD_NO_ERROR:
mc_probe_cycle(gc_block.values.xyz, pl_data, false, true);
break;
case MOTION_MODE_PROBE_AWAY:
mc_probe_cycle(gc_block.values.xyz, pl_data, true, false);
break;
case MOTION_MODE_PROBE_AWAY_NO_ERROR:
mc_probe_cycle(gc_block.values.xyz, pl_data, true, true);
}
uint8_t gc_update_pos = GC_UPDATE_POS_TARGET;
if (gc_state.modal.motion == MOTION_MODE_LINEAR) {
mc_line(gc_block.values.xyz, pl_data);
} else if (gc_state.modal.motion == MOTION_MODE_SEEK) {
pl_data->condition |= PL_COND_FLAG_RAPID_MOTION; // Set rapid motion condition flag.
mc_line(gc_block.values.xyz, pl_data);
} else if ((gc_state.modal.motion == MOTION_MODE_CW_ARC) || (gc_state.modal.motion == MOTION_MODE_CCW_ARC)) {
uint8_t is_clockwise_arc;
if (gc_state.modal.motion == MOTION_MODE_CW_ARC) { is_clockwise_arc = true; }
else { is_clockwise_arc = false; }
mc_arc(gc_block.values.xyz, pl_data, gc_state.position, gc_block.values.ijk, gc_block.values.r,
axis_0, axis_1, axis_linear, is_clockwise_arc);
} else {
// NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So
// upon a successful probing cycle, the machine position and the returned value should be the same.
uint8_t is_probe_away = false;
uint8_t is_no_error = false;
if ((gc_state.modal.motion == MOTION_MODE_PROBE_AWAY) || (gc_state.modal.motion == MOTION_MODE_PROBE_AWAY_NO_ERROR)) { is_probe_away = true; }
if ((gc_state.modal.motion == MOTION_MODE_PROBE_TOWARD_NO_ERROR) || (gc_state.modal.motion == MOTION_MODE_PROBE_AWAY_NO_ERROR)) { is_no_error = true; }
gc_update_pos = mc_probe_cycle(gc_block.values.xyz, pl_data, is_probe_away, is_no_error);
}
// As far as the parser is concerned, the position is now == target. In reality the
// motion control system might still be processing the action and the real tool position
// in any intermediate location.
memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); // gc_state.position[] = gc_block.values.xyz[]
}
if (gc_update_pos == GC_UPDATE_POS_TARGET) {
memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); // gc_state.position[] = gc_block.values.xyz[]
} else if (gc_update_pos == GC_UPDATE_POS_SYSTEM) {
gc_sync_position(); // gc_state.position[] = sys_position
} // == GC_UPDATE_POS_NONE
}
}
// [21. Program flow ]:

View File

@ -123,7 +123,6 @@
// Modal Group G12: Active work coordinate system
// N/A: Stores coordinate system value (54-59) to change to.
// Define parameter word mapping.
#define WORD_F 0
#define WORD_I 1
@ -139,6 +138,23 @@
#define WORD_Y 11
#define WORD_Z 12
// Define g-code parser position updating flags
#define GC_UPDATE_POS_TARGET 0
#define GC_UPDATE_POS_SYSTEM 1
#define GC_UPDATE_POS_NONE 2
// Define probe cycle exit states and assign proper position updating.
#define GC_PROBE_FOUND GC_UPDATE_POS_SYSTEM
#define GC_PROBE_ABORT GC_UPDATE_POS_NONE
#define GC_PROBE_FAIL_INIT GC_UPDATE_POS_NONE
#define GC_PROBE_FAIL_END GC_UPDATE_POS_TARGET
#ifdef SET_CHECK_MODE_PROBE_TO_START
#define GC_PROBE_CHECK_MODE GC_UPDATE_POS_NONE
#else
#define GC_PROBE_CHECK_MODE GC_UPDATE_POS_TARGET
#endif
// NOTE: When this struct is zeroed, the above defines set the defaults for the system.
typedef struct {

View File

@ -22,8 +22,8 @@
#define grbl_h
// Grbl versioning system
#define GRBL_VERSION "1.1a"
#define GRBL_VERSION_BUILD "20160925"
#define GRBL_VERSION "1.1b"
#define GRBL_VERSION_BUILD "20160926"
// Define standard libraries used by Grbl.
#include <avr/io.h>

View File

@ -237,13 +237,14 @@ void mc_homing_cycle()
// Perform tool length probe cycle. Requires probe switch.
// NOTE: Upon probe failure, the program will be stopped and placed into ALARM state.
void mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t is_probe_away, uint8_t is_no_error)
uint8_t mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t is_probe_away, uint8_t is_no_error)
{
// TODO: Need to update this cycle so it obeys a non-auto cycle start.
if (sys.state == STATE_CHECK_MODE) { return; }
if (sys.state == STATE_CHECK_MODE) { return(GC_PROBE_CHECK_MODE); }
// Finish all queued commands and empty planner buffer before starting probe cycle.
protocol_buffer_synchronize();
if (sys.abort) { return(GC_PROBE_ABORT); } // Return if system reset has been issued.
// Initialize probing control variables
sys.probe_succeeded = false; // Re-initialize probe history before beginning cycle.
@ -254,8 +255,9 @@ void mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t is_probe_a
if ( probe_get_state() ) { // Check probe pin state.
system_set_exec_alarm(EXEC_ALARM_PROBE_FAIL_INITIAL);
protocol_execute_realtime();
probe_configure_invert_mask(false); // Re-initialize invert mask before returning.
return(GC_PROBE_FAIL_INIT); // Nothing else to do but bail.
}
if (sys.abort) { return; } // Return if system reset has been issued.
// Setup and queue probing motion. Auto cycle-start should not start the cycle.
mc_line(target, pl_data);
@ -267,7 +269,7 @@ void mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t is_probe_a
system_set_exec_state_flag(EXEC_CYCLE_START);
do {
protocol_execute_realtime();
if (sys.abort) { return; } // Check for system abort
if (sys.abort) { return(GC_PROBE_ABORT); } // Check for system abort
} while (sys.state != STATE_IDLE);
// Probing cycle complete!
@ -280,8 +282,8 @@ void mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t is_probe_a
sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully.
}
sys_probe_state = PROBE_OFF; // Ensure probe state monitor is disabled.
probe_configure_invert_mask(false); // Re-initialize invert mask.
protocol_execute_realtime(); // Check and execute run-time commands
if (sys.abort) { return; } // Check for system abort
// Reset the stepper and planner buffers to remove the remainder of the probe motion.
st_reset(); // Reset step segment buffer.
@ -290,12 +292,21 @@ void mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t is_probe_a
// TODO: Update the g-code parser code to not require this target calculation but uses a gc_sync_position() call.
// NOTE: The target[] variable updated here will be sent back and synced with the g-code parser.
system_convert_array_steps_to_mpos(target, sys_position);
//!!! This is the problem. Need to set the g-code parser to update the position appropriately.
// - Probe initialization fail: Retain current position.
// - Probe successful: Update new positions across everything, since held before the target.
// - Probe did not contact (alarm or not): Copy original target position as normal
// system_convert_array_steps_to_mpos(target, sys_position);
#ifdef MESSAGE_PROBE_COORDINATES
// All done! Output the probe position as message.
report_probe_parameters();
#endif
if (sys.probe_succeeded) { return(GC_PROBE_FOUND); } // Successful probe cycle.
else { return(GC_PROBE_FAIL_END); } // Failed to trigger probe within travel. With or without error.
}

View File

@ -46,7 +46,7 @@ void mc_dwell(float seconds);
void mc_homing_cycle();
// Perform tool length probe cycle. Requires probe switch.
void mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t is_probe_away, uint8_t is_no_error);
uint8_t mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t is_probe_away, uint8_t is_no_error);
// Plans and executes the single special motion case for parking. Independent of main planner buffer.
void mc_parking_motion(float *parking_target, plan_line_data_t *pl_data);

View File

@ -55,6 +55,7 @@
// #define clear_vector_long(a) memset(a, 0.0, sizeof(long)*N_AXIS)
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define isequal_position_vector(a,b) !(memcmp(a, b, sizeof(float)*N_AXIS))
// Bit field and masking macros
#define bit(n) (1 << n)

View File

@ -487,7 +487,16 @@ void plan_sync_position()
}
// Returns the number of available blocks are in the planner buffer.
uint8_t plan_get_block_buffer_available()
{
if (block_buffer_head >= block_buffer_tail) { return((BLOCK_BUFFER_SIZE-1)-(block_buffer_head-block_buffer_tail)); }
return((block_buffer_tail-block_buffer_head-1));
}
// Returns the number of active blocks are in the planner buffer.
// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h
uint8_t plan_get_block_buffer_count()
{
if (block_buffer_head >= block_buffer_tail) { return(block_buffer_head-block_buffer_tail); }

View File

@ -131,7 +131,11 @@ void plan_sync_position();
// Reinitialize plan with a partially completed block
void plan_cycle_reinitialize();
// Returns the number of available blocks are in the planner buffer.
uint8_t plan_get_block_buffer_available();
// Returns the number of active blocks are in the planner buffer.
// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h
uint8_t plan_get_block_buffer_count();
// Returns the status of the block ring buffer. True, if buffer is full.

View File

@ -725,10 +725,12 @@ void report_realtime_status()
// Returns planner and serial read buffer states.
#ifdef REPORT_FIELD_BUFFER_STATE
printPgmString(PSTR("|Bf:"));
print_uint8_base10(plan_get_block_buffer_count());
serial_write(',');
print_uint8_base10(serial_get_rx_buffer_count());
if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_BUFFER_STATE)) {
printPgmString(PSTR("|Bf:"));
print_uint8_base10(plan_get_block_buffer_available());
serial_write(',');
print_uint8_base10(serial_get_rx_buffer_available());
}
#endif
#ifdef USE_LINE_NUMBERS

View File

@ -33,12 +33,17 @@ uint8_t serial_tx_buffer_head = 0;
volatile uint8_t serial_tx_buffer_tail = 0;
#ifdef ENABLE_XONXOFF
volatile uint8_t flow_ctrl = XON_SENT; // Flow control state variable
#endif
// Returns the number of bytes available in the RX serial buffer.
uint8_t serial_get_rx_buffer_available()
{
uint8_t rtail = serial_rx_buffer_tail; // Copy to limit multiple calls to volatile
if (serial_rx_buffer_head >= rtail) { return(RX_BUFFER_SIZE - (serial_rx_buffer_head-rtail)); }
return((rtail-serial_rx_buffer_head-1));
}
// Returns the number of bytes used in the RX serial buffer.
// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h.
uint8_t serial_get_rx_buffer_count()
{
uint8_t rtail = serial_rx_buffer_tail; // Copy to limit multiple calls to volatile
@ -104,25 +109,14 @@ ISR(SERIAL_UDRE)
{
uint8_t tail = serial_tx_buffer_tail; // Temporary serial_tx_buffer_tail (to optimize for volatile)
#ifdef ENABLE_XONXOFF
if (flow_ctrl == SEND_XOFF) {
UDR0 = XOFF_CHAR;
flow_ctrl = XOFF_SENT;
} else if (flow_ctrl == SEND_XON) {
UDR0 = XON_CHAR;
flow_ctrl = XON_SENT;
} else
#endif
{
// Send a byte from the buffer
UDR0 = serial_tx_buffer[tail];
// Send a byte from the buffer
UDR0 = serial_tx_buffer[tail];
// Update tail position
tail++;
if (tail == TX_RING_BUFFER) { tail = 0; }
// Update tail position
tail++;
if (tail == TX_RING_BUFFER) { tail = 0; }
serial_tx_buffer_tail = tail;
}
serial_tx_buffer_tail = tail;
// Turn off Data Register Empty Interrupt to stop tx-streaming if this concludes the transfer
if (tail == serial_tx_buffer_head) { UCSR0B &= ~(1 << UDRIE0); }
@ -142,13 +136,6 @@ uint8_t serial_read()
if (tail == RX_RING_BUFFER) { tail = 0; }
serial_rx_buffer_tail = tail;
#ifdef ENABLE_XONXOFF
if ((serial_get_rx_buffer_count() < RX_BUFFER_LOW) && flow_ctrl == XOFF_SENT) {
flow_ctrl = SEND_XON;
UCSR0B |= (1 << UDRIE0); // Force TX
}
#endif
return data;
}
}
@ -201,14 +188,6 @@ ISR(SERIAL_RX)
if (next_head != serial_rx_buffer_tail) {
serial_rx_buffer[serial_rx_buffer_head] = data;
serial_rx_buffer_head = next_head;
#ifdef ENABLE_XONXOFF
if ((serial_get_rx_buffer_count() >= RX_BUFFER_FULL) && flow_ctrl == XON_SENT) {
flow_ctrl = SEND_XOFF;
UCSR0B |= (1 << UDRIE0); // Force TX
}
#endif
}
}
}
@ -218,8 +197,4 @@ ISR(SERIAL_RX)
void serial_reset_read_buffer()
{
serial_rx_buffer_tail = serial_rx_buffer_head;
#ifdef ENABLE_XONXOFF
flow_ctrl = XON_SENT;
#endif
}

View File

@ -36,16 +36,6 @@
#define SERIAL_NO_DATA 0xff
#ifdef ENABLE_XONXOFF
#define RX_BUFFER_FULL 96 // XOFF high watermark
#define RX_BUFFER_LOW 64 // XON low watermark
#define SEND_XOFF 1
#define SEND_XON 2
#define XOFF_SENT 3
#define XON_SENT 4
#define XOFF_CHAR 0x13
#define XON_CHAR 0x11
#endif
void serial_init();
@ -58,7 +48,11 @@ uint8_t serial_read();
// Reset and empty data in read buffer. Used by e-stop and reset.
void serial_reset_read_buffer();
// Returns the number of bytes available in the RX serial buffer.
uint8_t serial_get_rx_buffer_available();
// Returns the number of bytes used in the RX serial buffer.
// NOTE: Deprecated. Not used unless classic status reports are enabled in config.h.
uint8_t serial_get_rx_buffer_count();
// Returns the number of bytes used in the TX serial buffer.

View File

@ -51,6 +51,7 @@
#define BITFLAG_RT_STATUS_OVERRIDES bit(7)
#else
#define BITFLAG_RT_STATUS_POSITION_TYPE bit(0)
#define BITFLAG_RT_STATUS_BUFFER_STATE bit(1)
#endif
// Define settings restore bitflags.