diff --git a/Marlin/G26_Mesh_Validation_Tool.cpp b/Marlin/G26_Mesh_Validation_Tool.cpp index 4b4f6e5c0f70..7c780c676d6c 100644 --- a/Marlin/G26_Mesh_Validation_Tool.cpp +++ b/Marlin/G26_Mesh_Validation_Tool.cpp @@ -638,11 +638,11 @@ g26_hotend_temp = HOTEND_TEMP; g26_prime_flag = 0; - g26_ooze_amount = parser.seen('O') && parser.has_value() ? parser.value_linear_units() : OOZE_AMOUNT; - g26_keep_heaters_on = parser.seen('K') && parser.value_bool(); - g26_continue_with_closest = parser.seen('C') && parser.value_bool(); + g26_ooze_amount = parser.linearval('O', OOZE_AMOUNT); + g26_keep_heaters_on = parser.boolval('K'); + g26_continue_with_closest = parser.boolval('C'); - if (parser.seen('B')) { + if (parser.seenval('B')) { g26_bed_temp = parser.value_celsius(); if (!WITHIN(g26_bed_temp, 15, 140)) { SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible."); @@ -650,7 +650,7 @@ } } - if (parser.seen('L')) { + if (parser.seenval('L')) { g26_layer_height = parser.value_linear_units(); if (!WITHIN(g26_layer_height, 0.0, 2.0)) { SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible."); @@ -672,7 +672,7 @@ } } - if (parser.seen('S')) { + if (parser.seenval('S')) { g26_nozzle = parser.value_float(); if (!WITHIN(g26_nozzle, 0.1, 1.0)) { SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible."); @@ -699,7 +699,7 @@ } } - if (parser.seen('F')) { + if (parser.seenval('F')) { g26_filament_diameter = parser.value_linear_units(); if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) { SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible."); @@ -712,7 +712,7 @@ g26_extrusion_multiplier *= g26_filament_diameter * sq(g26_nozzle) / sq(0.3); // Scale up by nozzle size - if (parser.seen('H')) { + if (parser.seenval('H')) { g26_hotend_temp = parser.value_celsius(); if (!WITHIN(g26_hotend_temp, 165, 280)) { SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible."); @@ -727,7 +727,7 @@ } #if ENABLED(NEWPANEL) - g26_repeats = parser.seen('R') && parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1; + g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1); #else if (!parser.seen('R')) { SERIAL_PROTOCOLLNPGM("?(R)epeat must be specified when not using an LCD."); @@ -741,8 +741,8 @@ return UBL_ERR; } - g26_x_pos = parser.seen('X') ? parser.value_linear_units() : current_position[X_AXIS]; - g26_y_pos = parser.seen('Y') ? parser.value_linear_units() : current_position[Y_AXIS]; + g26_x_pos = parser.linearval('X', current_position[X_AXIS]); + g26_y_pos = parser.linearval('Y', current_position[Y_AXIS]); if (!position_is_reachable_xy(g26_x_pos, g26_y_pos)) { SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds."); return UBL_ERR; diff --git a/Marlin/M100_Free_Mem_Chk.cpp b/Marlin/M100_Free_Mem_Chk.cpp index be418b049e34..6620b0a16efb 100644 --- a/Marlin/M100_Free_Mem_Chk.cpp +++ b/Marlin/M100_Free_Mem_Chk.cpp @@ -189,19 +189,17 @@ void free_memory_pool_report(char * const ptr, const int16_t size) { * This is useful to check the correctness of the M100 D and the M100 F commands. */ void corrupt_free_memory(char *ptr, const uint16_t size) { - if (parser.seen('C')) { - ptr += 8; - const uint16_t near_top = top_of_stack() - ptr - 250, // -250 to avoid interrupt activity that's altered the stack. - j = near_top / (size + 1); - - SERIAL_ECHOLNPGM("Corrupting free memory block.\n"); - for (uint16_t i = 1; i <= size; i++) { - char * const addr = ptr + i * j; - *addr = i; - SERIAL_ECHOPAIR("\nCorrupting address: ", hex_address(addr)); - } - SERIAL_EOL(); + ptr += 8; + const uint16_t near_top = top_of_stack() - ptr - 250, // -250 to avoid interrupt activity that's altered the stack. + j = near_top / (size + 1); + + SERIAL_ECHOLNPGM("Corrupting free memory block.\n"); + for (uint16_t i = 1; i <= size; i++) { + char * const addr = ptr + i * j; + *addr = i; + SERIAL_ECHOPAIR("\nCorrupting address: ", hex_address(addr)); } + SERIAL_EOL(); } #endif // M100_FREE_MEMORY_CORRUPTOR diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 48cf72cc022f..f46125af7d46 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -1276,16 +1276,17 @@ void get_available_commands() { * * Returns TRUE if the target is invalid */ -bool get_target_extruder_from_command(int code) { - if (parser.seen('T')) { - if (parser.value_byte() >= EXTRUDERS) { +bool get_target_extruder_from_command(const uint16_t code) { + if (parser.seenval('T')) { + const int8_t e = parser.value_byte(); + if (e >= EXTRUDERS) { SERIAL_ECHO_START(); SERIAL_CHAR('M'); SERIAL_ECHO(code); - SERIAL_ECHOLNPAIR(" " MSG_INVALID_EXTRUDER " ", parser.value_byte()); + SERIAL_ECHOLNPAIR(" " MSG_INVALID_EXTRUDER " ", e); return true; } - target_extruder = parser.value_byte(); + target_extruder = e; } else target_extruder = active_extruder; @@ -3134,7 +3135,7 @@ static void homeaxis(const AxisEnum axis) { const char* mixing_codes = "ABCDHI"; byte mix_bits = 0; for (uint8_t i = 0; i < MIXING_STEPPERS; i++) { - if (parser.seen(mixing_codes[i])) { + if (parser.seenval(mixing_codes[i])) { SBI(mix_bits, i); float v = parser.value_float(); NOLESS(v, 0.0); @@ -3174,7 +3175,7 @@ void gcode_get_destination() { destination[i] = current_position[i]; } - if (parser.seen('F') && parser.value_linear_units() > 0.0) + if (parser.linearval('F') > 0.0) feedrate_mm_s = MMM_TO_MMS(parser.value_feedrate()); #if ENABLED(PRINTCOUNTER) @@ -3303,7 +3304,7 @@ inline void gcode_G0_G1( #endif float arc_offset[2] = { 0.0, 0.0 }; - if (parser.seen('R')) { + if (parser.seenval('R')) { const float r = parser.value_linear_units(), p1 = current_position[X_AXIS], q1 = current_position[Y_AXIS], p2 = destination[X_AXIS], q2 = destination[Y_AXIS]; @@ -3320,15 +3321,15 @@ inline void gcode_G0_G1( } } else { - if (parser.seen('I')) arc_offset[0] = parser.value_linear_units(); - if (parser.seen('J')) arc_offset[1] = parser.value_linear_units(); + if (parser.seenval('I')) arc_offset[0] = parser.value_linear_units(); + if (parser.seenval('J')) arc_offset[1] = parser.value_linear_units(); } if (arc_offset[0] || arc_offset[1]) { #if ENABLED(ARC_P_CIRCLES) // P indicates number of circles to do - int8_t circles_to_do = parser.seen('P') ? parser.value_byte() : 0; + int8_t circles_to_do = parser.byteval('P'); if (!WITHIN(circles_to_do, 0, 100)) { SERIAL_ERROR_START(); SERIAL_ERRORLNPGM(MSG_ERR_ARC_ARGS); @@ -3357,8 +3358,8 @@ inline void gcode_G0_G1( inline void gcode_G4() { millis_t dwell_ms = 0; - if (parser.seen('P')) dwell_ms = parser.value_millis(); // milliseconds to wait - if (parser.seen('S')) dwell_ms = parser.value_millis_from_seconds(); // seconds to wait + if (parser.seenval('P')) dwell_ms = parser.value_millis(); // milliseconds to wait + if (parser.seenval('S')) dwell_ms = parser.value_millis_from_seconds(); // seconds to wait stepper.synchronize(); refresh_cmd_timeout(); @@ -3387,10 +3388,10 @@ inline void gcode_G4() { gcode_get_destination(); const float offset[] = { - parser.seen('I') ? parser.value_linear_units() : 0.0, - parser.seen('J') ? parser.value_linear_units() : 0.0, - parser.seen('P') ? parser.value_linear_units() : 0.0, - parser.seen('Q') ? parser.value_linear_units() : 0.0 + parser.linearval('I'), + parser.linearval('J'), + parser.linearval('P'), + parser.linearval('Q') }; plan_cubic_move(offset); @@ -3407,9 +3408,8 @@ inline void gcode_G4() { */ inline void gcode_G10_G11(bool doRetract=false) { #if EXTRUDERS > 1 - if (doRetract) { - retracted_swap[active_extruder] = (parser.seen('S') && parser.value_bool()); // checks for swap retract argument - } + if (doRetract) + retracted_swap[active_extruder] = parser.boolval('S'); // checks for swap retract argument #endif retract(doRetract #if EXTRUDERS > 1 @@ -3428,10 +3428,10 @@ inline void gcode_G4() { // Don't allow nozzle cleaning without homing first if (axis_unhomed_error()) return; - const uint8_t pattern = parser.seen('P') ? parser.value_ushort() : 0, - strokes = parser.seen('S') ? parser.value_ushort() : NOZZLE_CLEAN_STROKES, - objects = parser.seen('T') ? parser.value_ushort() : NOZZLE_CLEAN_TRIANGLES; - const float radius = parser.seen('R') ? parser.value_float() : NOZZLE_CLEAN_CIRCLE_RADIUS; + const uint8_t pattern = parser.ushortval('P', 0), + strokes = parser.ushortval('S', NOZZLE_CLEAN_STROKES), + objects = parser.ushortval('T', NOZZLE_CLEAN_TRIANGLES); + const float radius = parser.floatval('R', NOZZLE_CLEAN_CIRCLE_RADIUS); Nozzle::clean(pattern, strokes, radius, objects); } @@ -3475,7 +3475,7 @@ inline void gcode_G4() { inline void gcode_G27() { // Don't allow nozzle parking without homing first if (axis_unhomed_error()) return; - Nozzle::park(parser.seen('P') ? parser.value_ushort() : 0); + Nozzle::park(parser.ushortval('P')); } #endif // NOZZLE_PARK_FEATURE @@ -4038,7 +4038,7 @@ void home_all_axes() { gcode_G28(true); } static bool enable_soft_endstops; #endif - const MeshLevelingState state = parser.seen('S') ? (MeshLevelingState)parser.value_byte() : MeshReport; + const MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport); if (!WITHIN(state, 0, 5)) { SERIAL_PROTOCOLLNPGM("S out of range (0-5)."); return; @@ -4110,7 +4110,7 @@ void home_all_axes() { gcode_G28(true); } break; case MeshSet: - if (parser.seen('X')) { + if (parser.seenval('X')) { px = parser.value_int() - 1; if (!WITHIN(px, 0, GRID_MAX_POINTS_X - 1)) { SERIAL_PROTOCOLLNPGM("X out of range (1-" STRINGIFY(GRID_MAX_POINTS_X) ")."); @@ -4122,7 +4122,7 @@ void home_all_axes() { gcode_G28(true); } return; } - if (parser.seen('Y')) { + if (parser.seenval('Y')) { py = parser.value_int() - 1; if (!WITHIN(py, 0, GRID_MAX_POINTS_Y - 1)) { SERIAL_PROTOCOLLNPGM("Y out of range (1-" STRINGIFY(GRID_MAX_POINTS_Y) ")."); @@ -4134,7 +4134,7 @@ void home_all_axes() { gcode_G28(true); } return; } - if (parser.seen('Z')) { + if (parser.seenval('Z')) { mbl.z_values[px][py] = parser.value_linear_units(); } else { @@ -4144,7 +4144,7 @@ void home_all_axes() { gcode_G28(true); } break; case MeshSetZOffset: - if (parser.seen('Z')) { + if (parser.seenval('Z')) { mbl.z_offset = parser.value_linear_units(); } else { @@ -4268,7 +4268,7 @@ void home_all_axes() { gcode_G28(true); } #endif #if ENABLED(DEBUG_LEVELING_FEATURE) && DISABLED(PROBE_MANUALLY) - const bool faux = parser.seen('C') && parser.value_bool(); + const bool faux = parser.boolval('C'); #elif ENABLED(PROBE_MANUALLY) const bool faux = no_action; #else @@ -4370,17 +4370,17 @@ void home_all_axes() { gcode_G28(true); } return; } - const float z = parser.seen('Z') && parser.has_value() ? parser.value_float() : RAW_CURRENT_POSITION(Z); + const float z = parser.floatval('Z', RAW_CURRENT_POSITION(Z)); if (!WITHIN(z, -10, 10)) { SERIAL_ERROR_START(); SERIAL_ERRORLNPGM("Bad Z value"); return; } - const float x = parser.seen('X') && parser.has_value() ? parser.value_float() : NAN, - y = parser.seen('Y') && parser.has_value() ? parser.value_float() : NAN; - int8_t i = parser.seen('I') && parser.has_value() ? parser.value_byte() : -1, - j = parser.seen('J') && parser.has_value() ? parser.value_byte() : -1; + const float x = parser.floatval('X', NAN), + y = parser.floatval('Y', NAN); + int8_t i = parser.byteval('I', -1), + j = parser.byteval('J', -1); if (!isnan(x) && !isnan(y)) { // Get nearest i / j from x / y @@ -4412,13 +4412,13 @@ void home_all_axes() { gcode_G28(true); } #endif - verbose_level = parser.seen('V') && parser.has_value() ? parser.value_int() : 0; + verbose_level = parser.intval('V'); if (!WITHIN(verbose_level, 0, 4)) { SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-4)."); return; } - dryrun = (parser.seen('D') && parser.value_bool()) + dryrun = parser.boolval('D') #if ENABLED(PROBE_MANUALLY) || no_action #endif @@ -4426,13 +4426,13 @@ void home_all_axes() { gcode_G28(true); } #if ENABLED(AUTO_BED_LEVELING_LINEAR) - do_topography_map = verbose_level > 2 || parser.seen('T'); + do_topography_map = verbose_level > 2 || parser.boolval('T'); // X and Y specify points in each direction, overriding the default // These values may be saved with the completed mesh - abl_grid_points_x = parser.seen('X') ? parser.value_int() : GRID_MAX_POINTS_X; - abl_grid_points_y = parser.seen('Y') ? parser.value_int() : GRID_MAX_POINTS_Y; - if (parser.seen('P')) abl_grid_points_x = abl_grid_points_y = parser.value_int(); + abl_grid_points_x = parser.intval('X', GRID_MAX_POINTS_X); + abl_grid_points_y = parser.intval('Y', GRID_MAX_POINTS_Y); + if (parser.seenval('P')) abl_grid_points_x = abl_grid_points_y = parser.value_int(); if (abl_grid_points_x < 2 || abl_grid_points_y < 2) { SERIAL_PROTOCOLLNPGM("?Number of probe points is implausible (2 minimum)."); @@ -4443,18 +4443,18 @@ void home_all_axes() { gcode_G28(true); } #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - zoffset = parser.seen('Z') ? parser.value_linear_units() : 0; + zoffset = parser.linearval('Z'); #endif #if ABL_GRID - xy_probe_feedrate_mm_s = MMM_TO_MMS(parser.seen('S') ? parser.value_linear_units() : XY_PROBE_SPEED); + xy_probe_feedrate_mm_s = MMM_TO_MMS(parser.linearval('S', XY_PROBE_SPEED)); - left_probe_bed_position = parser.seen('L') ? (int)parser.value_linear_units() : LOGICAL_X_POSITION(LEFT_PROBE_BED_POSITION); - right_probe_bed_position = parser.seen('R') ? (int)parser.value_linear_units() : LOGICAL_X_POSITION(RIGHT_PROBE_BED_POSITION); - front_probe_bed_position = parser.seen('F') ? (int)parser.value_linear_units() : LOGICAL_Y_POSITION(FRONT_PROBE_BED_POSITION); - back_probe_bed_position = parser.seen('B') ? (int)parser.value_linear_units() : LOGICAL_Y_POSITION(BACK_PROBE_BED_POSITION); + left_probe_bed_position = (int)parser.linearval('L', LOGICAL_X_POSITION(LEFT_PROBE_BED_POSITION)); + right_probe_bed_position = (int)parser.linearval('R', LOGICAL_X_POSITION(RIGHT_PROBE_BED_POSITION)); + front_probe_bed_position = (int)parser.linearval('F', LOGICAL_Y_POSITION(FRONT_PROBE_BED_POSITION)); + back_probe_bed_position = (int)parser.linearval('B', LOGICAL_Y_POSITION(BACK_PROBE_BED_POSITION)); const bool left_out_l = left_probe_bed_position < LOGICAL_X_POSITION(MIN_PROBE_X), left_out = left_out_l || left_probe_bed_position > right_probe_bed_position - (MIN_PROBE_EDGE), @@ -4734,7 +4734,7 @@ void home_all_axes() { gcode_G28(true); } #else // !PROBE_MANUALLY - const bool stow_probe_after_each = parser.seen('E'); + const bool stow_probe_after_each = parser.boolval('E'); #if ABL_GRID @@ -5085,8 +5085,8 @@ void home_all_axes() { gcode_G28(true); } * S0 Leave the probe deployed */ inline void gcode_G30() { - const float xpos = parser.seen('X') ? parser.value_linear_units() : current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER, - ypos = parser.seen('Y') ? parser.value_linear_units() : current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER; + const float xpos = parser.linearval('X', current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER), + ypos = parser.linearval('Y', current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER); if (!position_is_reachable_by_probe_xy(xpos, ypos)) return; @@ -5097,7 +5097,7 @@ void home_all_axes() { gcode_G28(true); } setup_for_endstop_or_probe_move(); - const float measured_z = probe_pt(xpos, ypos, !parser.seen('S') || parser.value_bool(), 1); + const float measured_z = probe_pt(xpos, ypos, parser.boolval('S', true), 1); if (!isnan(measured_z)) { SERIAL_PROTOCOLPAIR("Bed X: ", FIXFLOAT(xpos)); @@ -5163,32 +5163,32 @@ void home_all_axes() { gcode_G28(true); } inline void gcode_G33() { - const int8_t probe_points = parser.seen('P') ? parser.value_int() : DELTA_CALIBRATION_DEFAULT_POINTS; + const int8_t probe_points = parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS); if (!WITHIN(probe_points, 1, 7)) { SERIAL_PROTOCOLLNPGM("?(P)oints is implausible (1 to 7)."); return; } - const int8_t verbose_level = parser.seen('V') ? parser.value_byte() : 1; + const int8_t verbose_level = parser.byteval('V', 1); if (!WITHIN(verbose_level, 0, 2)) { SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-2)."); return; } - const float calibration_precision = parser.seen('C') ? parser.value_float() : 0.0; + const float calibration_precision = parser.floatval('C'); if (calibration_precision < 0) { SERIAL_PROTOCOLLNPGM("?(C)alibration precision is implausible (>0)."); return; } - const int8_t force_iterations = parser.seen('F') ? parser.value_int() : 1; + const int8_t force_iterations = parser.intval('F', 1); if (!WITHIN(force_iterations, 1, 30)) { SERIAL_PROTOCOLLNPGM("?(F)orce iteration is implausible (1-30)."); return; } - const bool towers_set = !parser.seen('T'), - stow_after_each = parser.seen('E') && parser.value_bool(), + const bool towers_set = !parser.boolval('T'), + stow_after_each = parser.boolval('E'), _1p_calibration = probe_points == 1, _4p_calibration = probe_points == 2, _4p_towers_points = _4p_calibration && towers_set, @@ -5594,7 +5594,7 @@ void home_all_axes() { gcode_G28(true); } // If any axis has enough movement, do the move LOOP_XYZ(i) if (FABS(destination[i] - current_position[i]) >= G38_MINIMUM_MOVE) { - if (!parser.seen('F')) feedrate_mm_s = homing_feedrate(i); + if (!parser.seenval('F')) feedrate_mm_s = homing_feedrate(i); // If G38.2 fails throw an error if (!G38_run_probe() && is_38_2) { SERIAL_ERROR_START(); @@ -5615,10 +5615,10 @@ void home_all_axes() { gcode_G28(true); } */ inline void gcode_G42() { if (IsRunning()) { - const bool hasI = parser.seen('I'); - const int8_t ix = parser.has_value() ? parser.value_int() : 0; - const bool hasJ = parser.seen('J'); - const int8_t iy = parser.has_value() ? parser.value_int() : 0; + const bool hasI = parser.seenval('I'); + const int8_t ix = hasI ? parser.value_int() : 0; + const bool hasJ = parser.seenval('J'); + const int8_t iy = hasJ ? parser.value_int() : 0; if ((hasI && !WITHIN(ix, 0, GRID_MAX_POINTS_X - 1)) || (hasJ && !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1))) { SERIAL_ECHOLNPGM(MSG_ERR_MESH_XY); @@ -5639,13 +5639,13 @@ void home_all_axes() { gcode_G28(true); } set_destination_to_current(); if (hasI) destination[X_AXIS] = LOGICAL_X_POSITION(_GET_MESH_X(ix)); if (hasJ) destination[Y_AXIS] = LOGICAL_Y_POSITION(_GET_MESH_Y(iy)); - if (parser.seen('P') && parser.value_bool()) { + if (parser.boolval('P')) { if (hasI) destination[X_AXIS] -= X_PROBE_OFFSET_FROM_EXTRUDER; if (hasJ) destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER; } - if (parser.seen('F') && parser.value_linear_units() > 0.0) - feedrate_mm_s = MMM_TO_MMS(parser.value_linear_units()); + const float fval = parser.linearval('F'); + if (fval > 0.0) feedrate_mm_s = MMM_TO_MMS(fval); // SCARA kinematic has "safe" XY raw moves #if IS_SCARA @@ -5663,12 +5663,12 @@ void home_all_axes() { gcode_G28(true); } */ inline void gcode_G92() { bool didXYZ = false, - didE = parser.seen('E'); + didE = parser.seenval('E'); if (!didE) stepper.synchronize(); LOOP_XYZE(i) { - if (parser.seen(axis_codes[i])) { + if (parser.seenval(axis_codes[i])) { #if IS_SCARA current_position[i] = parser.value_axis_units((AxisEnum)i); if (i != E_AXIS) didXYZ = true; @@ -5676,7 +5676,7 @@ inline void gcode_G92() { #if HAS_POSITION_SHIFT const float p = current_position[i]; #endif - float v = parser.value_axis_units((AxisEnum)i); + const float v = parser.value_axis_units((AxisEnum)i); current_position[i] = v; @@ -5714,11 +5714,11 @@ inline void gcode_G92() { millis_t ms = 0; bool hasP = false, hasS = false; - if (parser.seen('P')) { + if (parser.seenval('P')) { ms = parser.value_millis(); // milliseconds to wait hasP = ms > 0; } - if (parser.seen('S')) { + if (parser.seenval('S')) { ms = parser.value_millis_from_seconds(); // seconds to wait hasS = ms > 0; } @@ -5850,7 +5850,7 @@ inline void gcode_G92() { #if ENABLED(SPINDLE_LASER_PWM) if (parser.seen('O')) ocr_val_mode(); else { - const float spindle_laser_power = parser.seen('S') ? parser.value_float() : 0; + const float spindle_laser_power = parser.floatval('S'); if (spindle_laser_power == 0) { WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT); // turn spindle off (active low) delay_for_power_down(); @@ -6271,7 +6271,7 @@ inline void gcode_M17() { * M26: Set SD Card file index */ inline void gcode_M26() { - if (card.cardOK && parser.seen('S')) + if (card.cardOK && parser.seenval('S')) card.setIndex(parser.value_long()); } @@ -6328,12 +6328,12 @@ inline void gcode_M31() { stepper.synchronize(); char* namestartpos = parser.string_arg; - bool call_procedure = parser.seen('P'); + const bool call_procedure = parser.boolval('P'); if (card.cardOK) { card.openFile(namestartpos, true, call_procedure); - if (parser.seen('S')) + if (parser.seenval('S')) card.setIndex(parser.value_long()); card.startFileprint(); @@ -6369,8 +6369,8 @@ inline void gcode_M31() { */ inline void gcode_M34() { if (parser.seen('S')) card.setSortOn(parser.value_bool()); - if (parser.seen('F')) { - int v = parser.value_long(); + if (parser.seenval('F')) { + const int v = parser.value_long(); card.setSortFolders(v < 0 ? -1 : v > 0 ? 1 : 0); } //if (parser.seen('R')) card.setSortReverse(parser.value_bool()); @@ -6403,12 +6403,10 @@ static bool pin_is_protected(const int8_t pin) { * S Pin status from 0 - 255 */ inline void gcode_M42() { - if (!parser.seen('S')) return; - - int pin_status = parser.value_int(); - if (!WITHIN(pin_status, 0, 255)) return; + if (!parser.seenval('S')) return; + const byte pin_status = parser.value_byte(); - int pin_number = parser.seen('P') ? parser.value_int() : LED_PIN; + const int pin_number = parser.intval('P', LED_PIN); if (pin_number < 0) return; if (pin_is_protected(pin_number)) { @@ -6441,11 +6439,11 @@ inline void gcode_M42() { #include "pinsDebug.h" inline void toggle_pins() { - const bool I_flag = parser.seen('I') && parser.value_bool(); - const int repeat = parser.seen('R') ? parser.value_int() : 1, - start = parser.seen('S') ? parser.value_int() : 0, - end = parser.seen('E') ? parser.value_int() : NUM_DIGITAL_PINS - 1, - wait = parser.seen('W') ? parser.value_int() : 500; + const bool I_flag = parser.boolval('I'); + const int repeat = parser.intval('R', 1), + start = parser.intval('S'), + end = parser.intval('E', NUM_DIGITAL_PINS - 1), + wait = parser.intval('W', 500); for (uint8_t pin = start; pin <= end; pin++) { //report_pin_state_extended(pin, I_flag, false); @@ -6504,7 +6502,7 @@ inline void gcode_M42() { #else - const uint8_t probe_index = parser.seen('P') ? parser.value_byte() : Z_ENDSTOP_SERVO_NR; + const uint8_t probe_index = parser.byteval('P', Z_ENDSTOP_SERVO_NR); SERIAL_PROTOCOLLNPGM("Servo probe test"); SERIAL_PROTOCOLLNPAIR(". using index: ", probe_index); @@ -6645,7 +6643,7 @@ inline void gcode_M42() { */ inline void gcode_M43() { - if (parser.seen('T')) { // must be first or else it's "S" and "E" parameters will execute endstop or servo test + if (parser.seen('T')) { // must be first or else its "S" and "E" parameters will execute endstop or servo test toggle_pins(); return; } @@ -6665,15 +6663,15 @@ inline void gcode_M42() { } // Get the range of pins to test or watch - const uint8_t first_pin = parser.seen('P') ? parser.value_byte() : 0, - last_pin = parser.seen('P') ? first_pin : NUM_DIGITAL_PINS - 1; + const uint8_t first_pin = parser.byteval('P'), + last_pin = parser.seenval('P') ? first_pin : NUM_DIGITAL_PINS - 1; if (first_pin > last_pin) return; - const bool ignore_protection = parser.seen('I') && parser.value_bool(); + const bool ignore_protection = parser.boolval('I'); // Watch until click, M108, or reset - if (parser.seen('W') && parser.value_bool()) { + if (parser.boolval('W')) { SERIAL_PROTOCOLLNPGM("Watching pins"); byte pin_state[last_pin - first_pin + 1]; for (int8_t pin = first_pin; pin <= last_pin; pin++) { @@ -6752,7 +6750,7 @@ inline void gcode_M42() { if (axis_unhomed_error()) return; - const int8_t verbose_level = parser.seen('V') ? parser.value_byte() : 1; + const int8_t verbose_level = parser.byteval('V', 1); if (!WITHIN(verbose_level, 0, 4)) { SERIAL_PROTOCOLLNPGM("?(V)erbose level is implausible (0-4)."); return; @@ -6761,19 +6759,19 @@ inline void gcode_M42() { if (verbose_level > 0) SERIAL_PROTOCOLLNPGM("M48 Z-Probe Repeatability Test"); - int8_t n_samples = parser.seen('P') ? parser.value_byte() : 10; + const int8_t n_samples = parser.byteval('P', 10); if (!WITHIN(n_samples, 4, 50)) { SERIAL_PROTOCOLLNPGM("?Sample size not plausible (4-50)."); return; } - const bool stow_probe_after_each = parser.seen('E'); + const bool stow_probe_after_each = parser.boolval('E'); float X_current = current_position[X_AXIS], Y_current = current_position[Y_AXIS]; - const float X_probe_location = parser.seen('X') ? parser.value_linear_units() : X_current + X_PROBE_OFFSET_FROM_EXTRUDER, - Y_probe_location = parser.seen('Y') ? parser.value_linear_units() : Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER; + const float X_probe_location = parser.linearval('X', X_current + X_PROBE_OFFSET_FROM_EXTRUDER), + Y_probe_location = parser.linearval('Y', Y_current + Y_PROBE_OFFSET_FROM_EXTRUDER); #if DISABLED(DELTA) if (!WITHIN(X_probe_location, LOGICAL_X_POSITION(MIN_PROBE_X), LOGICAL_X_POSITION(MAX_PROBE_X))) { @@ -6799,7 +6797,7 @@ inline void gcode_M42() { } if (n_legs == 1) n_legs = 2; - bool schizoid_flag = parser.seen('S'); + const bool schizoid_flag = parser.boolval('S'); if (schizoid_flag && !seen_L) n_legs = 7; /** @@ -7007,7 +7005,7 @@ inline void gcode_M77() { print_job_timer.stop(); } */ inline void gcode_M78() { // "M78 S78" will reset the statistics - if (parser.seen('S') && parser.value_int() == 78) + if (parser.intval('S') == 78) print_job_timer.initStats(); else print_job_timer.showStats(); @@ -7025,7 +7023,7 @@ inline void gcode_M104() { if (target_extruder != active_extruder) return; #endif - if (parser.seen('S')) { + if (parser.seenval('S')) { const int16_t temp = parser.value_celsius(); thermalManager.setTargetHotend(temp, target_extruder); @@ -7152,7 +7150,7 @@ inline void gcode_M105() { * M155: Set temperature auto-report interval. M155 S */ inline void gcode_M155() { - if (parser.seen('S')) { + if (parser.seenval('S')) { auto_report_temp_interval = parser.value_byte(); NOMORE(auto_report_temp_interval, 60); next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval; @@ -7178,9 +7176,9 @@ inline void gcode_M105() { * P Fan index, if more than one fan */ inline void gcode_M106() { - uint16_t s = parser.seen('S') ? parser.value_ushort() : 255, - p = parser.seen('P') ? parser.value_ushort() : 0; + uint16_t s = parser.ushortval('S', 255); NOMORE(s, 255); + const uint8_t p = parser.byteval('P', 0); if (p < FAN_COUNT) fanSpeeds[p] = s; } @@ -7188,7 +7186,7 @@ inline void gcode_M105() { * M107: Fan Off */ inline void gcode_M107() { - uint16_t p = parser.seen('P') ? parser.value_ushort() : 0; + const uint16_t p = parser.ushortval('P'); if (p < FAN_COUNT) fanSpeeds[p] = 0; } @@ -7239,8 +7237,8 @@ inline void gcode_M109() { if (target_extruder != active_extruder) return; #endif - const bool no_wait_for_cooling = parser.seen('S'); - if (no_wait_for_cooling || parser.seen('R')) { + const bool no_wait_for_cooling = parser.seenval('S'); + if (no_wait_for_cooling || parser.seenval('R')) { const int16_t temp = parser.value_celsius(); thermalManager.setTargetHotend(temp, target_extruder); @@ -7388,8 +7386,8 @@ inline void gcode_M109() { if (DEBUGGING(DRYRUN)) return; LCD_MESSAGEPGM(MSG_BED_HEATING); - const bool no_wait_for_cooling = parser.seen('S'); - if (no_wait_for_cooling || parser.seen('R')) { + const bool no_wait_for_cooling = parser.seenval('S'); + if (no_wait_for_cooling || parser.seenval('R')) { thermalManager.setTargetBed(parser.value_celsius()); #if ENABLED(PRINTJOB_TIMER_AUTOSTART) if (parser.value_celsius() > BED_MINTEMP) @@ -7496,14 +7494,14 @@ inline void gcode_M109() { * M110: Set Current Line Number */ inline void gcode_M110() { - if (parser.seen('N')) gcode_LastN = parser.value_long(); + if (parser.seenval('N')) gcode_LastN = parser.value_long(); } /** * M111: Set the debug level */ inline void gcode_M111() { - marlin_debug_flags = parser.seen('S') ? parser.value_byte() : (uint8_t)DEBUG_NONE; + marlin_debug_flags = parser.byteval('S', (uint8_t)DEBUG_NONE); const static char str_debug_1[] PROGMEM = MSG_DEBUG_ECHO; const static char str_debug_2[] PROGMEM = MSG_DEBUG_INFO; @@ -7546,7 +7544,7 @@ inline void gcode_M111() { * S Optional. Set the keepalive interval. */ inline void gcode_M113() { - if (parser.seen('S')) { + if (parser.seenval('S')) { host_keepalive_interval = parser.value_byte(); NOMORE(host_keepalive_interval, 60); } @@ -7564,7 +7562,7 @@ inline void gcode_M111() { /** * M126: Heater 1 valve open */ - inline void gcode_M126() { baricuda_valve_pressure = parser.seen('S') ? parser.value_byte() : 255; } + inline void gcode_M126() { baricuda_valve_pressure = parser.byteval('S', 255); } /** * M127: Heater 1 valve close */ @@ -7575,7 +7573,7 @@ inline void gcode_M111() { /** * M128: Heater 2 valve open */ - inline void gcode_M128() { baricuda_e_to_p_pressure = parser.seen('S') ? parser.value_byte() : 255; } + inline void gcode_M128() { baricuda_e_to_p_pressure = parser.byteval('S', 255); } /** * M129: Heater 2 valve close */ @@ -7589,7 +7587,7 @@ inline void gcode_M111() { */ inline void gcode_M140() { if (DEBUGGING(DRYRUN)) return; - if (parser.seen('S')) thermalManager.setTargetBed(parser.value_celsius()); + if (parser.seenval('S')) thermalManager.setTargetBed(parser.value_celsius()); } #if ENABLED(ULTIPANEL) @@ -7603,23 +7601,23 @@ inline void gcode_M140() { * F */ inline void gcode_M145() { - uint8_t material = parser.seen('S') ? (uint8_t)parser.value_int() : 0; + const uint8_t material = (uint8_t)parser.intval('S'); if (material >= COUNT(lcd_preheat_hotend_temp)) { SERIAL_ERROR_START(); SERIAL_ERRORLNPGM(MSG_ERR_MATERIAL_INDEX); } else { int v; - if (parser.seen('H')) { + if (parser.seenval('H')) { v = parser.value_int(); lcd_preheat_hotend_temp[material] = constrain(v, EXTRUDE_MINTEMP, HEATER_0_MAXTEMP - 15); } - if (parser.seen('F')) { + if (parser.seenval('F')) { v = parser.value_int(); lcd_preheat_fan_speed[material] = constrain(v, 0, 255); } #if TEMP_SENSOR_BED != 0 - if (parser.seen('B')) { + if (parser.seenval('B')) { v = parser.value_int(); lcd_preheat_bed_temp[material] = constrain(v, BED_MINTEMP, BED_MAXTEMP - 15); } @@ -7634,9 +7632,9 @@ inline void gcode_M140() { * M149: Set temperature units */ inline void gcode_M149() { - if (parser.seen('C')) parser.set_input_temp_units(TEMPUNIT_C); - else if (parser.seen('K')) parser.set_input_temp_units(TEMPUNIT_K); - else if (parser.seen('F')) parser.set_input_temp_units(TEMPUNIT_F); + if (parser.seenval('C')) parser.set_input_temp_units(TEMPUNIT_C); + else if (parser.seenval('K')) parser.set_input_temp_units(TEMPUNIT_K); + else if (parser.seenval('F')) parser.set_input_temp_units(TEMPUNIT_F); } #endif @@ -7725,7 +7723,7 @@ inline void gcode_M83() { axis_relative_modes[E_AXIS] = true; } * M18, M84: Disable stepper motors */ inline void gcode_M18_M84() { - if (parser.seen('S')) { + if (parser.seenval('S')) { stepper_inactive_time = parser.value_millis_from_seconds(); } else { @@ -8035,16 +8033,14 @@ inline void gcode_M121() { endstops.enable_globally(false); } ; // Lift Z axis - const float z_lift = parser.seen('Z') ? parser.value_linear_units() : - #if defined(PAUSE_PARK_Z_ADD) && PAUSE_PARK_Z_ADD > 0 - PAUSE_PARK_Z_ADD - #else - 0 + const float z_lift = parser.linearval('Z') + #if PAUSE_PARK_Z_ADD > 0 + + PAUSE_PARK_Z_ADD #endif ; // Move XY axes to filament change position or given position - const float x_pos = parser.seen('X') ? parser.value_linear_units() : 0 + const float x_pos = parser.linearval('X') #ifdef PAUSE_PARK_X_POS + PAUSE_PARK_X_POS #endif @@ -8052,7 +8048,7 @@ inline void gcode_M121() { endstops.enable_globally(false); } + (active_extruder ? hotend_offset[X_AXIS][active_extruder] : 0) #endif ; - const float y_pos = parser.seen('Y') ? parser.value_linear_units() : 0 + const float y_pos = parser.linearval('Y') #ifdef PAUSE_PARK_Y_POS + PAUSE_PARK_Y_POS #endif @@ -8268,10 +8264,10 @@ inline void gcode_M205() { home_offset[Z_AXIS] = parser.value_linear_units() - DELTA_HEIGHT; update_software_endstops(Z_AXIS); } - if (parser.seen('L')) delta_diagonal_rod = parser.value_linear_units(); - if (parser.seen('R')) delta_radius = parser.value_linear_units(); - if (parser.seen('S')) delta_segments_per_second = parser.value_float(); - if (parser.seen('B')) delta_calibration_radius = parser.value_float(); + if (parser.seen('L')) delta_diagonal_rod = parser.value_linear_units(); + if (parser.seen('R')) delta_radius = parser.value_linear_units(); + if (parser.seen('S')) delta_segments_per_second = parser.value_float(); + if (parser.seen('B')) delta_calibration_radius = parser.value_float(); if (parser.seen('X')) delta_tower_angle_trim[A_AXIS] = parser.value_float(); if (parser.seen('Y')) delta_tower_angle_trim[B_AXIS] = parser.value_float(); if (parser.seen('Z')) { // rotate all 3 axis for Z = 0 @@ -8447,11 +8443,11 @@ inline void gcode_M211() { inline void gcode_M218() { if (get_target_extruder_from_command(218) || target_extruder == 0) return; - if (parser.seen('X')) hotend_offset[X_AXIS][target_extruder] = parser.value_linear_units(); - if (parser.seen('Y')) hotend_offset[Y_AXIS][target_extruder] = parser.value_linear_units(); + if (parser.seenval('X')) hotend_offset[X_AXIS][target_extruder] = parser.value_linear_units(); + if (parser.seenval('Y')) hotend_offset[Y_AXIS][target_extruder] = parser.value_linear_units(); #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_NOZZLE) - if (parser.seen('Z')) hotend_offset[Z_AXIS][target_extruder] = parser.value_linear_units(); + if (parser.seenval('Z')) hotend_offset[Z_AXIS][target_extruder] = parser.value_linear_units(); #endif SERIAL_ECHO_START(); @@ -8475,7 +8471,7 @@ inline void gcode_M211() { * M220: Set speed percentage factor, aka "Feed Rate" (M220 S95) */ inline void gcode_M220() { - if (parser.seen('S')) feedrate_percentage = parser.value_int(); + if (parser.seenval('S')) feedrate_percentage = parser.value_int(); } /** @@ -8483,7 +8479,7 @@ inline void gcode_M220() { */ inline void gcode_M221() { if (get_target_extruder_from_command(221)) return; - if (parser.seen('S')) + if (parser.seenval('S')) flow_percentage[target_extruder] = parser.value_int(); } @@ -8492,10 +8488,10 @@ inline void gcode_M221() { */ inline void gcode_M226() { if (parser.seen('P')) { - int pin_number = parser.value_int(), - pin_state = parser.seen('S') ? parser.value_int() : -1; // required pin state - default is inverted + const int pin_number = parser.value_int(), + pin_state = parser.intval('S', -1); // required pin state - default is inverted - if (pin_state >= -1 && pin_state <= 1 && pin_number > -1 && !pin_is_protected(pin_number)) { + if (WITHIN(pin_state, -1, 1) && pin_number > -1 && !pin_is_protected(pin_number)) { int target = LOW; @@ -8560,7 +8556,7 @@ inline void gcode_M226() { inline void gcode_M261() { if (parser.seen('A')) i2c.address(parser.value_byte()); - uint8_t bytes = parser.seen('B') ? parser.value_byte() : 1; + uint8_t bytes = parser.byteval('B', 1); if (i2c.addr && bytes && bytes <= TWIBUS_BUFFER_SIZE) { i2c.relay(bytes); @@ -8580,7 +8576,7 @@ inline void gcode_M226() { */ inline void gcode_M280() { if (!parser.seen('P')) return; - int servo_index = parser.value_int(); + const int servo_index = parser.value_int(); if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) { if (parser.seen('S')) MOVE_SERVO(servo_index, parser.value_int()); @@ -8605,8 +8601,8 @@ inline void gcode_M226() { * M300: Play beep sound S P */ inline void gcode_M300() { - uint16_t const frequency = parser.seen('S') ? parser.value_ushort() : 260; - uint16_t duration = parser.seen('P') ? parser.value_ushort() : 1000; + uint16_t const frequency = parser.ushortval('S', 260); + uint16_t duration = parser.ushortval('P', 1000); // Limits the tone duration to 0-5 seconds. NOMORE(duration, 5000); @@ -8634,7 +8630,7 @@ inline void gcode_M226() { // multi-extruder PID patch: M301 updates or prints a single extruder's PID values // default behaviour (omitting E parameter) is to update for extruder 0 only - int e = parser.seen('E') ? parser.value_int() : 0; // extruder being updated + const uint8_t e = parser.byteval('E'); // extruder being updated if (e < HOTENDS) { // catch bad input value if (parser.seen('P')) PID_PARAM(Kp, e) = parser.value_float(); @@ -8753,7 +8749,7 @@ inline void gcode_M226() { * M302 S170 P1 ; set min extrude temp to 170 but leave disabled */ inline void gcode_M302() { - bool seen_S = parser.seen('S'); + const bool seen_S = parser.seen('S'); if (seen_S) { thermalManager.extrude_min_temp = parser.value_celsius(); thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0); @@ -8782,11 +8778,10 @@ inline void gcode_M226() { */ inline void gcode_M303() { #if HAS_PID_HEATING - const int e = parser.seen('E') ? parser.value_int() : 0, - c = parser.seen('C') ? parser.value_int() : 5; - const bool u = parser.seen('U') && parser.value_bool(); + const int e = parser.intval('E'), c = parser.intval('C', 5); + const bool u = parser.boolval('U'); - int16_t temp = parser.seen('S') ? parser.value_celsius() : (e < 0 ? 70 : 150); + int16_t temp = parser.celsiusval('S', e < 0 ? 70 : 150); if (WITHIN(e, 0, HOTENDS - 1)) target_extruder = e; @@ -8960,10 +8955,12 @@ inline void gcode_M400() { stepper.synchronize(); } * M405: Turn on filament sensor for control */ inline void gcode_M405() { - // This is technically a linear measurement, but since it's quantized to centimeters and is a different unit than - // everything else, it uses parser.value_int() instead of parser.value_linear_units(). - if (parser.seen('D')) meas_delay_cm = parser.value_byte(); - NOMORE(meas_delay_cm, MAX_MEASUREMENT_DELAY); + // This is technically a linear measurement, but since it's quantized to centimeters and is a different + // unit than everything else, it uses parser.value_byte() instead of parser.value_linear_units(). + if (parser.seen('D')) { + meas_delay_cm = parser.value_byte(); + NOMORE(meas_delay_cm, MAX_MEASUREMENT_DELAY); + } if (filwidth_delay_index[1] == -1) { // Initialize the ring buffer if not done since startup const uint8_t temp_ratio = thermalManager.widthFil_to_size_ratio() - 100; // -100 to scale within a signed byte @@ -9077,11 +9074,9 @@ void quickstop_stepper() { #endif } - bool to_enable = false; - if (parser.seen('S')) { - to_enable = parser.value_bool(); + const bool to_enable = parser.boolval('S'); + if (parser.seen('S')) set_bed_leveling_enabled(to_enable); - } #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) if (parser.seen('Z')) set_z_fade_height(parser.value_linear_units()); @@ -9148,11 +9143,12 @@ void quickstop_stepper() { * M421 I J Q */ inline void gcode_M421() { - const bool hasI = parser.seen('I'); - const int8_t ix = hasI ? parser.value_int() : -1; - const bool hasJ = parser.seen('J'); - const int8_t iy = hasJ ? parser.value_int() : -1; - const bool hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q'); + int8_t ix = parser.intval('I', -1), iy = parser.intval('J', -1); + const bool hasI = ix >= 0, + hasJ = iy >= 0, + hasC = parser.seen('C'), + hasZ = parser.seen('Z'), + hasQ = !hasZ && parser.seen('Q'); if (!hasI || !hasJ || !(hasZ || hasQ)) { SERIAL_ERROR_START(); @@ -9182,11 +9178,12 @@ void quickstop_stepper() { * M421 C Q */ inline void gcode_M421() { - const bool hasC = parser.seen('C'), hasI = parser.seen('I'); - int8_t ix = hasI ? parser.value_int() : -1; - const bool hasJ = parser.seen('J'); - int8_t iy = hasJ ? parser.value_int() : -1; - const bool hasZ = parser.seen('Z'), hasQ = !hasZ && parser.seen('Q'); + int8_t ix = parser.intval('I', -1), iy = parser.intval('J', -1); + const bool hasI = ix >= 0, + hasJ = iy >= 0, + hasC = parser.seen('C'), + hasZ = parser.seen('Z'), + hasQ = !hasZ && parser.seen('Q'); if (hasC) { const mesh_index_pair location = ubl.find_closest_mesh_point_of_type(REAL, current_position[X_AXIS], current_position[Y_AXIS], USE_NOZZLE_AS_REFERENCE, NULL, false); @@ -9277,7 +9274,7 @@ inline void gcode_M502() { * M503: print settings currently in memory */ inline void gcode_M503() { - (void)settings.report(parser.seen('S') && !parser.value_bool()); + (void)settings.report(!parser.boolval('S', true)); } #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) @@ -9381,25 +9378,23 @@ inline void gcode_M503() { ; // Lift Z axis - const float z_lift = parser.seen('Z') ? parser.value_linear_units() : + const float z_lift = parser.linearval('Z', 0 #if defined(PAUSE_PARK_Z_ADD) && PAUSE_PARK_Z_ADD > 0 - PAUSE_PARK_Z_ADD - #else - 0 + + PAUSE_PARK_Z_ADD #endif - ; + ); // Move XY axes to filament exchange position - const float x_pos = parser.seen('X') ? parser.value_linear_units() : 0 + const float x_pos = parser.linearval('X', 0 #ifdef PAUSE_PARK_X_POS + PAUSE_PARK_X_POS #endif - ; - const float y_pos = parser.seen('Y') ? parser.value_linear_units() : 0 + ); + const float y_pos = parser.linearval('Y', 0 #ifdef PAUSE_PARK_Y_POS + PAUSE_PARK_Y_POS #endif - ; + ); // Unload filament const float unload_length = parser.seen('U') ? parser.value_axis_units(E_AXIS) : 0 @@ -9415,13 +9410,13 @@ inline void gcode_M503() { #endif ; - const int beep_count = parser.seen('B') ? parser.value_int() : + const int beep_count = parser.intval('B', #ifdef FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS FILAMENT_CHANGE_NUMBER_OF_ALERT_BEEPS #else -1 #endif - ; + ); const bool job_running = print_job_timer.isRunning(); @@ -9484,7 +9479,7 @@ inline void gcode_M503() { inline void gcode_M605() { stepper.synchronize(); - extruder_duplication_enabled = parser.seen('S') && parser.value_int() == (int)DXC_DUPLICATION_MODE; + extruder_duplication_enabled = parser.intval('S') == (int)DXC_DUPLICATION_MODE; SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(MSG_DUPLICATION_MODE, extruder_duplication_enabled ? MSG_ON : MSG_OFF); } @@ -9502,14 +9497,14 @@ inline void gcode_M503() { inline void gcode_M900() { stepper.synchronize(); - const float newK = parser.seen('K') ? parser.value_float() : -1; + const float newK = parser.floatval('K', -1); if (newK >= 0) planner.extruder_advance_k = newK; - float newR = parser.seen('R') ? parser.value_float() : -1; + float newR = parser.floatval('R', -1); if (newR < 0) { - const float newD = parser.seen('D') ? parser.value_float() : -1, - newW = parser.seen('W') ? parser.value_float() : -1, - newH = parser.seen('H') ? parser.value_float() : -1; + const float newD = parser.floatval('D', -1), + newW = parser.floatval('W', -1), + newH = parser.floatval('H', -1); if (newD >= 0 && newW >= 0 && newH >= 0) newR = newD ? (newW * newH) / (sq(newD * 0.5) * M_PI) : 0; } @@ -9578,7 +9573,7 @@ inline void gcode_M503() { inline void gcode_M906() { uint16_t values[XYZE]; LOOP_XYZE(i) - values[i] = parser.seen(axis_codes[i]) ? parser.value_int() : 0; + values[i] = parser.intval(axis_codes[i]); #if ENABLED(X_IS_TMC2130) if (values[X_AXIS]) tmc2130_set_current(stepperX, 'X', values[X_AXIS]); @@ -9650,7 +9645,7 @@ inline void gcode_M503() { inline void gcode_M913() { uint16_t values[XYZE]; LOOP_XYZE(i) - values[i] = parser.seen(axis_codes[i]) ? parser.value_int() : 0; + values[i] = parser.intval(axis_codes[i]); #if ENABLED(X_IS_TMC2130) if (values[X_AXIS]) tmc2130_set_pwmthrs(stepperX, 'X', values[X_AXIS], planner.axis_steps_per_mm[X_AXIS]); @@ -9737,14 +9732,14 @@ inline void gcode_M907() { inline void gcode_M908() { #if HAS_DIGIPOTSS stepper.digitalPotWrite( - parser.seen('P') ? parser.value_int() : 0, - parser.seen('S') ? parser.value_int() : 0 + parser.intval('P'), + parser.intval('S') ); #endif #ifdef DAC_STEPPER_CURRENT dac_current_raw( - parser.seen('P') ? parser.value_byte() : -1, - parser.seen('S') ? parser.value_ushort() : 0 + parser.byteval('P', -1), + parser.ushortval('S', 0) ); #endif } @@ -9774,14 +9769,14 @@ inline void gcode_M907() { * S# determines MS1 or MS2, X# sets the pin high/low. */ inline void gcode_M351() { - if (parser.seen('S')) switch (parser.value_byte()) { + if (parser.seenval('S')) switch (parser.value_byte()) { case 1: - LOOP_XYZE(i) if (parser.seen(axis_codes[i])) stepper.microstep_ms(i, parser.value_byte(), -1); - if (parser.seen('B')) stepper.microstep_ms(4, parser.value_byte(), -1); + LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, parser.value_byte(), -1); + if (parser.seenval('B')) stepper.microstep_ms(4, parser.value_byte(), -1); break; case 2: - LOOP_XYZE(i) if (parser.seen(axis_codes[i])) stepper.microstep_ms(i, -1, parser.value_byte()); - if (parser.seen('B')) stepper.microstep_ms(4, -1, parser.value_byte()); + LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, -1, parser.value_byte()); + if (parser.seenval('B')) stepper.microstep_ms(4, -1, parser.value_byte()); break; } stepper.microstep_readings(); @@ -9824,8 +9819,8 @@ inline void gcode_M907() { inline void gcode_M355() { #if HAS_CASE_LIGHT uint8_t args = 0; - if (parser.seen('P')) ++args, case_light_brightness = parser.value_byte(); - if (parser.seen('S')) ++args, case_light_on = parser.value_bool(); + if (parser.seenval('P')) ++args, case_light_brightness = parser.value_byte(); + if (parser.seenval('S')) ++args, case_light_on = parser.value_bool(); if (args) update_case_light(); // always report case light status @@ -9855,9 +9850,9 @@ inline void gcode_M355() { * */ inline void gcode_M163() { - const int mix_index = parser.seen('S') ? parser.value_int() : 0; + const int mix_index = parser.intval('S'); if (mix_index < MIXING_STEPPERS) { - float mix_value = parser.seen('P') ? parser.value_float() : 0.0; + float mix_value = parser.floatval('P'); NOLESS(mix_value, 0.0); mixing_factor[mix_index] = RECIPROCAL(mix_value); } @@ -9872,7 +9867,7 @@ inline void gcode_M355() { * */ inline void gcode_M164() { - const int tool_index = parser.seen('S') ? parser.value_int() : 0; + const int tool_index = parser.intval('S'); if (tool_index < MIXING_VIRTUAL_TOOLS) { normalize_mix(); for (uint8_t i = 0; i < MIXING_STEPPERS; i++) @@ -9915,7 +9910,7 @@ inline void gcode_M999() { Running = true; lcd_reset_alert_level(); - if (parser.seen('S') && parser.value_bool()) return; + if (parser.boolval('S')) return; // gcode_LastN = Stopped_gcode_LastN; FlushSerialRequestResend(); @@ -10297,8 +10292,8 @@ inline void gcode_T(uint8_t tmp_extruder) { tool_change( tmp_extruder, - parser.seen('F') ? MMM_TO_MMS(parser.value_linear_units()) : 0.0, - (tmp_extruder == active_extruder) || (parser.seen('S') && parser.value_bool()) + MMM_TO_MMS(parser.linearval('F')), + (tmp_extruder == active_extruder) || parser.boolval('S') ); #endif diff --git a/Marlin/SdFatStructs.h b/Marlin/SdFatStructs.h index 3e989dea9d02..3e78aa292778 100644 --- a/Marlin/SdFatStructs.h +++ b/Marlin/SdFatStructs.h @@ -523,7 +523,7 @@ struct directoryEntry { uint8_t reservedNT; /** * The granularity of the seconds part of creationTime is 2 seconds - * so this field is a count of tenths of a second and its valid + * so this field is a count of tenths of a second and it's valid * value range is 0-199 inclusive. (WHG note - seems to be hundredths) */ uint8_t creationTimeTenths; diff --git a/Marlin/example_configurations/K8400/README.md b/Marlin/example_configurations/K8400/README.md index c9089b5870bf..14c8f8362b8b 100644 --- a/Marlin/example_configurations/K8400/README.md +++ b/Marlin/example_configurations/K8400/README.md @@ -2,7 +2,7 @@ http://www.k8400.eu/ Configuration files for the K8400, ported upstream from the official Velleman firmware. -Like it's predecessor, (K8200), the K8400 is a 3Drag clone. There are some minor differences, documented in pins_K8400.h. +Like its predecessor, (K8200), the K8400 is a 3Drag clone. There are some minor differences, documented in pins_K8400.h. Single and dual head configurations provided. Copy the correct Configuration.h and Configuration_adv.h to the /Marlin/ directory. diff --git a/Marlin/gcode.h b/Marlin/gcode.h index 1cd1cfabcf38..42a5c89b1405 100644 --- a/Marlin/gcode.h +++ b/Marlin/gcode.h @@ -97,6 +97,13 @@ class GCodeParser { // Reset is done before parsing static void reset(); + // Index so that 'X' falls on index 24 + #define PARAM_IND(N) ((N) >> 3) + #define PARAM_BIT(N) ((N) & 0x7) + #define LETTER_OFF(N) ((N) - 'A' + 1) + #define LETTER_IND(N) PARAM_IND(LETTER_OFF(N)) + #define LETTER_BIT(N) PARAM_BIT(LETTER_OFF(N)) + #if ENABLED(FASTER_GCODE_PARSER) // Set the flag and pointer for a parameter @@ -105,14 +112,14 @@ class GCodeParser { , const bool debug=false #endif ) { - const uint8_t ind = c - 'A'; + const uint8_t ind = LETTER_OFF(c); if (ind >= COUNT(param)) return; // Only A-Z - SBI(codebits[ind >> 3], ind & 0x7); // parameter exists + SBI(codebits[PARAM_IND(ind)], PARAM_BIT(ind)); // parameter exists param[ind] = ptr ? ptr - command_ptr : 0; // parameter offset or 0 #if ENABLED(DEBUG_GCODE_PARSER) if (debug) { - SERIAL_ECHOPAIR("Set bit ", (int)(ind & 0x7)); - SERIAL_ECHOPAIR(" of index ", (int)(ind >> 3)); + SERIAL_ECHOPAIR("Set bit ", (int)PARAM_BIT(ind)); + SERIAL_ECHOPAIR(" of index ", (int)PARAM_IND(ind)); SERIAL_ECHOLNPAIR(" | param = ", hex_address((void*)param[ind])); } #endif @@ -120,22 +127,28 @@ class GCodeParser { // Code seen bit was set. If not found, value_ptr is unchanged. // This allows "if (seen('A')||seen('B'))" to use the last-found value. + // This is volatile because its side-effects are important static volatile bool seen(const char c) { - const uint8_t ind = c - 'A'; + const uint8_t ind = LETTER_OFF(c); if (ind >= COUNT(param)) return false; // Only A-Z - const bool b = TEST(codebits[ind >> 3], ind & 0x7); + const bool b = TEST(codebits[PARAM_IND(ind)], PARAM_BIT(ind)); if (b) value_ptr = command_ptr + param[ind]; return b; } - static volatile bool seen_any() { return codebits[3] || codebits[2] || codebits[1] || codebits[0]; } + static bool seen_any() { return codebits[3] || codebits[2] || codebits[1] || codebits[0]; } - #define SEEN_TEST(L) TEST(codebits[(L - 'A') >> 3], (L - 'A') & 0x7) + #define SEEN_TEST(L) TEST(codebits[LETTER_IND(L)], LETTER_BIT(L)) - #else + // Seen any axis parameter + // Optimized by moving 'X' up to index 24 + FORCE_INLINE bool seen_axis() { return codebits[3] || SEEN_TEST('E'); } + + #else // !FASTER_GCODE_PARSER // Code is found in the string. If not found, value_ptr is unchanged. // This allows "if (seen('A')||seen('B'))" to use the last-found value. + // This is volatile because its side-effects are important static volatile bool seen(const char c) { const char *p = strchr(command_args, c); const bool b = !!p; @@ -143,25 +156,26 @@ class GCodeParser { return b; } - static volatile bool seen_any() { return *command_args == '\0'; } + static bool seen_any() { return *command_args == '\0'; } #define SEEN_TEST(L) !!strchr(command_args, L) - #endif // FASTER_GCODE_PARSER + // Seen any axis parameter + static bool seen_axis() { + return SEEN_TEST('X') || SEEN_TEST('Y') || SEEN_TEST('Z') || SEEN_TEST('E'); + } + + #endif // !FASTER_GCODE_PARSER // Populate all fields by parsing a single line of GCode // This uses 54 bytes of SRAM to speed up seen/value static void parse(char * p); - // Code value pointer was set + // The code value pointer was set FORCE_INLINE static bool has_value() { return value_ptr != NULL; } - // Seen and has value - FORCE_INLINE static bool seenval(const char c) { return seen(c) && has_value(); } - - static volatile bool seen_axis() { - return SEEN_TEST('X') || SEEN_TEST('Y') || SEEN_TEST('Z') || SEEN_TEST('E'); - } + // Seen a parameter with a value + inline static bool seenval(const char c) { return seen(c) && has_value(); } // Float removes 'E' to prevent scientific notation interpretation inline static float value_float() { @@ -184,20 +198,20 @@ class GCodeParser { } // Code value as a long or ulong - inline static long value_long() { return value_ptr ? strtol(value_ptr, NULL, 10) : 0L; } - inline unsigned static long value_ulong() { return value_ptr ? strtoul(value_ptr, NULL, 10) : 0UL; } + inline static int32_t value_long() { return value_ptr ? strtol(value_ptr, NULL, 10) : 0L; } + inline static uint32_t value_ulong() { return value_ptr ? strtoul(value_ptr, NULL, 10) : 0UL; } // Code value for use as time FORCE_INLINE static millis_t value_millis() { return value_ulong(); } FORCE_INLINE static millis_t value_millis_from_seconds() { return value_float() * 1000UL; } // Reduce to fewer bits - FORCE_INLINE static int value_int() { return (int)value_long(); } - FORCE_INLINE uint16_t value_ushort() { return (uint16_t)value_long(); } - inline static uint8_t value_byte() { return (uint8_t)(constrain(value_long(), 0, 255)); } + FORCE_INLINE static int16_t value_int() { return (int16_t)value_long(); } + FORCE_INLINE static uint16_t value_ushort() { return (uint16_t)value_long(); } + inline static uint8_t value_byte() { return (uint8_t)constrain(value_long(), 0, 255); } // Bool is true with no value or non-zero - inline static bool value_bool() { return !has_value() || value_byte(); } + inline static bool value_bool() { return !has_value() || value_byte(); } // Units modes: Inches, Fahrenheit, Kelvin @@ -282,17 +296,28 @@ class GCodeParser { } } - #else + #else // !TEMPERATURE_UNITS_SUPPORT FORCE_INLINE static float value_celsius() { return value_float(); } FORCE_INLINE static float value_celsius_diff() { return value_float(); } - #endif + #endif // !TEMPERATURE_UNITS_SUPPORT FORCE_INLINE static float value_feedrate() { return value_linear_units(); } void unknown_command_error(); + // Provide simple value accessors with default option + FORCE_INLINE static float floatval(const char c, const float dval=0.0) { return seenval(c) ? value_float() : dval; } + FORCE_INLINE static bool boolval(const char c, const bool dval=false) { return seen(c) ? value_bool() : dval; } + FORCE_INLINE static uint8_t byteval(const char c, const uint8_t dval=0) { return seenval(c) ? value_byte() : dval; } + FORCE_INLINE static int16_t intval(const char c, const int16_t dval=0) { return seenval(c) ? value_int() : dval; } + FORCE_INLINE static uint16_t ushortval(const char c, const uint16_t dval=0) { return seenval(c) ? value_ushort() : dval; } + FORCE_INLINE static int32_t longval(const char c, const int32_t dval=0) { return seenval(c) ? value_long() : dval; } + FORCE_INLINE static uint32_t ulongval(const char c, const uint32_t dval=0) { return seenval(c) ? value_ulong() : dval; } + FORCE_INLINE static float linearval(const char c, const float dval=0.0) { return seenval(c) ? value_linear_units() : dval; } + FORCE_INLINE static float celsiusval(const char c, const float dval=0.0) { return seenval(c) ? value_celsius() : dval; } + }; extern GCodeParser parser; diff --git a/Marlin/servo.cpp b/Marlin/servo.cpp index 3536571c17fc..74feb5c61424 100644 --- a/Marlin/servo.cpp +++ b/Marlin/servo.cpp @@ -95,7 +95,7 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) { *OCRnA = *TCNTn + SERVO(timer, Channel[timer]).ticks; if (SERVO(timer, Channel[timer]).Pin.isActive) // check if activated - digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // its an active channel so pulse it high + digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high } else { // finished all channels so wait for the refresh period to expire before starting over diff --git a/Marlin/twibus.h b/Marlin/twibus.h index b93cd1c4ca7d..5d496393498c 100644 --- a/Marlin/twibus.h +++ b/Marlin/twibus.h @@ -38,18 +38,18 @@ typedef void (*twiRequestFunc_t)(); /** * TWIBUS class * - * This class implements a wrapper around the two wire (I2C) bus, it allows - * Marlin to send and request data from any slave device on the bus. This is - * an experimental feature and it's inner workings as well as public facing - * interface are prune to change in the future. + * This class implements a wrapper around the two wire (I2C) bus, allowing + * Marlin to send and request data from any slave device on the bus. * - * The two main consumers of this class are M260 and M261, where M260 allows - * Marlin to send a I2C packet to a device (please be aware that no repeated - * starts are possible), this can be done in caching method by calling multiple - * times M260 B or a one liner M260, have a look at - * the gcode_M260() function for more information. M261 allows Marlin to - * request data from a device, the received data is then relayed into the serial - * line for host interpretation. + * The two main consumers of this class are M260 and M261. M260 provides a way + * to send an I2C packet to a device (no repeated starts) by caching up to 32 + * bytes in a buffer and then sending the buffer. + * M261 requests data from a device. The received data is relayed to serial out + * for the host to interpret. + * + * For more information see + * - http://marlinfw.org/docs/gcode/M260.html + * - http://marlinfw.org/docs/gcode/M261.html * */ class TWIBus { diff --git a/Marlin/ubl_G29.cpp b/Marlin/ubl_G29.cpp index c70755a33124..294e3616a319 100644 --- a/Marlin/ubl_G29.cpp +++ b/Marlin/ubl_G29.cpp @@ -314,7 +314,7 @@ // Check for commands that require the printer to be homed if (axis_unhomed_error()) { - const int8_t p_val = parser.seen('P') && parser.has_value() ? parser.value_int() : -1; + const int8_t p_val = parser.intval('P', -1); if (p_val == 1 || p_val == 2 || p_val == 4 || parser.seen('J')) home_all_axes(); } @@ -492,7 +492,7 @@ return; } - const float height = parser.seen('H') && parser.has_value() ? parser.value_float() : Z_CLEARANCE_BETWEEN_PROBES; + const float height = parser.floatval('H', Z_CLEARANCE_BETWEEN_PROBES); manually_probe_remaining_mesh(g29_x_pos, g29_y_pos, height, g29_card_thickness, parser.seen('T')); SERIAL_PROTOCOLLNPGM("G29 P2 finished."); @@ -1094,9 +1094,9 @@ g29_constant = 0.0; g29_repetition_cnt = 0; - g29_x_flag = parser.seen('X') && parser.has_value(); + g29_x_flag = parser.seenval('X'); g29_x_pos = g29_x_flag ? parser.value_float() : current_position[X_AXIS]; - g29_y_flag = parser.seen('Y') && parser.has_value(); + g29_y_flag = parser.seenval('Y'); g29_y_pos = g29_y_flag ? parser.value_float() : current_position[Y_AXIS]; if (parser.seen('R')) { @@ -1170,7 +1170,7 @@ g29_constant = parser.value_float(); #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - if (parser.seen('F') && parser.has_value()) { + if (parser.seenval('F')) { const float fh = parser.value_float(); if (!WITHIN(fh, 0.0, 100.0)) { SERIAL_PROTOCOLLNPGM("?(F)ade height for Bed Level Correction not plausible.\n"); @@ -1180,7 +1180,7 @@ } #endif - g29_map_type = parser.seen('T') && parser.has_value() ? parser.value_int() : 0; + g29_map_type = parser.intval('T'); if (!WITHIN(g29_map_type, 0, 2)) { SERIAL_PROTOCOLLNPGM("Invalid map type.\n"); return UBL_ERR;