diff --git a/Marlin/src/gcode/host/M360.cpp b/Marlin/src/gcode/host/M360.cpp index 63071f6113..a3f86d615d 100644 --- a/Marlin/src/gcode/host/M360.cpp +++ b/Marlin/src/gcode/host/M360.cpp @@ -22,6 +22,10 @@ #include "../../inc/MarlinConfig.h" +/** + * M360 Report Printer Configuration - Repetier Firmware + * See https://github.com/repetier/Repetier-Firmware/blob/master/src/ArduinoAVR/Repetier/Printer.cpp + */ #if ENABLED(REPETIER_GCODE_M360) #include "../gcode.h" @@ -33,74 +37,112 @@ #include "../../module/temperature.h" #endif -static void config_prefix(PGM_P const name, PGM_P const pref=nullptr, const int8_t ind=-1) { +#include + +struct ProgStr { + PGM_P ptr; + constexpr ProgStr(PGM_P p) : ptr(p) {} + ProgStr(FSTR_P f) : ptr(FTOP(f)) {} + ProgStr(std::nullptr_t) : ptr(nullptr) {} + + constexpr operator PGM_P() const { return ptr; } + constexpr explicit operator bool() const { return ptr != nullptr; } +}; + +static void config_prefix(ProgStr name, ProgStr pref=nullptr, int8_t ind=-1) { SERIAL_ECHOPGM("Config:"); - if (pref) SERIAL_ECHOPGM_P(pref); + if (pref) SERIAL_ECHOPGM_P(static_cast(pref)); if (ind >= 0) { SERIAL_ECHO(ind); SERIAL_CHAR(':'); } - SERIAL_ECHOPGM_P(name, C(':')); + SERIAL_ECHOPGM_P(static_cast(name), C(':')); } -static void config_line(PGM_P const name, const float val, PGM_P const pref=nullptr, const int8_t ind=-1) { + +template +static void config_line(ProgStr name, const T val, ProgStr pref=nullptr, int8_t ind=-1) { config_prefix(name, pref, ind); SERIAL_ECHOLN(val); } -static void config_line(FSTR_P const name, const float val, FSTR_P const pref=nullptr, const int8_t ind=-1) { - config_line(FTOP(name), val, FTOP(pref), ind); -} -static void config_line_e(const int8_t e, PGM_P const name, const float val) { + +template +static void config_line_e(int8_t e, ProgStr name, const T val) { config_line(name, val, PSTR("Extr."), e + 1); } -static void config_line_e(const int8_t e, FSTR_P const name, const float val) { - config_line_e(e, FTOP(name), val); -} - /** * M360: Report Firmware configuration * in RepRapFirmware-compatible format */ void GcodeSuite::M360() { - PGMSTR(X_STR, "X"); - PGMSTR(Y_STR, "Y"); - PGMSTR(Z_STR, "Z"); - #if ANY(CLASSIC_JERK, HAS_LINEAR_E_JERK) - PGMSTR(JERK_STR, "Jerk"); - #endif - // // Basics and Enabled items // config_line(F("Baudrate"), BAUDRATE); config_line(F("InputBuffer"), MAX_CMD_SIZE); config_line(F("PrintlineCache"), BUFSIZE); - config_line(F("MixingExtruder"), ENABLED(MIXING_EXTRUDER)); - config_line(F("SDCard"), ENABLED(HAS_MEDIA)); - config_line(F("Fan"), ENABLED(HAS_FAN)); - config_line(F("LCD"), ENABLED(HAS_DISPLAY)); + config_line(F("MixingExtruder"), bool(ENABLED(MIXING_EXTRUDER))); + config_line(F("SDCard"), bool(ENABLED(HAS_MEDIA))); + config_line(F("Fan"), bool(ENABLED(HAS_FAN))); + config_line(F("LCD"), bool(ENABLED(HAS_DISPLAY))); config_line(F("SoftwarePowerSwitch"), 1); - config_line(F("SupportLocalFilamentchange"), ENABLED(ADVANCED_PAUSE_FEATURE)); - config_line(F("CaseLights"), ENABLED(CASE_LIGHT_ENABLE)); - config_line(F("ZProbe"), ENABLED(HAS_BED_PROBE)); - config_line(F("Autolevel"), ENABLED(HAS_LEVELING)); - config_line(F("EEPROM"), ENABLED(EEPROM_SETTINGS)); + config_line(F("SupportLocalFilamentchange"), bool(ENABLED(ADVANCED_PAUSE_FEATURE))); + config_line(F("CaseLights"), bool(ENABLED(CASE_LIGHT_ENABLE))); + config_line(F("ZProbe"), bool(ENABLED(HAS_BED_PROBE))); + config_line(F("Autolevel"), bool(ENABLED(HAS_LEVELING))); + config_line(F("EEPROM"), bool(ENABLED(EEPROM_SETTINGS))); + + // + // Axis letters, in PROGMEM + // + #define _DEFINE_A_STR(Q) PGMSTR(Q##_STR, STR_##Q); + MAIN_AXIS_MAP(_DEFINE_A_STR); // // Homing Directions // PGMSTR(H_DIR_STR, "HomeDir"); - config_line(H_DIR_STR, X_HOME_DIR, X_STR); - config_line(H_DIR_STR, Y_HOME_DIR, Y_STR); - config_line(H_DIR_STR, Z_HOME_DIR, Z_STR); + #if X_HOME_DIR + config_line(H_DIR_STR, X_HOME_DIR, X_STR); + #endif + #if Y_HOME_DIR + config_line(H_DIR_STR, Y_HOME_DIR, Y_STR); + #endif + #if Z_HOME_DIR + config_line(H_DIR_STR, Z_HOME_DIR, Z_STR); + #endif + #if I_HOME_DIR + config_line(H_DIR_STR, I_HOME_DIR, I_STR); + #endif + #if J_HOME_DIR + config_line(H_DIR_STR, J_HOME_DIR, J_STR); + #endif + #if K_HOME_DIR + config_line(H_DIR_STR, K_HOME_DIR, K_STR); + #endif + #if U_HOME_DIR + config_line(H_DIR_STR, U_HOME_DIR, U_STR); + #endif + #if V_HOME_DIR + config_line(H_DIR_STR, V_HOME_DIR, V_STR); + #endif + #if W_HOME_DIR + config_line(H_DIR_STR, W_HOME_DIR, W_STR); + #endif + + #if ANY(CLASSIC_JERK, HAS_LINEAR_E_JERK) + PGMSTR(JERK_STR, "Jerk"); + #endif // // XYZ Axis Jerk // #if ENABLED(CLASSIC_JERK) - if (planner.max_jerk.x == planner.max_jerk.y) - config_line(F("XY"), planner.max_jerk.x, FPSTR(JERK_STR)); + #define _REPORT_JERK(Q) config_line(Q##_STR, planner.max_jerk.Q, JERK_STR); + if (TERN0(HAS_Y_AXIS, planner.max_jerk.x == planner.max_jerk.y)) + config_line(F("XY"), planner.max_jerk.x, JERK_STR); else { - config_line(X_STR, planner.max_jerk.x, JERK_STR); - config_line(Y_STR, planner.max_jerk.y, JERK_STR); + TERN_(HAS_X_AXIS, _REPORT_JERK(X)); + TERN_(HAS_Y_AXIS, _REPORT_JERK(Y)); } - config_line(Z_STR, planner.max_jerk.z, JERK_STR); + TERN_(HAS_Z_AXIS, config_line(Z_STR, planner.max_jerk.z, JERK_STR)); + SECONDARY_AXIS_MAP(_REPORT_JERK); #endif // @@ -112,53 +154,62 @@ void GcodeSuite::M360() { PGMSTR(UNRET_STR, "RetractionUndo"); PGMSTR(SPEED_STR, "Speed"); // M10 Retract with swap (long) moves - config_line(F("Length"), fwretract.settings.retract_length, FPSTR(RET_STR)); + config_line(F("Length"), fwretract.settings.retract_length, RET_STR); + config_line(F("LongLength"), fwretract.settings.swap_retract_length, RET_STR); config_line(SPEED_STR, fwretract.settings.retract_feedrate_mm_s, RET_STR); - config_line(F("ZLift"), fwretract.settings.retract_zraise, FPSTR(RET_STR)); - config_line(F("LongLength"), fwretract.settings.swap_retract_length, FPSTR(RET_STR)); + config_line(F("ZLift"), fwretract.settings.retract_zraise, RET_STR); // M11 Recover (undo) with swap (long) moves + config_line(F("ExtraLength"), fwretract.settings.retract_recover_extra, UNRET_STR); + config_line(F("ExtraLongLength"), fwretract.settings.swap_retract_recover_extra, UNRET_STR); config_line(SPEED_STR, fwretract.settings.retract_recover_feedrate_mm_s, UNRET_STR); - config_line(F("ExtraLength"), fwretract.settings.retract_recover_extra, FPSTR(UNRET_STR)); - config_line(F("ExtraLongLength"), fwretract.settings.swap_retract_recover_extra, FPSTR(UNRET_STR)); - config_line(F("LongSpeed"), fwretract.settings.swap_retract_recover_feedrate_mm_s, FPSTR(UNRET_STR)); + config_line(F("LongSpeed"), fwretract.settings.swap_retract_recover_feedrate_mm_s, UNRET_STR); #endif // // Workspace boundaries // - const xyz_pos_t dmin = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS }, - dmax = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS }; + const xyz_pos_t dmin = NUM_AXIS_ARRAY(X_MIN_POS, Y_MIN_POS, Z_MIN_POS, I_MIN_POS, J_MIN_POS, K_MIN_POS, U_MIN_POS, V_MIN_POS, W_MIN_POS), + dmax = NUM_AXIS_ARRAY(X_MAX_POS, Y_MAX_POS, Z_MAX_POS, I_MAX_POS, J_MAX_POS, K_MAX_POS, U_MAX_POS, V_MAX_POS, W_MAX_POS); xyz_pos_t cmin = dmin, cmax = dmax; apply_motion_limits(cmin); apply_motion_limits(cmax); const xyz_pos_t wmin = cmin.asLogical(), wmax = cmax.asLogical(); PGMSTR(MIN_STR, "Min"); + #define _REPORT_MIN(Q) config_line(MIN_STR, wmin.Q, Q##_STR); + MAIN_AXIS_MAP(_REPORT_MIN); + PGMSTR(MAX_STR, "Max"); + #define _REPORT_MAX(Q) config_line(MAX_STR, wmax.Q, Q##_STR); + MAIN_AXIS_MAP(_REPORT_MAX); + PGMSTR(SIZE_STR, "Size"); - config_line(MIN_STR, wmin.x, X_STR); - config_line(MIN_STR, wmin.y, Y_STR); - config_line(MIN_STR, wmin.z, Z_STR); - config_line(MAX_STR, wmax.x, X_STR); - config_line(MAX_STR, wmax.y, Y_STR); - config_line(MAX_STR, wmax.z, Z_STR); - config_line(SIZE_STR, wmax.x - wmin.x, X_STR); - config_line(SIZE_STR, wmax.y - wmin.y, Y_STR); - config_line(SIZE_STR, wmax.z - wmin.z, Z_STR); + #define _REPORT_SIZE(Q) config_line(SIZE_STR, wmax.Q - wmin.Q, Q##_STR); + MAIN_AXIS_MAP(_REPORT_SIZE); + + // + // Axis Steps per mm + // + PGMSTR(S_MM_STR, "Steps/mm"); + #define _REPORT_S_MM(Q) config_line(S_MM_STR, planner.settings.axis_steps_per_mm[_AXIS(Q)], Q##_STR); + MAIN_AXIS_MAP(_REPORT_S_MM); // // Print and Travel Acceleration // - #define _ACCEL(A,B) _MIN(planner.settings.max_acceleration_mm_per_s2[A##_AXIS], planner.settings.B) - PGMSTR(P_ACC_STR, "PrintAccel"); - PGMSTR(T_ACC_STR, "TravelAccel"); - config_line(P_ACC_STR, _ACCEL(X, acceleration), X_STR); - config_line(P_ACC_STR, _ACCEL(Y, acceleration), Y_STR); - config_line(P_ACC_STR, _ACCEL(Z, acceleration), Z_STR); - config_line(T_ACC_STR, _ACCEL(X, travel_acceleration), X_STR); - config_line(T_ACC_STR, _ACCEL(Y, travel_acceleration), Y_STR); - config_line(T_ACC_STR, _ACCEL(Z, travel_acceleration), Z_STR); + #define _ACCEL(Q,B) _MIN(planner.settings.max_acceleration_mm_per_s2[Q##_AXIS], planner.settings.B) + PGMSTR(P_ACC_STR, "PrintAccel"); + #define _REPORT_P_ACC(Q) config_line(P_ACC_STR, _ACCEL(Q, acceleration), Q##_STR); + MAIN_AXIS_MAP(_REPORT_P_ACC); + + PGMSTR(T_ACC_STR, "TravelAccel"); + #define _REPORT_T_ACC(Q) config_line(T_ACC_STR, _ACCEL(Q, travel_acceleration), Q##_STR); + MAIN_AXIS_MAP(_REPORT_T_ACC); + + // + // Printer Type + // config_prefix(PSTR("PrinterType")); SERIAL_ECHOLNPGM( TERN_(DELTA, "Delta") @@ -189,12 +240,12 @@ void GcodeSuite::M360() { #elif ENABLED(CLASSIC_JERK) config_line_e(e, JERK_STR, planner.max_jerk.e); #endif - config_line_e(e, F("MaxSpeed"), planner.settings.max_feedrate_mm_s[E_AXIS_N(e)]); config_line_e(e, F("Acceleration"), planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(e)]); + config_line_e(e, F("MaxSpeed"), planner.settings.max_feedrate_mm_s[E_AXIS_N(e)]); config_line_e(e, F("Diameter"), TERN(NO_VOLUMETRICS, DEFAULT_NOMINAL_FILAMENT_DIA, planner.filament_size[e])); config_line_e(e, F("MaxTemp"), thermalManager.hotend_maxtemp[e]); } #endif } -#endif +#endif // REPETIER_GCODE_M360