Updates from #24560

This commit is contained in:
Keith Bennett 2022-07-29 04:12:38 -07:00 committed by Scott Lahteine
parent 752f3d440d
commit 2952f0be5d
23 changed files with 163 additions and 148 deletions

View file

@ -34,8 +34,11 @@ This project and everyone participating in it is governed by the [Marlin Code of
We have a Message Board and a Facebook group where our knowledgable user community can provide helpful advice if you have questions. We have a Message Board and a Facebook group where our knowledgable user community can provide helpful advice if you have questions.
* [Marlin RepRap forum](https://reprap.org/forum/list.php?415) - [Marlin Documentation](https://marlinfw.org) - Official Marlin documentation
* [MarlinFirmware on Facebook](https://www.facebook.com/groups/1049718498464482/) - Facebook Group ["Marlin Firmware"](https://www.facebook.com/groups/1049718498464482/)
- RepRap.org [Marlin Forum](https://forums.reprap.org/list.php?415)
- Facebook Group ["Marlin Firmware for 3D Printers"](https://www.facebook.com/groups/3Dtechtalk/)
- [Marlin Configuration](https://www.youtube.com/results?search_query=marlin+configuration) on YouTube
If chat is more your speed, you can join the MarlinFirmware Discord server: If chat is more your speed, you can join the MarlinFirmware Discord server:

View file

@ -2426,7 +2426,7 @@
/** /**
* Extra G-code to run while executing tool-change commands. Can be used to use an additional * Extra G-code to run while executing tool-change commands. Can be used to use an additional
* stepper motor (I axis, see option LINEAR_AXES in Configuration.h) to drive the tool-changer. * stepper motor (e.g., I axis in Configuration.h) to drive the tool-changer.
*/ */
//#define EVENT_GCODE_TOOLCHANGE_T0 "G28 A\nG1 A0" // Extra G-code to run while executing tool-change command T0 //#define EVENT_GCODE_TOOLCHANGE_T0 "G28 A\nG1 A0" // Extra G-code to run while executing tool-change command T0
//#define EVENT_GCODE_TOOLCHANGE_T1 "G1 A10" // Extra G-code to run while executing tool-change command T1 //#define EVENT_GCODE_TOOLCHANGE_T1 "G1 A10" // Extra G-code to run while executing tool-change command T1

View file

@ -91,7 +91,7 @@ void do_enable(const stepper_flags_t to_enable) {
if ((also_enabled &= ~(shall_enable | was_enabled))) { if ((also_enabled &= ~(shall_enable | was_enabled))) {
SERIAL_CHAR('('); SERIAL_CHAR('(');
LOOP_LINEAR_AXES(a) if (TEST(also_enabled, a)) SERIAL_CHAR(axis_codes[a], ' '); LOOP_LINEAR_AXES(a) if (TEST(also_enabled, a)) SERIAL_CHAR(AXIS_CHAR(a), ' ');
#if HAS_EXTRUDERS #if HAS_EXTRUDERS
#define _EN_ALSO(N) if (TEST(also_enabled, INDEX_OF_AXIS(E_AXIS, N))) SERIAL_CHAR('E', '0' + N, ' '); #define _EN_ALSO(N) if (TEST(also_enabled, INDEX_OF_AXIS(E_AXIS, N))) SERIAL_CHAR('E', '0' + N, ' ');
REPEAT(EXTRUDERS, _EN_ALSO) REPEAT(EXTRUDERS, _EN_ALSO)

View file

@ -186,7 +186,6 @@ void GcodeSuite::M569_report(const bool forReplay/*=true*/) {
if (TERN0(Z3_HAS_STEALTHCHOP, stepperZ3.get_stored_stealthChop())) { say_M569(forReplay, F("I2 Z"), true); } if (TERN0(Z3_HAS_STEALTHCHOP, stepperZ3.get_stored_stealthChop())) { say_M569(forReplay, F("I2 Z"), true); }
if (TERN0(Z4_HAS_STEALTHCHOP, stepperZ4.get_stored_stealthChop())) { say_M569(forReplay, F("I3 Z"), true); } if (TERN0(Z4_HAS_STEALTHCHOP, stepperZ4.get_stored_stealthChop())) { say_M569(forReplay, F("I3 Z"), true); }
#if HAS_I_AXIS #if HAS_I_AXIS
if (TERN0(I_HAS_STEALTHCHOP, stepperI.get_stored_stealthChop())) { say_M569(forReplay, FPSTR(SP_I_STR), true); } if (TERN0(I_HAS_STEALTHCHOP, stepperI.get_stored_stealthChop())) { say_M569(forReplay, FPSTR(SP_I_STR), true); }
#endif #endif

View file

@ -39,10 +39,8 @@
*/ */
void GcodeSuite::M206() { void GcodeSuite::M206() {
if (!parser.seen_any()) return M206_report(); if (!parser.seen_any()) return M206_report();
LOOP_LINEAR_AXES(a) LOOP_LINEAR_AXES(a)
if (parser.seenval(AXIS_CHAR(a))) set_home_offset((AxisEnum)a, parser.value_axis_units((AxisEnum)a)); if (parser.seenval(AXIS_CHAR(a))) set_home_offset((AxisEnum)a, parser.value_axis_units((AxisEnum)a));
#if ENABLED(MORGAN_SCARA) #if ENABLED(MORGAN_SCARA)
if (parser.seenval('T')) set_home_offset(A_AXIS, parser.value_float()); // Theta if (parser.seenval('T')) set_home_offset(A_AXIS, parser.value_float()); // Theta
if (parser.seenval('P')) set_home_offset(B_AXIS, parser.value_float()); // Psi if (parser.seenval('P')) set_home_offset(B_AXIS, parser.value_float()); // Psi

View file

@ -824,7 +824,7 @@
* Number of Primary Linear Axes (e.g., XYZ) * Number of Primary Linear Axes (e.g., XYZ)
* X, XY, or XYZ axes. Excluding duplicate axes (X2, Y2. Z2. Z3, Z4) * X, XY, or XYZ axes. Excluding duplicate axes (X2, Y2. Z2. Z3, Z4)
*/ */
#if HAS_I_AXIS #if LINEAR_AXES >= 3
#define PRIMARY_LINEAR_AXES 3 #define PRIMARY_LINEAR_AXES 3
#else #else
#define PRIMARY_LINEAR_AXES LINEAR_AXES #define PRIMARY_LINEAR_AXES LINEAR_AXES
@ -961,7 +961,7 @@
#endif #endif
/** /**
* Set a flag for any type of bed probe, including the paper-test * Set flags for any form of bed probe
*/ */
#if ANY(HAS_Z_SERVO_PROBE, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, SOLENOID_PROBE, SENSORLESS_PROBING, RACK_AND_PINION_PROBE, MAGLEV4) #if ANY(HAS_Z_SERVO_PROBE, FIX_MOUNTED_PROBE, NOZZLE_AS_PROBE, TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, Z_PROBE_SLED, SOLENOID_PROBE, SENSORLESS_PROBING, RACK_AND_PINION_PROBE, MAGLEV4)
#define HAS_BED_PROBE 1 #define HAS_BED_PROBE 1
@ -1284,29 +1284,6 @@
#define HAS_ETHERNET 1 #define HAS_ETHERNET 1
#endif #endif
// Fallback axis inverting
#ifndef INVERT_X_DIR
#define INVERT_X_DIR false
#endif
#if HAS_Y_AXIS && !defined(INVERT_Y_DIR)
#define INVERT_Y_DIR false
#endif
#if HAS_Z_AXIS && !defined(INVERT_Z_DIR)
#define INVERT_Z_DIR false
#endif
#if HAS_I_AXIS && !defined(INVERT_I_DIR)
#define INVERT_I_DIR false
#endif
#if HAS_J_AXIS && !defined(INVERT_J_DIR)
#define INVERT_J_DIR false
#endif
#if HAS_K_AXIS && !defined(INVERT_K_DIR)
#define INVERT_K_DIR false
#endif
#if HAS_EXTRUDERS && !defined(INVERT_E_DIR)
#define INVERT_E_DIR false
#endif
/** /**
* This setting is also used by M109 when trying to calculate * This setting is also used by M109 when trying to calculate
* a ballpark safe margin to prevent wait-forever situation. * a ballpark safe margin to prevent wait-forever situation.

View file

@ -120,10 +120,11 @@ static void createChar_P(const char c, const byte * const ptr) {
#endif #endif
#if ENABLED(LCD_USE_I2C_BUZZER) #if ENABLED(LCD_USE_I2C_BUZZER)
void MarlinUI::buzz(const long duration, const uint16_t freq) { void MarlinUI::buzz(const long duration, const uint16_t freq) {
if (!sound_on) return; if (sound_on) lcd.buzz(duration, freq);
lcd.buzz(duration, freq);
} }
#endif #endif
void MarlinUI::set_custom_characters(const HD44780CharSet screen_charset/*=CHARSET_INFO*/) { void MarlinUI::set_custom_characters(const HD44780CharSet screen_charset/*=CHARSET_INFO*/) {

View file

@ -44,7 +44,7 @@ extern xyze_pos_t current_position, // High-level current tool position
// G60/G61 Position Save and Return // G60/G61 Position Save and Return
#if SAVED_POSITIONS #if SAVED_POSITIONS
extern uint8_t saved_slots[(SAVED_POSITIONS + 7) >> 3]; // TODO: Add support for LINEAR_AXES >= 4 extern uint8_t saved_slots[(SAVED_POSITIONS + 7) >> 3]; // TODO: Add support for HAS_I_AXIS
extern xyze_pos_t stored_position[SAVED_POSITIONS]; extern xyze_pos_t stored_position[SAVED_POSITIONS];
#endif #endif

View file

@ -877,7 +877,6 @@
#undef BOARD_STM32F103R #undef BOARD_STM32F103R
#undef BOARD_ESP32 #undef BOARD_ESP32
#undef BOARD_STEVAL #undef BOARD_STEVAL
#undef BOARD_BIGTREE_SKR_MINI_E3
#undef BOARD_BIGTREE_SKR_V1_1 #undef BOARD_BIGTREE_SKR_V1_1
#undef BOARD_BIGTREE_SKR_V1_3 #undef BOARD_BIGTREE_SKR_V1_3
#undef BOARD_BIGTREE_SKR_V1_4 #undef BOARD_BIGTREE_SKR_V1_4
@ -885,6 +884,7 @@
#undef BOARD_BIGTREE_BTT002_V1_0 #undef BOARD_BIGTREE_BTT002_V1_0
#undef BOARD_BIGTREE_SKR_PRO_V1_1 #undef BOARD_BIGTREE_SKR_PRO_V1_1
#undef BOARD_BIGTREE_SKR_MINI_V1_1 #undef BOARD_BIGTREE_SKR_MINI_V1_1
#undef BOARD_BIGTREE_SKR_MINI_E3
#undef BOARD_BIGTREE_SKR_E3_DIP #undef BOARD_BIGTREE_SKR_E3_DIP
#undef BOARD_RUMBA32 #undef BOARD_RUMBA32
#undef BOARD_RUMBA32_AUS3D #undef BOARD_RUMBA32_AUS3D

View file

@ -272,7 +272,9 @@
#if HAS_CUTTER && !defined(SPINDLE_LASER_ENA_PIN) #if HAS_CUTTER && !defined(SPINDLE_LASER_ENA_PIN)
#if NUM_SERVOS < 2 // Use servo connector if possible #if NUM_SERVOS < 2 // Use servo connector if possible
#define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown! #define SPINDLE_LASER_ENA_PIN 4 // Pullup or pulldown!
#define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM #ifndef SPINDLE_LASER_PWM_PIN
#define SPINDLE_LASER_PWM_PIN 6 // Hardware PWM
#endif
#define SPINDLE_DIR_PIN 5 #define SPINDLE_DIR_PIN 5
#elif HAS_FREE_AUX2_PINS #elif HAS_FREE_AUX2_PINS
#define SPINDLE_LASER_ENA_PIN 40 // Pullup or pulldown! #define SPINDLE_LASER_ENA_PIN 40 // Pullup or pulldown!

View file

@ -64,7 +64,7 @@
// Z Probe // Z Probe
// //
#if ENABLED(BLTOUCH) #if ENABLED(BLTOUCH)
#error "You will need to use 24V to 5V converter and remove one resistor and capacitor from the motherboard. See https://github.com/davidtgbe/Marlin/blob/bugfix-2.0.x/docs/Tutorials/bltouch-en.md for more information. Comment out this line to proceed at your own risk." #error "You will need to use 24V to 5V converter and remove one resistor and capacitor from the motherboard. See https://bit.ly/3xg9cXO for more information. Comment out this line to proceed at your own risk."
#define SERVO0_PIN PC3 #define SERVO0_PIN PC3
#elif !defined(Z_MIN_PROBE_PIN) #elif !defined(Z_MIN_PROBE_PIN)
#define Z_MIN_PROBE_PIN PC3 #define Z_MIN_PROBE_PIN PC3

View file

@ -80,7 +80,7 @@ Regular users can open and close their own issues, but only the administrators c
- Scott Lahteine [[@thinkyhead](https://github.com/thinkyhead)] - USA - Project Maintainer &nbsp; [💸 Donate](https://www.thinkyhead.com/donate-to-marlin) - Scott Lahteine [[@thinkyhead](https://github.com/thinkyhead)] - USA - Project Maintainer &nbsp; [💸 Donate](https://www.thinkyhead.com/donate-to-marlin)
- Roxanne Neufeld [[@Roxy-3D](https://github.com/Roxy-3D)] - USA - Roxanne Neufeld [[@Roxy-3D](https://github.com/Roxy-3D)] - USA
- Keith Bennett [[@thisiskeithb](https://github.com/thisiskeithb)] - USA &nbsp; [💸 Donate](https://github.com/sponsors/thisiskeithb) - Keith Bennett [[@thisiskeithb](https://github.com/thisiskeithb)] - USA &nbsp; [💸 Donate](https://github.com/sponsors/thisiskeithb)
- Peter Ellens [[@ellensp](https://github.com/ellensp)] - New Zealand - Peter Ellens [[@ellensp](https://github.com/ellensp)] - New Zealand &nbsp; [💸 Donate](https://ko-fi.com/ellensp)
- Victor Oliveira [[@rhapsodyv](https://github.com/rhapsodyv)] - Brazil - Victor Oliveira [[@rhapsodyv](https://github.com/rhapsodyv)] - Brazil
- Chris Pepper [[@p3p](https://github.com/p3p)] - UK - Chris Pepper [[@p3p](https://github.com/p3p)] - UK
- Jason Smith [[@sjasonsmith](https://github.com/sjasonsmith)] - USA - Jason Smith [[@sjasonsmith](https://github.com/sjasonsmith)] - USA

View file

@ -13,9 +13,7 @@ which curl >/dev/null && TOOL='curl -L -s -S -f -o wgot'
which wget >/dev/null && TOOL='wget -q -O wgot' which wget >/dev/null && TOOL='wget -q -O wgot'
CURR=$(git branch 2>/dev/null | grep ^* | sed 's/\* //g') CURR=$(git branch 2>/dev/null | grep ^* | sed 's/\* //g')
[[ $CURR == "bugfix-2.0.x" ]] && BRANCH=bugfix-2.0.x || BRANCH=bugfix-2.1.x REPO=bugfix-2.0.x
REPO=$BRANCH
if [[ $# > 0 ]]; then if [[ $# > 0 ]]; then
IFS=: read -r PART1 PART2 <<< "$@" IFS=: read -r PART1 PART2 <<< "$@"

View file

@ -70,10 +70,9 @@ if pioutil.is_pio_build():
feat['lib_deps'] = list(filter(lib_re.match, feat['lib_deps'])) + [dep] feat['lib_deps'] = list(filter(lib_re.match, feat['lib_deps'])) + [dep]
blab("[%s] lib_deps = %s" % (feature, dep), 3) blab("[%s] lib_deps = %s" % (feature, dep), 3)
def load_config(): def load_features():
blab("========== Gather [features] entries...") blab("========== Gather [features] entries...")
items = ProjectConfig().items('features') for key in ProjectConfig().items('features'):
for key in items:
feature = key[0].upper() feature = key[0].upper()
if not feature in FEATURE_CONFIG: if not feature in FEATURE_CONFIG:
FEATURE_CONFIG[feature] = { 'lib_deps': [] } FEATURE_CONFIG[feature] = { 'lib_deps': [] }
@ -81,8 +80,7 @@ if pioutil.is_pio_build():
# Add options matching custom_marlin.MY_OPTION to the pile # Add options matching custom_marlin.MY_OPTION to the pile
blab("========== Gather custom_marlin entries...") blab("========== Gather custom_marlin entries...")
all_opts = env.GetProjectOptions() for n in env.GetProjectOptions():
for n in all_opts:
key = n[0] key = n[0]
mat = re.match(r'custom_marlin\.(.+)', key) mat = re.match(r'custom_marlin\.(.+)', key)
if mat: if mat:
@ -127,10 +125,10 @@ if pioutil.is_pio_build():
set_env_field('lib_ignore', lib_ignore) set_env_field('lib_ignore', lib_ignore)
def apply_features_config(): def apply_features_config():
load_config() load_features()
blab("========== Apply enabled features...") blab("========== Apply enabled features...")
for feature in FEATURE_CONFIG: for feature in FEATURE_CONFIG:
if not env.MarlinFeatureIsEnabled(feature): if not env.MarlinHas(feature):
continue continue
feat = FEATURE_CONFIG[feature] feat = FEATURE_CONFIG[feature]
@ -212,7 +210,7 @@ if pioutil.is_pio_build():
# #
# Return True if a matching feature is enabled # Return True if a matching feature is enabled
# #
def MarlinFeatureIsEnabled(env, feature): def MarlinHas(env, feature):
load_marlin_features() load_marlin_features()
r = re.compile('^' + feature + '$') r = re.compile('^' + feature + '$')
found = list(filter(r.match, env['MARLIN_FEATURES'])) found = list(filter(r.match, env['MARLIN_FEATURES']))
@ -225,7 +223,7 @@ if pioutil.is_pio_build():
if val in [ '', '1', 'true' ]: if val in [ '', '1', 'true' ]:
some_on = True some_on = True
elif val in env['MARLIN_FEATURES']: elif val in env['MARLIN_FEATURES']:
some_on = env.MarlinFeatureIsEnabled(val) some_on = env.MarlinHas(val)
return some_on return some_on
@ -239,7 +237,7 @@ if pioutil.is_pio_build():
# #
# Add a method for other PIO scripts to query enabled features # Add a method for other PIO scripts to query enabled features
# #
env.AddMethod(MarlinFeatureIsEnabled) env.AddMethod(MarlinHas)
# #
# Add dependencies for enabled Marlin features # Add dependencies for enabled Marlin features

View file

@ -10,7 +10,7 @@ if pioutil.is_pio_build():
Import("env") Import("env")
if env.MarlinFeatureIsEnabled("POSTMORTEM_DEBUGGING"): if env.MarlinHas("POSTMORTEM_DEBUGGING"):
FRAMEWORK_DIR = env.PioPlatform().get_package_dir("framework-arduinoststm32-maple") FRAMEWORK_DIR = env.PioPlatform().get_package_dir("framework-arduinoststm32-maple")
patchflag_path = join(FRAMEWORK_DIR, ".exc-patching-done") patchflag_path = join(FRAMEWORK_DIR, ".exc-patching-done")

View file

@ -4,5 +4,10 @@
# Make sure 'vscode init' is not the current command # Make sure 'vscode init' is not the current command
def is_pio_build(): def is_pio_build():
from SCons.Script import COMMAND_LINE_TARGETS from SCons.Script import DefaultEnvironment
return "idedata" not in COMMAND_LINE_TARGETS and "_idedata" not in COMMAND_LINE_TARGETS env = DefaultEnvironment()
return not env.IsIntegrationDump()
def get_pio_version():
from platformio import util
return util.pioversion_to_intstr()

View file

@ -40,7 +40,10 @@ def run_preprocessor(env, fn=None):
depcmd = cmd + [ filename ] depcmd = cmd + [ filename ]
cmd = ' '.join(depcmd) cmd = ' '.join(depcmd)
blab(cmd) blab(cmd)
define_list = subprocess.check_output(cmd, shell=True).splitlines() try:
define_list = subprocess.check_output(cmd, shell=True).splitlines()
except:
define_list = {}
preprocessor_cache[filename] = define_list preprocessor_cache[filename] = define_list
return define_list return define_list

View file

@ -110,53 +110,15 @@ if [[ $ACTION == "init" ]]; then
((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Commit for comparison" >/dev/null ((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Commit for comparison" >/dev/null
# Init Cartesian/SCARA/TPARA configurations to default # Init Cartesian/SCARA/TPARA configurations to default
echo "- Initializing Cartesian/SCARA/TPARA configs to default state..." echo "- Initializing configs to default state..."
find "$CEXA" -name $BC ! -path */delta/* -print0 \ find "$CEXA" -name $BC -print0 \
| while read -d $'\0' F ; do cp "$CDEF/$BC" "$F" ; done | while read -d $'\0' F ; do cp "$CDEF/$BC" "$F" ; done
find "$CEXA" -name $AC ! -path */delta/* -print0 \ find "$CEXA" -name $AC -print0 \
| while read -d $'\0' F ; do cp "$CDEF/$AC" "$F" ; done | while read -d $'\0' F ; do cp "$CDEF/$AC" "$F" ; done
# DEBUG: Commit the reset for review # DEBUG: Commit the reset for review
((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Reset Cartesian/SCARA/TPARA configs..." >/dev/null ((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Reset configs..." >/dev/null
# Create base Delta configurations
cp "$CDEF"/* "$CEXA/delta/generic"
# DEBUG: Commit the reset for review
((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Reset Generic Delta..." >/dev/null
cp -R "$TEMP/$CEXA/delta/generic"/Conf* "$CEXA/delta/generic"
# DEBUG: Commit Generic Delta changes for review
((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Apply Generic Delta..." >/dev/null
# Reset all Delta configs to the generic version
find "$CEXA/delta" -name $BC ! -path */generic/* -print0 \
| while read -d $'\0' F ; do cp "$CEXA/delta/generic/$BC" "$F" ; done
find "$CEXA/delta" -name $AC ! -path */generic/* -print0 \
| while read -d $'\0' F ; do cp "$CEXA/delta/generic/$AC" "$F" ; done
# DEBUG: Commit the Delta reset for review
((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Reset Delta configs..." >/dev/null
# Reset all SCARA configs to the default cartesian
find "$CEXA/SCARA" -name $BC \
| while read -d $'\0' F ; do cp "$CDEF/$BC" "$F" ; done
find "$CEXA/SCARA" -name $AC \
| while read -d $'\0' F ; do cp "$CDEF/$AC" "$F" ; done
# DEBUG: Commit the SCARA reset for review
((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Reset SCARA..." >/dev/null
# Reset all TPARA configs to the default cartesian
find "$CEXA/TPARA" -name $BC \
| while read -d $'\0' F ; do cp "$CDEF/$BC" "$F" ; done
find "$CEXA/TPARA" -name $AC \
| while read -d $'\0' F ; do cp "$CDEF/$AC" "$F" ; done
# DEBUG: Commit the TPARA reset for review
((COMMIT_STEPS)) && git add . >/dev/null && git commit -m "Reset TPARA..." >/dev/null
# Update the %VERSION% in the README.md file # Update the %VERSION% in the README.md file
VERS=$( echo $EXPORT | $SED 's/release-//' ) VERS=$( echo $EXPORT | $SED 's/release-//' )

View file

@ -376,11 +376,13 @@ class FileTransferProtocol(object):
token, data = self.await_response(1000) token, data = self.await_response(1000)
if token == 'PFT:success': if token == 'PFT:success':
print("File closed") print("File closed")
return return True
elif token == 'PFT:ioerror': elif token == 'PFT:ioerror':
print("Client storage device IO error") print("Client storage device IO error")
return False
elif token == 'PFT:invalid': elif token == 'PFT:invalid':
print("No open file") print("No open file")
return False
def abort(self): def abort(self):
self.protocol.send(FileTransferProtocol.protocol_id, FileTransferProtocol.Packet.ABORT); self.protocol.send(FileTransferProtocol.protocol_id, FileTransferProtocol.Packet.ABORT);
@ -417,12 +419,23 @@ class FileTransferProtocol(object):
self.write(data[start:end]) self.write(data[start:end])
kibs = (( (i+1) * block_size) / 1024) / (millis() + 1 - start_time) * 1000 kibs = (( (i+1) * block_size) / 1024) / (millis() + 1 - start_time) * 1000
if (i / blocks) >= dump_pctg: if (i / blocks) >= dump_pctg:
print("\r{0:2.2f}% {1:4.2f}KiB/s {2} Errors: {3}".format((i / blocks) * 100, kibs, "[{0:4.2f}KiB/s]".format(kibs * cratio) if compression_support else "", self.protocol.errors), end='') print("\r{0:2.0f}% {1:4.2f}KiB/s {2} Errors: {3}".format((i / blocks) * 100, kibs, "[{0:4.2f}KiB/s]".format(kibs * cratio) if compression_support else "", self.protocol.errors), end='')
dump_pctg += 0.1 dump_pctg += 0.1
print("\r{0:2.2f}% {1:4.2f}KiB/s {2} Errors: {3}".format(100, kibs, "[{0:4.2f}KiB/s]".format(kibs * cratio) if compression_support else "", self.protocol.errors)) # no one likes transfers finishing at 99.8% if self.protocol.errors > 0:
# Dump last status (errors may not be visible)
print("\r{0:2.0f}% {1:4.2f}KiB/s {2} Errors: {3} - Aborting...".format((i / blocks) * 100, kibs, "[{0:4.2f}KiB/s]".format(kibs * cratio) if compression_support else "", self.protocol.errors), end='')
print("") # New line to break the transfer speed line
self.close()
print("Transfer aborted due to protocol errors")
#raise Exception("Transfer aborted due to protocol errors")
return False;
print("\r{0:2.0f}% {1:4.2f}KiB/s {2} Errors: {3}".format(100, kibs, "[{0:4.2f}KiB/s]".format(kibs * cratio) if compression_support else "", self.protocol.errors)) # no one likes transfers finishing at 99.8%
self.close() if not self.close():
print("Transfer failed")
return False
print("Transfer complete") print("Transfer complete")
return True
class EchoProtocol(object): class EchoProtocol(object):

View file

@ -20,14 +20,18 @@ Import("env")
import MarlinBinaryProtocol import MarlinBinaryProtocol
# Internal debug flag
Debug = False
#-----------------# #-----------------#
# Upload Callback # # Upload Callback #
#-----------------# #-----------------#
def Upload(source, target, env): def Upload(source, target, env):
#-------#
# Debug #
#-------#
Debug = False # Set to True to enable script debug
def debugPrint(data):
if Debug: print(f"[Debug]: {data}")
#------------------# #------------------#
# Marlin functions # # Marlin functions #
#------------------# #------------------#
@ -39,19 +43,35 @@ def Upload(source, target, env):
# Port functions # # Port functions #
#----------------# #----------------#
def _GetUploadPort(env): def _GetUploadPort(env):
if Debug: print('Autodetecting upload port...') debugPrint('Autodetecting upload port...')
env.AutodetectUploadPort(env) env.AutodetectUploadPort(env)
port = env.subst('$UPLOAD_PORT') portName = env.subst('$UPLOAD_PORT')
if not port: if not portName:
raise Exception('Error detecting the upload port.') raise Exception('Error detecting the upload port.')
if Debug: print('OK') debugPrint('OK')
return port return portName
#-------------------------# #-------------------------#
# Simple serial functions # # Simple serial functions #
#-------------------------# #-------------------------#
def _OpenPort():
# Open serial port
if port.is_open: return
debugPrint('Opening upload port...')
port.open()
port.reset_input_buffer()
debugPrint('OK')
def _ClosePort():
# Open serial port
if port is None: return
if not port.is_open: return
debugPrint('Closing upload port...')
port.close()
debugPrint('OK')
def _Send(data): def _Send(data):
if Debug: print(f'>> {data}') debugPrint(f'>> {data}')
strdata = bytearray(data, 'utf8') + b'\n' strdata = bytearray(data, 'utf8') + b'\n'
port.write(strdata) port.write(strdata)
time.sleep(0.010) time.sleep(0.010)
@ -60,7 +80,7 @@ def Upload(source, target, env):
clean_responses = [] clean_responses = []
responses = port.readlines() responses = port.readlines()
for Resp in responses: for Resp in responses:
# Test: suppress invaid chars (coming from debug info) # Suppress invalid chars (coming from debug info)
try: try:
clean_response = Resp.decode('utf8').rstrip().lstrip() clean_response = Resp.decode('utf8').rstrip().lstrip()
clean_responses.append(clean_response) clean_responses.append(clean_response)
@ -73,24 +93,24 @@ def Upload(source, target, env):
# SDCard functions # # SDCard functions #
#------------------# #------------------#
def _CheckSDCard(): def _CheckSDCard():
if Debug: print('Checking SD card...') debugPrint('Checking SD card...')
_Send('M21') _Send('M21')
Responses = _Recv() Responses = _Recv()
if len(Responses) < 1 or not any('SD card ok' in r for r in Responses): if len(Responses) < 1 or not any('SD card ok' in r for r in Responses):
raise Exception('Error accessing SD card') raise Exception('Error accessing SD card')
if Debug: print('SD Card OK') debugPrint('SD Card OK')
return True return True
#----------------# #----------------#
# File functions # # File functions #
#----------------# #----------------#
def _GetFirmwareFiles(UseLongFilenames): def _GetFirmwareFiles(UseLongFilenames):
if Debug: print('Get firmware files...') debugPrint('Get firmware files...')
_Send(f"M20 F{'L' if UseLongFilenames else ''}") _Send(f"M20 F{'L' if UseLongFilenames else ''}")
Responses = _Recv() Responses = _Recv()
if len(Responses) < 3 or not any('file list' in r for r in Responses): if len(Responses) < 3 or not any('file list' in r for r in Responses):
raise Exception('Error getting firmware files') raise Exception('Error getting firmware files')
if Debug: print('OK') debugPrint('OK')
return Responses return Responses
def _FilterFirmwareFiles(FirmwareList, UseLongFilenames): def _FilterFirmwareFiles(FirmwareList, UseLongFilenames):
@ -114,6 +134,17 @@ def Upload(source, target, env):
raise Exception(f"Firmware file '{FirmwareFile}' not removed") raise Exception(f"Firmware file '{FirmwareFile}' not removed")
return Removed return Removed
def _RollbackUpload(FirmwareFile):
if not rollback: return
print(f"Rollback: trying to delete firmware '{FirmwareFile}'...")
_OpenPort()
# Wait for SD card release
time.sleep(1)
# Remount SD card
_CheckSDCard()
print(' OK' if _RemoveFirmwareFile(FirmwareFile) else ' Error!')
_ClosePort()
#---------------------# #---------------------#
# Callback Entrypoint # # Callback Entrypoint #
@ -121,6 +152,7 @@ def Upload(source, target, env):
port = None port = None
protocol = None protocol = None
filetransfer = None filetransfer = None
rollback = False
# Get Marlin evironment vars # Get Marlin evironment vars
MarlinEnv = env['MARLIN_FEATURES'] MarlinEnv = env['MARLIN_FEATURES']
@ -204,9 +236,9 @@ def Upload(source, target, env):
if not marlin_custom_firmware_upload: if not marlin_custom_firmware_upload:
raise Exception(f"CUSTOM_FIRMWARE_UPLOAD must be enabled in 'Configuration_adv.h' for '{marlin_motherboard}'") raise Exception(f"CUSTOM_FIRMWARE_UPLOAD must be enabled in 'Configuration_adv.h' for '{marlin_motherboard}'")
# Init serial port # Init & Open serial port
port = serial.Serial(upload_port, baudrate = upload_speed, write_timeout = 0, timeout = 0.1) port = serial.Serial(upload_port, baudrate = upload_speed, write_timeout = 0, timeout = 0.1)
port.reset_input_buffer() _OpenPort()
# Check SD card status # Check SD card status
_CheckSDCard() _CheckSDCard()
@ -228,24 +260,26 @@ def Upload(source, target, env):
print(' OK' if _RemoveFirmwareFile(OldFirmwareFile) else ' Error!') print(' OK' if _RemoveFirmwareFile(OldFirmwareFile) else ' Error!')
# Close serial # Close serial
port.close() _ClosePort()
# Cleanup completed # Cleanup completed
if Debug: print('Cleanup completed') debugPrint('Cleanup completed')
# WARNING! The serial port must be closed here because the serial transfer that follow needs it! # WARNING! The serial port must be closed here because the serial transfer that follow needs it!
# Upload firmware file # Upload firmware file
if Debug: print(f"Copy '{upload_firmware_source_name}' --> '{upload_firmware_target_name}'") debugPrint(f"Copy '{upload_firmware_source_name}' --> '{upload_firmware_target_name}'")
protocol = MarlinBinaryProtocol.Protocol(upload_port, upload_speed, upload_blocksize, float(upload_error_ratio), int(upload_timeout)) protocol = MarlinBinaryProtocol.Protocol(upload_port, upload_speed, upload_blocksize, float(upload_error_ratio), int(upload_timeout))
#echologger = MarlinBinaryProtocol.EchoProtocol(protocol) #echologger = MarlinBinaryProtocol.EchoProtocol(protocol)
protocol.connect() protocol.connect()
# Mark the rollback (delete broken transfer) from this point on
rollback = True
filetransfer = MarlinBinaryProtocol.FileTransferProtocol(protocol) filetransfer = MarlinBinaryProtocol.FileTransferProtocol(protocol)
filetransfer.copy(upload_firmware_source_name, upload_firmware_target_name, upload_compression, upload_test) transferOK = filetransfer.copy(upload_firmware_source_name, upload_firmware_target_name, upload_compression, upload_test)
protocol.disconnect() protocol.disconnect()
# Notify upload completed # Notify upload completed
protocol.send_ascii('M117 Firmware uploaded') protocol.send_ascii('M117 Firmware uploaded' if transferOK else 'M117 Firmware upload failed')
# Remount SD card # Remount SD card
print('Wait for SD card release...') print('Wait for SD card release...')
@ -253,34 +287,56 @@ def Upload(source, target, env):
print('Remount SD card') print('Remount SD card')
protocol.send_ascii('M21') protocol.send_ascii('M21')
# Trigger firmware update # Transfer failed?
if upload_reset: if not transferOK:
print('Trigger firmware update...') protocol.shutdown()
protocol.send_ascii('M997', True) _RollbackUpload(upload_firmware_target_name)
else:
# Trigger firmware update
if upload_reset:
print('Trigger firmware update...')
protocol.send_ascii('M997', True)
protocol.shutdown()
protocol.shutdown() print('Firmware update completed' if transferOK else 'Firmware update failed')
print('Firmware update completed') return 0 if transferOK else -1
except KeyboardInterrupt: except KeyboardInterrupt:
if port: port.close() print('Aborted by user')
if filetransfer: filetransfer.abort() if filetransfer: filetransfer.abort()
if protocol: protocol.shutdown() if protocol:
protocol.disconnect()
protocol.shutdown()
_RollbackUpload(upload_firmware_target_name)
_ClosePort()
raise raise
except serial.SerialException as se: except serial.SerialException as se:
if port: port.close() # This exception is raised only for send_ascii data (not for binary transfer)
print(f'Serial excepion: {se}') print(f'Serial excepion: {se}, transfer aborted')
if protocol:
protocol.disconnect()
protocol.shutdown()
_RollbackUpload(upload_firmware_target_name)
_ClosePort()
raise Exception(se) raise Exception(se)
except MarlinBinaryProtocol.FatalError: except MarlinBinaryProtocol.FatalError:
if port: port.close() print('Too many retries, transfer aborted')
if protocol: protocol.shutdown() if protocol:
print('Too many retries, Abort') protocol.disconnect()
protocol.shutdown()
_RollbackUpload(upload_firmware_target_name)
_ClosePort()
raise raise
except: except Exception as ex:
if port: port.close() print(f"\nException: {ex}, transfer aborted")
if protocol: protocol.shutdown() if protocol:
protocol.disconnect()
protocol.shutdown()
_RollbackUpload(upload_firmware_target_name)
_ClosePort()
print('Firmware not updated') print('Firmware not updated')
raise raise

View file

@ -1,9 +1,9 @@
# Configuration Embedding # Configuration Embedding
Starting with version 2.0.9.3, Marlin automatically extracts the configuration used to generate the firmware and stores it in the firmware binary. This is enabled by defining `CONFIGURATION_EMBEDDING` in `Configuration_adv.h`. Starting with version 2.0.9.3, Marlin can automatically extract the configuration used to generate the firmware and store it in the firmware binary. This is enabled by defining `CONFIGURATION_EMBEDDING` in `Configuration_adv.h`.
## How it's done ## How it's done
To create the embedded configuration, we do a compiler pass to process the Configuration files and extract all active options. The active options are parsed into key/value pairs, serialized to JSON format, and stored in a file called `marlin_config.json`, which also includes specific build information (like the git revision, the build date, and some version information. The JSON file is then compressed in a ZIP archive called `.pio/build/mc.zip` which is converted into a C array and stored in a C++ file called `mc.h` which is included in the build. At the start of the PlatformIO build process, we create an embedded configuration by extracting all active options from the Configuration files and writing them out as JSON to `marlin_config.json`, which also includes specific build information (like the git revision, the build date, and some version information. The JSON file is then compressed in a ZIP archive called `.pio/build/mc.zip` which is converted into a C array and stored in a C++ file called `mc.h` which is included in the build.
## Extracting configurations from a Marlin binary ## Extracting configurations from a Marlin binary
To get the configuration out of a binary firmware, you'll need a non-write-protected SD card inserted into the printer while running the firmware. To get the configuration out of a binary firmware, you'll need a non-write-protected SD card inserted into the printer while running the firmware.

View file

@ -28,13 +28,13 @@ extends = env:esp32
board_build.partitions = default_16MB.csv board_build.partitions = default_16MB.csv
[env:PANDA] [env:PANDA]
extends = env:esp32 extends = env:esp32
build_flags = ${env:esp32.build_flags} -DUSE_ESP32_EXIO -DUSE_ESP32_TASK_WDT build_flags = ${env:esp32.build_flags} -DUSE_ESP32_EXIO -DUSE_ESP32_TASK_WDT
lib_deps = ${common.lib_deps} lib_deps = ${common.lib_deps}
SoftwareSerialEsp32 SoftwareSerialEsp32
board_build.partitions = Marlin/src/HAL/ESP32/esp32.csv board_build.partitions = Marlin/src/HAL/ESP32/esp32.csv
upload_speed = 115200 upload_speed = 115200
monitor_speed = 115200 monitor_speed = 115200
[env:mks_tinybee] [env:mks_tinybee]
extends = env:esp32 extends = env:esp32

View file

@ -239,5 +239,5 @@ HAS_MICROSTEPS = src_filter=+<src/gcode/control/M350_M35
(ESP3D_)?WIFISUPPORT = AsyncTCP, ESP Async WebServer (ESP3D_)?WIFISUPPORT = AsyncTCP, ESP Async WebServer
ESP3DLib=https://github.com/luc-github/ESP3DLib/archive/master.zip ESP3DLib=https://github.com/luc-github/ESP3DLib/archive/master.zip
arduinoWebSockets=links2004/WebSockets@2.3.4 arduinoWebSockets=links2004/WebSockets@2.3.4
luc-github/ESP32SSDP@^1.1.1 luc-github/ESP32SSDP@1.1.1
lib_ignore=ESPAsyncTCP lib_ignore=ESPAsyncTCP