Make CardReader class static (#12451)
* Make CardReader a static class * Make CardReader flags into bitfields
This commit is contained in:
parent
3e9ffaddb6
commit
66580f32c2
|
@ -19,7 +19,7 @@ void sd_mmc_spi_mem_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ctrl_status sd_mmc_spi_test_unit_ready(void) {
|
Ctrl_status sd_mmc_spi_test_unit_ready(void) {
|
||||||
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.cardOK)
|
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.flag.cardOK)
|
||||||
return CTRL_NO_PRESENT;
|
return CTRL_NO_PRESENT;
|
||||||
return CTRL_GOOD;
|
return CTRL_GOOD;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ Ctrl_status sd_mmc_spi_test_unit_ready(void) {
|
||||||
// NOTE: This function is defined as returning the address of the last block
|
// NOTE: This function is defined as returning the address of the last block
|
||||||
// in the card, which is cardSize() - 1
|
// in the card, which is cardSize() - 1
|
||||||
Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector) {
|
Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector) {
|
||||||
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.cardOK)
|
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.flag.cardOK)
|
||||||
return CTRL_NO_PRESENT;
|
return CTRL_NO_PRESENT;
|
||||||
*nb_sector = card.getSd2Card().cardSize() - 1;
|
*nb_sector = card.getSd2Card().cardSize() - 1;
|
||||||
return CTRL_GOOD;
|
return CTRL_GOOD;
|
||||||
|
@ -42,7 +42,7 @@ bool sd_mmc_spi_wr_protect(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sd_mmc_spi_removal(void) {
|
bool sd_mmc_spi_removal(void) {
|
||||||
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.cardOK)
|
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.flag.cardOK)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ uint8_t sector_buf[SD_MMC_BLOCK_SIZE];
|
||||||
// #define DEBUG_MMC
|
// #define DEBUG_MMC
|
||||||
|
|
||||||
Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
|
Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
|
||||||
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.cardOK)
|
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.flag.cardOK)
|
||||||
return CTRL_NO_PRESENT;
|
return CTRL_NO_PRESENT;
|
||||||
|
|
||||||
#ifdef DEBUG_MMC
|
#ifdef DEBUG_MMC
|
||||||
|
@ -95,7 +95,7 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
|
Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
|
||||||
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.cardOK)
|
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.flag.cardOK)
|
||||||
return CTRL_NO_PRESENT;
|
return CTRL_NO_PRESENT;
|
||||||
|
|
||||||
#ifdef DEBUG_MMC
|
#ifdef DEBUG_MMC
|
||||||
|
|
|
@ -106,7 +106,7 @@ void HAL_idletask(void) {
|
||||||
// the disk if Marlin has it mounted. Unfortuately there is currently no way
|
// the disk if Marlin has it mounted. Unfortuately there is currently no way
|
||||||
// to unmount the disk from the LCD menu.
|
// to unmount the disk from the LCD menu.
|
||||||
// if (IS_SD_PRINTING() || IS_SD_FILE_OPEN())
|
// if (IS_SD_PRINTING() || IS_SD_FILE_OPEN())
|
||||||
if (card.cardOK)
|
if (card.flag.cardOK)
|
||||||
MSC_Aquire_Lock();
|
MSC_Aquire_Lock();
|
||||||
else
|
else
|
||||||
MSC_Release_Lock();
|
MSC_Release_Lock();
|
||||||
|
|
|
@ -41,7 +41,7 @@ char HAL_STM32F1_eeprom_content[HAL_STM32F1_EEPROM_SIZE];
|
||||||
char eeprom_filename[] = "eeprom.dat";
|
char eeprom_filename[] = "eeprom.dat";
|
||||||
|
|
||||||
bool PersistentStore::access_start() {
|
bool PersistentStore::access_start() {
|
||||||
if (!card.cardOK) return false;
|
if (!card.flag.cardOK) return false;
|
||||||
int16_t bytes_read = 0;
|
int16_t bytes_read = 0;
|
||||||
constexpr char eeprom_zero = 0xFF;
|
constexpr char eeprom_zero = 0xFF;
|
||||||
card.openFile(eeprom_filename, true);
|
card.openFile(eeprom_filename, true);
|
||||||
|
@ -54,7 +54,7 @@ bool PersistentStore::access_start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PersistentStore::access_finish() {
|
bool PersistentStore::access_finish() {
|
||||||
if (!card.cardOK) return false;
|
if (!card.flag.cardOK) return false;
|
||||||
card.openFile(eeprom_filename, true);
|
card.openFile(eeprom_filename, true);
|
||||||
int16_t bytes_written = card.write(HAL_STM32F1_eeprom_content, HAL_STM32F1_EEPROM_SIZE);
|
int16_t bytes_written = card.write(HAL_STM32F1_eeprom_content, HAL_STM32F1_EEPROM_SIZE);
|
||||||
card.closefile();
|
card.closefile();
|
||||||
|
|
|
@ -967,7 +967,7 @@ void loop() {
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
card.checkautostart();
|
card.checkautostart();
|
||||||
|
|
||||||
if (card.abort_sd_printing) {
|
if (card.flag.abort_sd_printing) {
|
||||||
card.stopSDPrint(
|
card.stopSDPrint(
|
||||||
#if SD_RESORT
|
#if SD_RESORT
|
||||||
true
|
true
|
||||||
|
|
|
@ -84,8 +84,8 @@ void PrintJobRecovery::changed() {
|
||||||
*/
|
*/
|
||||||
void PrintJobRecovery::check() {
|
void PrintJobRecovery::check() {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (!card.cardOK) card.initsd();
|
if (!card.flag.cardOK) card.initsd();
|
||||||
if (card.cardOK) {
|
if (card.flag.cardOK) {
|
||||||
load();
|
load();
|
||||||
if (!valid()) return purge();
|
if (!valid()) return purge();
|
||||||
enqueue_and_echo_commands_P(PSTR("M1000 S"));
|
enqueue_and_echo_commands_P(PSTR("M1000 S"));
|
||||||
|
|
|
@ -68,7 +68,7 @@ typedef struct {
|
||||||
char command_queue[BUFSIZE][MAX_CMD_SIZE];
|
char command_queue[BUFSIZE][MAX_CMD_SIZE];
|
||||||
|
|
||||||
// SD Filename and position
|
// SD Filename and position
|
||||||
char sd_filename[MAXPATHNAMELENGTH];
|
char sd_filename[MAXPATHNAMELENGTH + 1];
|
||||||
uint32_t sdpos;
|
uint32_t sdpos;
|
||||||
|
|
||||||
// Job elapsed time
|
// Job elapsed time
|
||||||
|
|
|
@ -503,7 +503,7 @@ static int read_serial(const uint8_t index) {
|
||||||
break;
|
break;
|
||||||
case StreamState::STREAM_COMPLETE:
|
case StreamState::STREAM_COMPLETE:
|
||||||
stream_state = StreamState::STREAM_RESET;
|
stream_state = StreamState::STREAM_RESET;
|
||||||
card.binary_mode = false;
|
card.flag.binary_mode = false;
|
||||||
card.closefile();
|
card.closefile();
|
||||||
CARD_ECHO_P("echo: ");
|
CARD_ECHO_P("echo: ");
|
||||||
CARD_ECHO_P(card.filename);
|
CARD_ECHO_P(card.filename);
|
||||||
|
@ -514,7 +514,7 @@ static int read_serial(const uint8_t index) {
|
||||||
return;
|
return;
|
||||||
case StreamState::STREAM_FAILED:
|
case StreamState::STREAM_FAILED:
|
||||||
stream_state = StreamState::STREAM_RESET;
|
stream_state = StreamState::STREAM_RESET;
|
||||||
card.binary_mode = false;
|
card.flag.binary_mode = false;
|
||||||
card.closefile();
|
card.closefile();
|
||||||
card.removeFile(card.filename);
|
card.removeFile(card.filename);
|
||||||
CARD_ECHOLN_P("echo: File transfer failed");
|
CARD_ECHOLN_P("echo: File transfer failed");
|
||||||
|
@ -549,7 +549,7 @@ inline void get_serial_commands() {
|
||||||
;
|
;
|
||||||
|
|
||||||
#if ENABLED(FAST_FILE_TRANSFER)
|
#if ENABLED(FAST_FILE_TRANSFER)
|
||||||
if (card.saving && card.binary_mode) {
|
if (card.flag.saving && card.flag.binary_mode) {
|
||||||
/**
|
/**
|
||||||
* For binary stream file transfer, use serial_line_buffer as the working
|
* For binary stream file transfer, use serial_line_buffer as the working
|
||||||
* receive buffer (which limits the packet size to MAX_CMD_SIZE).
|
* receive buffer (which limits the packet size to MAX_CMD_SIZE).
|
||||||
|
@ -630,7 +630,7 @@ inline void get_serial_commands() {
|
||||||
gcode_LastN = gcode_N;
|
gcode_LastN = gcode_N;
|
||||||
}
|
}
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
else if (card.saving && strcmp(command, "M29") != 0) // No line number with M29 in Pronterface
|
else if (card.flag.saving && strcmp(command, "M29") != 0) // No line number with M29 in Pronterface
|
||||||
return gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM), i);
|
return gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM), i);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -838,7 +838,7 @@ void advance_command_queue() {
|
||||||
|
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
|
|
||||||
if (card.saving) {
|
if (card.flag.saving) {
|
||||||
char* command = command_queue[cmd_queue_index_r];
|
char* command = command_queue[cmd_queue_index_r];
|
||||||
if (strstr_P(command, PSTR("M29"))) {
|
if (strstr_P(command, PSTR("M29"))) {
|
||||||
// M29 closes the file
|
// M29 closes the file
|
||||||
|
@ -860,7 +860,7 @@ void advance_command_queue() {
|
||||||
else {
|
else {
|
||||||
// Write the string from the read buffer to SD
|
// Write the string from the read buffer to SD
|
||||||
card.write_command(command);
|
card.write_command(command);
|
||||||
if (card.logging)
|
if (card.flag.logging)
|
||||||
gcode.process_next_command(); // The card is saving because it's logging
|
gcode.process_next_command(); // The card is saving because it's logging
|
||||||
else
|
else
|
||||||
ok_to_send();
|
ok_to_send();
|
||||||
|
|
|
@ -118,7 +118,7 @@ void GcodeSuite::M25() {
|
||||||
* M26: Set SD Card file index
|
* M26: Set SD Card file index
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::M26() {
|
void GcodeSuite::M26() {
|
||||||
if (card.cardOK && parser.seenval('S'))
|
if (card.flag.cardOK && parser.seenval('S'))
|
||||||
card.setIndex(parser.value_long());
|
card.setIndex(parser.value_long());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ void GcodeSuite::M28() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Binary transfer mode
|
// Binary transfer mode
|
||||||
if ((card.binary_mode = binary_mode)) {
|
if ((card.flag.binary_mode = binary_mode)) {
|
||||||
SERIAL_ECHO_START_P(port);
|
SERIAL_ECHO_START_P(port);
|
||||||
SERIAL_ECHO_P(port, " preparing to receive: ");
|
SERIAL_ECHO_P(port, " preparing to receive: ");
|
||||||
SERIAL_ECHOLN_P(port, p);
|
SERIAL_ECHOLN_P(port, p);
|
||||||
|
@ -202,14 +202,14 @@ void GcodeSuite::M28() {
|
||||||
* Processed in write to file routine
|
* Processed in write to file routine
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::M29() {
|
void GcodeSuite::M29() {
|
||||||
// card.saving = false;
|
// card.flag.saving = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* M30 <filename>: Delete SD Card file
|
* M30 <filename>: Delete SD Card file
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::M30() {
|
void GcodeSuite::M30() {
|
||||||
if (card.cardOK) {
|
if (card.flag.cardOK) {
|
||||||
card.closefile();
|
card.closefile();
|
||||||
card.removeFile(parser.string_arg);
|
card.removeFile(parser.string_arg);
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ void GcodeSuite::M30() {
|
||||||
void GcodeSuite::M32() {
|
void GcodeSuite::M32() {
|
||||||
if (IS_SD_PRINTING()) planner.synchronize();
|
if (IS_SD_PRINTING()) planner.synchronize();
|
||||||
|
|
||||||
if (card.cardOK) {
|
if (card.flag.cardOK) {
|
||||||
const bool call_procedure = parser.boolval('P');
|
const bool call_procedure = parser.boolval('P');
|
||||||
|
|
||||||
card.openFile(parser.string_arg, true, call_procedure);
|
card.openFile(parser.string_arg, true, call_procedure);
|
||||||
|
@ -286,7 +286,7 @@ void GcodeSuite::M32() {
|
||||||
* M524: Abort the current SD print job (started with M24)
|
* M524: Abort the current SD print job (started with M24)
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::M524() {
|
void GcodeSuite::M524() {
|
||||||
if (IS_SD_PRINTING()) card.abort_sd_printing = true;
|
if (IS_SD_PRINTING()) card.flag.abort_sd_printing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -575,7 +575,7 @@ namespace ExtUI {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPrintingFromMedia() {
|
bool isPrintingFromMedia() {
|
||||||
return IFSD(card.cardOK && card.isFileOpen(), false);
|
return IFSD(card.flag.cardOK && card.isFileOpen(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPrinting() {
|
bool isPrinting() {
|
||||||
|
@ -583,7 +583,7 @@ namespace ExtUI {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isMediaInserted() {
|
bool isMediaInserted() {
|
||||||
return IFSD(IS_SD_INSERTED() && card.cardOK, false);
|
return IFSD(IS_SD_INSERTED() && card.flag.cardOK, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pausePrint() {
|
void pausePrint() {
|
||||||
|
@ -612,7 +612,7 @@ namespace ExtUI {
|
||||||
void stopPrint() {
|
void stopPrint() {
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
wait_for_heatup = wait_for_user = false;
|
wait_for_heatup = wait_for_user = false;
|
||||||
card.abort_sd_printing = true;
|
card.flag.abort_sd_printing = true;
|
||||||
ExtUI::onStatusChanged(PSTR(MSG_PRINT_ABORTED));
|
ExtUI::onStatusChanged(PSTR(MSG_PRINT_ABORTED));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -648,7 +648,7 @@ namespace ExtUI {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileList::isDir() {
|
bool FileList::isDir() {
|
||||||
return IFSD(card.filenameIsDir, false);
|
return IFSD(card.flag.filenameIsDir, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t FileList::count() {
|
uint16_t FileList::count() {
|
||||||
|
@ -697,13 +697,13 @@ void MarlinUI::update() {
|
||||||
last_sd_status = sd_status;
|
last_sd_status = sd_status;
|
||||||
if (sd_status) {
|
if (sd_status) {
|
||||||
card.initsd();
|
card.initsd();
|
||||||
if (card.cardOK)
|
if (card.flag.cardOK)
|
||||||
ExtUI::onMediaInserted();
|
ExtUI::onMediaInserted();
|
||||||
else
|
else
|
||||||
ExtUI::onMediaError();
|
ExtUI::onMediaError();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const bool ok = card.cardOK;
|
const bool ok = card.flag.cardOK;
|
||||||
card.release();
|
card.release();
|
||||||
if (ok) ExtUI::onMediaRemoved();
|
if (ok) ExtUI::onMediaRemoved();
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,7 +278,7 @@ void process_lcd_p_command(const char* command) {
|
||||||
// There may be a difference in how V1 and V2 LCDs handle subdirectory
|
// There may be a difference in how V1 and V2 LCDs handle subdirectory
|
||||||
// prints. Investigate more. This matches the V1 motion controller actions
|
// prints. Investigate more. This matches the V1 motion controller actions
|
||||||
// but the V2 LCD switches to "print" mode on {SYS:DIR} response.
|
// but the V2 LCD switches to "print" mode on {SYS:DIR} response.
|
||||||
if (card.filenameIsDir) {
|
if (card.flag.filenameIsDir) {
|
||||||
card.chdir(card.filename);
|
card.chdir(card.filename);
|
||||||
write_to_lcd_P(PSTR("{SYS:DIR}"));
|
write_to_lcd_P(PSTR("{SYS:DIR}"));
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@ void process_lcd_s_command(const char* command) {
|
||||||
|
|
||||||
case 'L': {
|
case 'L': {
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
if (!card.cardOK) card.initsd();
|
if (!card.flag.cardOK) card.initsd();
|
||||||
|
|
||||||
// A more efficient way to do this would be to
|
// A more efficient way to do this would be to
|
||||||
// implement a callback in the ls_SerialPrint code, but
|
// implement a callback in the ls_SerialPrint code, but
|
||||||
|
@ -342,7 +342,7 @@ void process_lcd_s_command(const char* command) {
|
||||||
uint16_t file_count = card.get_num_Files();
|
uint16_t file_count = card.get_num_Files();
|
||||||
for (uint16_t i = 0; i < file_count; i++) {
|
for (uint16_t i = 0; i < file_count; i++) {
|
||||||
card.getfilename(i);
|
card.getfilename(i);
|
||||||
sprintf_P(message_buffer, card.filenameIsDir ? PSTR("{DIR:%s}") : PSTR("{FILE:%s}"), card.longest_filename());
|
sprintf_P(message_buffer, card.flag.filenameIsDir ? PSTR("{DIR:%s}") : PSTR("{FILE:%s}"), card.longest_filename());
|
||||||
write_to_lcd(message_buffer);
|
write_to_lcd(message_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
void lcd_sdcard_stop() {
|
void lcd_sdcard_stop() {
|
||||||
wait_for_heatup = wait_for_user = false;
|
wait_for_heatup = wait_for_user = false;
|
||||||
card.abort_sd_printing = true;
|
card.flag.abort_sd_printing = true;
|
||||||
ui.setstatusPGM(PSTR(MSG_PRINT_ABORTED), -1);
|
ui.setstatusPGM(PSTR(MSG_PRINT_ABORTED), -1);
|
||||||
ui.return_to_status();
|
ui.return_to_status();
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ void menu_main() {
|
||||||
MENU_BACK(MSG_WATCH);
|
MENU_BACK(MSG_WATCH);
|
||||||
|
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
if (card.cardOK) {
|
if (card.flag.cardOK) {
|
||||||
if (card.isFileOpen()) {
|
if (card.isFileOpen()) {
|
||||||
if (IS_SD_PRINTING())
|
if (IS_SD_PRINTING())
|
||||||
MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_sdcard_pause);
|
MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_sdcard_pause);
|
||||||
|
|
|
@ -125,7 +125,7 @@ void menu_sdcard() {
|
||||||
|
|
||||||
card.getfilename_sorted(nr);
|
card.getfilename_sorted(nr);
|
||||||
|
|
||||||
if (card.filenameIsDir)
|
if (card.flag.filenameIsDir)
|
||||||
MENU_ITEM(sdfolder, MSG_CARD_MENU, card);
|
MENU_ITEM(sdfolder, MSG_CARD_MENU, card);
|
||||||
else
|
else
|
||||||
MENU_ITEM(sdfile, MSG_CARD_MENU, card);
|
MENU_ITEM(sdfile, MSG_CARD_MENU, card);
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
* Defines for 8.3 and long (vfat) filenames
|
* Defines for 8.3 and long (vfat) filenames
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define FILENAME_LENGTH 13 // Number of UTF-16 characters per entry
|
#define FILENAME_LENGTH 12 // Number of UTF-16 characters per entry
|
||||||
|
|
||||||
// Total bytes needed to store a single long filename
|
// Total bytes needed to store a single long filename
|
||||||
#define LONG_FILENAME_LENGTH (FILENAME_LENGTH * MAX_VFAT_ENTRIES + 1)
|
#define LONG_FILENAME_LENGTH ((FILENAME_LENGTH) * (MAX_VFAT_ENTRIES))
|
||||||
|
|
|
@ -45,7 +45,83 @@
|
||||||
#include "../feature/pause.h"
|
#include "../feature/pause.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
// public:
|
||||||
|
|
||||||
|
card_flags_t CardReader::flag;
|
||||||
|
char CardReader::filename[FILENAME_LENGTH + 1], CardReader::longFilename[LONG_FILENAME_LENGTH + 1];
|
||||||
|
int8_t CardReader::autostart_index;
|
||||||
|
|
||||||
|
#if ENABLED(FAST_FILE_TRANSFER)
|
||||||
|
#if NUM_SERIAL > 1
|
||||||
|
uint8_t CardReader::transfer_port;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// private:
|
||||||
|
|
||||||
|
SdFile CardReader::root, CardReader::workDir, CardReader::workDirParents[MAX_DIR_DEPTH];
|
||||||
|
uint8_t CardReader::workDirDepth;
|
||||||
|
|
||||||
|
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||||
|
uint16_t CardReader::sort_count;
|
||||||
|
#if ENABLED(SDSORT_GCODE)
|
||||||
|
bool CardReader::sort_alpha;
|
||||||
|
int CardReader::sort_folders;
|
||||||
|
//bool CardReader::sort_reverse;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
||||||
|
uint8_t *CardReader::sort_order;
|
||||||
|
#else
|
||||||
|
uint8_t CardReader::sort_order[SDSORT_LIMIT];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(SDSORT_USES_RAM)
|
||||||
|
|
||||||
|
#if ENABLED(SDSORT_CACHE_NAMES)
|
||||||
|
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
||||||
|
char **CardReader::sortshort, **CardReader::sortnames;
|
||||||
|
#else
|
||||||
|
char CardReader::sortshort[SDSORT_LIMIT][FILENAME_LENGTH + 1];
|
||||||
|
char CardReader::sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN + 1];
|
||||||
|
#endif
|
||||||
|
#elif DISABLED(SDSORT_USES_STACK)
|
||||||
|
char CardReader::sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN + 1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_FOLDER_SORTING
|
||||||
|
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
||||||
|
uint8_t *CardReader::isDir;
|
||||||
|
#elif ENABLED(SDSORT_CACHE_NAMES) || DISABLED(SDSORT_USES_STACK)
|
||||||
|
uint8_t CardReader::isDir[(SDSORT_LIMIT+7)>>3];
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SDSORT_USES_RAM
|
||||||
|
|
||||||
|
#endif // SDCARD_SORT_ALPHA
|
||||||
|
|
||||||
|
Sd2Card CardReader::sd2card;
|
||||||
|
SdVolume CardReader::volume;
|
||||||
|
SdFile CardReader::file;
|
||||||
|
|
||||||
|
uint8_t CardReader::file_subcall_ctr;
|
||||||
|
uint32_t CardReader::filespos[SD_PROCEDURE_DEPTH];
|
||||||
|
char CardReader::proc_filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH + 1];
|
||||||
|
|
||||||
|
uint32_t CardReader::filesize, CardReader::sdpos;
|
||||||
|
|
||||||
|
LsAction CardReader::lsAction; //stored for recursion.
|
||||||
|
uint16_t CardReader::nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory.
|
||||||
|
char *CardReader::diveDirName;
|
||||||
|
|
||||||
|
#if ENABLED(AUTO_REPORT_SD_STATUS)
|
||||||
|
uint8_t CardReader::auto_report_sd_interval;
|
||||||
|
millis_t CardReader::next_sd_report_ms;
|
||||||
|
#if NUM_SERIAL > 1
|
||||||
|
int8_t CardReader::serialport;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
CardReader::CardReader() {
|
CardReader::CardReader() {
|
||||||
#if ENABLED(SDCARD_SORT_ALPHA)
|
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||||
|
@ -56,9 +132,8 @@ CardReader::CardReader() {
|
||||||
//sort_reverse = false;
|
//sort_reverse = false;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
sdprinting = cardOK = saving = logging = false;
|
flag.sdprinting = flag.cardOK = flag.saving = flag.logging = false;
|
||||||
filesize = 0;
|
filesize = sdpos = 0;
|
||||||
sdpos = 0;
|
|
||||||
file_subcall_ctr = 0;
|
file_subcall_ctr = 0;
|
||||||
|
|
||||||
workDirDepth = 0;
|
workDirDepth = 0;
|
||||||
|
@ -73,7 +148,7 @@ CardReader::CardReader() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char *createFilename(char *buffer, const dir_t &p) { //buffer > 12characters
|
char *createFilename(char *buffer, const dir_t &p) {
|
||||||
char *pos = buffer;
|
char *pos = buffer;
|
||||||
for (uint8_t i = 0; i < 11; i++) {
|
for (uint8_t i = 0; i < 11; i++) {
|
||||||
if (p.name[i] == ' ') continue;
|
if (p.name[i] == ' ') continue;
|
||||||
|
@ -108,7 +183,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
|
||||||
if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) {
|
if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) {
|
||||||
|
|
||||||
// Get the short name for the item, which we know is a folder
|
// Get the short name for the item, which we know is a folder
|
||||||
char dosFilename[FILENAME_LENGTH];
|
char dosFilename[FILENAME_LENGTH + 1];
|
||||||
createFilename(dosFilename, p);
|
createFilename(dosFilename, p);
|
||||||
|
|
||||||
// Allocate enough stack space for the full path to a folder, trailing slash, and nul
|
// Allocate enough stack space for the full path to a folder, trailing slash, and nul
|
||||||
|
@ -120,8 +195,8 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
|
||||||
// It contains the full path to the "parent" argument.
|
// It contains the full path to the "parent" argument.
|
||||||
// We now have the full path to the item in this folder.
|
// We now have the full path to the item in this folder.
|
||||||
strcpy(path, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty
|
strcpy(path, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty
|
||||||
strcat(path, dosFilename); // FILENAME_LENGTH-1 characters maximum
|
strcat(path, dosFilename); // FILENAME_LENGTH characters maximum
|
||||||
strcat(path, "/"); // 1 character
|
strcat(path, "/"); // 1 character
|
||||||
|
|
||||||
// Serial.print(path);
|
// Serial.print(path);
|
||||||
|
|
||||||
|
@ -150,9 +225,9 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
|
||||||
|
|
||||||
if (!DIR_IS_FILE_OR_SUBDIR(&p) || (p.attributes & DIR_ATT_HIDDEN)) continue;
|
if (!DIR_IS_FILE_OR_SUBDIR(&p) || (p.attributes & DIR_ATT_HIDDEN)) continue;
|
||||||
|
|
||||||
filenameIsDir = DIR_IS_SUBDIR(&p);
|
flag.filenameIsDir = DIR_IS_SUBDIR(&p);
|
||||||
|
|
||||||
if (!filenameIsDir && (p.name[8] != 'G' || p.name[9] == '~')) continue;
|
if (!flag.filenameIsDir && (p.name[8] != 'G' || p.name[9] == '~')) continue;
|
||||||
|
|
||||||
switch (lsAction) { // 1 based file count
|
switch (lsAction) { // 1 based file count
|
||||||
case LS_Count:
|
case LS_Count:
|
||||||
|
@ -242,7 +317,7 @@ void CardReader::ls(
|
||||||
SERIAL_PROTOCOL_P(port, longFilename[0] ? longFilename : "???");
|
SERIAL_PROTOCOL_P(port, longFilename[0] ? longFilename : "???");
|
||||||
|
|
||||||
// If the filename was printed then that's it
|
// If the filename was printed then that's it
|
||||||
if (!filenameIsDir) break;
|
if (!flag.filenameIsDir) break;
|
||||||
|
|
||||||
// SERIAL_ECHOPGM_P(port, "Opening dir: "); SERIAL_ECHOLN_P(port, segment);
|
// SERIAL_ECHOPGM_P(port, "Opening dir: "); SERIAL_ECHOLN_P(port, segment);
|
||||||
|
|
||||||
|
@ -275,7 +350,7 @@ void CardReader::printFilename(
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
if (file.isOpen()) {
|
if (file.isOpen()) {
|
||||||
char dosFilename[FILENAME_LENGTH];
|
char dosFilename[FILENAME_LENGTH + 1];
|
||||||
file.getFilename(dosFilename);
|
file.getFilename(dosFilename);
|
||||||
SERIAL_ECHO_P(port, dosFilename);
|
SERIAL_ECHO_P(port, dosFilename);
|
||||||
#if ENABLED(LONG_FILENAME_HOST_SUPPORT)
|
#if ENABLED(LONG_FILENAME_HOST_SUPPORT)
|
||||||
|
@ -293,7 +368,7 @@ void CardReader::printFilename(
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::initsd() {
|
void CardReader::initsd() {
|
||||||
cardOK = false;
|
flag.cardOK = false;
|
||||||
if (root.isOpen()) root.close();
|
if (root.isOpen()) root.close();
|
||||||
|
|
||||||
#ifndef SPI_SPEED
|
#ifndef SPI_SPEED
|
||||||
|
@ -318,7 +393,7 @@ void CardReader::initsd() {
|
||||||
SERIAL_ERRORLNPGM(MSG_SD_OPENROOT_FAIL);
|
SERIAL_ERRORLNPGM(MSG_SD_OPENROOT_FAIL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cardOK = true;
|
flag.cardOK = true;
|
||||||
SERIAL_ECHO_START();
|
SERIAL_ECHO_START();
|
||||||
SERIAL_ECHOLNPGM(MSG_SD_CARD_OK);
|
SERIAL_ECHOLNPGM(MSG_SD_CARD_OK);
|
||||||
}
|
}
|
||||||
|
@ -327,7 +402,7 @@ void CardReader::initsd() {
|
||||||
|
|
||||||
void CardReader::release() {
|
void CardReader::release() {
|
||||||
stopSDPrint();
|
stopSDPrint();
|
||||||
cardOK = false;
|
flag.cardOK = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::openAndPrintFile(const char *name) {
|
void CardReader::openAndPrintFile(const char *name) {
|
||||||
|
@ -339,8 +414,8 @@ void CardReader::openAndPrintFile(const char *name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::startFileprint() {
|
void CardReader::startFileprint() {
|
||||||
if (cardOK) {
|
if (flag.cardOK) {
|
||||||
sdprinting = true;
|
flag.sdprinting = true;
|
||||||
#if SD_RESORT
|
#if SD_RESORT
|
||||||
flush_presort();
|
flush_presort();
|
||||||
#endif
|
#endif
|
||||||
|
@ -355,7 +430,7 @@ void CardReader::stopSDPrint(
|
||||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||||
did_pause_print = 0;
|
did_pause_print = 0;
|
||||||
#endif
|
#endif
|
||||||
sdprinting = abort_sd_printing = false;
|
flag.sdprinting = flag.abort_sd_printing = false;
|
||||||
if (isFileOpen()) file.close();
|
if (isFileOpen()) file.close();
|
||||||
#if SD_RESORT
|
#if SD_RESORT
|
||||||
if (re_sort) presort();
|
if (re_sort) presort();
|
||||||
|
@ -363,7 +438,7 @@ void CardReader::stopSDPrint(
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::openLogFile(char * const path) {
|
void CardReader::openLogFile(char * const path) {
|
||||||
logging = true;
|
flag.logging = true;
|
||||||
openFile(path, false);
|
openFile(path, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +455,7 @@ void CardReader::getAbsFilename(char *t) {
|
||||||
for (uint8_t i = 0; i < workDirDepth; i++) // Loop to current work dir
|
for (uint8_t i = 0; i < workDirDepth; i++) // Loop to current work dir
|
||||||
appendAtom(workDirParents[i], t, cnt);
|
appendAtom(workDirParents[i], t, cnt);
|
||||||
|
|
||||||
if (cnt < MAXPATHNAMELENGTH - (FILENAME_LENGTH)) {
|
if (cnt < MAXPATHNAMELENGTH - (FILENAME_LENGTH) - 1) { // Leave room for filename and nul
|
||||||
appendAtom(file, t, cnt);
|
appendAtom(file, t, cnt);
|
||||||
--t;
|
--t;
|
||||||
}
|
}
|
||||||
|
@ -389,7 +464,7 @@ void CardReader::getAbsFilename(char *t) {
|
||||||
|
|
||||||
void CardReader::openFile(char * const path, const bool read, const bool subcall/*=false*/) {
|
void CardReader::openFile(char * const path, const bool read, const bool subcall/*=false*/) {
|
||||||
|
|
||||||
if (!cardOK) return;
|
if (!flag.cardOK) return;
|
||||||
|
|
||||||
uint8_t doing = 0;
|
uint8_t doing = 0;
|
||||||
if (isFileOpen()) { // Replacing current file or doing a subroutine
|
if (isFileOpen()) { // Replacing current file or doing a subroutine
|
||||||
|
@ -464,7 +539,7 @@ void CardReader::openFile(char * const path, const bool read, const bool subcall
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
saving = true;
|
flag.saving = true;
|
||||||
getfilename(0, fname);
|
getfilename(0, fname);
|
||||||
#if ENABLED(EMERGENCY_PARSER)
|
#if ENABLED(EMERGENCY_PARSER)
|
||||||
emergency_parser.disable();
|
emergency_parser.disable();
|
||||||
|
@ -476,7 +551,7 @@ void CardReader::openFile(char * const path, const bool read, const bool subcall
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::removeFile(const char * const name) {
|
void CardReader::removeFile(const char * const name) {
|
||||||
if (!cardOK) return;
|
if (!flag.cardOK) return;
|
||||||
|
|
||||||
//stopSDPrint();
|
//stopSDPrint();
|
||||||
|
|
||||||
|
@ -504,7 +579,7 @@ void CardReader::getStatus(
|
||||||
const int8_t port/*= -1*/
|
const int8_t port/*= -1*/
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
if (cardOK && sdprinting) {
|
if (flag.cardOK && flag.sdprinting) {
|
||||||
SERIAL_PROTOCOLPGM_P(port, MSG_SD_PRINTING_BYTE);
|
SERIAL_PROTOCOLPGM_P(port, MSG_SD_PRINTING_BYTE);
|
||||||
SERIAL_PROTOCOL_P(port, sdpos);
|
SERIAL_PROTOCOL_P(port, sdpos);
|
||||||
SERIAL_PROTOCOLCHAR_P(port, '/');
|
SERIAL_PROTOCOLCHAR_P(port, '/');
|
||||||
|
@ -543,11 +618,11 @@ void CardReader::write_command(char *buf) {
|
||||||
|
|
||||||
void CardReader::checkautostart() {
|
void CardReader::checkautostart() {
|
||||||
|
|
||||||
if (autostart_index < 0 || sdprinting) return;
|
if (autostart_index < 0 || flag.sdprinting) return;
|
||||||
|
|
||||||
if (!cardOK) initsd();
|
if (!flag.cardOK) initsd();
|
||||||
|
|
||||||
if (cardOK
|
if (flag.cardOK
|
||||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||||
&& !recovery.valid() // Don't run auto#.g when a resume file exists
|
&& !recovery.valid() // Don't run auto#.g when a resume file exists
|
||||||
#endif
|
#endif
|
||||||
|
@ -576,7 +651,7 @@ void CardReader::beginautostart() {
|
||||||
void CardReader::closefile(const bool store_location) {
|
void CardReader::closefile(const bool store_location) {
|
||||||
file.sync();
|
file.sync();
|
||||||
file.close();
|
file.close();
|
||||||
saving = logging = false;
|
flag.saving = flag.logging = false;
|
||||||
sdpos = 0;
|
sdpos = 0;
|
||||||
#if ENABLED(EMERGENCY_PARSER)
|
#if ENABLED(EMERGENCY_PARSER)
|
||||||
emergency_parser.enable();
|
emergency_parser.enable();
|
||||||
|
@ -603,7 +678,7 @@ void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/) {
|
||||||
if (nr < sort_count) {
|
if (nr < sort_count) {
|
||||||
strcpy(filename, sortshort[nr]);
|
strcpy(filename, sortshort[nr]);
|
||||||
strcpy(longFilename, sortnames[nr]);
|
strcpy(longFilename, sortnames[nr]);
|
||||||
filenameIsDir = TEST(isDir[nr>>3], nr & 0x07);
|
flag.filenameIsDir = TEST(isDir[nr>>3], nr & 0x07);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif // SDSORT_CACHE_NAMES
|
#endif // SDSORT_CACHE_NAMES
|
||||||
|
@ -712,6 +787,33 @@ void CardReader::setroot() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLED(SDSORT_USES_RAM)
|
||||||
|
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
||||||
|
// Use dynamic method to copy long filename
|
||||||
|
#define SET_SORTNAME(I) (sortnames[I] = strdup(longest_filename()))
|
||||||
|
#if ENABLED(SDSORT_CACHE_NAMES)
|
||||||
|
// When caching also store the short name, since
|
||||||
|
// we're replacing the getfilename() behavior.
|
||||||
|
#define SET_SORTSHORT(I) (sortshort[I] = strdup(filename))
|
||||||
|
#else
|
||||||
|
#define SET_SORTSHORT(I) NOOP
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// Copy filenames into the static array
|
||||||
|
#if SORTED_LONGNAME_MAXLEN != LONG_FILENAME_LENGTH
|
||||||
|
#define SET_SORTNAME(I) do{ strncpy(sortnames[I], longest_filename(), SORTED_LONGNAME_MAXLEN); \
|
||||||
|
sortnames[I][SORTED_LONGNAME_MAXLEN] = '\0'; }while(0)
|
||||||
|
#else
|
||||||
|
#define SET_SORTNAME(I) strncpy(sortnames[I], longest_filename(), SORTED_LONGNAME_MAXLEN)
|
||||||
|
#endif
|
||||||
|
#if ENABLED(SDSORT_CACHE_NAMES)
|
||||||
|
#define SET_SORTSHORT(I) strcpy(sortshort[I], filename)
|
||||||
|
#else
|
||||||
|
#define SET_SORTSHORT(I) NOOP
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read all the files and produce a sort key
|
* Read all the files and produce a sort key
|
||||||
*
|
*
|
||||||
|
@ -754,7 +856,7 @@ void CardReader::setroot() {
|
||||||
sortnames = new char*[fileCnt];
|
sortnames = new char*[fileCnt];
|
||||||
#endif
|
#endif
|
||||||
#elif ENABLED(SDSORT_USES_STACK)
|
#elif ENABLED(SDSORT_USES_STACK)
|
||||||
char sortnames[fileCnt][SORTED_LONGNAME_MAXLEN];
|
char sortnames[fileCnt][SORTED_LONGNAME_MAXLEN + 1];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Folder sorting needs 1 bit per entry for flags.
|
// Folder sorting needs 1 bit per entry for flags.
|
||||||
|
@ -783,33 +885,15 @@ void CardReader::setroot() {
|
||||||
// If using RAM then read all filenames now.
|
// If using RAM then read all filenames now.
|
||||||
#if ENABLED(SDSORT_USES_RAM)
|
#if ENABLED(SDSORT_USES_RAM)
|
||||||
getfilename(i);
|
getfilename(i);
|
||||||
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
SET_SORTNAME(i);
|
||||||
// Use dynamic method to copy long filename
|
SET_SORTSHORT(i);
|
||||||
sortnames[i] = strdup(longest_filename());
|
|
||||||
#if ENABLED(SDSORT_CACHE_NAMES)
|
|
||||||
// When caching also store the short name, since
|
|
||||||
// we're replacing the getfilename() behavior.
|
|
||||||
sortshort[i] = strdup(filename);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
// Copy filenames into the static array
|
|
||||||
#if SORTED_LONGNAME_MAXLEN != LONG_FILENAME_LENGTH
|
|
||||||
strncpy(sortnames[i], longest_filename(), SORTED_LONGNAME_MAXLEN);
|
|
||||||
sortnames[i][SORTED_LONGNAME_MAXLEN - 1] = '\0';
|
|
||||||
#else
|
|
||||||
strncpy(sortnames[i], longest_filename(), SORTED_LONGNAME_MAXLEN);
|
|
||||||
#endif
|
|
||||||
#if ENABLED(SDSORT_CACHE_NAMES)
|
|
||||||
strcpy(sortshort[i], filename);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
// char out[30];
|
// char out[30];
|
||||||
// sprintf_P(out, PSTR("---- %i %s %s"), i, filenameIsDir ? "D" : " ", sortnames[i]);
|
// sprintf_P(out, PSTR("---- %i %s %s"), i, flag.filenameIsDir ? "D" : " ", sortnames[i]);
|
||||||
// SERIAL_ECHOLN(out);
|
// SERIAL_ECHOLN(out);
|
||||||
#if HAS_FOLDER_SORTING
|
#if HAS_FOLDER_SORTING
|
||||||
const uint16_t bit = i & 0x07, ind = i >> 3;
|
const uint16_t bit = i & 0x07, ind = i >> 3;
|
||||||
if (bit == 0) isDir[ind] = 0x00;
|
if (bit == 0) isDir[ind] = 0x00;
|
||||||
if (filenameIsDir) isDir[ind] |= _BV(bit);
|
if (flag.filenameIsDir) isDir[ind] |= _BV(bit);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -837,7 +921,7 @@ void CardReader::setroot() {
|
||||||
? _SORT_CMP_NODIR() \
|
? _SORT_CMP_NODIR() \
|
||||||
: (isDir[fs > 0 ? ind1 : ind2] & (fs > 0 ? _BV(bit1) : _BV(bit2))) != 0)
|
: (isDir[fs > 0 ? ind1 : ind2] & (fs > 0 ? _BV(bit1) : _BV(bit2))) != 0)
|
||||||
#else
|
#else
|
||||||
#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1))
|
#define _SORT_CMP_DIR(fs) ((dir1 == flag.filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -847,7 +931,7 @@ void CardReader::setroot() {
|
||||||
getfilename(o1);
|
getfilename(o1);
|
||||||
strcpy(name1, longest_filename()); // save (or getfilename below will trounce it)
|
strcpy(name1, longest_filename()); // save (or getfilename below will trounce it)
|
||||||
#if HAS_FOLDER_SORTING
|
#if HAS_FOLDER_SORTING
|
||||||
bool dir1 = filenameIsDir;
|
bool dir1 = flag.filenameIsDir;
|
||||||
#endif
|
#endif
|
||||||
getfilename(o2);
|
getfilename(o2);
|
||||||
char *name2 = longest_filename(); // use the string in-place
|
char *name2 = longest_filename(); // use the string in-place
|
||||||
|
@ -885,27 +969,17 @@ void CardReader::setroot() {
|
||||||
else {
|
else {
|
||||||
sort_order[0] = 0;
|
sort_order[0] = 0;
|
||||||
#if ENABLED(SDSORT_USES_RAM) && ENABLED(SDSORT_CACHE_NAMES)
|
#if ENABLED(SDSORT_USES_RAM) && ENABLED(SDSORT_CACHE_NAMES)
|
||||||
getfilename(0);
|
|
||||||
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
||||||
sortnames = new char*[1];
|
sortnames = new char*[1];
|
||||||
sortnames[0] = strdup(longest_filename()); // malloc
|
|
||||||
#if ENABLED(SDSORT_CACHE_NAMES)
|
#if ENABLED(SDSORT_CACHE_NAMES)
|
||||||
sortshort = new char*[1];
|
sortshort = new char*[1];
|
||||||
sortshort[0] = strdup(filename); // malloc
|
|
||||||
#endif
|
#endif
|
||||||
isDir = new uint8_t[1];
|
isDir = new uint8_t[1];
|
||||||
#else
|
|
||||||
#if SORTED_LONGNAME_MAXLEN != LONG_FILENAME_LENGTH
|
|
||||||
strncpy(sortnames[0], longest_filename(), SORTED_LONGNAME_MAXLEN);
|
|
||||||
sortnames[0][SORTED_LONGNAME_MAXLEN - 1] = '\0';
|
|
||||||
#else
|
|
||||||
strncpy(sortnames[0], longest_filename(), SORTED_LONGNAME_MAXLEN);
|
|
||||||
#endif
|
|
||||||
#if ENABLED(SDSORT_CACHE_NAMES)
|
|
||||||
strcpy(sortshort[0], filename);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
isDir[0] = filenameIsDir ? 0x01 : 0x00;
|
getfilename(0);
|
||||||
|
SET_SORTNAME(0);
|
||||||
|
SET_SORTSHORT(0);
|
||||||
|
isDir[0] = flag.filenameIsDir ? 0x01 : 0x00;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1007,7 +1081,7 @@ void CardReader::printingHasFinished() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::openJobRecoveryFile(const bool read) {
|
void CardReader::openJobRecoveryFile(const bool read) {
|
||||||
if (!cardOK) return;
|
if (!flag.cardOK) return;
|
||||||
if (recovery.file.isOpen()) return;
|
if (recovery.file.isOpen()) return;
|
||||||
if (!recovery.file.open(&root, job_recovery_file_name, read ? O_READ : O_CREAT | O_WRITE | O_TRUNC | O_SYNC)) {
|
if (!recovery.file.open(&root, job_recovery_file_name, read ? O_READ : O_CREAT | O_WRITE | O_TRUNC | O_SYNC)) {
|
||||||
SERIAL_PROTOCOLPAIR(MSG_SD_OPEN_FILE_FAIL, job_recovery_file_name);
|
SERIAL_PROTOCOLPAIR(MSG_SD_OPEN_FILE_FAIL, job_recovery_file_name);
|
||||||
|
|
|
@ -27,106 +27,121 @@
|
||||||
|
|
||||||
#define SD_RESORT ENABLED(SDCARD_SORT_ALPHA) && ENABLED(SDSORT_DYNAMIC_RAM)
|
#define SD_RESORT ENABLED(SDCARD_SORT_ALPHA) && ENABLED(SDSORT_DYNAMIC_RAM)
|
||||||
|
|
||||||
#define MAX_DIR_DEPTH 10 // Maximum folder depth
|
#define MAX_DIR_DEPTH 10 // Maximum folder depth
|
||||||
|
#define MAXDIRNAMELENGTH 8 // DOS folder name size
|
||||||
|
#define MAXPATHNAMELENGTH (1 + (MAXDIRNAMELENGTH + 1) * (MAX_DIR_DEPTH) + 1 + FILENAME_LENGTH) // "/" + N * ("ADIRNAME/") + "filename.ext"
|
||||||
|
|
||||||
#include "SdFile.h"
|
#include "SdFile.h"
|
||||||
|
|
||||||
enum LsAction : uint8_t { LS_SerialPrint, LS_Count, LS_GetFilename };
|
enum LsAction : uint8_t { LS_SerialPrint, LS_Count, LS_GetFilename };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool saving:1,
|
||||||
|
logging:1,
|
||||||
|
sdprinting:1,
|
||||||
|
cardOK:1,
|
||||||
|
filenameIsDir:1,
|
||||||
|
abort_sd_printing:1
|
||||||
|
#if ENABLED(FAST_FILE_TRANSFER)
|
||||||
|
, binary_mode:1
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
} card_flags_t;
|
||||||
|
|
||||||
class CardReader {
|
class CardReader {
|
||||||
public:
|
public:
|
||||||
CardReader();
|
CardReader();
|
||||||
|
|
||||||
void initsd();
|
static void initsd();
|
||||||
void write_command(char *buf);
|
static void write_command(char *buf);
|
||||||
|
|
||||||
void beginautostart();
|
static void beginautostart();
|
||||||
void checkautostart();
|
static void checkautostart();
|
||||||
|
|
||||||
void openFile(char * const path, const bool read, const bool subcall=false);
|
static void openFile(char * const path, const bool read, const bool subcall=false);
|
||||||
void openLogFile(char * const path);
|
static void openLogFile(char * const path);
|
||||||
void removeFile(const char * const name);
|
static void removeFile(const char * const name);
|
||||||
void closefile(const bool store_location=false);
|
static void closefile(const bool store_location=false);
|
||||||
void release();
|
static void release();
|
||||||
void openAndPrintFile(const char *name);
|
static void openAndPrintFile(const char *name);
|
||||||
void startFileprint();
|
static void startFileprint();
|
||||||
void stopSDPrint(
|
static void stopSDPrint(
|
||||||
#if SD_RESORT
|
#if SD_RESORT
|
||||||
const bool re_sort=false
|
const bool re_sort=false
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
void getStatus(
|
static void getStatus(
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
const int8_t port = -1
|
const int8_t port = -1
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
void printingHasFinished();
|
static void printingHasFinished();
|
||||||
void printFilename(
|
static void printFilename(
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
const int8_t port = -1
|
const int8_t port = -1
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
#if ENABLED(LONG_FILENAME_HOST_SUPPORT)
|
#if ENABLED(LONG_FILENAME_HOST_SUPPORT)
|
||||||
void printLongPath(char *path
|
static void printLongPath(char *path
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
, const int8_t port = -1
|
, const int8_t port = -1
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void getfilename(uint16_t nr, const char* const match=NULL);
|
static void getfilename(uint16_t nr, const char* const match=NULL);
|
||||||
uint16_t getnrfilenames();
|
static uint16_t getnrfilenames();
|
||||||
|
|
||||||
void getAbsFilename(char *t);
|
static void getAbsFilename(char *t);
|
||||||
|
|
||||||
void ls(
|
static void ls(
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
const int8_t port = -1
|
const int8_t port = -1
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
void chdir(const char *relpath);
|
static void chdir(const char *relpath);
|
||||||
int8_t updir();
|
static int8_t updir();
|
||||||
void setroot();
|
static void setroot();
|
||||||
|
|
||||||
const char* diveToFile(SdFile*& curDir, const char * const path, const bool echo);
|
static const char* diveToFile(SdFile*& curDir, const char * const path, const bool echo);
|
||||||
|
|
||||||
uint16_t get_num_Files();
|
static uint16_t get_num_Files();
|
||||||
|
|
||||||
#if ENABLED(SDCARD_SORT_ALPHA)
|
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||||
void presort();
|
static void presort();
|
||||||
void getfilename_sorted(const uint16_t nr);
|
static void getfilename_sorted(const uint16_t nr);
|
||||||
#if ENABLED(SDSORT_GCODE)
|
#if ENABLED(SDSORT_GCODE)
|
||||||
FORCE_INLINE void setSortOn(bool b) { sort_alpha = b; presort(); }
|
FORCE_INLINE static void setSortOn(bool b) { sort_alpha = b; presort(); }
|
||||||
FORCE_INLINE void setSortFolders(int i) { sort_folders = i; presort(); }
|
FORCE_INLINE static void setSortFolders(int i) { sort_folders = i; presort(); }
|
||||||
//FORCE_INLINE void setSortReverse(bool b) { sort_reverse = b; }
|
//FORCE_INLINE static void setSortReverse(bool b) { sort_reverse = b; }
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
FORCE_INLINE void getfilename_sorted(const uint16_t nr) { getfilename(nr); }
|
FORCE_INLINE static void getfilename_sorted(const uint16_t nr) { getfilename(nr); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||||
bool jobRecoverFileExists();
|
static bool jobRecoverFileExists();
|
||||||
void openJobRecoveryFile(const bool read);
|
static void openJobRecoveryFile(const bool read);
|
||||||
void removeJobRecoveryFile();
|
static void removeJobRecoveryFile();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void pauseSDPrint() { sdprinting = false; }
|
static inline void pauseSDPrint() { flag.sdprinting = false; }
|
||||||
inline bool isFileOpen() { return file.isOpen(); }
|
static inline bool isFileOpen() { return file.isOpen(); }
|
||||||
inline bool eof() { return sdpos >= filesize; }
|
static inline bool eof() { return sdpos >= filesize; }
|
||||||
inline int16_t get() { sdpos = file.curPosition(); return (int16_t)file.read(); }
|
static inline int16_t get() { sdpos = file.curPosition(); return (int16_t)file.read(); }
|
||||||
inline void setIndex(const uint32_t index) { sdpos = index; file.seekSet(index); }
|
static inline void setIndex(const uint32_t index) { sdpos = index; file.seekSet(index); }
|
||||||
inline uint32_t getIndex() { return sdpos; }
|
static inline uint32_t getIndex() { return sdpos; }
|
||||||
inline uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; }
|
static inline uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; }
|
||||||
inline char* getWorkDirName() { workDir.getFilename(filename); return filename; }
|
static inline char* getWorkDirName() { workDir.getFilename(filename); return filename; }
|
||||||
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; }
|
||||||
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; }
|
||||||
|
|
||||||
Sd2Card& getSd2Card() { return sd2card; }
|
static Sd2Card& getSd2Card() { return sd2card; }
|
||||||
|
|
||||||
#if ENABLED(AUTO_REPORT_SD_STATUS)
|
#if ENABLED(AUTO_REPORT_SD_STATUS)
|
||||||
void auto_report_sd_status(void);
|
static void auto_report_sd_status(void);
|
||||||
inline void set_auto_report_interval(uint8_t v
|
static inline void set_auto_report_interval(uint8_t v
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
, int8_t port
|
, int8_t port
|
||||||
#endif
|
#endif
|
||||||
|
@ -140,40 +155,39 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline char* longest_filename() { return longFilename[0] ? longFilename : filename; }
|
static inline char* longest_filename() { return longFilename[0] ? longFilename : filename; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool saving, logging, sdprinting, cardOK, filenameIsDir, abort_sd_printing;
|
static card_flags_t flag;
|
||||||
char filename[FILENAME_LENGTH], longFilename[LONG_FILENAME_LENGTH];
|
static char filename[FILENAME_LENGTH + 1], longFilename[LONG_FILENAME_LENGTH + 1];
|
||||||
int8_t autostart_index;
|
static int8_t autostart_index;
|
||||||
|
|
||||||
#if ENABLED(FAST_FILE_TRANSFER)
|
#if ENABLED(FAST_FILE_TRANSFER)
|
||||||
bool binary_mode;
|
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
uint8_t transfer_port;
|
static uint8_t transfer_port;
|
||||||
#else
|
#else
|
||||||
static constexpr uint8_t transfer_port = 0;
|
static constexpr uint8_t transfer_port = 0;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SdFile root, workDir, workDirParents[MAX_DIR_DEPTH];
|
static SdFile root, workDir, workDirParents[MAX_DIR_DEPTH];
|
||||||
uint8_t workDirDepth;
|
static uint8_t workDirDepth;
|
||||||
|
|
||||||
// Sort files and folders alphabetically.
|
// Sort files and folders alphabetically.
|
||||||
#if ENABLED(SDCARD_SORT_ALPHA)
|
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||||
uint16_t sort_count; // Count of sorted items in the current directory
|
static uint16_t sort_count; // Count of sorted items in the current directory
|
||||||
#if ENABLED(SDSORT_GCODE)
|
#if ENABLED(SDSORT_GCODE)
|
||||||
bool sort_alpha; // Flag to enable / disable the feature
|
static bool sort_alpha; // Flag to enable / disable the feature
|
||||||
int sort_folders; // Flag to enable / disable folder sorting
|
static int sort_folders; // Folder sorting before/none/after
|
||||||
//bool sort_reverse; // Flag to enable / disable reverse sorting
|
//static bool sort_reverse; // Flag to enable / disable reverse sorting
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// By default the sort index is static
|
// By default the sort index is static
|
||||||
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
||||||
uint8_t *sort_order;
|
static uint8_t *sort_order;
|
||||||
#else
|
#else
|
||||||
uint8_t sort_order[SDSORT_LIMIT];
|
static uint8_t sort_order[SDSORT_LIMIT];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(SDSORT_USES_RAM) && ENABLED(SDSORT_CACHE_NAMES) && DISABLED(SDSORT_DYNAMIC_RAM)
|
#if ENABLED(SDSORT_USES_RAM) && ENABLED(SDSORT_CACHE_NAMES) && DISABLED(SDSORT_DYNAMIC_RAM)
|
||||||
|
@ -188,21 +202,21 @@ private:
|
||||||
// If using dynamic ram for names, allocate on the heap.
|
// If using dynamic ram for names, allocate on the heap.
|
||||||
#if ENABLED(SDSORT_CACHE_NAMES)
|
#if ENABLED(SDSORT_CACHE_NAMES)
|
||||||
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
||||||
char **sortshort, **sortnames;
|
static char **sortshort, **sortnames;
|
||||||
#else
|
#else
|
||||||
char sortshort[SDSORT_LIMIT][FILENAME_LENGTH];
|
static char sortshort[SDSORT_LIMIT][FILENAME_LENGTH + 1];
|
||||||
char sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN];
|
static char sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN + 1];
|
||||||
#endif
|
#endif
|
||||||
#elif DISABLED(SDSORT_USES_STACK)
|
#elif DISABLED(SDSORT_USES_STACK)
|
||||||
char sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN];
|
static char sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN + 1];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Folder sorting uses an isDir array when caching items.
|
// Folder sorting uses an isDir array when caching items.
|
||||||
#if HAS_FOLDER_SORTING
|
#if HAS_FOLDER_SORTING
|
||||||
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
||||||
uint8_t *isDir;
|
static uint8_t *isDir;
|
||||||
#elif ENABLED(SDSORT_CACHE_NAMES) || DISABLED(SDSORT_USES_STACK)
|
#elif ENABLED(SDSORT_CACHE_NAMES) || DISABLED(SDSORT_USES_STACK)
|
||||||
uint8_t isDir[(SDSORT_LIMIT+7)>>3];
|
static uint8_t isDir[(SDSORT_LIMIT+7)>>3];
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -210,28 +224,31 @@ private:
|
||||||
|
|
||||||
#endif // SDCARD_SORT_ALPHA
|
#endif // SDCARD_SORT_ALPHA
|
||||||
|
|
||||||
Sd2Card sd2card;
|
static Sd2Card sd2card;
|
||||||
SdVolume volume;
|
static SdVolume volume;
|
||||||
SdFile file;
|
static SdFile file;
|
||||||
|
|
||||||
#define SD_PROCEDURE_DEPTH 1
|
#ifndef SD_PROCEDURE_DEPTH
|
||||||
#define MAXPATHNAMELENGTH (FILENAME_LENGTH*MAX_DIR_DEPTH + MAX_DIR_DEPTH + 1)
|
#define SD_PROCEDURE_DEPTH 1
|
||||||
uint8_t file_subcall_ctr;
|
#endif
|
||||||
uint32_t filespos[SD_PROCEDURE_DEPTH];
|
|
||||||
char proc_filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
|
|
||||||
uint32_t filesize, sdpos;
|
|
||||||
|
|
||||||
LsAction lsAction; //stored for recursion.
|
static uint8_t file_subcall_ctr;
|
||||||
uint16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory.
|
static uint32_t filespos[SD_PROCEDURE_DEPTH];
|
||||||
char* diveDirName;
|
static char proc_filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH + 1];
|
||||||
void lsDive(const char *prepend, SdFile parent, const char * const match=NULL
|
|
||||||
|
static uint32_t filesize, sdpos;
|
||||||
|
|
||||||
|
static LsAction lsAction; //stored for recursion.
|
||||||
|
static uint16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory.
|
||||||
|
static char *diveDirName;
|
||||||
|
static void lsDive(const char *prepend, SdFile parent, const char * const match=NULL
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
, const int8_t port = -1
|
, const int8_t port = -1
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
#if ENABLED(SDCARD_SORT_ALPHA)
|
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||||
void flush_presort();
|
static void flush_presort();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(AUTO_REPORT_SD_STATUS)
|
#if ENABLED(AUTO_REPORT_SD_STATUS)
|
||||||
|
@ -256,7 +273,7 @@ private:
|
||||||
#define IS_SD_INSERTED() true
|
#define IS_SD_INSERTED() true
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IS_SD_PRINTING() card.sdprinting
|
#define IS_SD_PRINTING() card.flag.sdprinting
|
||||||
#define IS_SD_FILE_OPEN() card.isFileOpen()
|
#define IS_SD_FILE_OPEN() card.isFileOpen()
|
||||||
|
|
||||||
extern CardReader card;
|
extern CardReader card;
|
||||||
|
|
Loading…
Reference in a new issue