Signal SD completion later (#21840)

This commit is contained in:
Scott Lahteine 2021-05-08 04:35:35 -05:00 committed by Scott Lahteine
parent 83309c1ac8
commit c5c8ef436c
23 changed files with 133 additions and 116 deletions

View file

@ -331,18 +331,14 @@ void disable_all_steppers() {
} }
/** /**
* A Print Job exists when the timer is running or SD printing * A Print Job exists when the timer is running or SD is printing
*/ */
bool printJobOngoing() { bool printJobOngoing() { return print_job_timer.isRunning() || IS_SD_PRINTING(); }
return print_job_timer.isRunning() || IS_SD_PRINTING();
}
/** /**
* Printing is active when the print job timer is running * Printing is active when a job is underway but not paused
*/ */
bool printingIsActive() { bool printingIsActive() { return !did_pause_print && printJobOngoing(); }
return !did_pause_print && (print_job_timer.isRunning() || IS_SD_PRINTING());
}
/** /**
* Printing is paused according to SD or host indicators * Printing is paused according to SD or host indicators
@ -367,7 +363,7 @@ void startOrResumeJob() {
inline void abortSDPrinting() { inline void abortSDPrinting() {
IF_DISABLED(NO_SD_AUTOSTART, card.autofile_cancel()); IF_DISABLED(NO_SD_AUTOSTART, card.autofile_cancel());
card.endFilePrint(TERN_(SD_RESORT, true)); card.abortFilePrintNow(TERN_(SD_RESORT, true));
queue.clear(); queue.clear();
quickstop_stepper(); quickstop_stepper();
@ -748,7 +744,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
// Handle Power-Loss Recovery // Handle Power-Loss Recovery
#if ENABLED(POWER_LOSS_RECOVERY) && PIN_EXISTS(POWER_LOSS) #if ENABLED(POWER_LOSS_RECOVERY) && PIN_EXISTS(POWER_LOSS)
if (printJobOngoing()) recovery.outage(); if (IS_SD_PRINTING()) recovery.outage();
#endif #endif
// Run StallGuard endstop checks // Run StallGuard endstop checks
@ -901,7 +897,7 @@ void stop() {
thermalManager.set_fans_paused(false); // Un-pause fans for safety thermalManager.set_fans_paused(false); // Un-pause fans for safety
#endif #endif
if (IsRunning()) { if (!IsStopped()) {
SERIAL_ERROR_MSG(STR_ERR_STOPPED); SERIAL_ERROR_MSG(STR_ERR_STOPPED);
LCD_MESSAGEPGM(MSG_STOPPED); LCD_MESSAGEPGM(MSG_STOPPED);
safe_delay(350); // allow enough time for messages to get out before stopping safe_delay(350); // allow enough time for messages to get out before stopping

View file

@ -70,6 +70,7 @@ inline bool IsRunning() { return marlin_state >= MF_RUNNING; }
inline bool IsStopped() { return marlin_state == MF_STOPPED; } inline bool IsStopped() { return marlin_state == MF_STOPPED; }
bool printingIsActive(); bool printingIsActive();
bool printJobOngoing();
bool printingIsPaused(); bool printingIsPaused();
void startOrResumeJob(); void startOrResumeJob();

View file

@ -649,7 +649,7 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
if (did_pause_print) { if (did_pause_print) {
--did_pause_print; --did_pause_print;
card.startFileprint(); card.startOrResumeFilePrinting();
// Write PLR now to update the z axis value // Write PLR now to update the z axis value
TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true)); TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true));
} }

View file

@ -137,7 +137,7 @@ void PrintJobRecovery::load() {
* Set info fields that won't change * Set info fields that won't change
*/ */
void PrintJobRecovery::prepare() { void PrintJobRecovery::prepare() {
card.getAbsFilename(info.sd_filename); // SD filename card.getAbsFilenameInCWD(info.sd_filename); // SD filename
cmd_sdpos = 0; cmd_sdpos = 0;
} }

View file

@ -550,7 +550,8 @@ void GCodeQueue::get_serial_commands() {
inline void GCodeQueue::get_sdcard_commands() { inline void GCodeQueue::get_sdcard_commands() {
static uint8_t sd_input_state = PS_NORMAL; static uint8_t sd_input_state = PS_NORMAL;
if (!IS_SD_PRINTING()) return; // Get commands if there are more in the file
if (!IS_SD_FETCHING()) return;
int sd_count = 0; int sd_count = 0;
while (!ring_buffer.full() && !card.eof()) { while (!ring_buffer.full() && !card.eof()) {

View file

@ -25,6 +25,7 @@
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
#include "../gcode.h" #include "../gcode.h"
#include "../../module/planner.h"
#include "../../module/printcounter.h" #include "../../module/printcounter.h"
#if DISABLED(NO_SD_AUTOSTART) #if DISABLED(NO_SD_AUTOSTART)
@ -64,6 +65,11 @@
* M1001: Execute actions for SD print completion * M1001: Execute actions for SD print completion
*/ */
void GcodeSuite::M1001() { void GcodeSuite::M1001() {
planner.synchronize();
// SD Printing is finished when the queue reaches M1001
card.flag.sdprinting = card.flag.sdprintdone = false;
// If there's another auto#.g file to run... // If there's another auto#.g file to run...
if (TERN(NO_SD_AUTOSTART, false, card.autofile_check())) return; if (TERN(NO_SD_AUTOSTART, false, card.autofile_check())) return;

View file

@ -70,7 +70,7 @@ void GcodeSuite::M24() {
#endif #endif
if (card.isFileOpen()) { if (card.isFileOpen()) {
card.startFileprint(); // SD card will now be read for commands card.startOrResumeFilePrinting(); // SD card will now be read for commands
startOrResumeJob(); // Start (or resume) the print job timer startOrResumeJob(); // Start (or resume) the print job timer
TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
} }

View file

@ -35,7 +35,7 @@
void GcodeSuite::M27() { void GcodeSuite::M27() {
if (parser.seen('C')) { if (parser.seen('C')) {
SERIAL_ECHOPGM("Current file: "); SERIAL_ECHOPGM("Current file: ");
card.printFilename(); card.printSelectedFilename();
return; return;
} }

View file

@ -49,7 +49,7 @@ void GcodeSuite::M32() {
if (parser.seenval('S')) card.setIndex(parser.value_long()); if (parser.seenval('S')) card.setIndex(parser.value_long());
card.startFileprint(); card.startOrResumeFilePrinting();
// Procedure calls count as normal print time. // Procedure calls count as normal print time.
if (!call_procedure) startOrResumeJob(); if (!call_procedure) startOrResumeJob();

View file

@ -33,7 +33,7 @@
void GcodeSuite::M524() { void GcodeSuite::M524() {
if (IS_SD_PRINTING()) if (IS_SD_PRINTING())
card.flag.abort_sd_printing = true; card.abortFilePrintSoon();
else if (card.isMounted()) else if (card.isMounted())
card.closefile(); card.closefile();

View file

@ -755,7 +755,7 @@ inline uint8_t draw_elapsed_or_remaining_time(uint8_t timepos, const bool blink)
char buffer[14]; char buffer[14];
#if ENABLED(SHOW_REMAINING_TIME) #if ENABLED(SHOW_REMAINING_TIME)
const bool show_remain = TERN1(ROTATE_PROGRESS_DISPLAY, blink) && (printingIsActive() || marlin_state == MF_SD_COMPLETE); const bool show_remain = TERN1(ROTATE_PROGRESS_DISPLAY, blink) && printingIsActive();
if (show_remain) { if (show_remain) {
#if ENABLED(USE_M73_REMAINING_TIME) #if ENABLED(USE_M73_REMAINING_TIME)
duration_t remaining = ui.get_remaining_time(); duration_t remaining = ui.get_remaining_time();
@ -889,7 +889,7 @@ void MarlinUI::draw_status_screen() {
#else // !HAS_DUAL_MIXING #else // !HAS_DUAL_MIXING
const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive() || marlin_state == MF_SD_COMPLETE); const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive());
if (show_e_total) { if (show_e_total) {
#if ENABLED(LCD_SHOW_E_TOTAL) #if ENABLED(LCD_SHOW_E_TOTAL)

View file

@ -41,7 +41,7 @@
#include "../../gcode/parser.h" // for units (and volumetric) #include "../../gcode/parser.h" // for units (and volumetric)
#if ENABLED(LCD_SHOW_E_TOTAL) #if ENABLED(LCD_SHOW_E_TOTAL)
#include "../../MarlinCore.h" // for printingIsActive(), marlin_state and MF_SD_COMPLETE #include "../../MarlinCore.h" // for printingIsActive()
#endif #endif
#if ENABLED(FILAMENT_LCD_DISPLAY) #if ENABLED(FILAMENT_LCD_DISPLAY)
@ -464,7 +464,7 @@ void MarlinUI::draw_status_screen() {
#endif #endif
#endif #endif
const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive() || marlin_state == MF_SD_COMPLETE); const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive());
// At the first page, generate new display values // At the first page, generate new display values
if (first_page) { if (first_page) {

View file

@ -1891,7 +1891,7 @@ void HMI_SDCardUpdate() {
else if (checkkey == PrintProcess || checkkey == Tune || printingIsActive()) { else if (checkkey == PrintProcess || checkkey == Tune || printingIsActive()) {
// TODO: Move card removed abort handling // TODO: Move card removed abort handling
// to CardReader::manage_media. // to CardReader::manage_media.
card.flag.abort_sd_printing = true; card.abortFilePrintSoon();
wait_for_heatup = wait_for_user = false; wait_for_heatup = wait_for_user = false;
dwin_abort_flag = true; // Reset feedrate, return to Home dwin_abort_flag = true; // Reset feedrate, return to Home
} }
@ -2311,7 +2311,7 @@ void HMI_PauseOrStop() {
checkkey = Back_Main; checkkey = Back_Main;
if (HMI_flag.home_flag) planner.synchronize(); // Wait for planner moves to finish! if (HMI_flag.home_flag) planner.synchronize(); // Wait for planner moves to finish!
wait_for_heatup = wait_for_user = false; // Stop waiting for heating/user wait_for_heatup = wait_for_user = false; // Stop waiting for heating/user
card.flag.abort_sd_printing = true; // Let the main loop handle SD abort card.abortFilePrintSoon(); // Let the main loop handle SD abort
dwin_abort_flag = true; // Reset feedrate, return to Home dwin_abort_flag = true; // Reset feedrate, return to Home
#ifdef ACTION_ON_CANCEL #ifdef ACTION_ON_CANCEL
host_action_cancel(); host_action_cancel();

View file

@ -289,7 +289,7 @@ void DGUSScreenHandler::ScreenChangeHook(DGUS_VP_Variable &var, void *val_ptr) {
// if robin nano is printing. when it is, dgus will enter the printing // if robin nano is printing. when it is, dgus will enter the printing
// page to continue print; // page to continue print;
// //
//if (print_job_timer.isRunning() || print_job_timer.isPaused()) { //if (printJobOngoing() || printingIsPaused()) {
// if (target == MKSLCD_PAUSE_SETTING_MOVE || target == MKSLCD_PAUSE_SETTING_EX // if (target == MKSLCD_PAUSE_SETTING_MOVE || target == MKSLCD_PAUSE_SETTING_EX
// || target == MKSLCD_SCREEN_PRINT || target == MKSLCD_SCREEN_PAUSE // || target == MKSLCD_SCREEN_PRINT || target == MKSLCD_SCREEN_PAUSE
// ) { // ) {
@ -324,7 +324,7 @@ void DGUSScreenHandler::ScreenBackChange(DGUS_VP_Variable &var, void *val_ptr) {
void DGUSScreenHandler::ZoffsetConfirm(DGUS_VP_Variable &var, void *val_ptr) { void DGUSScreenHandler::ZoffsetConfirm(DGUS_VP_Variable &var, void *val_ptr) {
settings.save(); settings.save();
if (print_job_timer.isRunning()) if (printJobOngoing())
GotoScreen(MKSLCD_SCREEN_PRINT); GotoScreen(MKSLCD_SCREEN_PRINT);
else if (print_job_timer.isPaused) else if (print_job_timer.isPaused)
GotoScreen(MKSLCD_SCREEN_PAUSE); GotoScreen(MKSLCD_SCREEN_PAUSE);
@ -1442,8 +1442,7 @@ bool DGUSScreenHandler::loop() {
} }
#if ENABLED(DGUS_MKS_RUNOUT_SENSOR) #if ENABLED(DGUS_MKS_RUNOUT_SENSOR)
if (booted && (IS_SD_PRINTING() || IS_SD_PAUSED())) if (booted && printingIsActive()) DGUS_Runout_Idle();
DGUS_Runout_Idle();
#endif #endif
#endif // SHOW_BOOTSCREEN #endif // SHOW_BOOTSCREEN

View file

@ -91,8 +91,8 @@ static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) {
cur_name = strrchr(list_file.file_name[sel_id], '/'); cur_name = strrchr(list_file.file_name[sel_id], '/');
SdFile file, *curDir; SdFile file, *curDir;
card.endFilePrint(); card.abortFilePrintNow();
const char * const fname = card.diveToFile(true, curDir, cur_name); const char * const fname = card.diveToFile(false, curDir, cur_name);
if (!fname) return; if (!fname) return;
if (file.open(curDir, fname, O_READ)) { if (file.open(curDir, fname, O_READ)) {
gCfgItems.curFilesize = file.fileSize(); gCfgItems.curFilesize = file.fileSize();
@ -108,7 +108,7 @@ static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) {
planner.flow_percentage[1] = 100; planner.flow_percentage[1] = 100;
planner.e_factor[1] = planner.flow_percentage[1] * 0.01f; planner.e_factor[1] = planner.flow_percentage[1] * 0.01f;
#endif #endif
card.startFileprint(); card.startOrResumeFilePrinting();
#if ENABLED(POWER_LOSS_RECOVERY) #if ENABLED(POWER_LOSS_RECOVERY)
recovery.prepare(); recovery.prepare();
#endif #endif
@ -125,7 +125,7 @@ static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) {
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
uiCfg.print_state = IDLE; uiCfg.print_state = IDLE;
card.flag.abort_sd_printing = true; card.abortFilePrintSoon();
#endif #endif
} }
else if (DIALOG_IS(TYPE_FINISH_PRINT)) { else if (DIALOG_IS(TYPE_FINISH_PRINT)) {

View file

@ -638,19 +638,18 @@ char *creat_title_text() {
W25QXX.SPI_FLASH_BufferWrite(bmp_public_buf, BAK_VIEW_ADDR_TFT35 + row * 400, 400); W25QXX.SPI_FLASH_BufferWrite(bmp_public_buf, BAK_VIEW_ADDR_TFT35 + row * 400, 400);
#endif #endif
row++; row++;
card.abortFilePrintNow();
if (row >= 200) { if (row >= 200) {
size = 809; size = 809;
row = 0; row = 0;
gcode_preview_over = false; gcode_preview_over = false;
card.closefile();
char *cur_name = strrchr(list_file.file_name[sel_id], '/'); char *cur_name = strrchr(list_file.file_name[sel_id], '/');
SdFile file; SdFile file;
SdFile *curDir; SdFile *curDir;
card.endFilePrint(); const char * const fname = card.diveToFile(false, curDir, cur_name);
const char * const fname = card.diveToFile(true, curDir, cur_name);
if (!fname) return; if (!fname) return;
if (file.open(curDir, fname, O_READ)) { if (file.open(curDir, fname, O_READ)) {
gCfgItems.curFilesize = file.fileSize(); gCfgItems.curFilesize = file.fileSize();
@ -667,13 +666,12 @@ char *creat_title_text() {
planner.flow_percentage[1] = 100; planner.flow_percentage[1] = 100;
planner.e_factor[1] = planner.flow_percentage[1] * 0.01; planner.e_factor[1] = planner.flow_percentage[1] * 0.01;
#endif #endif
card.startFileprint(); card.startOrResumeFilePrinting();
TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
once_flag = false; once_flag = false;
} }
return; return;
} }
card.closefile();
#endif // SDSUPPORT #endif // SDSUPPORT
} }

View file

@ -505,7 +505,7 @@ int write_to_file(char *buf, int len) {
if (res == -1) { if (res == -1) {
upload_file.close(); upload_file.close();
const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath); const char * const fname = card.diveToFile(false, upload_curDir, saveFilePath);
if (upload_file.open(upload_curDir, fname, O_WRITE)) { if (upload_file.open(upload_curDir, fname, O_WRITE)) {
upload_file.setpos(&pos); upload_file.setpos(&pos);
@ -732,12 +732,10 @@ static void wifi_gcode_exec(uint8_t *cmd_line) {
if (!gcode_preview_over) { if (!gcode_preview_over) {
char *cur_name = strrchr(list_file.file_name[sel_id], '/'); char *cur_name = strrchr(list_file.file_name[sel_id], '/');
card.endFilePrint();
SdFile file; SdFile file;
SdFile *curDir; SdFile *curDir;
card.endFilePrint(); card.abortFilePrintNow();
const char * const fname = card.diveToFile(true, curDir, cur_name); const char * const fname = card.diveToFile(false, curDir, cur_name);
if (!fname) return; if (!fname) return;
if (file.open(curDir, fname, O_READ)) { if (file.open(curDir, fname, O_READ)) {
gCfgItems.curFilesize = file.fileSize(); gCfgItems.curFilesize = file.fileSize();
@ -754,7 +752,7 @@ static void wifi_gcode_exec(uint8_t *cmd_line) {
planner.flow_percentage[1] = 100; planner.flow_percentage[1] = 100;
planner.e_factor[1] = planner.flow_percentage[1] * 0.01f; planner.e_factor[1] = planner.flow_percentage[1] * 0.01f;
#endif #endif
card.startFileprint(); card.startOrResumeFilePrinting();
TERN_(POWER_LOSS_RECOVERY, recovery.prepare()); TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
once_flag = false; once_flag = false;
} }
@ -814,7 +812,7 @@ static void wifi_gcode_exec(uint8_t *cmd_line) {
clear_cur_ui(); clear_cur_ui();
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
uiCfg.print_state = IDLE; uiCfg.print_state = IDLE;
card.flag.abort_sd_printing = true; card.abortFilePrintSoon();
#endif #endif
lv_draw_ready_print(); lv_draw_ready_print();
@ -1317,7 +1315,7 @@ static void file_first_msg_handle(uint8_t * msg, uint16_t msgLen) {
card.cdroot(); card.cdroot();
upload_file.close(); upload_file.close();
const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath); const char * const fname = card.diveToFile(false, upload_curDir, saveFilePath);
if (!upload_file.open(upload_curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) { if (!upload_file.open(upload_curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
clear_cur_ui(); clear_cur_ui();
@ -1370,7 +1368,7 @@ static void file_fragment_msg_handle(uint8_t * msg, uint16_t msgLen) {
int res = upload_file.write(public_buf, file_writer.write_index); int res = upload_file.write(public_buf, file_writer.write_index);
if (res == -1) { if (res == -1) {
upload_file.close(); upload_file.close();
const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath); const char * const fname = card.diveToFile(false, upload_curDir, saveFilePath);
if (upload_file.open(upload_curDir, fname, O_WRITE)) { if (upload_file.open(upload_curDir, fname, O_WRITE)) {
upload_file.setpos(&pos); upload_file.setpos(&pos);
res = upload_file.write(public_buf, file_writer.write_index); res = upload_file.write(public_buf, file_writer.write_index);
@ -1378,7 +1376,7 @@ static void file_fragment_msg_handle(uint8_t * msg, uint16_t msgLen) {
} }
upload_file.close(); upload_file.close();
SdFile file, *curDir; SdFile file, *curDir;
const char * const fname = card.diveToFile(true, curDir, saveFilePath); const char * const fname = card.diveToFile(false, curDir, saveFilePath);
if (file.open(curDir, fname, O_RDWR)) { if (file.open(curDir, fname, O_RDWR)) {
gCfgItems.curFilesize = file.fileSize(); gCfgItems.curFilesize = file.fileSize();
file.close(); file.close();
@ -1744,7 +1742,7 @@ void mks_wifi_firmware_update() {
if (wifi_upload(0) >= 0) { if (wifi_upload(0) >= 0) {
card.removeFile((char *)ESP_FIRMWARE_FILE_RENAME); card.removeFile((char *)ESP_FIRMWARE_FILE_RENAME);
SdFile file, *curDir; SdFile file, *curDir;
const char * const fname = card.diveToFile(true, curDir, ESP_FIRMWARE_FILE); const char * const fname = card.diveToFile(false, curDir, ESP_FIRMWARE_FILE);
if (file.open(curDir, fname, O_READ)) { if (file.open(curDir, fname, O_READ)) {
file.rename(curDir, (char *)ESP_FIRMWARE_FILE_RENAME); file.rename(curDir, (char *)ESP_FIRMWARE_FILE_RENAME);
file.close(); file.close();

View file

@ -625,7 +625,7 @@ void upload_spin() {
// Try to upload the given file at the given address // Try to upload the given file at the given address
void SendUpdateFile(const char *file, uint32_t address) { void SendUpdateFile(const char *file, uint32_t address) {
const char * const fname = card.diveToFile(true, update_curDir, ESP_FIRMWARE_FILE); const char * const fname = card.diveToFile(false, update_curDir, ESP_FIRMWARE_FILE);
if (!update_file.open(update_curDir, fname, O_READ)) return; if (!update_file.open(update_curDir, fname, O_READ)) return;
esp_upload.fileSize = update_file.fileSize(); esp_upload.fileSize = update_file.fileSize();

View file

@ -54,6 +54,7 @@
#include "../../module/printcounter.h" #include "../../module/printcounter.h"
#include "../../libs/duration_t.h" #include "../../libs/duration_t.h"
#include "../../HAL/shared/Delay.h" #include "../../HAL/shared/Delay.h"
#include "../../MarlinCore.h"
#include "../../sd/cardreader.h" #include "../../sd/cardreader.h"
#if ENABLED(PRINTCOUNTER) #if ENABLED(PRINTCOUNTER)
@ -106,9 +107,6 @@ namespace ExtUI {
#if ENABLED(JOYSTICK) #if ENABLED(JOYSTICK)
uint8_t jogging : 1; uint8_t jogging : 1;
#endif #endif
#if ENABLED(SDSUPPORT)
uint8_t was_sd_printing : 1;
#endif
} flags; } flags;
#ifdef __SAM3X8E__ #ifdef __SAM3X8E__
@ -1017,27 +1015,17 @@ namespace ExtUI {
void setUserConfirmed() { TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); } void setUserConfirmed() { TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); }
void printFile(const char *filename) { void printFile(const char *filename) {
UNUSED(filename); TERN(SDSUPPORT, card.openAndPrintFile(filename), UNUSED(filename));
TERN_(SDSUPPORT, card.openAndPrintFile(filename));
} }
bool isPrintingFromMediaPaused() { bool isPrintingFromMediaPaused() {
return TERN0(SDSUPPORT, isPrintingFromMedia() && !IS_SD_PRINTING()); return TERN0(SDSUPPORT, isPrintingFromMedia() && printingIsPaused());
} }
bool isPrintingFromMedia() { bool isPrintingFromMedia() { return IS_SD_PRINTING(); }
#if ENABLED(SDSUPPORT)
// Account for when IS_SD_PRINTING() reports the end of the
// print when there is still SD card data in the planner.
flags.was_sd_printing = card.isFileOpen() || (flags.was_sd_printing && commandsInQueue());
return flags.was_sd_printing;
#else
return false;
#endif
}
bool isPrinting() { bool isPrinting() {
return (commandsInQueue() || isPrintingFromMedia() || TERN0(SDSUPPORT, IS_SD_PRINTING())) || print_job_timer.isRunning() || print_job_timer.isPaused(); return commandsInQueue() || isPrintingFromMedia() || printJobOngoing() || printingIsPaused();
} }
bool isPrintingPaused() { bool isPrintingPaused() {

View file

@ -1487,7 +1487,7 @@ void MarlinUI::update() {
void MarlinUI::abort_print() { void MarlinUI::abort_print() {
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
wait_for_heatup = wait_for_user = false; wait_for_heatup = wait_for_user = false;
card.flag.abort_sd_printing = true; card.abortFilePrintSoon();
#endif #endif
#ifdef ACTION_ON_CANCEL #ifdef ACTION_ON_CANCEL
host_action_cancel(); host_action_cancel();

View file

@ -395,7 +395,7 @@ void Endstops::event_handler() {
#if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT) #if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT)
if (planner.abort_on_endstop_hit) { if (planner.abort_on_endstop_hit) {
card.endFilePrint(); card.abortFilePrintNow();
quickstop_stepper(); quickstop_stepper();
thermalManager.disable_all_heaters(); thermalManager.disable_all_heaters();
print_job_timer.stop(); print_job_timer.stop();

View file

@ -161,7 +161,7 @@ CardReader::CardReader() {
#endif #endif
#endif #endif
flag.sdprinting = flag.mounted = flag.saving = flag.logging = false; flag.sdprinting = flag.sdprintdone = flag.mounted = flag.saving = flag.logging = false;
filesize = sdpos = 0; filesize = sdpos = 0;
TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0); TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0);
@ -379,7 +379,7 @@ void CardReader::ls() {
// //
// Echo the DOS 8.3 filename (and long filename, if any) // Echo the DOS 8.3 filename (and long filename, if any)
// //
void CardReader::printFilename() { void CardReader::printSelectedFilename() {
if (file.isOpen()) { if (file.isOpen()) {
char dosFilename[FILENAME_LENGTH]; char dosFilename[FILENAME_LENGTH];
file.getDosName(dosFilename); file.getDosName(dosFilename);
@ -487,9 +487,9 @@ void CardReader::manage_media() {
void CardReader::release() { void CardReader::release() {
// Card removed while printing? Abort! // Card removed while printing? Abort!
if (IS_SD_PRINTING()) if (IS_SD_PRINTING())
card.flag.abort_sd_printing = true; abortFilePrintSoon();
else else
endFilePrint(); endFilePrintNow();
flag.mounted = false; flag.mounted = false;
flag.workDirIsRoot = true; flag.workDirIsRoot = true;
@ -516,9 +516,10 @@ void CardReader::openAndPrintFile(const char *name) {
* since you cannot browse files during active printing. * since you cannot browse files during active printing.
* Used by M24 and anywhere Start / Resume applies. * Used by M24 and anywhere Start / Resume applies.
*/ */
void CardReader::startFileprint() { void CardReader::startOrResumeFilePrinting() {
if (isMounted()) { if (isMounted()) {
flag.sdprinting = true; flag.sdprinting = true;
flag.sdprintdone = false;
TERN_(SD_RESORT, flush_presort()); TERN_(SD_RESORT, flush_presort());
} }
} }
@ -526,14 +527,19 @@ void CardReader::startFileprint() {
// //
// Run tasks upon finishing or aborting a file print. // Run tasks upon finishing or aborting a file print.
// //
void CardReader::endFilePrint(TERN_(SD_RESORT, const bool re_sort/*=false*/)) { void CardReader::endFilePrintNow(TERN_(SD_RESORT, const bool re_sort/*=false*/)) {
TERN_(ADVANCED_PAUSE_FEATURE, did_pause_print = 0); TERN_(ADVANCED_PAUSE_FEATURE, did_pause_print = 0);
TERN_(DWIN_CREALITY_LCD, HMI_flag.print_finish = flag.sdprinting); TERN_(DWIN_CREALITY_LCD, HMI_flag.print_finish = flag.sdprinting);
flag.sdprinting = flag.abort_sd_printing = false; flag.abort_sd_printing = false;
if (isFileOpen()) file.close(); if (isFileOpen()) file.close();
TERN_(SD_RESORT, if (re_sort) presort()); TERN_(SD_RESORT, if (re_sort) presort());
} }
void CardReader::abortFilePrintNow(TERN_(SD_RESORT, const bool re_sort/*=false*/)) {
flag.sdprinting = flag.sdprintdone = false;
endFilePrintNow(TERN_(SD_RESORT, re_sort));
}
void CardReader::openLogFile(const char * const path) { void CardReader::openLogFile(const char * const path) {
flag.logging = DISABLED(SDCARD_READONLY); flag.logging = DISABLED(SDCARD_READONLY);
IF_DISABLED(SDCARD_READONLY, openFileWrite(path)); IF_DISABLED(SDCARD_READONLY, openFileWrite(path));
@ -542,7 +548,7 @@ void CardReader::openLogFile(const char * const path) {
// //
// Get the root-relative DOS path of the selected file // Get the root-relative DOS path of the selected file
// //
void CardReader::getAbsFilename(char *dst) { void CardReader::getAbsFilenameInCWD(char *dst) {
*dst++ = '/'; *dst++ = '/';
uint8_t cnt = 1; uint8_t cnt = 1;
@ -608,7 +614,7 @@ void CardReader::openFileRead(const char * const path, const uint8_t subcall_typ
} }
// Store current filename (based on workDirParents) and position // Store current filename (based on workDirParents) and position
getAbsFilename(proc_filenames[file_subcall_ctr]); getAbsFilenameInCWD(proc_filenames[file_subcall_ctr]);
filespos[file_subcall_ctr] = sdpos; filespos[file_subcall_ctr] = sdpos;
// For sub-procedures say 'SUBROUTINE CALL target: "..." parent: "..." pos12345' // For sub-procedures say 'SUBROUTINE CALL target: "..." parent: "..." pos12345'
@ -623,7 +629,7 @@ void CardReader::openFileRead(const char * const path, const uint8_t subcall_typ
#endif #endif
} }
endFilePrint(); abortFilePrintNow();
SdFile *diveDir; SdFile *diveDir;
const char * const fname = diveToFile(true, diveDir, path); const char * const fname = diveToFile(true, diveDir, path);
@ -659,7 +665,7 @@ void CardReader::openFileWrite(const char * const path) {
announceOpen(2, path); announceOpen(2, path);
TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0); TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0);
endFilePrint(); abortFilePrintNow();
SdFile *diveDir; SdFile *diveDir;
const char * const fname = diveToFile(false, diveDir, path); const char * const fname = diveToFile(false, diveDir, path);
@ -712,7 +718,7 @@ bool CardReader::fileExists(const char * const path) {
void CardReader::removeFile(const char * const name) { void CardReader::removeFile(const char * const name) {
if (!isMounted()) return; if (!isMounted()) return;
//endFilePrint(); //abortFilePrintNow();
SdFile *curDir; SdFile *curDir;
const char * const fname = diveToFile(false, curDir, name); const char * const fname = diveToFile(false, curDir, name);
@ -856,6 +862,9 @@ uint16_t CardReader::countFilesInWorkDir() {
/** /**
* Dive to the given DOS 8.3 file path, with optional echo of the dive paths. * Dive to the given DOS 8.3 file path, with optional echo of the dive paths.
* *
* On entry:
* - The workDir points to the last-set navigation target by cd, cdup, cdroot, or diveToFile(true, ...)
*
* On exit: * On exit:
* - Your curDir pointer contains an SdFile reference to the file's directory. * - Your curDir pointer contains an SdFile reference to the file's directory.
* - If update_cwd was 'true' the workDir now points to the file's directory. * - If update_cwd was 'true' the workDir now points to the file's directory.
@ -865,6 +874,8 @@ uint16_t CardReader::countFilesInWorkDir() {
* A nullptr result indicates an unrecoverable error. * A nullptr result indicates an unrecoverable error.
*/ */
const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, const char * const path, const bool echo/*=false*/) { const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, const char * const path, const bool echo/*=false*/) {
DEBUG_SECTION(est, "diveToFile", true);
// Track both parent and subfolder // Track both parent and subfolder
static SdFile newDir1, newDir2; static SdFile newDir1, newDir2;
SdFile *sub = &newDir1, *startDir; SdFile *sub = &newDir1, *startDir;
@ -872,12 +883,12 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
// Parsing the path string // Parsing the path string
const char *item_name_adr = path; const char *item_name_adr = path;
DEBUG_ECHOLNPAIR("diveToFile: path = '", path, "'"); DEBUG_ECHOLNPAIR(" path = '", path, "'");
if (path[0] == '/') { // Starting at the root directory? if (path[0] == '/') { // Starting at the root directory?
diveDir = &root; diveDir = &root;
item_name_adr++; item_name_adr++;
DEBUG_ECHOLNPAIR("diveToFile: CWD to root: ", hex_address((void*)diveDir)); DEBUG_ECHOLNPAIR(" CWD to root: ", hex_address((void*)diveDir));
if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
} }
else else
@ -885,7 +896,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
startDir = diveDir; startDir = diveDir;
DEBUG_ECHOLNPAIR("diveToFile: startDir = ", hex_address((void*)startDir)); DEBUG_ECHOLNPAIR(" startDir = ", hex_address((void*)startDir));
while (item_name_adr) { while (item_name_adr) {
// Find next subdirectory delimiter // Find next subdirectory delimiter
@ -902,7 +913,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
if (echo) SERIAL_ECHOLN(dosSubdirname); if (echo) SERIAL_ECHOLN(dosSubdirname);
DEBUG_ECHOLNPAIR("diveToFile: sub = ", hex_address((void*)sub)); DEBUG_ECHOLNPAIR(" sub = ", hex_address((void*)sub));
// Open diveDir (closing first) // Open diveDir (closing first)
sub->close(); sub->close();
@ -914,24 +925,24 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
// Close diveDir if not at starting-point // Close diveDir if not at starting-point
if (diveDir != startDir) { if (diveDir != startDir) {
DEBUG_ECHOLNPAIR("diveToFile: closing diveDir: ", hex_address((void*)diveDir)); DEBUG_ECHOLNPAIR(" closing diveDir: ", hex_address((void*)diveDir));
diveDir->close(); diveDir->close();
} }
// diveDir now subDir // diveDir now subDir
diveDir = sub; diveDir = sub;
DEBUG_ECHOLNPAIR("diveToFile: diveDir = sub: ", hex_address((void*)diveDir)); DEBUG_ECHOLNPAIR(" diveDir = sub: ", hex_address((void*)diveDir));
// Update workDirParents and workDirDepth // Update workDirParents and workDirDepth
if (update_cwd) { if (update_cwd) {
DEBUG_ECHOLNPAIR("diveToFile: update_cwd"); DEBUG_ECHOLNPAIR(" update_cwd");
if (workDirDepth < MAX_DIR_DEPTH) if (workDirDepth < MAX_DIR_DEPTH)
workDirParents[workDirDepth++] = *diveDir; workDirParents[workDirDepth++] = *diveDir;
} }
// Point sub at the other scratch object // Point sub at the other scratch object
sub = (diveDir != &newDir1) ? &newDir1 : &newDir2; sub = (diveDir != &newDir1) ? &newDir1 : &newDir2;
DEBUG_ECHOLNPAIR("diveToFile: swapping sub = ", hex_address((void*)sub)); DEBUG_ECHOLNPAIR(" swapping sub = ", hex_address((void*)sub));
// Next path atom address // Next path atom address
item_name_adr = name_end + 1; item_name_adr = name_end + 1;
@ -939,11 +950,12 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
if (update_cwd) { if (update_cwd) {
workDir = *diveDir; workDir = *diveDir;
DEBUG_ECHOLNPAIR("diveToFile: final workDir = ", hex_address((void*)diveDir)); DEBUG_ECHOLNPAIR(" final workDir = ", hex_address((void*)diveDir));
flag.workDirIsRoot = (workDirDepth == 0); flag.workDirIsRoot = (workDirDepth == 0);
TERN_(SDCARD_SORT_ALPHA, presort()); TERN_(SDCARD_SORT_ALPHA, presort());
} }
DEBUG_ECHOLNPAIR(" returning string ", item_name_adr ?: "nullptr");
return item_name_adr; return item_name_adr;
} }
@ -1225,21 +1237,21 @@ uint16_t CardReader::get_num_Files() {
// Return from procedure or close out the Print Job // Return from procedure or close out the Print Job
// //
void CardReader::fileHasFinished() { void CardReader::fileHasFinished() {
planner.synchronize();
file.close(); file.close();
#if HAS_MEDIA_SUBCALLS #if HAS_MEDIA_SUBCALLS
if (file_subcall_ctr > 0) { // Resume calling file after closing procedure if (file_subcall_ctr > 0) { // Resume calling file after closing procedure
file_subcall_ctr--; file_subcall_ctr--;
openFileRead(proc_filenames[file_subcall_ctr], 2); // 2 = Returning from sub-procedure openFileRead(proc_filenames[file_subcall_ctr], 2); // 2 = Returning from sub-procedure
setIndex(filespos[file_subcall_ctr]); setIndex(filespos[file_subcall_ctr]);
startFileprint(); startOrResumeFilePrinting();
return; return;
} }
#endif #endif
endFilePrint(TERN_(SD_RESORT, true)); endFilePrintNow(TERN_(SD_RESORT, true));
marlin_state = MF_SD_COMPLETE;
flag.sdprintdone = true; // Stop getting bytes from the SD card
marlin_state = MF_SD_COMPLETE; // Tell Marlin to enqueue M1001 soon
} }
#if ENABLED(AUTO_REPORT_SD_STATUS) #if ENABLED(AUTO_REPORT_SD_STATUS)

View file

@ -70,6 +70,7 @@ typedef struct {
bool saving:1, bool saving:1,
logging:1, logging:1,
sdprinting:1, sdprinting:1,
sdprintdone:1,
mounted:1, mounted:1,
filenameIsDir:1, filenameIsDir:1,
workDirIsRoot:1, workDirIsRoot:1,
@ -147,23 +148,33 @@ public:
// Select a file // Select a file
static void selectFileByIndex(const uint16_t nr); static void selectFileByIndex(const uint16_t nr);
static void selectFileByName(const char * const match); static void selectFileByName(const char * const match); // (working directory only)
// Print job // Print job
static void openAndPrintFile(const char *name); // (working directory)
static void fileHasFinished();
static void getAbsFilename(char *dst);
static void printFilename();
static void startFileprint();
static void endFilePrint(TERN_(SD_RESORT, const bool re_sort=false));
static void report_status(); static void report_status();
static void getAbsFilenameInCWD(char *dst);
static void printSelectedFilename();
static void openAndPrintFile(const char *name); // (working directory or full path)
static void startOrResumeFilePrinting();
static void endFilePrintNow(TERN_(SD_RESORT, const bool re_sort=false));
static void abortFilePrintNow(TERN_(SD_RESORT, const bool re_sort=false));
static void fileHasFinished();
static inline void abortFilePrintSoon() { flag.abort_sd_printing = true; }
static inline void pauseSDPrint() { flag.sdprinting = false; } static inline void pauseSDPrint() { flag.sdprinting = false; }
static inline bool isPaused() { return isFileOpen() && !flag.sdprinting; }
static inline bool isPrinting() { return flag.sdprinting; } static inline bool isPrinting() { return flag.sdprinting; }
static inline bool isPaused() { return isFileOpen() && !isPrinting(); }
#if HAS_PRINT_PROGRESS_PERMYRIAD #if HAS_PRINT_PROGRESS_PERMYRIAD
static inline uint16_t permyriadDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 9999) / 10000) : 0; } static inline uint16_t permyriadDone() {
if (flag.sdprintdone) return 10000;
if (isFileOpen() && filesize) return sdpos / ((filesize + 9999) / 10000);
return 0;
}
#endif #endif
static inline uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; } static inline uint8_t percentDone() {
if (flag.sdprintdone) return 100;
if (isFileOpen() && filesize) return sdpos / ((filesize + 99) / 100);
return 0;
}
// Helper for open and remove // Helper for open and remove
static const char* diveToFile(const bool update_cwd, SdFile* &curDir, const char * const path, const bool echo=false); static const char* diveToFile(const bool update_cwd, SdFile* &curDir, const char * const path, const bool echo=false);
@ -186,15 +197,20 @@ public:
static void removeJobRecoveryFile(); static void removeJobRecoveryFile();
#endif #endif
static inline bool isFileOpen() { return isMounted() && file.isOpen(); } // Current Working Dir - Set by cd, cdup, cdroot, and diveToFile(true, ...)
static inline uint32_t getIndex() { return sdpos; }
static inline uint32_t getFileSize() { return filesize; }
static inline bool eof() { return sdpos >= filesize; }
static inline void setIndex(const uint32_t index) { file.seekSet((sdpos = index)); }
static inline char* getWorkDirName() { workDir.getDosName(filename); return filename; } static inline char* getWorkDirName() { workDir.getDosName(filename); return filename; }
// Print File stats
static inline uint32_t getFileSize() { return filesize; }
static inline uint32_t getIndex() { return sdpos; }
static inline bool isFileOpen() { return isMounted() && file.isOpen(); }
static inline bool eof() { return getIndex() >= getFileSize(); }
// File data operations
static inline int16_t get() { int16_t out = (int16_t)file.read(); sdpos = file.curPosition(); return out; } static inline int16_t get() { int16_t out = (int16_t)file.read(); sdpos = file.curPosition(); return out; }
static inline int16_t read(void *buf, uint16_t nbyte) { return file.isOpen() ? file.read(buf, nbyte) : -1; } static inline int16_t read(void *buf, uint16_t nbyte) { return file.isOpen() ? file.read(buf, nbyte) : -1; }
static inline int16_t write(void *buf, uint16_t nbyte) { return file.isOpen() ? file.write(buf, nbyte) : -1; } static inline int16_t write(void *buf, uint16_t nbyte) { return file.isOpen() ? file.write(buf, nbyte) : -1; }
static inline void setIndex(const uint32_t index) { file.seekSet((sdpos = index)); }
// TODO: rename to diskIODriver() // TODO: rename to diskIODriver()
static DiskIODriver* diskIODriver() { return driver; } static DiskIODriver* diskIODriver() { return driver; }
@ -318,7 +334,8 @@ private:
#define IS_SD_INSERTED() true #define IS_SD_INSERTED() true
#endif #endif
#define IS_SD_PRINTING() card.flag.sdprinting #define IS_SD_PRINTING() (card.flag.sdprinting && !card.flag.abort_sd_printing)
#define IS_SD_FETCHING() (!card.flag.sdprintdone && IS_SD_PRINTING())
#define IS_SD_PAUSED() card.isPaused() #define IS_SD_PAUSED() card.isPaused()
#define IS_SD_FILE_OPEN() card.isFileOpen() #define IS_SD_FILE_OPEN() card.isFileOpen()
@ -327,6 +344,7 @@ extern CardReader card;
#else // !SDSUPPORT #else // !SDSUPPORT
#define IS_SD_PRINTING() false #define IS_SD_PRINTING() false
#define IS_SD_FETCHING() false
#define IS_SD_PAUSED() false #define IS_SD_PAUSED() false
#define IS_SD_FILE_OPEN() false #define IS_SD_FILE_OPEN() false