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() {
return print_job_timer.isRunning() || IS_SD_PRINTING();
}
bool printJobOngoing() { 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() {
return !did_pause_print && (print_job_timer.isRunning() || IS_SD_PRINTING());
}
bool printingIsActive() { return !did_pause_print && printJobOngoing(); }
/**
* Printing is paused according to SD or host indicators
@ -367,7 +363,7 @@ void startOrResumeJob() {
inline void abortSDPrinting() {
IF_DISABLED(NO_SD_AUTOSTART, card.autofile_cancel());
card.endFilePrint(TERN_(SD_RESORT, true));
card.abortFilePrintNow(TERN_(SD_RESORT, true));
queue.clear();
quickstop_stepper();
@ -748,7 +744,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
// Handle Power-Loss Recovery
#if ENABLED(POWER_LOSS_RECOVERY) && PIN_EXISTS(POWER_LOSS)
if (printJobOngoing()) recovery.outage();
if (IS_SD_PRINTING()) recovery.outage();
#endif
// Run StallGuard endstop checks
@ -901,7 +897,7 @@ void stop() {
thermalManager.set_fans_paused(false); // Un-pause fans for safety
#endif
if (IsRunning()) {
if (!IsStopped()) {
SERIAL_ERROR_MSG(STR_ERR_STOPPED);
LCD_MESSAGEPGM(MSG_STOPPED);
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; }
bool printingIsActive();
bool printJobOngoing();
bool printingIsPaused();
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 (did_pause_print) {
--did_pause_print;
card.startFileprint();
card.startOrResumeFilePrinting();
// Write PLR now to update the z axis value
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
*/
void PrintJobRecovery::prepare() {
card.getAbsFilename(info.sd_filename); // SD filename
card.getAbsFilenameInCWD(info.sd_filename); // SD filename
cmd_sdpos = 0;
}

View file

@ -550,7 +550,8 @@ void GCodeQueue::get_serial_commands() {
inline void GCodeQueue::get_sdcard_commands() {
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;
while (!ring_buffer.full() && !card.eof()) {

View file

@ -25,6 +25,7 @@
#if ENABLED(SDSUPPORT)
#include "../gcode.h"
#include "../../module/planner.h"
#include "../../module/printcounter.h"
#if DISABLED(NO_SD_AUTOSTART)
@ -64,6 +65,11 @@
* M1001: Execute actions for SD print completion
*/
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 (TERN(NO_SD_AUTOSTART, false, card.autofile_check())) return;

View file

@ -70,7 +70,7 @@ void GcodeSuite::M24() {
#endif
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
TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
}

View file

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

View file

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

View file

@ -33,7 +33,7 @@
void GcodeSuite::M524() {
if (IS_SD_PRINTING())
card.flag.abort_sd_printing = true;
card.abortFilePrintSoon();
else if (card.isMounted())
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];
#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 ENABLED(USE_M73_REMAINING_TIME)
duration_t remaining = ui.get_remaining_time();
@ -889,7 +889,7 @@ void MarlinUI::draw_status_screen() {
#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 ENABLED(LCD_SHOW_E_TOTAL)

View file

@ -41,7 +41,7 @@
#include "../../gcode/parser.h" // for units (and volumetric)
#if ENABLED(LCD_SHOW_E_TOTAL)
#include "../../MarlinCore.h" // for printingIsActive(), marlin_state and MF_SD_COMPLETE
#include "../../MarlinCore.h" // for printingIsActive()
#endif
#if ENABLED(FILAMENT_LCD_DISPLAY)
@ -464,7 +464,7 @@ void MarlinUI::draw_status_screen() {
#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
if (first_page) {

View file

@ -1891,7 +1891,7 @@ void HMI_SDCardUpdate() {
else if (checkkey == PrintProcess || checkkey == Tune || printingIsActive()) {
// TODO: Move card removed abort handling
// to CardReader::manage_media.
card.flag.abort_sd_printing = true;
card.abortFilePrintSoon();
wait_for_heatup = wait_for_user = false;
dwin_abort_flag = true; // Reset feedrate, return to Home
}
@ -2311,7 +2311,7 @@ void HMI_PauseOrStop() {
checkkey = Back_Main;
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
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
#ifdef ACTION_ON_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
// 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
// || 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) {
settings.save();
if (print_job_timer.isRunning())
if (printJobOngoing())
GotoScreen(MKSLCD_SCREEN_PRINT);
else if (print_job_timer.isPaused)
GotoScreen(MKSLCD_SCREEN_PAUSE);
@ -1442,8 +1442,7 @@ bool DGUSScreenHandler::loop() {
}
#if ENABLED(DGUS_MKS_RUNOUT_SENSOR)
if (booted && (IS_SD_PRINTING() || IS_SD_PAUSED()))
DGUS_Runout_Idle();
if (booted && printingIsActive()) DGUS_Runout_Idle();
#endif
#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], '/');
SdFile file, *curDir;
card.endFilePrint();
const char * const fname = card.diveToFile(true, curDir, cur_name);
card.abortFilePrintNow();
const char * const fname = card.diveToFile(false, curDir, cur_name);
if (!fname) return;
if (file.open(curDir, fname, O_READ)) {
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.e_factor[1] = planner.flow_percentage[1] * 0.01f;
#endif
card.startFileprint();
card.startOrResumeFilePrinting();
#if ENABLED(POWER_LOSS_RECOVERY)
recovery.prepare();
#endif
@ -124,8 +124,8 @@ static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) {
lv_draw_ready_print();
#if ENABLED(SDSUPPORT)
uiCfg.print_state = IDLE;
card.flag.abort_sd_printing = true;
uiCfg.print_state = IDLE;
card.abortFilePrintSoon();
#endif
}
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);
#endif
row++;
card.abortFilePrintNow();
if (row >= 200) {
size = 809;
row = 0;
gcode_preview_over = false;
card.closefile();
char *cur_name = strrchr(list_file.file_name[sel_id], '/');
SdFile file;
SdFile *curDir;
card.endFilePrint();
const char * const fname = card.diveToFile(true, curDir, cur_name);
const char * const fname = card.diveToFile(false, curDir, cur_name);
if (!fname) return;
if (file.open(curDir, fname, O_READ)) {
gCfgItems.curFilesize = file.fileSize();
@ -667,13 +666,12 @@ char *creat_title_text() {
planner.flow_percentage[1] = 100;
planner.e_factor[1] = planner.flow_percentage[1] * 0.01;
#endif
card.startFileprint();
card.startOrResumeFilePrinting();
TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
once_flag = false;
}
return;
}
card.closefile();
#endif // SDSUPPORT
}

View file

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

View file

@ -625,7 +625,7 @@ void upload_spin() {
// Try to upload the given file at the given 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;
esp_upload.fileSize = update_file.fileSize();

View file

@ -54,6 +54,7 @@
#include "../../module/printcounter.h"
#include "../../libs/duration_t.h"
#include "../../HAL/shared/Delay.h"
#include "../../MarlinCore.h"
#include "../../sd/cardreader.h"
#if ENABLED(PRINTCOUNTER)
@ -106,9 +107,6 @@ namespace ExtUI {
#if ENABLED(JOYSTICK)
uint8_t jogging : 1;
#endif
#if ENABLED(SDSUPPORT)
uint8_t was_sd_printing : 1;
#endif
} flags;
#ifdef __SAM3X8E__
@ -1017,27 +1015,17 @@ namespace ExtUI {
void setUserConfirmed() { TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); }
void printFile(const char *filename) {
UNUSED(filename);
TERN_(SDSUPPORT, card.openAndPrintFile(filename));
TERN(SDSUPPORT, card.openAndPrintFile(filename), UNUSED(filename));
}
bool isPrintingFromMediaPaused() {
return TERN0(SDSUPPORT, isPrintingFromMedia() && !IS_SD_PRINTING());
return TERN0(SDSUPPORT, isPrintingFromMedia() && printingIsPaused());
}
bool isPrintingFromMedia() {
#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 isPrintingFromMedia() { return IS_SD_PRINTING(); }
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() {

View file

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

View file

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

View file

@ -161,7 +161,7 @@ CardReader::CardReader() {
#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;
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)
//
void CardReader::printFilename() {
void CardReader::printSelectedFilename() {
if (file.isOpen()) {
char dosFilename[FILENAME_LENGTH];
file.getDosName(dosFilename);
@ -487,9 +487,9 @@ void CardReader::manage_media() {
void CardReader::release() {
// Card removed while printing? Abort!
if (IS_SD_PRINTING())
card.flag.abort_sd_printing = true;
abortFilePrintSoon();
else
endFilePrint();
endFilePrintNow();
flag.mounted = false;
flag.workDirIsRoot = true;
@ -516,9 +516,10 @@ void CardReader::openAndPrintFile(const char *name) {
* since you cannot browse files during active printing.
* Used by M24 and anywhere Start / Resume applies.
*/
void CardReader::startFileprint() {
void CardReader::startOrResumeFilePrinting() {
if (isMounted()) {
flag.sdprinting = true;
flag.sdprintdone = false;
TERN_(SD_RESORT, flush_presort());
}
}
@ -526,14 +527,19 @@ void CardReader::startFileprint() {
//
// 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_(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();
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) {
flag.logging = DISABLED(SDCARD_READONLY);
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
//
void CardReader::getAbsFilename(char *dst) {
void CardReader::getAbsFilenameInCWD(char *dst) {
*dst++ = '/';
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
getAbsFilename(proc_filenames[file_subcall_ctr]);
getAbsFilenameInCWD(proc_filenames[file_subcall_ctr]);
filespos[file_subcall_ctr] = sdpos;
// 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
}
endFilePrint();
abortFilePrintNow();
SdFile *diveDir;
const char * const fname = diveToFile(true, diveDir, path);
@ -659,7 +665,7 @@ void CardReader::openFileWrite(const char * const path) {
announceOpen(2, path);
TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0);
endFilePrint();
abortFilePrintNow();
SdFile *diveDir;
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) {
if (!isMounted()) return;
//endFilePrint();
//abortFilePrintNow();
SdFile *curDir;
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.
*
* On entry:
* - The workDir points to the last-set navigation target by cd, cdup, cdroot, or diveToFile(true, ...)
*
* On exit:
* - 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.
@ -865,6 +874,8 @@ uint16_t CardReader::countFilesInWorkDir() {
* 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*/) {
DEBUG_SECTION(est, "diveToFile", true);
// Track both parent and subfolder
static SdFile newDir1, newDir2;
SdFile *sub = &newDir1, *startDir;
@ -872,12 +883,12 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
// Parsing the path string
const char *item_name_adr = path;
DEBUG_ECHOLNPAIR("diveToFile: path = '", path, "'");
DEBUG_ECHOLNPAIR(" path = '", path, "'");
if (path[0] == '/') { // Starting at the root directory?
diveDir = &root;
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
}
else
@ -885,7 +896,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
startDir = diveDir;
DEBUG_ECHOLNPAIR("diveToFile: startDir = ", hex_address((void*)startDir));
DEBUG_ECHOLNPAIR(" startDir = ", hex_address((void*)startDir));
while (item_name_adr) {
// Find next subdirectory delimiter
@ -902,7 +913,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
if (echo) SERIAL_ECHOLN(dosSubdirname);
DEBUG_ECHOLNPAIR("diveToFile: sub = ", hex_address((void*)sub));
DEBUG_ECHOLNPAIR(" sub = ", hex_address((void*)sub));
// Open diveDir (closing first)
sub->close();
@ -914,24 +925,24 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
// Close diveDir if not at starting-point
if (diveDir != startDir) {
DEBUG_ECHOLNPAIR("diveToFile: closing diveDir: ", hex_address((void*)diveDir));
DEBUG_ECHOLNPAIR(" closing diveDir: ", hex_address((void*)diveDir));
diveDir->close();
}
// diveDir now subDir
diveDir = sub;
DEBUG_ECHOLNPAIR("diveToFile: diveDir = sub: ", hex_address((void*)diveDir));
DEBUG_ECHOLNPAIR(" diveDir = sub: ", hex_address((void*)diveDir));
// Update workDirParents and workDirDepth
if (update_cwd) {
DEBUG_ECHOLNPAIR("diveToFile: update_cwd");
DEBUG_ECHOLNPAIR(" update_cwd");
if (workDirDepth < MAX_DIR_DEPTH)
workDirParents[workDirDepth++] = *diveDir;
}
// Point sub at the other scratch object
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
item_name_adr = name_end + 1;
@ -939,11 +950,12 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
if (update_cwd) {
workDir = *diveDir;
DEBUG_ECHOLNPAIR("diveToFile: final workDir = ", hex_address((void*)diveDir));
DEBUG_ECHOLNPAIR(" final workDir = ", hex_address((void*)diveDir));
flag.workDirIsRoot = (workDirDepth == 0);
TERN_(SDCARD_SORT_ALPHA, presort());
}
DEBUG_ECHOLNPAIR(" returning string ", item_name_adr ?: "nullptr");
return item_name_adr;
}
@ -1225,21 +1237,21 @@ uint16_t CardReader::get_num_Files() {
// Return from procedure or close out the Print Job
//
void CardReader::fileHasFinished() {
planner.synchronize();
file.close();
#if HAS_MEDIA_SUBCALLS
if (file_subcall_ctr > 0) { // Resume calling file after closing procedure
file_subcall_ctr--;
openFileRead(proc_filenames[file_subcall_ctr], 2); // 2 = Returning from sub-procedure
setIndex(filespos[file_subcall_ctr]);
startFileprint();
startOrResumeFilePrinting();
return;
}
#endif
endFilePrint(TERN_(SD_RESORT, true));
marlin_state = MF_SD_COMPLETE;
endFilePrintNow(TERN_(SD_RESORT, true));
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)

View file

@ -70,6 +70,7 @@ typedef struct {
bool saving:1,
logging:1,
sdprinting:1,
sdprintdone:1,
mounted:1,
filenameIsDir:1,
workDirIsRoot:1,
@ -147,23 +148,33 @@ public:
// Select a file
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
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 inline void pauseSDPrint() { flag.sdprinting = false; }
static inline bool isPaused() { return isFileOpen() && !flag.sdprinting; }
static inline bool isPrinting() { return flag.sdprinting; }
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 bool isPrinting() { return flag.sdprinting; }
static inline bool isPaused() { return isFileOpen() && !isPrinting(); }
#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
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
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();
#endif
static inline bool isFileOpen() { return isMounted() && file.isOpen(); }
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 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; }
// Current Working Dir - Set by cd, cdup, cdroot, and diveToFile(true, ...)
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 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 void setIndex(const uint32_t index) { file.seekSet((sdpos = index)); }
// TODO: rename to diskIODriver()
static DiskIODriver* diskIODriver() { return driver; }
@ -318,7 +334,8 @@ private:
#define IS_SD_INSERTED() true
#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_FILE_OPEN() card.isFileOpen()
@ -327,6 +344,7 @@ extern CardReader card;
#else // !SDSUPPORT
#define IS_SD_PRINTING() false
#define IS_SD_FETCHING() false
#define IS_SD_PAUSED() false
#define IS_SD_FILE_OPEN() false