Skip to content

Commit b737687

Browse files
committed
Reduced default step pulse length to 5 microseconds.
Added HAL parameter for minimum step pulse length set by driver, used for validation of $0 setting. Changed HAL API signature for outputting step pulses, optimized to allow drivers to only change direction outputs when there is an actual direction change. Improved handling of overrides at end of program when all motion is buffered. Possible fix for issue #714. Some optimizations to allow higher step rates.
1 parent 3d7cb52 commit b737687

20 files changed

+332
-175
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## grblHAL ##
22

3-
Latest build date is 20250320, see the [changelog](changelog.md) for details.
3+
Latest build date is 20250328, see the [changelog](changelog.md) for details.
44

55
> [!NOTE]
66
> A settings reset will be performed on an update of builds prior to 20241208. Backup and restore of settings is recommended.
@@ -89,4 +89,4 @@ G/M-codes not supported by [legacy Grbl](https://github.com/gnea/grbl/wiki) are
8989
Some [plugins](https://github.com/grblHAL/plugins) implements additional M-codes.
9090

9191
---
92-
20250320
92+
20250328

changelog.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,34 @@
11
## grblHAL changelog
22

3+
<a name="20250328">Build 20250328
4+
5+
Core:
6+
7+
* Reduced default step pulse length to 5 microseconds. Added HAL parameter for minimum step pulse length set by driver, used for validation of $0 setting.
8+
9+
* Changed HAL API signature for outputting step pulses, optimized to allow drivers to only change direction outputs when there is an actual direction change.
10+
11+
* Improved handling of overrides at end of program when all motion is buffered. Possible fix for issue [#714](https://github.com/grblHAL/core/discussions/714).
12+
13+
* Some optimizations to allow higher step rates.
14+
15+
Drivers:
16+
17+
* All: updated for core HAL signature change.
18+
19+
* Most: added hardcoded (compile time overridable) minimum step pulse off time, defaults to 2 microseconds. This will limit max. possible step rate with a given step pulse length \(from $0 setting\).
20+
21+
* iMRXT1062, RP2040: reduced minimum step pulse length to 1 microsecond.
22+
23+
* STM32F1xx, STM32F3xx: increased minimum step pulse length to 3.5 microseconds.
24+
25+
* STM32F7xx: reduced minimum step pulse length to 1.5 microsecond, moved critical code run in IRQ context to ITC RAM.
26+
27+
* STM32F1xx, STM32F3xx, STM32F4xx and STM32F7xx: changed to use single timer for step generation, eliminates \(reduces?\) risk for lost steps at very high step rates and reduces jitter.
28+
Added new compile time tuning parameters for interrupt latency used for step pulse timings, board developers may want to check and possibly override these in their board maps.
29+
30+
---
31+
332
<a name="20250320">Build 20250320
433

534
Core:

config.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ Set to \ref On or 1 to enable experimental support for expressions.
530530
Some LinuxCNC extensions are supported, conditionals and subroutines are not.
531531
*/
532532
#if !defined NGC_EXPRESSIONS_ENABLE || defined __DOXYGEN__
533-
#define NGC_EXPRESSIONS_ENABLE Off
533+
#define NGC_EXPRESSIONS_ENABLE On
534534
#endif
535535

536536
/*! \def NGC_PARAMETERS_ENABLE
@@ -1818,15 +1818,15 @@ machine limits this setting, when enabled, keeps them with the limits.
18181818
<br>__NOTE:__ The different MCUs supported have different interrupt latencies
18191819
and some drivers may enable features that are not available on others. This may
18201820
lead to this setting not beeing respected exactly over the supported range.
1821-
Typically drivers are calibrated to be correct for 10 microsecond pulse lengths,
1821+
Typically drivers are calibrated to be correct for 5 microsecond pulse lengths,
18221822
however if a precise pulse length is required it should be measured and
18231823
adjusted either by changing this value or by changing the `STEP_PULSE_LATENCY` symbol
18241824
value that many drivers supports. Note that `STEP_PULSE_LATENCY` symbol is driver
18251825
specific - it is _not_ defined in the core.
18261826
*/
18271827
///@{
18281828
#if !defined DEFAULT_STEP_PULSE_MICROSECONDS || defined __DOXYGEN__
1829-
#define DEFAULT_STEP_PULSE_MICROSECONDS 10.0f
1829+
#define DEFAULT_STEP_PULSE_MICROSECONDS 5.0f
18301830
#endif
18311831
///@}
18321832

crossbar.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void xbar_set_homing_source (void)
117117
}
118118

119119
// Returns limit signals used by homing when home signals are not available.
120-
limit_signals_t xbar_get_homing_source (void)
120+
ISR_CODE limit_signals_t xbar_get_homing_source (void)
121121
{
122122
return home_source;
123123
}

driver_opts2.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@
4949
#error "MPG_MODE_PIN must be defined!"
5050
#endif
5151

52-
#if KEYPAD_ENABLE == 1 && !defined(I2C_STROBE_PORT)
52+
#if KEYPAD_ENABLE == 1 && !defined(I2C_STROBE_PIN)
5353
#error Keypad plugin not supported!
54-
#elif I2C_STROBE_ENABLE && !defined(I2C_STROBE_PORT)
54+
#elif I2C_STROBE_ENABLE && !defined(I2C_STROBE_PIN)
5555
#error "I2C strobe not supported!"
5656
#endif
5757

gcode.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3821,8 +3821,7 @@ status_code_t gc_execute_block (char *block)
38213821

38223822
mc_line(gc_block.values.xyz, &plan_data);
38233823

3824-
protocol_buffer_synchronize(); // Wait until synchronized move is finished,
3825-
sys.override.control = overrides; // then restore previous override disable status.
3824+
mc_override_ctrl_update(overrides); // Wait until synchronized move is finished, then restore previous override disable status.
38263825
}
38273826
break;
38283827

@@ -3838,7 +3837,7 @@ status_code_t gc_execute_block (char *block)
38383837

38393838
mc_thread(&plan_data, gc_state.position, &thread, overrides.feed_hold_disable);
38403839

3841-
sys.override.control = overrides; // then restore previous override disable status.
3840+
mc_override_ctrl_update(overrides); // Wait until synchronized move is finished, then restore previous override disable status.
38423841
}
38433842
break;
38443843

@@ -3889,9 +3888,7 @@ status_code_t gc_execute_block (char *block)
38893888
// [21. Program flow ]:
38903889
// M0,M1,M2,M30,M60: Perform non-running program flow actions. During a program pause, the buffer may
38913890
// refill and can only be resumed by the cycle start run-time command.
3892-
gc_state.modal.program_flow = gc_block.modal.program_flow;
3893-
3894-
if(gc_state.modal.program_flow || sys.flags.single_block) {
3891+
if((gc_state.modal.program_flow = gc_block.modal.program_flow) || sys.flags.single_block) {
38953892

38963893
protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on.
38973894

grbl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
#else
4343
#define GRBL_VERSION "1.1f"
4444
#endif
45-
#define GRBL_BUILD 20250317
45+
#define GRBL_BUILD 20250328
4646

4747
#define GRBL_URL "https://github.com/grblHAL"
4848

@@ -52,7 +52,7 @@
5252
#ifdef GRBL_ESP32
5353
#include "esp_attr.h"
5454
#define ISR_CODE IRAM_ATTR
55-
#else
55+
#elif !defined(ISR_CODE)
5656
// #define ISR_CODE __attribute__((long_call, section(".data")))
5757
// Used to decorate code run in interrupt context.
5858
// Do not remove or change unless you know what you are doing.

grbllib.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ int grbl_enter (void)
212212
hal.irq_disable = dummy_handler;
213213
hal.irq_claim = dummy_irq_claim;
214214
hal.nvs.size = GRBL_NVS_SIZE;
215+
hal.step_us_min = 2.0f;
215216
hal.coolant_cap.flood = On;
216217
hal.limits.interrupt_callback = limit_interrupt_handler;
217218
hal.control.interrupt_callback = control_interrupt_handler;
@@ -536,7 +537,7 @@ ISR_CODE bool ISR_FUNC(task_add_delayed)(foreground_task_ptr fn, void *data, uin
536537
return task != NULL;
537538
}
538539

539-
void task_delete (foreground_task_ptr fn, void *data)
540+
ISR_CODE void task_delete (foreground_task_ptr fn, void *data)
540541
{
541542
core_task_t *task, *prev = NULL;
542543

hal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ typedef struct {
562562
char *driver_url; //!< Pointer to optional URL for the driver.
563563
char *board; //!< Pointer to optional board name string.
564564
char *board_url; //!< Pointer to optional URL for the board.
565+
float step_us_min; //!< Minimum step pulse width (microseconds).
565566
uint32_t f_step_timer; //!< Frequency of main stepper timer in Hz.
566567
uint32_t f_mcu; //!< Frequency of MCU in MHz.
567568
uint32_t rx_buffer_size; //!< Input stream buffer size in bytes.

nuts_bolts.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,30 @@ typedef union {
138138
};
139139
} axes_signals_t;
140140

141+
typedef union {
142+
int32_t value[N_AXIS];
143+
struct {
144+
int32_t x;
145+
int32_t y;
146+
int32_t z;
147+
#ifdef A_AXIS
148+
int32_t a;
149+
#endif
150+
#ifdef B_AXIS
151+
int32_t b;
152+
#endif
153+
#ifdef C_AXIS
154+
int32_t c;
155+
#endif
156+
#ifdef U_AXIS
157+
int32_t u;
158+
#endif
159+
#ifdef V_AXIS
160+
int32_t v;
161+
#endif
162+
};
163+
} mpos_t;
164+
141165
typedef union {
142166
float values[2];
143167
struct {

planner.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,8 @@ static inline float limit_max_rate_by_axis_maximum (float *unit_vec)
394394
to execute the special system motion. */
395395
bool plan_buffer_line (float *target, plan_line_data_t *pl_data)
396396
{
397+
static axes_signals_t direction = {};
398+
397399
// Prepare and initialize new block. Copy relevant pl_data for block execution.
398400
plan_block_t *block = block_buffer_head;
399401
int32_t target_steps[N_AXIS], position_steps[N_AXIS], delta_steps;
@@ -427,23 +429,25 @@ bool plan_buffer_line (float *target, plan_line_data_t *pl_data)
427429

428430
target_steps[idx] = lroundf(target[idx] * settings.axis[idx].steps_per_mm);
429431
if((delta_steps = target_steps[idx] - position_steps[idx])) {
430-
block->steps[idx] = labs(delta_steps);
431-
block->step_event_count = max(block->step_event_count, block->steps[idx]);
432+
block->steps.value[idx] = labs(delta_steps);
433+
block->step_event_count = max(block->step_event_count, block->steps.value[idx]);
432434
unit_vec[idx] = (float)delta_steps / settings.axis[idx].steps_per_mm; // Store unit vector numerator
435+
// Set direction bits. Bit enabled always means direction is negative.
436+
if(delta_steps < 0)
437+
direction.bits |= bit(idx);
438+
else
439+
direction.bits &= ~bit(idx);
433440
#if N_AXIS > 3 && ROTARY_FIX
434441
motion.mask |= bit(idx);
435442
#endif
436443
} else {
437-
block->steps[idx] = 0;
444+
block->steps.value[idx] = 0;
438445
unit_vec[idx] = 0.0f; // Store unit vector numerator
439446
}
440-
441-
// Set direction bits. Bit enabled always means direction is negative.
442-
if (delta_steps < 0)
443-
block->direction_bits.mask |= bit(idx);
444-
445447
} while(idx);
446448

449+
block->direction = direction;
450+
447451
// Calculate RPMs to be used for Constant Surface Speed (CSS) calculations.
448452
if(block->spindle.css) {
449453

planner.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
Part of grblHAL
55
6-
Copyright (c) 2019-2024 Terje Io
6+
Copyright (c) 2019-2025 Terje Io
77
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
88
Copyright (c) 2009-2011 Simen Svale Skogsrud
99
@@ -43,14 +43,38 @@ typedef union {
4343
};
4444
} planner_cond_t;
4545

46+
typedef union {
47+
uint32_t value[N_AXIS];
48+
struct {
49+
uint32_t x;
50+
uint32_t y;
51+
uint32_t z;
52+
#ifdef A_AXIS
53+
uint32_t a;
54+
#endif
55+
#ifdef B_AXIS
56+
uint32_t b;
57+
#endif
58+
#ifdef C_AXIS
59+
uint32_t c;
60+
#endif
61+
#ifdef U_AXIS
62+
uint32_t u;
63+
#endif
64+
#ifdef V_AXIS
65+
uint32_t v;
66+
#endif
67+
};
68+
} steps_t;
69+
4670
// This struct stores a linear movement of a g-code block motion with its critical "nominal" values
4771
// are as specified in the source g-code.
4872
typedef struct plan_block {
4973
// Fields used by the bresenham algorithm for tracing the line
5074
// NOTE: Used by stepper algorithm to execute the block correctly. Do not alter these values.
51-
uint32_t steps[N_AXIS]; // Step count along each axis
75+
steps_t steps; // Step count along each axis
5276
uint32_t step_event_count; // The maximum step axis count and number of steps required to complete this block.
53-
axes_signals_t direction_bits; // The direction bit set for this block (refers to *_DIRECTION_PIN in config.h)
77+
axes_signals_t direction; // The direction bit set for this block (refers to *_DIRECTION_PIN in config.h)
5478

5579
offset_id_t offset_id;
5680
// Block condition data to ensure correct execution depending on states and overrides.

protocol.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ static bool recheck_line (char *line, line_flags_t *flags)
138138
}
139139

140140
/*
141-
GRBL PRIMARY LOOP:
141+
grblHAL PRIMARY LOOP:
142142
*/
143143
bool protocol_main_loop (void)
144144
{
@@ -274,8 +274,15 @@ bool protocol_main_loop (void)
274274
}
275275
} else if(*line == '[' && grbl.on_user_command)
276276
gc_state.last_error = grbl.on_user_command(line);
277-
else if (state_get() & (STATE_ALARM|STATE_ESTOP|STATE_JOG)) // Everything else is gcode. Block if in alarm, eStop or jog mode.
278-
gc_state.last_error = Status_SystemGClock;
277+
else if(state_get() & (STATE_ALARM|STATE_ESTOP|STATE_JOG)) { // Everything else is gcode. Block if in alarm, eStop or jog mode.
278+
if(*line == CMD_PROGRAM_DEMARCATION && line[1] == '\0' && (state_get() & (STATE_ALARM|STATE_ESTOP))) {
279+
gc_state.file_run = !gc_state.file_run;
280+
gc_state.last_error = Status_OK;
281+
if(grbl.on_file_demarcate)
282+
grbl.on_file_demarcate(gc_state.file_run);
283+
} else
284+
gc_state.last_error = Status_SystemGClock;
285+
}
279286
#if COMPATIBILITY_LEVEL == 0
280287
else if(gc_state.last_error == Status_OK || gc_state.last_error == Status_GcodeToolChangePending) { // Parse and execute g-code block.
281288
#else
@@ -383,7 +390,7 @@ bool protocol_buffer_synchronize (void)
383390
// If system is queued, ensure cycle resumes if the auto start flag is present.
384391
protocol_auto_cycle_start();
385392

386-
sys.flags.synchronizing = On;
393+
sys.flags.synchronizing = gc_state.modal.program_flow == ProgramFlow_Running;
387394
while ((ok = protocol_execute_realtime()) && (plan_get_current_block() || state_get() == STATE_CYCLE));
388395
sys.flags.synchronizing = Off;
389396

report.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,9 +1338,11 @@ void report_realtime_status (void)
13381338

13391339
if (override_counter > 0 && !report.overrides)
13401340
override_counter--;
1341-
else if((report.overrides = !report.wco)) {
1342-
report.spindle = report.spindle || spindle_0_state.on;
1343-
report.coolant = report.coolant || hal.coolant.get_state().value != 0;
1341+
else {
1342+
if((report.overrides = !report.wco)) {
1343+
report.spindle = report.spindle || spindle_0_state.on;
1344+
report.coolant = report.coolant || hal.coolant.get_state().value != 0;
1345+
}
13441346
override_counter = state & (STATE_HOMING|STATE_CYCLE|STATE_HOLD|STATE_JOG|STATE_SAFETY_DOOR)
13451347
? (REPORT_OVERRIDE_REFRESH_BUSY_COUNT - 1) // Reset counter for slow refresh
13461348
: (REPORT_OVERRIDE_REFRESH_IDLE_COUNT - 1);

0 commit comments

Comments
 (0)