diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 03c9ba55eb..92de09eec9 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1197,6 +1197,7 @@ #define SD_MENU_CONFIRM_START // Confirm the selected SD file before printing + //#define NO_SD_AUTOSTART // Remove auto#.g file support completely to save some Flash, SRAM //#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files //#define BROWSE_MEDIA_ON_INSERT // Open the file browser when media is inserted diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index 84eb7e21d1..0171690d4e 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -460,6 +460,7 @@ void startOrResumeJob() { #if ENABLED(SDSUPPORT) inline void abortSDPrinting() { + IF_DISABLED(NO_SD_AUTOSTART, card.autofile_cancel()); card.endFilePrint(TERN_(SD_RESORT, true)); queue.clear(); quickstop_stepper(); @@ -585,7 +586,7 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) { if (ELAPSED(ms, next_home_key_ms)) { next_home_key_ms = ms + HOME_DEBOUNCE_DELAY; LCD_MESSAGEPGM(MSG_AUTO_HOME); - queue.enqueue_now_P(G28_STR); + queue.inject_P(G28_STR); } } #endif @@ -1354,7 +1355,6 @@ void loop() { idle(); #if ENABLED(SDSUPPORT) - card.checkautostart(); if (card.flag.abort_sd_printing) abortSDPrinting(); if (marlin_state == MF_SD_COMPLETE) finishSDPrinting(); #endif diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index f964f12294..25581e1723 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -152,7 +152,7 @@ class PrintJobRecovery { static void resume(); static void purge(); - static inline void cancel() { purge(); card.autostart_index = 0; } + static inline void cancel() { purge(); IF_DISABLED(NO_SD_AUTOSTART, card.autofile_begin()); } static void load(); static void save(const bool force=ENABLED(SAVE_EACH_CMD_MODE), const float zraise=0); diff --git a/Marlin/src/gcode/sd/M1001.cpp b/Marlin/src/gcode/sd/M1001.cpp index e4b7054bf2..406cd074c3 100644 --- a/Marlin/src/gcode/sd/M1001.cpp +++ b/Marlin/src/gcode/sd/M1001.cpp @@ -27,6 +27,10 @@ #include "../gcode.h" #include "../../module/printcounter.h" +#if DISABLED(NO_SD_AUTOSTART) + #include "../../sd/cardreader.h" +#endif + #ifdef SD_FINISHED_RELEASECOMMAND #include "../queue.h" #endif @@ -60,6 +64,11 @@ * M1001: Execute actions for SD print completion */ void GcodeSuite::M1001() { + // If there's another auto#.g file to run... + if (TERN(NO_SD_AUTOSTART, false, card.autofile_check())) return; + + // Purge the recovery file... + TERN_(POWER_LOSS_RECOVERY, recovery.purge()); // Report total print time const bool long_print = print_job_timer.duration() > 60; @@ -71,9 +80,6 @@ void GcodeSuite::M1001() { // Set the progress bar "done" state TERN_(LCD_SET_PROGRESS_MANUALLY, ui.set_progress_done()); - // Purge the recovery file - TERN_(POWER_LOSS_RECOVERY, recovery.purge()); - // Announce SD file completion { PORT_REDIRECT(SERIAL_BOTH); @@ -93,7 +99,7 @@ void GcodeSuite::M1001() { // Inject SD_FINISHED_RELEASECOMMAND, if any #ifdef SD_FINISHED_RELEASECOMMAND - queue.inject_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + gcode.process_subcommands_now_P(PSTR(SD_FINISHED_RELEASECOMMAND)); #endif TERN_(EXTENSIBLE_UI, ExtUI::onPrintFinished()); diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 1bd9dc47a4..f99e363d7b 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -142,6 +142,10 @@ #undef SD_FINISHED_RELEASECOMMAND #endif +#if ENABLED(NO_SD_AUTOSTART) + #undef MENU_ADDAUTOSTART +#endif + #if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) #define HAS_PRINT_PROGRESS 1 #endif diff --git a/Marlin/src/lcd/menu/menu_main.cpp b/Marlin/src/lcd/menu/menu_main.cpp index cda11bfc57..1b87e06cc8 100644 --- a/Marlin/src/lcd/menu/menu_main.cpp +++ b/Marlin/src/lcd/menu/menu_main.cpp @@ -136,7 +136,7 @@ void menu_main() { // Run Auto Files // #if ENABLED(MENU_ADDAUTOSTART) - ACTION_ITEM(MSG_RUN_AUTO_FILES, card.beginautostart); + ACTION_ITEM(MSG_RUN_AUTO_FILES, card.autofile_begin); #endif if (card_detected) { @@ -238,7 +238,7 @@ void menu_main() { // Autostart // #if ENABLED(MENU_ADDAUTOSTART) - ACTION_ITEM(MSG_RUN_AUTO_FILES, card.beginautostart); + ACTION_ITEM(MSG_RUN_AUTO_FILES, card.autofile_begin); #endif if (card_detected) { diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 7ba9f3d3d6..fe8bc4879a 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -61,7 +61,8 @@ card_flags_t CardReader::flag; char CardReader::filename[FILENAME_LENGTH], CardReader::longFilename[LONG_FILENAME_LENGTH]; -int8_t CardReader::autostart_index; + +IF_DISABLED(NO_SD_AUTOSTART, uint8_t CardReader::autofile_index); // = 0 #if BOTH(HAS_MULTI_SERIAL, BINARY_FILE_TRANSFER) int8_t CardReader::transfer_port_index; @@ -135,17 +136,17 @@ CardReader::CardReader() { //sort_reverse = false; #endif #endif + flag.sdprinting = flag.mounted = flag.saving = flag.logging = false; filesize = sdpos = 0; TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0); + IF_DISABLED(NO_SD_AUTOSTART, autofile_cancel()); + workDirDepth = 0; ZERO(workDirParents); - // Disable autostart until card is initialized - autostart_index = -1; - #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) SET_INPUT_PULLUP(SD_DETECT_PIN); #endif @@ -442,12 +443,14 @@ void CardReader::manage_media() { if (stat) { TERN_(SDCARD_EEPROM_EMULATION, settings.first_load()); - if (old_stat == 2) // First mount? + if (old_stat == 2) { // First mount? DEBUG_ECHOLNPGM("First mount."); - TERN(POWER_LOSS_RECOVERY, - recovery.check(), // Check for PLR file. (If not there it will beginautostart) - beginautostart() // Look for auto0.g on the next loop - ); + #if ENABLED(POWER_LOSS_RECOVERY) + recovery.check(); // Check for PLR file. (If not there then call autofile_begin) + #elif DISABLED(NO_SD_AUTOSTART) + autofile_begin(); // Look for auto0.g on the next loop + #endif + } } } else @@ -477,12 +480,12 @@ void CardReader::release() { * Enqueues M23 and M24 commands to initiate a media print. */ void CardReader::openAndPrintFile(const char *name) { - char cmd[4 + strlen(name) + 1]; // Room for "M23 ", filename, and null + char cmd[4 + strlen(name) + 1 + 3 + 1]; // Room for "M23 ", filename, "\n", "M24", and null extern const char M23_STR[]; sprintf_P(cmd, M23_STR, name); for (char *c = &cmd[4]; *c; c++) *c = tolower(*c); - queue.enqueue_one_now(cmd); - queue.enqueue_now_P(M24_STR); + strcat_P(cmd, PSTR("\nM24")); + queue.inject(cmd); } /** @@ -511,7 +514,7 @@ void CardReader::endFilePrint(TERN_(SD_RESORT, const bool re_sort/*=false*/)) { void CardReader::openLogFile(char * const path) { flag.logging = DISABLED(SDCARD_READONLY); - TERN(SDCARD_READONLY,,openFileWrite(path)); + IF_DISABLED(SDCARD_READONLY, openFileWrite(path)); } // @@ -735,42 +738,48 @@ void CardReader::write_command(char * const buf) { if (file.writeError) SERIAL_ERROR_MSG(STR_SD_ERR_WRITE_TO_FILE); } -// -// Run the next autostart file. Called: -// - On boot after successful card init -// - After finishing the previous autostart file -// - From the LCD command to run the autostart file -// +#if DISABLED(NO_SD_AUTOSTART) + /** + * Run all the auto#.g files. Called: + * - On boot after successful card init. + * - From the LCD command to Run Auto Files + */ + void CardReader::autofile_begin() { + autofile_index = 1; + (void)autofile_check(); + } -void CardReader::checkautostart() { + /** + * Run the next auto#.g file. Called: + * - On boot after successful card init + * - After finishing the previous auto#.g file + * - From the LCD command to begin the auto#.g files + * + * Return 'true' if there was nothing to do + */ + bool CardReader::autofile_check() { + if (!autofile_index) return true; - if (autostart_index < 0 || flag.sdprinting) return; + if (!isMounted()) + mount(); + else if (ENABLED(SDCARD_EEPROM_EMULATION)) + settings.first_load(); - if (!isMounted()) mount(); - TERN_(SDCARD_EEPROM_EMULATION, else settings.first_load()); - - // Don't run auto#.g when a PLR file exists - if (isMounted() && TERN1(POWER_LOSS_RECOVERY, !recovery.valid())) { - char autoname[8]; - sprintf_P(autoname, PSTR("auto%c.g"), autostart_index + '0'); - dir_t p; - root.rewind(); - while (root.readDir(&p, nullptr) > 0) { - for (int8_t i = (int8_t)strlen((char*)p.name); i--;) p.name[i] = tolower(p.name[i]); - if (p.name[9] != '~' && strncmp((char*)p.name, autoname, 5) == 0) { + // Don't run auto#.g when a PLR file exists + if (isMounted() && TERN1(POWER_LOSS_RECOVERY, !recovery.valid())) { + char autoname[10]; + sprintf_P(autoname, PSTR("/auto%c.g"), '0' + autofile_index - 1); + if (fileExists(autoname)) { + cdroot(); openAndPrintFile(autoname); - autostart_index++; - return; + autofile_index++; + return false; } } + autofile_cancel(); + return true; } - autostart_index = -1; -} - -void CardReader::beginautostart() { - autostart_index = 0; - cdroot(); -} +#endif void CardReader::closefile(const bool store_location/*=false*/) { file.sync(); diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index dabbf719f9..b775d8a873 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -90,10 +90,12 @@ public: static void openLogFile(char * const path); static void write_command(char * const buf); - // Auto-Start files - static int8_t autostart_index; // Index of autoX.g files - static void beginautostart(); - static void checkautostart(); + #if DISABLED(NO_SD_AUTOSTART) // Auto-Start auto#.g file handling + static uint8_t autofile_index; // Next auto#.g index to run, plus one. Ignored by autofile_check when zero. + static void autofile_begin(); // Begin check. Called automatically after boot-up. + static bool autofile_check(); // Check for the next auto-start file and run it. + static inline void autofile_cancel() { autofile_index = 0; } + #endif // Basic file ops static void openFileRead(char * const path, const uint8_t subcall=0); diff --git a/buildroot/tests/mega2560-tests b/buildroot/tests/mega2560-tests index da3a79f58c..0a17cacba1 100755 --- a/buildroot/tests/mega2560-tests +++ b/buildroot/tests/mega2560-tests @@ -49,7 +49,7 @@ opt_set TEMP_SENSOR_4 1000 opt_set TEMP_SENSOR_BED 1 opt_enable AUTO_BED_LEVELING_UBL RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_VALIDATION ENABLE_LEVELING_FADE_HEIGHT SKEW_CORRECTION \ REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER LIGHTWEIGHT_UI STATUS_MESSAGE_SCROLLING BOOT_MARLIN_LOGO_SMALL \ - SDSUPPORT SDCARD_SORT_ALPHA USB_FLASH_DRIVE_SUPPORT SCROLL_LONG_FILENAMES CANCEL_OBJECTS \ + SDSUPPORT SDCARD_SORT_ALPHA USB_FLASH_DRIVE_SUPPORT SCROLL_LONG_FILENAMES CANCEL_OBJECTS NO_SD_AUTOSTART \ EEPROM_SETTINGS EEPROM_CHITCHAT GCODE_MACROS CUSTOM_USER_MENUS \ MULTI_NOZZLE_DUPLICATION CLASSIC_JERK LIN_ADVANCE QUICK_HOME \ LCD_SET_PROGRESS_MANUALLY PRINT_PROGRESS_SHOW_DECIMALS SHOW_REMAINING_TIME \