diff --git a/Grbl_Esp32/Custom/polar_coaster.cpp b/Grbl_Esp32/Custom/polar_coaster.cpp index 777113a2..157f98ec 100644 --- a/Grbl_Esp32/Custom/polar_coaster.cpp +++ b/Grbl_Esp32/Custom/polar_coaster.cpp @@ -105,7 +105,7 @@ void inverse_kinematics(float* target, plan_line_data_t* pl_data, float* positio // calculate the total X,Y axis move distance // Z axis is the same in both coord systems, so it is ignored dist = sqrt((dx * dx) + (dy * dy) + (dz * dz)); - if (pl_data->motion & PL_MOTION_RAPID_MOTION) { + if (pl_data->motion.rapidMotion) { segment_count = 1; // rapid G0 motion is not used to draw, so skip the segmentation } else { segment_count = ceil(dist / SEGMENT_LENGTH); // determine the number of segments we need ... round up so there is at least 1 diff --git a/Grbl_Esp32/src/GCode.cpp b/Grbl_Esp32/src/GCode.cpp index c059ee80..def44ce0 100644 --- a/Grbl_Esp32/src/GCode.cpp +++ b/Grbl_Esp32/src/GCode.cpp @@ -1224,7 +1224,7 @@ Error gc_execute_line(char* line, uint8_t client) { // [2. Set feed rate mode ]: gc_state.modal.feed_rate = gc_block.modal.feed_rate; if (gc_state.modal.feed_rate == FeedRate::InverseTime) { - pl_data->motion |= PL_MOTION_INVERSE_TIME; // Set condition flag for planner use. + pl_data->motion.inverseTime = 1; // Set condition flag for planner use. } // [3. Set feed rate ]: gc_state.feed_rate = gc_block.values.f; // Always copy this value. See feed rate error-checking. @@ -1350,7 +1350,7 @@ Error gc_execute_line(char* line, uint8_t client) { case NonModal::GoHome1: // Move to intermediate position before going home. Obeys current coordinate system and offsets // and absolute and incremental modes. - pl_data->motion |= PL_MOTION_RAPID_MOTION; // Set rapid motion flag. + pl_data->motion.rapidMotion = 1; // Set rapid motion flag. if (axis_command != AxisCommand::None) { mc_line(gc_block.values.xyz, pl_data); // kinematics kinematics not used for homing righ now } @@ -1383,7 +1383,7 @@ Error gc_execute_line(char* line, uint8_t client) { //mc_line(gc_block.values.xyz, pl_data); mc_line_kins(gc_block.values.xyz, pl_data, gc_state.position); } else if (gc_state.modal.motion == Motion::Seek) { - pl_data->motion |= PL_MOTION_RAPID_MOTION; // Set rapid motion flag. + pl_data->motion.rapidMotion = 1; // Set rapid motion flag. //mc_line(gc_block.values.xyz, pl_data); mc_line_kins(gc_block.values.xyz, pl_data, gc_state.position); } else if ((gc_state.modal.motion == Motion::CwArc) || (gc_state.modal.motion == Motion::CcwArc)) { @@ -1400,7 +1400,7 @@ Error gc_execute_line(char* line, uint8_t client) { // 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. #ifndef ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES - pl_data->motion |= PL_MOTION_NO_FEED_OVERRIDE; + pl_data->motion.noFeedOverride = 1; #endif #ifdef USE_I2S_STEPS save_stepper = current_stepper; // remember the stepper diff --git a/Grbl_Esp32/src/Jog.cpp b/Grbl_Esp32/src/Jog.cpp index e053e39f..b3ff8853 100644 --- a/Grbl_Esp32/src/Jog.cpp +++ b/Grbl_Esp32/src/Jog.cpp @@ -28,7 +28,7 @@ Error jog_execute(plan_line_data_t* pl_data, parser_block_t* gc_block) { // Initialize planner data struct for jogging motions. // NOTE: Spindle and coolant are allowed to fully function with overrides during a jog. pl_data->feed_rate = gc_block->values.f; - pl_data->motion |= PL_MOTION_NO_FEED_OVERRIDE; + pl_data->motion.noFeedOverride = 1; #ifdef USE_LINE_NUMBERS pl_data->line_number = gc_block->values.n; #endif diff --git a/Grbl_Esp32/src/Limits.cpp b/Grbl_Esp32/src/Limits.cpp index 99e31ab3..044c4f3a 100644 --- a/Grbl_Esp32/src/Limits.cpp +++ b/Grbl_Esp32/src/Limits.cpp @@ -98,7 +98,9 @@ void limits_go_home(uint8_t cycle_mask) { plan_line_data_t plan_data; plan_line_data_t* pl_data = &plan_data; memset(pl_data, 0, sizeof(plan_line_data_t)); - pl_data->motion = (PL_MOTION_SYSTEM_MOTION | PL_MOTION_NO_FEED_OVERRIDE); + pl_data->motion = {}; + pl_data->motion.systemMotion = 1; + pl_data->motion.noFeedOverride = 1; #ifdef USE_LINE_NUMBERS pl_data->line_number = HOMING_CYCLE_LINE_NUMBER; #endif diff --git a/Grbl_Esp32/src/MotionControl.cpp b/Grbl_Esp32/src/MotionControl.cpp index aebe2383..b3e88612 100644 --- a/Grbl_Esp32/src/MotionControl.cpp +++ b/Grbl_Esp32/src/MotionControl.cpp @@ -142,9 +142,9 @@ void mc_arc(float* target, // Multiply inverse feed_rate to compensate for the fact that this movement is approximated // by a number of discrete segments. The inverse feed_rate should be correct for the sum of // all segments. - if (pl_data->motion & PL_MOTION_INVERSE_TIME) { + if (pl_data->motion.inverseTime) { pl_data->feed_rate *= segments; - bit_false(pl_data->motion, PL_MOTION_INVERSE_TIME); // Force as feed absolute mode over arc segments. + pl_data->motion.inverseTime = 0; // Force as feed absolute mode over arc segments. } float theta_per_segment = angular_travel / segments; float linear_per_segment = (target[axis_linear] - position[axis_linear]) / segments; diff --git a/Grbl_Esp32/src/Planner.cpp b/Grbl_Esp32/src/Planner.cpp index a47ae2e9..119b22aa 100644 --- a/Grbl_Esp32/src/Planner.cpp +++ b/Grbl_Esp32/src/Planner.cpp @@ -248,10 +248,10 @@ uint8_t plan_check_full_buffer() { // NOTE: All system motion commands, such as homing/parking, are not subject to overrides. float plan_compute_profile_nominal_speed(plan_block_t* block) { float nominal_speed = block->programmed_rate; - if (block->motion & PL_MOTION_RAPID_MOTION) { + if (block->motion.rapidMotion) { nominal_speed *= (0.01 * sys.r_override); } else { - if (!(block->motion & PL_MOTION_NO_FEED_OVERRIDE)) { + if (!(block->motion.noFeedOverride)) { nominal_speed *= (0.01 * sys.f_override); } if (nominal_speed > block->rapid_rate) { @@ -312,7 +312,7 @@ uint8_t plan_buffer_line(float* target, plan_line_data_t* pl_data) { float unit_vec[N_AXIS], delta_mm; uint8_t idx; // Copy position data based on type of motion being planned. - if (block->motion & PL_MOTION_SYSTEM_MOTION) { + if (block->motion.systemMotion) { #ifdef COREXY position_steps[X_AXIS] = system_convert_corexy_to_x_axis_steps(sys_position); position_steps[Y_AXIS] = system_convert_corexy_to_y_axis_steps(sys_position); @@ -373,16 +373,16 @@ uint8_t plan_buffer_line(float* target, plan_line_data_t* pl_data) { block->acceleration = limit_acceleration_by_axis_maximum(unit_vec); block->rapid_rate = limit_rate_by_axis_maximum(unit_vec); // Store programmed rate. - if (block->motion & PL_MOTION_RAPID_MOTION) { + if (block->motion.rapidMotion) { block->programmed_rate = block->rapid_rate; } else { block->programmed_rate = pl_data->feed_rate; - if (block->motion & PL_MOTION_INVERSE_TIME) { + if (block->motion.inverseTime) { block->programmed_rate *= block->millimeters; } } // TODO: Need to check this method handling zero junction speeds when starting from rest. - if ((block_buffer_head == block_buffer_tail) || (block->motion & PL_MOTION_SYSTEM_MOTION)) { + if ((block_buffer_head == block_buffer_tail) || (block->motion.systemMotion)) { // Initialize block entry speed as zero. Assume it will be starting from rest. Planner will correct this later. // If system motion, the system motion block always is assumed to start from rest and end at a complete stop. block->entry_speed_sqr = 0.0; @@ -434,7 +434,7 @@ uint8_t plan_buffer_line(float* target, plan_line_data_t* pl_data) { } } // Block system motion from updating this data to ensure next g-code motion is computed correctly. - if (!(block->motion & PL_MOTION_SYSTEM_MOTION)) { + if (!(block->motion.systemMotion)) { float nominal_speed = plan_compute_profile_nominal_speed(block); plan_compute_profile_parameters(block, nominal_speed, pl.previous_nominal_speed); pl.previous_nominal_speed = nominal_speed; diff --git a/Grbl_Esp32/src/Planner.h b/Grbl_Esp32/src/Planner.h index f05250cd..c1aeb659 100644 --- a/Grbl_Esp32/src/Planner.h +++ b/Grbl_Esp32/src/Planner.h @@ -34,14 +34,16 @@ #endif // Returned status message from planner. -const int PLAN_OK = true; -const int PLAN_EMPTY_BLOCK = false; +const int PLAN_OK = true; +const int PLAN_EMPTY_BLOCK = false; // Define planner data condition flags. Used to denote running conditions of a block. -#define PL_MOTION_RAPID_MOTION bit(0) -#define PL_MOTION_SYSTEM_MOTION bit(1) // Single motion. Circumvents planner state. Used by home/park. -#define PL_MOTION_NO_FEED_OVERRIDE bit(2) // Motion does not honor feed override. -#define PL_MOTION_INVERSE_TIME bit(3) // Interprets feed rate value as inverse time when set. +struct PlMotion { + uint8_t rapidMotion : 1; + uint8_t systemMotion : 1; // Single motion. Circumvents planner state. Used by home/park. + uint8_t noFeedOverride : 1; // Motion does not honor feed override. + uint8_t inverseTime : 1; // Interprets feed rate value as inverse time when set. +}; // This struct stores a linear movement of a g-code block motion with its critical "nominal" values // are as specified in the source g-code. @@ -53,7 +55,7 @@ typedef struct { uint8_t direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) // Block condition data to ensure correct execution depending on states and overrides. - uint8_t motion; // Block bitflag motion conditions. Copied from pl_line_data. + PlMotion motion; // Block bitflag motion conditions. Copied from pl_line_data. SpindleState spindle; // Spindle enable state CoolantState coolant; // Coolant state #ifdef USE_LINE_NUMBERS @@ -83,7 +85,7 @@ typedef struct { typedef struct { float feed_rate; // Desired feed rate for line motion. Value is ignored, if rapid motion. uint32_t spindle_speed; // Desired spindle speed through line motion. - uint8_t motion; // Bitflag variable to indicate motion conditions. See defines above. + PlMotion motion; // Bitflag variable to indicate motion conditions. See defines above. SpindleState spindle; // Spindle enable state CoolantState coolant; // Coolant state #ifdef USE_LINE_NUMBERS diff --git a/Grbl_Esp32/src/Protocol.cpp b/Grbl_Esp32/src/Protocol.cpp index 6d6f0385..83584aa2 100644 --- a/Grbl_Esp32/src/Protocol.cpp +++ b/Grbl_Esp32/src/Protocol.cpp @@ -576,7 +576,9 @@ static void protocol_exec_rt_suspend() { plan_line_data_t plan_data; plan_line_data_t* pl_data = &plan_data; memset(pl_data, 0, sizeof(plan_line_data_t)); - pl_data->motion = (PL_MOTION_SYSTEM_MOTION | PL_MOTION_NO_FEED_OVERRIDE); + pl_data->motion = {}; + pl_data->motion.systemMotion = 1; + pl_data->motion.noFeedOverride = 1; # ifdef USE_LINE_NUMBERS pl_data->line_number = PARKING_MOTION_LINE_NUMBER; # endif @@ -641,7 +643,9 @@ static void protocol_exec_rt_suspend() { // NOTE: Clear accessory state after retract and after an aborted restore motion. pl_data->spindle = SpindleState::Disable; pl_data->coolant = {}; - pl_data->motion = (PL_MOTION_SYSTEM_MOTION | PL_MOTION_NO_FEED_OVERRIDE); + pl_data->motion = {}; + pl_data->motion.systemMotion = 1; + pl_data->motion.noFeedOverride = 1; pl_data->spindle_speed = 0.0; spindle->set_state(pl_data->spindle, 0); // De-energize coolant_set_state(pl_data->coolant); diff --git a/Grbl_Esp32/src/Stepper.cpp b/Grbl_Esp32/src/Stepper.cpp index 2a435d34..e652e672 100644 --- a/Grbl_Esp32/src/Stepper.cpp +++ b/Grbl_Esp32/src/Stepper.cpp @@ -114,7 +114,7 @@ bool stepper_idle; // based on the current executing planner block. typedef struct { uint8_t st_block_index; // Index of stepper common data block being prepped - uint8_t recalculate_flag; + PrepFlag recalculate_flag; float dt_remainder; float steps_remaining; @@ -738,7 +738,7 @@ void st_go_idle() { // Called by planner_recalculate() when the executing block is updated by the new plan. void st_update_plan_block_parameters() { if (pl_block != NULL) { // Ignore if at start of a new block. - prep.recalculate_flag |= PREP_FLAG_RECALCULATE; + prep.recalculate_flag.recalculate = 1; pl_block->entry_speed_sqr = prep.current_speed * prep.current_speed; // Update entry speed. pl_block = NULL; // Flag st_prep_segment() to load and check active velocity profile. } @@ -748,31 +748,32 @@ void st_update_plan_block_parameters() { // Changes the run state of the step segment buffer to execute the special parking motion. void st_parking_setup_buffer() { // Store step execution data of partially completed block, if necessary. - if (prep.recalculate_flag & PREP_FLAG_HOLD_PARTIAL_BLOCK) { + if (prep.recalculate_flag.holdPartialBlock) { prep.last_st_block_index = prep.st_block_index; prep.last_steps_remaining = prep.steps_remaining; prep.last_dt_remainder = prep.dt_remainder; prep.last_step_per_mm = prep.step_per_mm; } // Set flags to execute a parking motion - prep.recalculate_flag |= PREP_FLAG_PARKING; - prep.recalculate_flag &= ~(PREP_FLAG_RECALCULATE); + prep.recalculate_flag.parking = 1; + prep.recalculate_flag.recalculate = 0; pl_block = NULL; // Always reset parking motion to reload new block. } // Restores the step segment buffer to the normal run state after a parking motion. void st_parking_restore_buffer() { // Restore step execution data and flags of partially completed block, if necessary. - if (prep.recalculate_flag & PREP_FLAG_HOLD_PARTIAL_BLOCK) { + if (prep.recalculate_flag.holdPartialBlock) { st_prep_block = &st_block_buffer[prep.last_st_block_index]; prep.st_block_index = prep.last_st_block_index; prep.steps_remaining = prep.last_steps_remaining; prep.dt_remainder = prep.last_dt_remainder; prep.step_per_mm = prep.last_step_per_mm; - prep.recalculate_flag = (PREP_FLAG_HOLD_PARTIAL_BLOCK | PREP_FLAG_RECALCULATE); + prep.recalculate_flag.holdPartialBlock = 1; + prep.recalculate_flag.recalculate = 1; prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR / prep.step_per_mm; // Recompute this value. } else { - prep.recalculate_flag = false; + prep.recalculate_flag = {}; } pl_block = NULL; // Set to reload next block. @@ -819,15 +820,15 @@ void st_prep_buffer() { } // Check if we need to only recompute the velocity profile or load a new block. - if (prep.recalculate_flag & PREP_FLAG_RECALCULATE) { + if (prep.recalculate_flag.recalculate) { #ifdef PARKING_ENABLE - if (prep.recalculate_flag & PREP_FLAG_PARKING) { - prep.recalculate_flag &= ~(PREP_FLAG_RECALCULATE); + if (prep.recalculate_flag.parking) { + prep.recalculate_flag.recalculate = 0; } else { - prep.recalculate_flag = false; + prep.recalculate_flag = {}; } #else - prep.recalculate_flag = false; + prep.recalculate_flag = {}; #endif } else { // Load the Bresenham stepping data for the block. @@ -857,11 +858,11 @@ void st_prep_buffer() { prep.step_per_mm = prep.steps_remaining / pl_block->millimeters; prep.req_mm_increment = REQ_MM_INCREMENT_SCALAR / prep.step_per_mm; prep.dt_remainder = 0.0; // Reset for new segment block - if ((sys.step_control & STEP_CONTROL_EXECUTE_HOLD) || (prep.recalculate_flag & PREP_FLAG_DECEL_OVERRIDE)) { + if ((sys.step_control & STEP_CONTROL_EXECUTE_HOLD) || prep.recalculate_flag.decelOverride) { // New block loaded mid-hold. Override planner block entry speed to enforce deceleration. prep.current_speed = prep.exit_speed; pl_block->entry_speed_sqr = prep.exit_speed * prep.exit_speed; - prep.recalculate_flag &= ~(PREP_FLAG_DECEL_OVERRIDE); + prep.recalculate_flag.decelOverride = 0; } else { prep.current_speed = sqrt(pl_block->entry_speed_sqr); } @@ -919,7 +920,7 @@ void st_prep_buffer() { // prep.maximum_speed = prep.current_speed; // Compute override block exit speed since it doesn't match the planner exit speed. prep.exit_speed = sqrt(pl_block->entry_speed_sqr - 2 * pl_block->acceleration * pl_block->millimeters); - prep.recalculate_flag |= PREP_FLAG_DECEL_OVERRIDE; // Flag to load next block as deceleration override. + prep.recalculate_flag.decelOverride = 1; // Flag to load next block as deceleration override. // TODO: Determine correct handling of parameters in deceleration-only. // Can be tricky since entry speed will be current speed, as in feed holds. // Also, look into near-zero speed handling issues with this. @@ -1121,8 +1122,8 @@ void st_prep_buffer() { // requires full steps to execute. So, just bail. bit_true(sys.step_control, STEP_CONTROL_END_MOTION); #ifdef PARKING_ENABLE - if (!(prep.recalculate_flag & PREP_FLAG_PARKING)) { - prep.recalculate_flag |= PREP_FLAG_HOLD_PARTIAL_BLOCK; + if (!(prep.recalculate_flag.parking)) { + prep.recalculate_flag.holdPartialBlock = 1; } #endif return; // Segment not generated, but current step data still retained. @@ -1200,8 +1201,8 @@ void st_prep_buffer() { // cycle stop flag from the ISR. Prep_segment is blocked until then. bit_true(sys.step_control, STEP_CONTROL_END_MOTION); #ifdef PARKING_ENABLE - if (!(prep.recalculate_flag & PREP_FLAG_PARKING)) { - prep.recalculate_flag |= PREP_FLAG_HOLD_PARTIAL_BLOCK; + if (!(prep.recalculate_flag.parking)) { + prep.recalculate_flag.holdPartialBlock = 1; } #endif return; // Bail! diff --git a/Grbl_Esp32/src/Stepper.h b/Grbl_Esp32/src/Stepper.h index 3141e522..b7f36265 100644 --- a/Grbl_Esp32/src/Stepper.h +++ b/Grbl_Esp32/src/Stepper.h @@ -39,10 +39,12 @@ const int RAMP_CRUISE = 1; const int RAMP_DECEL = 2; const int RAMP_DECEL_OVERRIDE = 3; -#define PREP_FLAG_RECALCULATE bit(0) -#define PREP_FLAG_HOLD_PARTIAL_BLOCK bit(1) -#define PREP_FLAG_PARKING bit(2) -#define PREP_FLAG_DECEL_OVERRIDE bit(3) +struct PrepFlag { + uint8_t recalculate : 1; + uint8_t holdPartialBlock : 1; + uint8_t parking : 1; + uint8_t decelOverride : 1; +}; // Define Adaptive Multi-Axis Step-Smoothing(AMASS) levels and cutoff frequencies. The highest level // frequency bin starts at 0Hz and ends at its cutoff frequency. The next lower level frequency bin