diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 4cbacf6e531b1..8cf29f9adbd0b 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -108,12 +108,16 @@ void PrintJobRecovery::changed() { * * If a saved state exists send 'M1000 S' to initiate job recovery. */ -void PrintJobRecovery::check() { +bool PrintJobRecovery::check() { //if (!card.isMounted()) card.mount(); if (card.isMounted()) { load(); - if (!valid()) return cancel(); + if (!valid()) { + cancel(); + return false; + } queue.inject(F("M1000S")); + return true; } } diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index 4e97109bb7b93..93347917b51a7 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -176,7 +176,7 @@ class PrintJobRecovery { static void open(const bool read) { card.openJobRecoveryFile(read); } static void close() { file.close(); } - static void check(); + static bool check(); static void resume(); static void purge(); diff --git a/Marlin/src/gcode/feature/powerloss/M413.cpp b/Marlin/src/gcode/feature/powerloss/M413.cpp index 4807d3e8f95b9..f6d82b0ad9449 100644 --- a/Marlin/src/gcode/feature/powerloss/M413.cpp +++ b/Marlin/src/gcode/feature/powerloss/M413.cpp @@ -49,7 +49,7 @@ void GcodeSuite::M413() { if (parser.seen_test('P')) recovery.purge(); if (parser.seen_test('D')) recovery.debug(F("M413")); if (parser.seen_test('O')) recovery._outage(true); - if (parser.seen_test('C')) recovery.check(); + if (parser.seen_test('C')) (void)recovery.check(); if (parser.seen_test('E')) SERIAL_ECHOF(recovery.exists() ? F("PLR Exists\n") : F("No PLR\n")); if (parser.seen_test('V')) SERIAL_ECHOF(recovery.valid() ? F("Valid\n") : F("Invalid\n")); #endif diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index d2af634896dac..cb101595ff887 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -24,7 +24,11 @@ #include "../MarlinCore.h" // for printingIsPaused -#if LED_POWEROFF_TIMEOUT > 0 || BOTH(HAS_WIRED_LCD, PRINTER_EVENT_LEDS) +#if LED_POWEROFF_TIMEOUT > 0 + #define HAS_LED_POWEROFF_TIMEOUT 1 +#endif + +#if HAS_LED_POWEROFF_TIMEOUT || BOTH(HAS_WIRED_LCD, PRINTER_EVENT_LEDS) #include "../feature/leds/leds.h" #endif @@ -300,7 +304,7 @@ void MarlinUI::init() { #include "../feature/power_monitor.h" #endif - #if LED_POWEROFF_TIMEOUT > 0 + #if HAS_LED_POWEROFF_TIMEOUT #include "../feature/power.h" #endif @@ -919,9 +923,7 @@ void MarlinUI::init() { static uint16_t max_display_update_time = 0; millis_t ms = millis(); - #if LED_POWEROFF_TIMEOUT > 0 - leds.update_timeout(powerManager.psu_on); - #endif + TERN_(HAS_LED_POWEROFF_TIMEOUT, leds.update_timeout(powerManager.psu_on)); #if HAS_MARLINUI_MENU @@ -1076,9 +1078,7 @@ void MarlinUI::init() { refresh(LCDVIEW_REDRAW_NOW); - #if LED_POWEROFF_TIMEOUT > 0 - if (!powerManager.psu_on) leds.reset_timeout(ms); - #endif + TERN_(HAS_LED_POWEROFF_TIMEOUT, if (!powerManager.psu_on) leds.reset_timeout(ms)); } // encoder activity #endif // HAS_ENCODER_ACTION @@ -1733,14 +1733,14 @@ void MarlinUI::init() { #include "extui/ui_api.h" #endif - void MarlinUI::media_changed(const uint8_t old_status, const uint8_t status) { + void MarlinUI::media_changed(const bool old_status, const bool status, const bool first/*=false*/) { if (old_status == status) { TERN_(EXTENSIBLE_UI, ExtUI::onMediaError()); // Failed to mount/unmount return; } - if (status) { - if (old_status < 2) { + if (!first) { + if (status) { #if ENABLED(EXTENSIBLE_UI) ExtUI::onMediaInserted(); #elif ENABLED(BROWSE_MEDIA_ON_INSERT) @@ -1751,9 +1751,7 @@ void MarlinUI::init() { LCD_MESSAGE(MSG_MEDIA_INSERTED); #endif } - } - else { - if (old_status < 2) { + else { #if ENABLED(EXTENSIBLE_UI) ExtUI::onMediaRemoved(); #elif PIN_EXISTS(SD_DETECT) @@ -1766,18 +1764,14 @@ void MarlinUI::init() { } reinit_lcd(); // Revive a noisy shared SPI LCD - refresh(); - #if HAS_WIRED_LCD || LED_POWEROFF_TIMEOUT > 0 + #if HAS_WIRED_LCD || HAS_LED_POWEROFF_TIMEOUT const millis_t ms = millis(); #endif TERN_(HAS_WIRED_LCD, next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL); // Delay LCD update for SD activity - - #if LED_POWEROFF_TIMEOUT > 0 - leds.reset_timeout(ms); - #endif + TERN_(HAS_LED_POWEROFF_TIMEOUT, leds.reset_timeout(ms)); } #endif // SDSUPPORT diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index 4cff3c30f271b..9c9743ee5be6a 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -253,7 +253,7 @@ class MarlinUI { #if ENABLED(SDSUPPORT) #define MEDIA_MENU_GATEWAY TERN(PASSWORD_ON_SD_PRINT_MENU, password.media_gatekeeper, menu_media) - static void media_changed(const uint8_t old_stat, const uint8_t stat); + static void media_changed(const bool old_stat, const bool stat, const bool first=false); #endif #if HAS_LCD_BRIGHTNESS diff --git a/Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h b/Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h index de91db22d5545..fe6fd6fa5733d 100644 --- a/Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h +++ b/Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h @@ -27,7 +27,7 @@ #define BOARD_WEBSITE_URL "fysetc.com" #define BOARD_NO_NATIVE_USB - +#define RESET_STEPPERS_ON_MEDIA_INSERT #define DISABLE_JTAG #define pins_v2_20190128 // new pins define diff --git a/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h b/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h index e0f906bf9ecc6..08aeca8c5b592 100644 --- a/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h +++ b/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h @@ -32,7 +32,7 @@ //#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000 #define BOARD_NO_NATIVE_USB - +#define RESET_STEPPERS_ON_MEDIA_INSERT #define DISABLE_JTAG #if EITHER(NO_EEPROM_SELECTED, FLASH_EEPROM_EMULATION) diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index a0172737cdc2a..85c22fa5b7a25 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -465,59 +465,63 @@ void CardReader::mount() { } /** - * Handle SD card events + * Handle SD card events from the idle() loop */ #if MB(FYSETC_CHEETAH, FYSETC_AIO_II) #include "../module/stepper.h" #endif void CardReader::manage_media() { - static bool first_mount = true; // Check first successful mount - static uint8_t prev_stat = 2; // First call, no prior state - uint8_t stat = uint8_t(IS_SD_INSERTED()); - if (stat == prev_stat) return; + DEBUG_SECTION("CardReader::manage_media()"); - DEBUG_ECHOLNPGM("SD: Status changed from ", prev_stat, " to ", stat); + if (!ui.detected()) { + DEBUG_ECHOLNPGM("SD: No UI Detected."); // Exit if LCD is uninitialized + return; + } - flag.workDirIsRoot = true; // Return to root on mount/release + static sd_state_t stat = { false, false }; - if (ui.detected()) { + const bool is_present = IS_SD_INSERTED(); + if (!stat.inited && is_present == stat.present) return; // Done if not first init and nothing changed - uint8_t old_stat = prev_stat; - prev_stat = stat; // Change now to prevent re-entry + const bool was_present = stat.present; - if (stat) { // Media Inserted - safe_delay(500); // Some boards need a delay to get settled - if (TERN1(SD_IGNORE_AT_STARTUP, old_stat != 2)) - mount(); // Try to mount the media - #if MB(FYSETC_CHEETAH, FYSETC_CHEETAH_V12, FYSETC_AIO_II) - reset_stepper_drivers(); // Workaround for Cheetah bug - #endif - if (!isMounted()) stat = 0; // Not mounted? - } - else { - #if PIN_EXISTS(SD_DETECT) - release(); // Card is released - #endif - } + if (is_present) { // Media Inserted + safe_delay(500); // Some boards need a delay to get settled + if (TERN1(SD_IGNORE_AT_STARTUP, stat.inited)) + mount(); // Try to mount the media - ui.media_changed(old_stat, stat); // Update the UI + TERN_(RESET_STEPPERS_ON_MEDIA_INSERT, reset_stepper_drivers()); // Workaround for some boards - if (stat) { - TERN_(SDCARD_EEPROM_EMULATION, settings.first_load()); - if (first_mount) { // First mount? - DEBUG_ECHOLNPGM("First mount."); - #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 - first_mount = false; // clear first mount flag - } - } + if (!isMounted()) is_present = 0; // Not mounted? Then it fails } - else - DEBUG_ECHOLNPGM("SD: No UI Detected."); + else { + #if PIN_EXISTS(SD_DETECT) + release(); // Card is released (or first init) + #endif + } + + flag.workDirIsRoot = true; // Return to root on any mount/release + stat.present = is_present; // Update media presence state + + DEBUG_ECHOLNPGM("Media changed: ", old_stat, " -> ", is_present); + ui.media_changed(was_present, is_present, !stat.inited); // Update the UI for the new state + + if (!is_present) return; // Done if no media is present + if (stat.inited) return; // Done if the first mount was handled + + DEBUG_ECHOLNPGM("First mount."); + stat.inited = true; + + TERN_(SDCARD_EEPROM_EMULATION, settings.first_load()); // Try to load settings + + bool do_auto = true; UNUSED(do_auto); + + // Check for PLR file. (If not there then call autofile_begin) + TERN_(POWER_LOSS_RECOVERY, if (recovery.check()) do_auto = false); + + // Look for auto0.g on the next loop + IF_DISABLED(NO_SD_AUTOSTART, if (do_auto) autofile_begin()); } /** diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index 483ab81395848..e39f5365fa921 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -89,6 +89,11 @@ typedef struct { ; } card_flags_t; +typedef struct { + bool present:1, // First call, no prior state + inited:1, // Initialized yet? +} sd_state_t; + #if ENABLED(AUTO_REPORT_SD_STATUS) #include "../libs/autoreport.h" #endif