25 #define DT_SEGMENT (1.0/(ACCELERATION_TICKS_PER_SECOND*60.0))
26 #define REQ_MM_INCREMENT_SCALAR 1.25
30 #define RAMP_DECEL_OVERRIDE 3
32 #define PREP_FLAG_RECALCULATE bit(0)
33 #define PREP_FLAG_HOLD_PARTIAL_BLOCK bit(1)
34 #define PREP_FLAG_PARKING bit(2)
35 #define PREP_FLAG_DECEL_OVERRIDE bit(3)
49 #define MAX_AMASS_LEVEL 3
51 #define AMASS_LEVEL1 (F_CPU/8000)
52 #define AMASS_LEVEL2 (F_CPU/4000)
53 #define AMASS_LEVEL3 (F_CPU/2000)
77 #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
92 #ifdef STEP_PULSE_DELAY
100 #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
111 static volatile uint8_t segment_buffer_tail;
112 static uint8_t segment_buffer_head;
113 static uint8_t segment_next_head;
115 static uint8_t step_port_invert_mask;
116 static uint8_t dir_port_invert_mask;
118 static volatile uint8_t busy;
134 #ifdef PARKING_ENABLE
135 uint8_t last_st_block_index;
136 float last_steps_remaining;
137 float last_step_per_mm;
138 float last_dt_remainder;
203 else { STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT); }
209 #ifdef STEP_PULSE_DELAY
215 // Set step pulse time. Ad hoc computation from oscilloscope. Uses two's complement.
220 TIMSK1 |= (1<<OCIE1A);
227 TIMSK1 &= ~(1<<OCIE1A);
228 TCCR1B = (TCCR1B & ~((1<<CS12) | (1<<CS11))) | (1<<CS10);
232 bool pin_state =
false;
240 if (pin_state) { STEPPERS_DISABLE_PORT |= (1<<STEPPERS_DISABLE_BIT); }
241 else { STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT); }
306 if (busy) {
return; }
312 #ifdef STEP_PULSE_DELAY
313 st.step_bits = (STEP_PORT & ~STEP_MASK) | st.
step_outbits;
330 if (segment_buffer_head != segment_buffer_tail) {
334 #ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
336 TCCR1B = (TCCR1B & ~(0x07<<CS10)) | (st.
exec_segment->prescaler<<CS10);
353 #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
381 #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
392 #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
403 #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
447 STEP_PORT_SET((STEP_PORT & ~STEP_MASK) | (step_port_invert_mask & STEP_MASK));
450 #ifdef STEP_PULSE_DELAY
457 ISR(TIMER0_COMPA_vect)
467 step_port_invert_mask = 0;
468 dir_port_invert_mask = 0;
469 for (idx=0; idx<
N_AXIS; idx++) {
486 segment_buffer_tail = 0;
487 segment_buffer_head = 0;
488 segment_next_head = 1;
495 STEP_PORT_SET((STEP_PORT & ~STEP_MASK) | step_port_invert_mask);
503 STEP_DDR |= STEP_MASK;
504 STEPPERS_DISABLE_DDR |= 1<<STEPPERS_DISABLE_BIT;
505 DIRECTION_DDR |= DIRECTION_MASK;
508 TCCR1B &= ~(1<<WGM13);
509 TCCR1B |= (1<<WGM12);
510 TCCR1A &= ~((1<<WGM11) | (1<<WGM10));
511 TCCR1A &= ~((1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0));
516 TIMSK0 &= ~((1<<OCIE0B) | (1<<OCIE0A) | (1<<TOIE0));
519 TIMSK0 |= (1<<TOIE0);
520 #ifdef STEP_PULSE_DELAY
521 TIMSK0 |= (1<<OCIE0A);
528 if (pl_block != NULL) {
536 static uint8_t st_next_block_index(uint8_t block_index)
544 #ifdef PARKING_ENABLE
567 st_prep_block = &st_block_buffer[prep.last_st_block_index];
599 while (segment_buffer_tail != segment_next_head) {
602 if (pl_block == NULL) {
607 if (pl_block == NULL) {
return; }
612 #ifdef PARKING_ENABLE
630 #ifndef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
631 for (idx=0; idx<
N_AXIS; idx++) { st_prep_block->
steps[idx] = pl_block->
steps[idx]; }
682 if (decel_dist < 0.0) {
694 float exit_speed_sqr;
704 float nominal_speed_sqr = nominal_speed*nominal_speed;
705 float intersect_distance =
729 }
else if (intersect_distance > 0.0) {
730 if (intersect_distance < pl_block->millimeters) {
763 segment_t *prep_segment = &segment_buffer[segment_buffer_head];
784 float time_var = dt_max;
789 if (minimum_mm < 0.0) { minimum_mm = 0.0; }
796 mm_remaining -= mm_var;
810 mm_remaining -= time_var*(prep.
current_speed + 0.5*speed_var);
833 mm_remaining = mm_var;
841 mm_var = mm_remaining - time_var*(prep.
current_speed - 0.5*speed_var);
843 mm_remaining = mm_var;
854 if (dt < dt_max) { time_var = dt_max - dt; }
856 if (mm_remaining > minimum_mm) {
860 time_var = dt_max - dt;
899 float step_dist_remaining = prep.
step_per_mm*mm_remaining;
900 float n_steps_remaining = ceil(step_dist_remaining);
902 prep_segment->
n_step = last_n_steps_remaining-n_steps_remaining;
905 if (prep_segment->
n_step == 0) {
910 #ifdef PARKING_ENABLE
926 float inv_rate = dt/(last_n_steps_remaining - step_dist_remaining);
931 #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
946 if (cycles < (1UL << 16)) {
947 prep_segment->prescaler = 1;
949 }
else if (cycles < (1UL << 19)) {
950 prep_segment->prescaler = 2;
953 prep_segment->prescaler = 3;
954 if (cycles < (1UL << 22)) {
963 segment_buffer_head = segment_next_head;
969 prep.
dt_remainder = (n_steps_remaining - step_dist_remaining)*inv_rate;
974 if (mm_remaining > 0.0) {
979 #ifdef PARKING_ENABLE
void st_parking_restore_buffer()
Restores the step segment buffer to the normal run state after a parking motion.
#define BITFLAG_INVERT_ST_ENABLE
#define AMASS_LEVEL1
Over-drives ISR (x2). Defined as F_CPU/(Cutoff frequency in Hz)
volatile uint8_t sys_probe_state
Probing state value. Used to coordinate the probing cycle with stepper ISR.
float accelerate_until
Acceleration ramp end measured from end of block (mm)
float exit_speed
Exit speed of executing block (mm/min)
plan_block_t * plan_get_current_block()
Returns address of first planner block, if available. Called by various main program functions...
void st_parking_setup_buffer()
Changes the run state of the step segment buffer to execute the special parking motion.
if(axis_words)
STEP 3: Error-check all commands and values passed in this block. This step ensures all of the comma...
float programmed_rate
Programmed rate of this block (mm/min).
void probe_state_monitor()
Monitors probe pin state and records the system position when detected. Called by the...
#define N_AXIS
Axis array index values. Must start with 0 and be continuous.
#define SEGMENT_BUFFER_SIZE
float mm_complete
End of velocity profile from end of current planner block in (mm).
Primary stepper segment ring buffer. Contains small, short line segments for the stepper.
#define STATE_HOLD
Active feed hold.
uint16_t current_spindle_pwm
uint16_t spindle_compute_pwm_value(float rpm)
Called by spindle_set_state() and step segment generator. Keep routine small and efficient.
#define bit_true(x, mask)
#define STEP_CONTROL_UPDATE_SPINDLE_PWM
#define RAMP_DECEL_OVERRIDE
uint8_t st_block_index
Index of stepper common data block being prepped.
uint8_t direction_bits
The direction bit set for this block (refers to *_DIRECTION_BIT in config.h)
void system_set_exec_state_flag(uint8_t mask)
Special handlers for setting and clearing Grbl's real-time execution flags.
Stores the planner block Bresenham algorithm execution data for the segments in the segment...
uint32_t step_event_count
#define EXEC_CYCLE_STOP
bitmask 00000100
#define PROBE_ACTIVE
Actively watching the input pin.
#define PREP_FLAG_RECALCULATE
float plan_compute_profile_nominal_speed(plan_block_t *block)
Computes and returns block nominal speed based on running condition and override values.
float current_speed
Current speed at the end of the segment buffer (mm/min)
void stepper_init()
Initialize and start the stepper motor subsystem.
uint32_t counter_x
Counter variables for the bresenham line tracer.
uint16_t cycles_per_tick
Step distance traveled per ISR tick, aka step rate.
uint8_t st_block_index
Stepper block data index. Uses this information to execute this segment.
#define PL_COND_FLAG_SPINDLE_CW
volatile uint8_t sys_rt_exec_alarm
Global realtime executor bitflag variable for setting various alarms.
segment_t * exec_segment
Pointer to the segment being executed.
float st_get_realtime_rate()
Called by realtime status reporting to fetch the current speed being executed. This value...
uint8_t condition
Block bitflag variable defining block run conditions. Copied from pl_line_data.
#define PREP_FLAG_DECEL_OVERRIDE
uint8_t execute_step
Flags step execution for each interrupt.
uint8_t state
Tracks the current system state of Grbl.
float plan_get_exec_block_exit_speed_sqr()
Called by step segment buffer when computing executing block velocity profile.
#define STEP_CONTROL_EXECUTE_HOLD
float entry_speed_sqr
The current planned entry speed at block junction in (mm/min)^2.
float millimeters
The remaining distance for this block to be executed in (mm).
#define BITFLAG_LASER_MODE
Stepper ISR data struct. Contains the running data for the main stepper ISR.
float acceleration
Axis-limit adjusted line acceleration in (mm/min^2). Does not change.
Segment preparation data struct. Contains all the necessary information to compute new segments...
uint8_t get_direction_pin_mask(uint8_t axis_idx)
Returns direction pin mask according to Grbl internal axis indexing.
#define X_AXIS
Axis indexing value.
float spindle_speed
Block spindle speed. Copied from pl_line_data.
#define bit(n)
Bit field and masking macros.
plan_block_t * plan_get_system_motion_block()
Returns address of planner buffer block used by system motions. Called by segment generator...
#define STATE_SLEEP
Sleep state.
#define STATE_CYCLE
Cycle is running or motions are being executed.
uint8_t flags
Contains default boolean settings.
#define AMASS_LEVEL2
Over-drives ISR (x4)
#define DT_SEGMENT
Some useful constants.
uint8_t exec_block_index
Tracks the current st_block index. Change indicates new block.
system_t sys
Declare system global variable structure.
int32_t sys_position[N_AXIS]
NOTE: These position variables may need to be declared as volatiles, if problems arise.
void spindle_set_speed(uint16_t pwm_value)
Sets spindle speed PWM output and enable pin, if configured. Called by spindle_set_state() ...
void st_go_idle()
Stepper shutdown.
ISR(TIMER1_COMPA_vect)
"The Stepper Driver Interrupt" - This timer interrupt is the workhorse of Grbl.
uint8_t step_control
Governs the step segment generator depending on system state.
void st_prep_buffer()
Prepares step segment buffer. Continuously called from main program.
#define PREP_FLAG_PARKING
void plan_discard_current_block()
Called when the current block is no longer needed. Discards the block and makes the memory...
void st_wake_up()
BLOCK VELOCITY PROFILE DEFINITION.
uint8_t get_step_pin_mask(uint8_t axis_idx)
Returns step pin mask according to Grbl internal axis indexing.
float inv_rate
Used by PWM laser mode to speed up segment calculations.
uint32_t step_event_count
The maximum step axis count and number of steps required to complete this block.
#define PREP_FLAG_HOLD_PARTIAL_BLOCK
#define STEP_PORT_SET(i)
The cpu_map.h files serve as a central pin mapping selection file for different processor types or al...
memset(pl_data, 0, sizeof(plan_line_data_t))
Zero pl_data struct.
uint8_t homing_axis_lock
Locks axes when limits engage. Used as an axis motion mask in the stepper ISR.
float decelerate_after
Deceleration ramp start measured from end of block (mm)
#define MAX_AMASS_LEVEL
Define Adaptive Multi-Axis Step-Smoothing(AMASS) levels and cutoff frequencies. The highest level...
uint8_t pulse_microseconds
#define DIRECTION_PORT_SET(i)
uint8_t ramp_type
Current segment ramp state.
#define AMASS_LEVEL3
Over-drives ISR (x8)
uint8_t step_pulse_time
Step pulse reset time after step rise.
#define bit_false(x, mask)
#define STEP_CONTROL_END_MOTION
uint16_t step_count
Steps remaining in line segment motion.
float maximum_speed
Maximum speed of executing block. Not always nominal speed. (mm/min)
#define STATE_JOG
Jogging mode.
#define STATE_HOMING
Performing homing cycle.
uint16_t n_step
Number of step events to be executed for this segment.
st_block_t * exec_block
Pointer to the block data for the segment being executed.
uint8_t step_outbits
The next stepping-bits to be output.
This struct stores a linear movement of a g-code block motion with its critical "nominal" values...
void st_update_plan_block_parameters()
Called by planner_recalculate() when the executing block is updated by the new plan.
#define STEP_CONTROL_EXECUTE_SYS_MOTION
void delay_ms(uint16_t ms)
Delays variable defined milliseconds. Compiler compatibility fix for _delay_ms(),.
uint32_t steps[N_AXIS]
NOTE: Used by stepper algorithm to execute the block correctly. Do not alter these values...
#define PL_COND_FLAG_SPINDLE_CCW
uint8_t is_pwm_rate_adjusted
Tracks motions that require constant laser power/rate.
void st_generate_step_dir_invert_masks()
Generates the step and direction port invert masks used in the Stepper Interrupt Driver.
uint8_t amass_level
Indicates AMASS level for the ISR to execute this segment.
#define TICKS_PER_MICROSECOND
void st_reset()
Reset and clear stepper subsystem variables.
uint8_t stepper_idle_lock_time
If max value 255, steppers do not disable.
#define REQ_MM_INCREMENT_SCALAR
#define bit_istrue(x, mask)
#define STATE_SAFETY_DOOR
Safety door is ajar. Feed holds and de-energizes system.