diff --git a/README.md b/README.md
index 81ddca8..ee4da54 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa
---
-Latest build date is 20231210, see the [changelog](changelog.md) for details.
+Latest build date is 20231216, see the [changelog](changelog.md) for details.
__NOTE:__ A settings reset will be performed on an update of builds earlier than 20230125. Backup and restore of settings is recommended.
---
diff --git a/changelog.md b/changelog.md
index e7bd105..479b80f 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,20 @@
## grblHAL changelog
+Build 20231216
+
+Core:
+
+* Refactored canned cycles to better match how LinuxCNC actually implements them. Ref. [ioSender issue 348](https://github.com/terjeio/ioSender/issues/348).
+__NOTE:__ The implementation may still be incorrect - use with care!
+
+Drivers:
+
+* SAM3X8E: added laser plugins.
+
+* LPC176x: added laser and spindle plugins.
+
+---
+
Build 20231210
Core:
diff --git a/crossbar.h b/crossbar.h
index 19b323c..271dfc6 100644
--- a/crossbar.h
+++ b/crossbar.h
@@ -70,6 +70,7 @@ typedef enum {
Input_RX,
Input_KeypadStrobe, // To be deprecated? Use Input_I2CStrobe instead.
Input_I2CStrobe,
+ Input_SdCardDetect,
Input_QEI_A,
Input_QEI_B,
Input_QEI_Select,
@@ -217,6 +218,7 @@ PROGMEM static const pin_name_t pin_names[] = {
{ .function = Input_RX, .name = "RX" },
{ .function = Input_KeypadStrobe, .name = "Keypad strobe" },
{ .function = Input_I2CStrobe, .name = "I2C strobe" },
+ { .function = Input_SdCardDetect, .name = "SD card detect" },
{ .function = Input_QEI_A, .name = "QEI A" },
{ .function = Input_QEI_B, .name = "QEI B" },
{ .function = Input_QEI_Select, .name = "QEI select" },
diff --git a/gcode.c b/gcode.c
index e727ee0..39405ac 100644
--- a/gcode.c
+++ b/gcode.c
@@ -2494,7 +2494,6 @@ status_code_t gc_execute_block (char *block)
gc_state.canned.xyz[plane.axis_1] = 0.0f;
gc_state.canned.rapid_retract = On;
gc_state.canned.spindle_off = Off;
- gc_state.canned.prev_position = gc_state.position[plane.axis_linear];
}
if(!gc_block.words.l)
diff --git a/gcode.h b/gcode.h
index 856a9e5..e399bd1 100644
--- a/gcode.h
+++ b/gcode.h
@@ -478,7 +478,6 @@ typedef struct {
float xyz[3];
float delta;
float dwell;
- float prev_position;
float retract_position; //!< Canned cycle retract position
bool rapid_retract;
bool spindle_off;
diff --git a/grbl.h b/grbl.h
index 3c74805..ca7c987 100644
--- a/grbl.h
+++ b/grbl.h
@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
-#define GRBL_BUILD 20231210
+#define GRBL_BUILD 20231216
#define GRBL_URL "https://github.com/grblHAL"
diff --git a/motion_control.c b/motion_control.c
index 21fb0fd..7db630b 100644
--- a/motion_control.c
+++ b/motion_control.c
@@ -570,35 +570,35 @@ void mc_canned_drill (motion_mode_t motion, float *target, plan_line_data_t *pl_
return;
}
+ float position_linear = position[plane.axis_linear],
+ retract_to = canned->retract_mode == CCRetractMode_RPos ? canned->retract_position : position_linear;
+
// rapid move to X, Y
memcpy(position, target, sizeof(float) * N_AXIS);
- position[plane.axis_linear] = canned->prev_position > canned->retract_position ? canned->prev_position : canned->retract_position;
+ position[plane.axis_linear] = position_linear;
if(!mc_line(position, pl_data))
return;
- // if current Z > R, rapid move to R
- if(position[plane.axis_linear] > canned->retract_position) {
- position[plane.axis_linear] = canned->retract_position;
- if(!mc_line(position, pl_data))
- return;
- }
-
- if(canned->retract_mode == CCRetractMode_RPos)
- canned->prev_position = canned->retract_position;
-
while(repeats--) {
- float current_z = canned->retract_position;
+ // if current Z > R, rapid move to R
+ if(position[plane.axis_linear] > canned->retract_position) {
+ position[plane.axis_linear] = canned->retract_position;
+ if(!mc_line(position, pl_data))
+ return;
+ }
- while(current_z > canned->xyz[plane.axis_linear]) {
+ position_linear = position[plane.axis_linear];
- current_z -= canned->delta;
- if(current_z < canned->xyz[plane.axis_linear])
- current_z = canned->xyz[plane.axis_linear];
+ while(position_linear > canned->xyz[plane.axis_linear]) {
+
+ position_linear -= canned->delta;
+ if(position_linear < canned->xyz[plane.axis_linear])
+ position_linear = canned->xyz[plane.axis_linear];
pl_data->condition.rapid_motion = Off;
- position[plane.axis_linear] = current_z;
+ position[plane.axis_linear] = position_linear;
if(!mc_line(position, pl_data)) // drill
return;
@@ -613,12 +613,12 @@ void mc_canned_drill (motion_mode_t motion, float *target, plan_line_data_t *pl_
case MotionMode_DrillChipBreak:
position[plane.axis_linear] = position[plane.axis_linear] == canned->xyz[plane.axis_linear]
- ? canned->retract_position
+ ? retract_to
: position[plane.axis_linear] + settings.g73_retract;
break;
default:
- position[plane.axis_linear] = canned->retract_position;
+ position[plane.axis_linear] = retract_to;
break;
}
@@ -630,6 +630,8 @@ void mc_canned_drill (motion_mode_t motion, float *target, plan_line_data_t *pl_
spindle_sync(pl_data->spindle.hal, gc_state.modal.spindle.state, pl_data->spindle.rpm);
}
+ pl_data->condition.rapid_motion = On; // Set rapid motion condition flag.
+
// rapid move to next position if incremental mode
if(repeats && gc_state.modal.distance_incremental) {
position[plane.axis_0] += canned->xyz[plane.axis_0];
@@ -640,13 +642,6 @@ void mc_canned_drill (motion_mode_t motion, float *target, plan_line_data_t *pl_
}
memcpy(target, position, sizeof(float) * N_AXIS);
-
- if(canned->retract_mode == CCRetractMode_Previous && motion != MotionMode_DrillChipBreak && target[plane.axis_linear] < canned->prev_position) {
- pl_data->condition.rapid_motion = On;
- target[plane.axis_linear] = canned->prev_position;
- if(!mc_line(target, pl_data))
- return;
- }
}
// Calculates depth-of-cut (DOC) for a given threading pass.
diff --git a/report.c b/report.c
index dcb6869..9267e81 100644
--- a/report.c
+++ b/report.c
@@ -699,7 +699,7 @@ void report_gcode_modes (void)
hal.stream.write(gc_state.modal.tool_offset_mode == ToolLengthOffset_EnableDynamic ? ".1" : ".2");
}
- hal.stream.write(gc_state.canned.retract_mode == CCRetractMode_RPos ? " G99" : " G98");
+ hal.stream.write(gc_state.modal.retract_mode == CCRetractMode_RPos ? " G99" : " G98");
if(gc_state.modal.scaling_active) {
hal.stream.write(" G51:");