diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index a573b749a..fb2b9b53e 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/default/Configuration_adv.h b/Marlin/src/config/default/Configuration_adv.h
index a573b749a..fb2b9b53e 100755
--- a/Marlin/src/config/default/Configuration_adv.h
+++ b/Marlin/src/config/default/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/AlephObjects/TAZ4/Configuration_adv.h b/Marlin/src/config/examples/AlephObjects/TAZ4/Configuration_adv.h
index e61f6dd58..44ef0d4ea 100644
--- a/Marlin/src/config/examples/AlephObjects/TAZ4/Configuration_adv.h
+++ b/Marlin/src/config/examples/AlephObjects/TAZ4/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Anet/A2/Configuration_adv.h b/Marlin/src/config/examples/Anet/A2/Configuration_adv.h
index d1bd3f2c8..a7fb550d2 100644
--- a/Marlin/src/config/examples/Anet/A2/Configuration_adv.h
+++ b/Marlin/src/config/examples/Anet/A2/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Anet/A2plus/Configuration_adv.h b/Marlin/src/config/examples/Anet/A2plus/Configuration_adv.h
index d1bd3f2c8..a7fb550d2 100644
--- a/Marlin/src/config/examples/Anet/A2plus/Configuration_adv.h
+++ b/Marlin/src/config/examples/Anet/A2plus/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Anet/A6/Configuration_adv.h b/Marlin/src/config/examples/Anet/A6/Configuration_adv.h
index ee35ef4a0..6474e44fa 100644
--- a/Marlin/src/config/examples/Anet/A6/Configuration_adv.h
+++ b/Marlin/src/config/examples/Anet/A6/Configuration_adv.h
@@ -740,6 +740,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Anet/A8/Configuration_adv.h b/Marlin/src/config/examples/Anet/A8/Configuration_adv.h
index b1cccb210..e93e760c8 100644
--- a/Marlin/src/config/examples/Anet/A8/Configuration_adv.h
+++ b/Marlin/src/config/examples/Anet/A8/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/ArmEd/Configuration_adv.h b/Marlin/src/config/examples/ArmEd/Configuration_adv.h
index 421fa6f58..acde9b965 100644
--- a/Marlin/src/config/examples/ArmEd/Configuration_adv.h
+++ b/Marlin/src/config/examples/ArmEd/Configuration_adv.h
@@ -716,6 +716,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/BIBO/TouchX/cyclops/Configuration_adv.h b/Marlin/src/config/examples/BIBO/TouchX/cyclops/Configuration_adv.h
index ee91cbf0e..959a826c9 100644
--- a/Marlin/src/config/examples/BIBO/TouchX/cyclops/Configuration_adv.h
+++ b/Marlin/src/config/examples/BIBO/TouchX/cyclops/Configuration_adv.h
@@ -740,6 +740,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/BIBO/TouchX/default/Configuration_adv.h b/Marlin/src/config/examples/BIBO/TouchX/default/Configuration_adv.h
index 2dc7d6ec2..5aa619368 100644
--- a/Marlin/src/config/examples/BIBO/TouchX/default/Configuration_adv.h
+++ b/Marlin/src/config/examples/BIBO/TouchX/default/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/BQ/Hephestos/Configuration_adv.h b/Marlin/src/config/examples/BQ/Hephestos/Configuration_adv.h
index 79903fde5..b603bd27d 100644
--- a/Marlin/src/config/examples/BQ/Hephestos/Configuration_adv.h
+++ b/Marlin/src/config/examples/BQ/Hephestos/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/BQ/Hephestos_2/Configuration_adv.h b/Marlin/src/config/examples/BQ/Hephestos_2/Configuration_adv.h
index 5e41063d1..9bdb1c38b 100644
--- a/Marlin/src/config/examples/BQ/Hephestos_2/Configuration_adv.h
+++ b/Marlin/src/config/examples/BQ/Hephestos_2/Configuration_adv.h
@@ -749,6 +749,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/BQ/WITBOX/Configuration_adv.h b/Marlin/src/config/examples/BQ/WITBOX/Configuration_adv.h
index 79903fde5..b603bd27d 100644
--- a/Marlin/src/config/examples/BQ/WITBOX/Configuration_adv.h
+++ b/Marlin/src/config/examples/BQ/WITBOX/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Cartesio/Configuration_adv.h b/Marlin/src/config/examples/Cartesio/Configuration_adv.h
index fdf55dd51..0d64a27bf 100644
--- a/Marlin/src/config/examples/Cartesio/Configuration_adv.h
+++ b/Marlin/src/config/examples/Cartesio/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Creality/CR-10/Configuration_adv.h b/Marlin/src/config/examples/Creality/CR-10/Configuration_adv.h
index c0927a949..bb1070f9d 100755
--- a/Marlin/src/config/examples/Creality/CR-10/Configuration_adv.h
+++ b/Marlin/src/config/examples/Creality/CR-10/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Creality/CR-10S/Configuration_adv.h b/Marlin/src/config/examples/Creality/CR-10S/Configuration_adv.h
index 571f4fd3b..c2e7a2463 100644
--- a/Marlin/src/config/examples/Creality/CR-10S/Configuration_adv.h
+++ b/Marlin/src/config/examples/Creality/CR-10S/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Creality/CR-10mini/Configuration_adv.h b/Marlin/src/config/examples/Creality/CR-10mini/Configuration_adv.h
index b8756fc0a..b7b1e2d00 100644
--- a/Marlin/src/config/examples/Creality/CR-10mini/Configuration_adv.h
+++ b/Marlin/src/config/examples/Creality/CR-10mini/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Creality/CR-8/Configuration_adv.h b/Marlin/src/config/examples/Creality/CR-8/Configuration_adv.h
index 1ce26f98b..30c1eb9c0 100644
--- a/Marlin/src/config/examples/Creality/CR-8/Configuration_adv.h
+++ b/Marlin/src/config/examples/Creality/CR-8/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Creality/Ender-2/Configuration_adv.h b/Marlin/src/config/examples/Creality/Ender-2/Configuration_adv.h
index cab4f7998..b18029700 100644
--- a/Marlin/src/config/examples/Creality/Ender-2/Configuration_adv.h
+++ b/Marlin/src/config/examples/Creality/Ender-2/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Creality/Ender-3/Configuration_adv.h b/Marlin/src/config/examples/Creality/Ender-3/Configuration_adv.h
index 0f596ba70..83c2f52bc 100644
--- a/Marlin/src/config/examples/Creality/Ender-3/Configuration_adv.h
+++ b/Marlin/src/config/examples/Creality/Ender-3/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Creality/Ender-4/Configuration_adv.h b/Marlin/src/config/examples/Creality/Ender-4/Configuration_adv.h
index c78fe2090..6eefcaeab 100644
--- a/Marlin/src/config/examples/Creality/Ender-4/Configuration_adv.h
+++ b/Marlin/src/config/examples/Creality/Ender-4/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Einstart-S/Configuration_adv.h b/Marlin/src/config/examples/Einstart-S/Configuration_adv.h
index ad68331be..27d55ec29 100644
--- a/Marlin/src/config/examples/Einstart-S/Configuration_adv.h
+++ b/Marlin/src/config/examples/Einstart-S/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Felix/Configuration_adv.h b/Marlin/src/config/examples/Felix/Configuration_adv.h
index 30a223b07..ed70889c9 100644
--- a/Marlin/src/config/examples/Felix/Configuration_adv.h
+++ b/Marlin/src/config/examples/Felix/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/FolgerTech/i3-2020/Configuration_adv.h b/Marlin/src/config/examples/FolgerTech/i3-2020/Configuration_adv.h
index 2e860a74f..4a8c4f393 100644
--- a/Marlin/src/config/examples/FolgerTech/i3-2020/Configuration_adv.h
+++ b/Marlin/src/config/examples/FolgerTech/i3-2020/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Formbot/Raptor/Configuration_adv.h b/Marlin/src/config/examples/Formbot/Raptor/Configuration_adv.h
index eb6a44a4c..090e4f7a8 100644
--- a/Marlin/src/config/examples/Formbot/Raptor/Configuration_adv.h
+++ b/Marlin/src/config/examples/Formbot/Raptor/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Formbot/T_Rex_2+/Configuration_adv.h b/Marlin/src/config/examples/Formbot/T_Rex_2+/Configuration_adv.h
index a01289a7d..03945115f 100644
--- a/Marlin/src/config/examples/Formbot/T_Rex_2+/Configuration_adv.h
+++ b/Marlin/src/config/examples/Formbot/T_Rex_2+/Configuration_adv.h
@@ -745,6 +745,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Formbot/T_Rex_3/Configuration_adv.h b/Marlin/src/config/examples/Formbot/T_Rex_3/Configuration_adv.h
index 2bea700c9..bcc5ce5a2 100644
--- a/Marlin/src/config/examples/Formbot/T_Rex_3/Configuration_adv.h
+++ b/Marlin/src/config/examples/Formbot/T_Rex_3/Configuration_adv.h
@@ -746,6 +746,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Geeetech/MeCreator2/Configuration_adv.h b/Marlin/src/config/examples/Geeetech/MeCreator2/Configuration_adv.h
index 785228a81..2e514a184 100644
--- a/Marlin/src/config/examples/Geeetech/MeCreator2/Configuration_adv.h
+++ b/Marlin/src/config/examples/Geeetech/MeCreator2/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Geeetech/Prusa i3 Pro C/Configuration_adv.h b/Marlin/src/config/examples/Geeetech/Prusa i3 Pro C/Configuration_adv.h
index 22412c132..5bdadf0e4 100644
--- a/Marlin/src/config/examples/Geeetech/Prusa i3 Pro C/Configuration_adv.h
+++ b/Marlin/src/config/examples/Geeetech/Prusa i3 Pro C/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Geeetech/Prusa i3 Pro W/Configuration_adv.h b/Marlin/src/config/examples/Geeetech/Prusa i3 Pro W/Configuration_adv.h
index 22412c132..5bdadf0e4 100644
--- a/Marlin/src/config/examples/Geeetech/Prusa i3 Pro W/Configuration_adv.h
+++ b/Marlin/src/config/examples/Geeetech/Prusa i3 Pro W/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Infitary/i3-M508/Configuration_adv.h b/Marlin/src/config/examples/Infitary/i3-M508/Configuration_adv.h
index 604557261..b29fe3962 100644
--- a/Marlin/src/config/examples/Infitary/i3-M508/Configuration_adv.h
+++ b/Marlin/src/config/examples/Infitary/i3-M508/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/JGAurora/A5/Configuration_adv.h b/Marlin/src/config/examples/JGAurora/A5/Configuration_adv.h
index ed422df17..7bd95383f 100644
--- a/Marlin/src/config/examples/JGAurora/A5/Configuration_adv.h
+++ b/Marlin/src/config/examples/JGAurora/A5/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/MakerParts/Configuration_adv.h b/Marlin/src/config/examples/MakerParts/Configuration_adv.h
index 254126cf3..74d8e87eb 100644
--- a/Marlin/src/config/examples/MakerParts/Configuration_adv.h
+++ b/Marlin/src/config/examples/MakerParts/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Malyan/M150/Configuration_adv.h b/Marlin/src/config/examples/Malyan/M150/Configuration_adv.h
index 1804fd782..284b6f91f 100644
--- a/Marlin/src/config/examples/Malyan/M150/Configuration_adv.h
+++ b/Marlin/src/config/examples/Malyan/M150/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Malyan/M200/Configuration_adv.h b/Marlin/src/config/examples/Malyan/M200/Configuration_adv.h
index d9ce67232..73ff01aaf 100644
--- a/Marlin/src/config/examples/Malyan/M200/Configuration_adv.h
+++ b/Marlin/src/config/examples/Malyan/M200/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Micromake/C1/enhanced/Configuration_adv.h b/Marlin/src/config/examples/Micromake/C1/enhanced/Configuration_adv.h
index d4288d6d9..657650dec 100644
--- a/Marlin/src/config/examples/Micromake/C1/enhanced/Configuration_adv.h
+++ b/Marlin/src/config/examples/Micromake/C1/enhanced/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Mks/Sbase/Configuration_adv.h b/Marlin/src/config/examples/Mks/Sbase/Configuration_adv.h
index af8d3bb94..ca1f2c791 100644
--- a/Marlin/src/config/examples/Mks/Sbase/Configuration_adv.h
+++ b/Marlin/src/config/examples/Mks/Sbase/Configuration_adv.h
@@ -742,6 +742,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/RigidBot/Configuration_adv.h b/Marlin/src/config/examples/RigidBot/Configuration_adv.h
index b8d521d1e..03436dfa0 100644
--- a/Marlin/src/config/examples/RigidBot/Configuration_adv.h
+++ b/Marlin/src/config/examples/RigidBot/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/SCARA/Configuration_adv.h b/Marlin/src/config/examples/SCARA/Configuration_adv.h
index 64bca1220..dfed683bd 100644
--- a/Marlin/src/config/examples/SCARA/Configuration_adv.h
+++ b/Marlin/src/config/examples/SCARA/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Sanguinololu/Configuration_adv.h b/Marlin/src/config/examples/Sanguinololu/Configuration_adv.h
index c38b07df5..0f285de27 100644
--- a/Marlin/src/config/examples/Sanguinololu/Configuration_adv.h
+++ b/Marlin/src/config/examples/Sanguinololu/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/TheBorg/Configuration_adv.h b/Marlin/src/config/examples/TheBorg/Configuration_adv.h
index ec8420db8..ee5d1d8f4 100644
--- a/Marlin/src/config/examples/TheBorg/Configuration_adv.h
+++ b/Marlin/src/config/examples/TheBorg/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/TinyBoy2/Configuration_adv.h b/Marlin/src/config/examples/TinyBoy2/Configuration_adv.h
index f34ba365e..d3a9e52b1 100644
--- a/Marlin/src/config/examples/TinyBoy2/Configuration_adv.h
+++ b/Marlin/src/config/examples/TinyBoy2/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Tronxy/X3A/Configuration_adv.h b/Marlin/src/config/examples/Tronxy/X3A/Configuration_adv.h
index c7fadebc5..adc1a60c8 100644
--- a/Marlin/src/config/examples/Tronxy/X3A/Configuration_adv.h
+++ b/Marlin/src/config/examples/Tronxy/X3A/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/UltiMachine/Archim2/Configuration_adv.h b/Marlin/src/config/examples/UltiMachine/Archim2/Configuration_adv.h
index 1f8a03ed2..529cb3421 100644
--- a/Marlin/src/config/examples/UltiMachine/Archim2/Configuration_adv.h
+++ b/Marlin/src/config/examples/UltiMachine/Archim2/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Velleman/K8200/Configuration_adv.h b/Marlin/src/config/examples/Velleman/K8200/Configuration_adv.h
index 93ffcc8c4..603dcf46a 100644
--- a/Marlin/src/config/examples/Velleman/K8200/Configuration_adv.h
+++ b/Marlin/src/config/examples/Velleman/K8200/Configuration_adv.h
@@ -754,6 +754,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Velleman/K8400/Configuration_adv.h b/Marlin/src/config/examples/Velleman/K8400/Configuration_adv.h
index c2b7ce6b9..6d0cf435c 100644
--- a/Marlin/src/config/examples/Velleman/K8400/Configuration_adv.h
+++ b/Marlin/src/config/examples/Velleman/K8400/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/Wanhao/Duplicator 6/Configuration_adv.h b/Marlin/src/config/examples/Wanhao/Duplicator 6/Configuration_adv.h
index 8700573f0..39e3876df 100644
--- a/Marlin/src/config/examples/Wanhao/Duplicator 6/Configuration_adv.h
+++ b/Marlin/src/config/examples/Wanhao/Duplicator 6/Configuration_adv.h
@@ -743,6 +743,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/delta/Anycubic/Kossel/Configuration_adv.h b/Marlin/src/config/examples/delta/Anycubic/Kossel/Configuration_adv.h
index 80a13463b..bab6537ea 100644
--- a/Marlin/src/config/examples/delta/Anycubic/Kossel/Configuration_adv.h
+++ b/Marlin/src/config/examples/delta/Anycubic/Kossel/Configuration_adv.h
@@ -743,6 +743,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/delta/FLSUN/auto_calibrate/Configuration_adv.h b/Marlin/src/config/examples/delta/FLSUN/auto_calibrate/Configuration_adv.h
index 3f9820bc3..fb001f27e 100644
--- a/Marlin/src/config/examples/delta/FLSUN/auto_calibrate/Configuration_adv.h
+++ b/Marlin/src/config/examples/delta/FLSUN/auto_calibrate/Configuration_adv.h
@@ -743,6 +743,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/delta/FLSUN/kossel/Configuration_adv.h b/Marlin/src/config/examples/delta/FLSUN/kossel/Configuration_adv.h
index 3f9820bc3..fb001f27e 100644
--- a/Marlin/src/config/examples/delta/FLSUN/kossel/Configuration_adv.h
+++ b/Marlin/src/config/examples/delta/FLSUN/kossel/Configuration_adv.h
@@ -743,6 +743,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/delta/FLSUN/kossel_mini/Configuration_adv.h b/Marlin/src/config/examples/delta/FLSUN/kossel_mini/Configuration_adv.h
index 2e194fb3b..c7b280da8 100644
--- a/Marlin/src/config/examples/delta/FLSUN/kossel_mini/Configuration_adv.h
+++ b/Marlin/src/config/examples/delta/FLSUN/kossel_mini/Configuration_adv.h
@@ -743,6 +743,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/delta/generic/Configuration_adv.h b/Marlin/src/config/examples/delta/generic/Configuration_adv.h
index 2e194fb3b..c7b280da8 100644
--- a/Marlin/src/config/examples/delta/generic/Configuration_adv.h
+++ b/Marlin/src/config/examples/delta/generic/Configuration_adv.h
@@ -743,6 +743,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/delta/kossel_mini/Configuration_adv.h b/Marlin/src/config/examples/delta/kossel_mini/Configuration_adv.h
index 2e194fb3b..c7b280da8 100644
--- a/Marlin/src/config/examples/delta/kossel_mini/Configuration_adv.h
+++ b/Marlin/src/config/examples/delta/kossel_mini/Configuration_adv.h
@@ -743,6 +743,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/delta/kossel_xl/Configuration_adv.h b/Marlin/src/config/examples/delta/kossel_xl/Configuration_adv.h
index 2abf93992..0ebbfd81e 100644
--- a/Marlin/src/config/examples/delta/kossel_xl/Configuration_adv.h
+++ b/Marlin/src/config/examples/delta/kossel_xl/Configuration_adv.h
@@ -743,6 +743,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/gCreate/gMax1.5+/Configuration_adv.h b/Marlin/src/config/examples/gCreate/gMax1.5+/Configuration_adv.h
index f98d7a625..2900de435 100644
--- a/Marlin/src/config/examples/gCreate/gMax1.5+/Configuration_adv.h
+++ b/Marlin/src/config/examples/gCreate/gMax1.5+/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/makibox/Configuration_adv.h b/Marlin/src/config/examples/makibox/Configuration_adv.h
index 90841f237..275f541a3 100644
--- a/Marlin/src/config/examples/makibox/Configuration_adv.h
+++ b/Marlin/src/config/examples/makibox/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/tvrrug/Round2/Configuration_adv.h b/Marlin/src/config/examples/tvrrug/Round2/Configuration_adv.h
index a18f8dda3..ab96d1b15 100644
--- a/Marlin/src/config/examples/tvrrug/Round2/Configuration_adv.h
+++ b/Marlin/src/config/examples/tvrrug/Round2/Configuration_adv.h
@@ -741,6 +741,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/config/examples/wt150/Configuration_adv.h b/Marlin/src/config/examples/wt150/Configuration_adv.h
index 5d0e51e68..ad34793ad 100644
--- a/Marlin/src/config/examples/wt150/Configuration_adv.h
+++ b/Marlin/src/config/examples/wt150/Configuration_adv.h
@@ -742,6 +742,9 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ // Add an optimized binary file transfer mode, initiated with 'M28 B1'
+ //#define FAST_FILE_TRANSFER
+
#endif // SDSUPPORT
/**
diff --git a/Marlin/src/feature/emergency_parser.cpp b/Marlin/src/feature/emergency_parser.cpp
index 3c9cbf12e..7908f342d 100644
--- a/Marlin/src/feature/emergency_parser.cpp
+++ b/Marlin/src/feature/emergency_parser.cpp
@@ -31,7 +31,8 @@
#include "emergency_parser.h"
// Static data members
-bool EmergencyParser::killed_by_M112; // = false
+bool EmergencyParser::killed_by_M112, // = false
+ EmergencyParser::enabled;
// Global instance
EmergencyParser emergency_parser;
diff --git a/Marlin/src/feature/emergency_parser.h b/Marlin/src/feature/emergency_parser.h
index 127b5c20d..3684a3b12 100644
--- a/Marlin/src/feature/emergency_parser.h
+++ b/Marlin/src/feature/emergency_parser.h
@@ -19,13 +19,13 @@
* along with this program. If not, see .
*
*/
+#pragma once
/**
* emergency_parser.h - Intercept special commands directly in the serial stream
*/
-#ifndef _EMERGENCY_PARSER_H_
-#define _EMERGENCY_PARSER_H_
+#define FORCE_INLINE __attribute__((always_inline)) inline
// External references
extern volatile bool wait_for_user, wait_for_heatup;
@@ -53,11 +53,13 @@ public:
static bool killed_by_M112;
- EmergencyParser() {}
+ EmergencyParser() { enable(); }
- __attribute__((always_inline)) inline
- static void update(State &state, const uint8_t c) {
+ FORCE_INLINE static void enable() { enabled = true; }
+ FORCE_INLINE static void disable() { enabled = false; }
+
+ FORCE_INLINE static void update(State &state, const uint8_t c) {
switch (state) {
case EP_RESET:
switch (c) {
@@ -118,7 +120,7 @@ public:
default:
if (c == '\n') {
- switch (state) {
+ if (enabled) switch (state) {
case EP_M108:
wait_for_user = wait_for_heatup = false;
break;
@@ -136,8 +138,8 @@ public:
}
}
+private:
+ static bool enabled;
};
extern EmergencyParser emergency_parser;
-
-#endif // _EMERGENCY_PARSER_H_
diff --git a/Marlin/src/feature/fwretract.h b/Marlin/src/feature/fwretract.h
index 9da737465..247ea2202 100644
--- a/Marlin/src/feature/fwretract.h
+++ b/Marlin/src/feature/fwretract.h
@@ -56,7 +56,7 @@ public:
#if ENABLED(FWRETRACT_AUTORETRACT)
static bool autoretract_enabled; // M209 S - Autoretract switch
#else
- constexpr static bool autoretract_enabled = false;
+ static constexpr bool autoretract_enabled = false;
#endif
static bool retracted[EXTRUDERS]; // Which extruders are currently retracted
diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index 2d7fe1ab5..ad2887711 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -258,14 +258,15 @@ void gcode_line_error(PGM_P err, uint8_t port) {
}
static bool serial_data_available() {
- return (MYSERIAL0.available() ? true :
+ return false
+ || MYSERIAL0.available()
#if NUM_SERIAL > 1
- MYSERIAL1.available() ? true :
+ || MYSERIAL1.available()
#endif
- false);
+ ;
}
-static int read_serial(const int index) {
+static int read_serial(const uint8_t index) {
switch (index) {
case 0: return MYSERIAL0.read();
#if NUM_SERIAL > 1
@@ -275,6 +276,263 @@ static int read_serial(const int index) {
}
}
+#if ENABLED(FAST_FILE_TRANSFER)
+
+ #if ENABLED(SDSUPPORT)
+ #define CARD_CHAR_P(C) SERIAL_CHAR_P(card.transfer_port, C)
+ #define CARD_ECHO_P(V) SERIAL_ECHO_P(card.transfer_port, V)
+ #define CARD_ECHOLN_P(V) SERIAL_ECHOLN_P(card.transfer_port, V)
+ #endif
+
+ static bool serial_data_available(const uint8_t index) {
+ switch (index) {
+ case 0: return MYSERIAL0.available();
+ #if NUM_SERIAL > 1
+ case 1: return MYSERIAL1.available();
+ #endif
+ default: return false;
+ }
+ }
+
+ class BinaryStream {
+ public:
+ enum class StreamState : uint8_t {
+ STREAM_RESET,
+ PACKET_RESET,
+ STREAM_HEADER,
+ PACKET_HEADER,
+ PACKET_DATA,
+ PACKET_VALIDATE,
+ PACKET_RESEND,
+ PACKET_FLUSHRX,
+ PACKET_TIMEOUT,
+ STREAM_COMPLETE,
+ STREAM_FAILED,
+ };
+
+ #pragma pack(push, 1)
+
+ struct StreamHeader {
+ uint16_t token;
+ uint32_t filesize;
+ };
+ union {
+ uint8_t stream_header_bytes[sizeof(StreamHeader)];
+ StreamHeader stream_header;
+ };
+
+ struct Packet {
+ struct Header {
+ uint32_t id;
+ uint16_t size, checksum;
+ };
+ union {
+ uint8_t header_bytes[sizeof(Header)];
+ Header header;
+ };
+ uint32_t bytes_received;
+ uint16_t checksum;
+ millis_t timeout;
+ } packet{};
+
+ #pragma pack(pop)
+
+ void packet_reset() {
+ packet.header.id = 0;
+ packet.header.size = 0;
+ packet.header.checksum = 0;
+ packet.bytes_received = 0;
+ packet.checksum = 0x53A2;
+ packet.timeout = millis() + STREAM_MAX_WAIT;
+ }
+
+ void stream_reset() {
+ packets_received = 0;
+ bytes_received = 0;
+ packet_retries = 0;
+ buffer_next_index = 0;
+ stream_header.token = 0;
+ stream_header.filesize = 0;
+ }
+
+ uint32_t checksum(uint32_t seed, uint8_t value) {
+ return ((seed ^ value) ^ (seed << 8)) & 0xFFFF;
+ }
+
+ // read the next byte from the data stream keeping track of
+ // whether the stream times out from data starvation
+ // takes the data variable by reference in order to return status
+ bool stream_read(uint8_t& data) {
+ if (ELAPSED(millis(), packet.timeout)) {
+ stream_state = StreamState::PACKET_TIMEOUT;
+ return false;
+ }
+ if (!serial_data_available(card.transfer_port)) return false;
+ data = read_serial(card.transfer_port);
+ packet.timeout = millis() + STREAM_MAX_WAIT;
+ return true;
+ }
+
+ template
+ void receive(char (&buffer)[buffer_size]) {
+ uint8_t data = 0;
+ millis_t tranfer_timeout = millis() + RX_TIMESLICE;
+ while (PENDING(millis(), tranfer_timeout)) {
+ switch (stream_state) {
+ case StreamState::STREAM_RESET:
+ stream_reset();
+ case StreamState::PACKET_RESET:
+ packet_reset();
+ stream_state = StreamState::PACKET_HEADER;
+ break;
+ case StreamState::STREAM_HEADER: // we could also transfer the filename in this packet, rather than handling it in the gcode
+ for (size_t i = 0; i < sizeof(stream_header); ++i) {
+ stream_header_bytes[i] = buffer[i];
+ }
+ if (stream_header.token == 0x1234) {
+ stream_state = StreamState::PACKET_RESET;
+ bytes_received = 0;
+ time_stream_start = millis();
+ CARD_ECHO_P("echo: Datastream initialized (");
+ CARD_ECHO_P(stream_header.filesize);
+ CARD_ECHOLN_P("Bytes expected)");
+ CARD_ECHO_P("so"); // confirm active stream and the maximum block size supported
+ CARD_CHAR_P(static_cast(buffer_size & 0xFF));
+ CARD_CHAR_P(static_cast((buffer_size >> 8) & 0xFF));
+ CARD_CHAR_P('\n');
+ }
+ else {
+ CARD_ECHOLN_P("echo: Datastream initialization error (invalid token)");
+ stream_state = StreamState::STREAM_FAILED;
+ }
+ buffer_next_index = 0;
+ break;
+ case StreamState::PACKET_HEADER:
+ if (!stream_read(data)) break;
+
+ packet.header_bytes[packet.bytes_received++] = data;
+ if (packet.bytes_received == sizeof(Packet::Header)) {
+ if (packet.header.id == packets_received) {
+ buffer_next_index = 0;
+ packet.bytes_received = 0;
+ stream_state = StreamState::PACKET_DATA;
+ }
+ else {
+ CARD_ECHO_P("echo: Datastream packet out of order");
+ stream_state = StreamState::PACKET_FLUSHRX;
+ }
+ }
+ break;
+ case StreamState::PACKET_DATA:
+ if (!stream_read(data)) break;
+
+ if (buffer_next_index < buffer_size) {
+ buffer[buffer_next_index] = data;
+ }
+ else {
+ CARD_ECHO_P("echo: Datastream packet data buffer overrun");
+ stream_state = StreamState::STREAM_FAILED;
+ break;
+ }
+
+ packet.checksum = checksum(packet.checksum, data);
+ packet.bytes_received ++;
+ buffer_next_index ++;
+
+ if (packet.bytes_received == packet.header.size) {
+ stream_state = StreamState::PACKET_VALIDATE;
+ }
+ break;
+ case StreamState::PACKET_VALIDATE:
+ if (packet.header.checksum == packet.checksum) {
+ packet_retries = 0;
+ packets_received ++;
+ bytes_received += packet.header.size;
+
+ if (packet.header.id == 0) { // id 0 is always the stream descriptor
+ stream_state = StreamState::STREAM_HEADER; // defer packet confirmation to STREAM_HEADER state
+ }
+ else {
+ if (bytes_received < stream_header.filesize) {
+ stream_state = StreamState::PACKET_RESET; // reset and receive next packet
+ CARD_ECHOLN_P("ok"); // transmit confirm packet received and valid token
+ }
+ else {
+ stream_state = StreamState::STREAM_COMPLETE; // no more data required
+ }
+ if (card.write(buffer, buffer_next_index) < 0) {
+ stream_state = StreamState::STREAM_FAILED;
+ CARD_ECHO_P("echo: IO ERROR");
+ break;
+ };
+ }
+ }
+ else {
+ CARD_ECHO_P("echo: Block(");
+ CARD_ECHO_P(packet.header.id);
+ CARD_ECHOLN_P(") Corrupt");
+ stream_state = StreamState::PACKET_FLUSHRX;
+ }
+ break;
+ case StreamState::PACKET_RESEND:
+ if (packet_retries < MAX_RETRIES) {
+ packet_retries ++;
+ stream_state = StreamState::PACKET_RESET;
+ CARD_ECHO_P("echo: Resend request ");
+ CARD_ECHOLN_P(packet_retries);
+ CARD_ECHOLN_P("rs"); // transmit resend packet token
+ }
+ else {
+ stream_state = StreamState::STREAM_FAILED;
+ }
+ break;
+ case StreamState::PACKET_FLUSHRX:
+ if (ELAPSED(millis(), packet.timeout)) {
+ stream_state = StreamState::PACKET_RESEND;
+ break;
+ }
+ if (!serial_data_available(card.transfer_port)) break;
+ read_serial(card.transfer_port); // throw away data
+ packet.timeout = millis() + STREAM_MAX_WAIT;
+ break;
+ case StreamState::PACKET_TIMEOUT:
+ CARD_ECHOLN_P("echo: Datastream timeout");
+ stream_state = StreamState::PACKET_RESEND;
+ break;
+ case StreamState::STREAM_COMPLETE:
+ stream_state = StreamState::STREAM_RESET;
+ card.binary_mode = false;
+ card.closefile();
+ CARD_ECHO_P("echo: ");
+ CARD_ECHO_P(card.filename);
+ CARD_ECHO_P(" transfer completed @ ");
+ CARD_ECHO_P(((bytes_received / (millis() - time_stream_start) * 1000) / 1024 ));
+ CARD_ECHOLN_P("KiB/s");
+ CARD_ECHOLN_P("sc"); // transmit stream complete token
+ return;
+ case StreamState::STREAM_FAILED:
+ stream_state = StreamState::STREAM_RESET;
+ card.binary_mode = false;
+ card.closefile();
+ card.removeFile(card.filename);
+ CARD_ECHOLN_P("echo: File transfer failed");
+ CARD_ECHOLN_P("sf"); // transmit stream failed token
+ return;
+ }
+ }
+ }
+
+ static const uint16_t STREAM_MAX_WAIT = 500, RX_TIMESLICE = 20, MAX_RETRIES = 3;
+ uint8_t packet_retries;
+ uint16_t buffer_next_index;
+ uint32_t packets_received, bytes_received;
+ millis_t time_stream_start;
+ StreamState stream_state = StreamState::STREAM_RESET;
+
+ } binaryStream{};
+
+#endif // FAST_FILE_TRANSFER
+
/**
* Get all commands waiting on the serial port and queue them.
* Exit when the buffer is full or when no more characters are
@@ -288,6 +546,18 @@ inline void get_serial_commands() {
#endif
;
+ #if ENABLED(FAST_FILE_TRANSFER)
+ if (card.saving && card.binary_mode) {
+ /**
+ * For binary stream file transfer, use serial_line_buffer as the working
+ * receive buffer (which limits the packet size to MAX_CMD_SIZE).
+ * The receive buffer also limits the packet size for reliable transmission.
+ */
+ binaryStream.receive(serial_line_buffer[card.transfer_port]);
+ return;
+ }
+ #endif
+
// If the command buffer is empty for too long,
// send "wait" to indicate Marlin is still waiting.
#if NO_TIMEOUTS > 0
diff --git a/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M524_M928.cpp b/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M524_M928.cpp
index 81cca4c0d..d1e7ac5a5 100644
--- a/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M524_M928.cpp
+++ b/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M524_M928.cpp
@@ -157,7 +157,45 @@ void GcodeSuite::M27() {
/**
* M28: Start SD Write
*/
-void GcodeSuite::M28() { card.openFile(parser.string_arg, false); }
+void GcodeSuite::M28() {
+
+ #if ENABLED(FAST_FILE_TRANSFER)
+
+ const int16_t port =
+ #if NUM_SERIAL > 1
+ command_queue_port[cmd_queue_index_r]
+ #else
+ 0
+ #endif
+ ;
+
+ bool binary_mode = false;
+ char *p = parser.string_arg;
+ if (p[0] == 'B' && NUMERIC(p[1])) {
+ binary_mode = p[1] > '0';
+ p += 2;
+ while (*p == ' ') ++p;
+ }
+
+ // Binary transfer mode
+ if ((card.binary_mode = binary_mode)) {
+ SERIAL_ECHO_START_P(port);
+ SERIAL_ECHO_P(port, " preparing to receive: ");
+ SERIAL_ECHOLN_P(port, p);
+ card.openFile(p, false);
+ #if NUM_SERIAL > 1
+ card.transfer_port = port;
+ #endif
+ }
+ else
+ card.openFile(p, false);
+
+ #else
+
+ card.openFile(parser.string_arg, false);
+
+ #endif
+}
/**
* M29: Stop SD Write
diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp
index 91a3a8d04..5963aa8c2 100644
--- a/Marlin/src/sd/cardreader.cpp
+++ b/Marlin/src/sd/cardreader.cpp
@@ -33,6 +33,10 @@
#include "../core/language.h"
#include "../gcode/queue.h"
+#if ENABLED(EMERGENCY_PARSER)
+ #include "../feature/emergency_parser.h"
+#endif
+
#if ENABLED(POWER_LOSS_RECOVERY)
#include "../feature/power_loss_recovery.h"
#endif
@@ -461,7 +465,11 @@ void CardReader::openFile(char * const path, const bool read, const bool subcall
}
else {
saving = true;
- SERIAL_PROTOCOLLNPAIR(MSG_SD_WRITE_TO_FILE, path);
+ getfilename(0, fname);
+ #if ENABLED(EMERGENCY_PARSER)
+ emergency_parser.disable();
+ #endif
+ SERIAL_PROTOCOLLNPAIR(MSG_SD_WRITE_TO_FILE, fname);
lcd_setstatus(fname);
}
}
@@ -569,6 +577,9 @@ void CardReader::closefile(const bool store_location) {
file.sync();
file.close();
saving = logging = false;
+ #if ENABLED(EMERGENCY_PARSER)
+ emergency_parser.enable();
+ #endif
if (store_location) {
//future: store printer state, filename and position for continuing a stopped print
diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h
index b3c754cc9..feb64216e 100644
--- a/Marlin/src/sd/cardreader.h
+++ b/Marlin/src/sd/cardreader.h
@@ -124,11 +124,8 @@ public:
FORCE_INLINE uint32_t getIndex() { return sdpos; }
FORCE_INLINE uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; }
FORCE_INLINE char* getWorkDirName() { workDir.getFilename(filename); return filename; }
-
- #if defined(__STM32F1__) && ENABLED(EEPROM_SETTINGS) && DISABLED(FLASH_EEPROM_EMULATION)
- FORCE_INLINE int16_t read(void* buf, uint16_t nbyte) { return file.isOpen() ? file.read(buf, nbyte) : -1; }
- FORCE_INLINE int16_t write(void* buf, uint16_t nbyte) { return file.isOpen() ? file.write(buf, nbyte) : -1; }
- #endif
+ FORCE_INLINE int16_t read(void* buf, uint16_t nbyte) { return file.isOpen() ? file.read(buf, nbyte) : -1; }
+ FORCE_INLINE int16_t write(void* buf, uint16_t nbyte) { return file.isOpen() ? file.write(buf, nbyte) : -1; }
Sd2Card& getSd2Card() { return sd2card; }
@@ -154,6 +151,16 @@ public:
bool saving, logging, sdprinting, cardOK, filenameIsDir, abort_sd_printing;
char filename[FILENAME_LENGTH], longFilename[LONG_FILENAME_LENGTH];
int8_t autostart_index;
+
+ #if ENABLED(FAST_FILE_TRANSFER)
+ bool binary_mode;
+ #if NUM_SERIAL > 1
+ uint8_t transfer_port;
+ #else
+ constexpr uint8_t transfer_port = 0;
+ #endif
+ #endif
+
private:
SdFile root, workDir, workDirParents[MAX_DIR_DEPTH];
uint8_t workDirDepth;