diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 7f25f07d5..d25b345c3 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -287,6 +287,7 @@ #ifdef LIN_ADVANCE #define LIN_ADVANCE_K 0 // Unit: mm compression per 1mm/s extruder speed + //#define LA_NOCOMPAT // Disable Linear Advance 1.0 compatibility //#define LA_LIVE_K // Allow adjusting K in the Tune menu //#define LA_DEBUG // If enabled, this will generate debug information output over USB. //#define LA_DEBUG_LOGIC // @wavexx: setup logic channels for isr debugging diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 816763ac1..8959bdd31 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -83,6 +83,9 @@ #include "Dcodes.h" #include "AutoDeplete.h" +#ifndef LA_NOCOMPAT +#include "la10compat.h" +#endif #ifdef SWSPI #include "swspi.h" @@ -2068,12 +2071,23 @@ static float probe_pt(float x, float y, float z_before) { */ inline void gcode_M900() { st_synchronize(); - + const float newK = code_seen('K') ? code_value_float() : -1; +#ifdef LA_NOCOMPAT if (newK >= 0 && newK < 10) - extruder_advance_K = newK; + extruder_advance_K = newK; else - SERIAL_ECHOLNPGM("K out of allowed range!"); + SERIAL_ECHOLNPGM("K out of allowed range!"); +#else + if (newK == 0) { + la10c_reset(); + extruder_advance_K = 0; + } + else if(newK > 0) + extruder_advance_K = la10c_value(newK); + else + SERIAL_ECHOLNPGM("K out of allowed range!"); +#endif SERIAL_ECHO_START; SERIAL_ECHOPGM("Advance K="); @@ -4136,6 +4150,9 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) // -------------------------------------------- case 28: { +#ifndef LA_NOCOMPAT + la10c_reset(); +#endif long home_x_value = 0; long home_y_value = 0; long home_z_value = 0; @@ -5372,6 +5389,9 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) else { failstats_reset_print(); +#ifndef LA_NOCOMPAT + la10c_reset(); +#endif card.startFileprint(); starttime=_millis(); } @@ -5465,6 +5485,9 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) if(code_seen('S')) if(strchr_pointerLA15 conversion +// +// When the current mode is UNKNOWN autodetection is active and any K<10 +// will set the mode to LA15, LA10 is set otherwise. When LA10 +// compatbility mode is active the K factor is converted to a LA15 +// equivalent (that is, the return value is always a LA15 value). +// +// Once the interpretation mode has been set it is kept until the mode +// is explicitly reset. This is done to handle transparent fallback for +// old firmware revisions in combination with the following gcode +// sequence: +// +// M900 K0.01 ; set LA15 value (interpreted by any firmware) +// M900 K10 ; set LA10 value (ignored by LA15 firmware) +// +// A LA15 firmware without this module will only parse the first +// correctly, rejecting the second. A LA10 FW will parse both, but keep +// the last value. Since the LA15 value, if present, corresponds to the +// truth value, the compatibility stub needs to "lock" onto the first +// seen value for the current print. +// +// The mode needs to be carefully reset for each print in order for +// diffent versions of M900 to be interpreted independently. + +#pragma once + +enum __attribute__((packed)) LA10C_MODE +{ + LA10C_UNKNOWN = 0, + LA10C_LA15 = 1, + LA10C_LA10 = 2 +}; + +// Explicitly set/reset the interpretation mode for la10c_value() +void la10c_mode_change(LA10C_MODE mode); +static inline void la10c_reset() { la10c_mode_change(LA10C_UNKNOWN); } + +// Return a LA15 K value according to the supplied value and mode +float la10c_value(float k);