SDCARD_READONLY (#17884)
This commit is contained in:
parent
2ad3da98d4
commit
801f99edad
7 changed files with 108 additions and 40 deletions
|
@ -1084,6 +1084,8 @@
|
||||||
// Enable this option and set to HIGH if your SD cards are incorrectly detected.
|
// Enable this option and set to HIGH if your SD cards are incorrectly detected.
|
||||||
//#define SD_DETECT_STATE HIGH
|
//#define SD_DETECT_STATE HIGH
|
||||||
|
|
||||||
|
//#define SDCARD_READONLY // Read-only SD card (to save over 2K of flash)
|
||||||
|
|
||||||
#define SD_PROCEDURE_DEPTH 1 // Increase if you need more nested M32 calls
|
#define SD_PROCEDURE_DEPTH 1 // Increase if you need more nested M32 calls
|
||||||
|
|
||||||
#define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished
|
#define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished
|
||||||
|
|
|
@ -2062,6 +2062,20 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure features that need to write to the SD card are
|
||||||
|
* disabled unless write support is enabled.
|
||||||
|
*/
|
||||||
|
#if ENABLED(SDCARD_READONLY)
|
||||||
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||||
|
#error "POWER_LOSS_RECOVERY is incompatible with SDCARD_READONLY."
|
||||||
|
#elif ENABLED(BINARY_FILE_TRANSFER)
|
||||||
|
#error "BINARY_FILE_TRANSFER is incompatible with SDCARD_READONLY."
|
||||||
|
#elif ENABLED(SDCARD_EEPROM_EMULATION)
|
||||||
|
#error "SDCARD_EEPROM_EMULATION is incompatible with SDCARD_READONLY."
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure only one display is enabled
|
* Make sure only one display is enabled
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -179,8 +179,11 @@ void Sd2Card::chipSelect() {
|
||||||
* \return true for success, false for failure.
|
* \return true for success, false for failure.
|
||||||
*/
|
*/
|
||||||
bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
|
bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
csd_t csd;
|
csd_t csd;
|
||||||
if (!readCSD(&csd)) goto FAIL;
|
if (!readCSD(&csd)) goto FAIL;
|
||||||
|
|
||||||
// check for single block erase
|
// check for single block erase
|
||||||
if (!csd.v1.erase_blk_en) {
|
if (!csd.v1.erase_blk_en) {
|
||||||
// erase size mask
|
// erase size mask
|
||||||
|
@ -535,9 +538,10 @@ bool Sd2Card::waitNotBusy(const millis_t timeout_ms) {
|
||||||
* \return true for success, false for failure.
|
* \return true for success, false for failure.
|
||||||
*/
|
*/
|
||||||
bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
|
bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
|
||||||
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card
|
||||||
if (!cardCommand(CMD24, blockNumber)) {
|
if (!cardCommand(CMD24, blockNumber)) {
|
||||||
if (writeData(DATA_START_BLOCK, src)) {
|
if (writeData(DATA_START_BLOCK, src)) {
|
||||||
if (waitNotBusy(SD_WRITE_TIMEOUT)) { // Wait for flashing to complete
|
if (waitNotBusy(SD_WRITE_TIMEOUT)) { // Wait for flashing to complete
|
||||||
|
@ -561,6 +565,8 @@ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
|
||||||
* \return true for success, false for failure.
|
* \return true for success, false for failure.
|
||||||
*/
|
*/
|
||||||
bool Sd2Card::writeData(const uint8_t* src) {
|
bool Sd2Card::writeData(const uint8_t* src) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
chipSelect();
|
chipSelect();
|
||||||
// Wait for previous write to finish
|
// Wait for previous write to finish
|
||||||
|
@ -574,14 +580,9 @@ bool Sd2Card::writeData(const uint8_t* src) {
|
||||||
|
|
||||||
// Send one block of data for write block or write multiple blocks
|
// Send one block of data for write block or write multiple blocks
|
||||||
bool Sd2Card::writeData(const uint8_t token, const uint8_t* src) {
|
bool Sd2Card::writeData(const uint8_t token, const uint8_t* src) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
const uint16_t crc =
|
const uint16_t crc = TERN(SD_CHECK_AND_RETRY, CRC_CCITT(src, 512), 0xFFFF);
|
||||||
#if ENABLED(SD_CHECK_AND_RETRY)
|
|
||||||
CRC_CCITT(src, 512)
|
|
||||||
#else
|
|
||||||
0xFFFF
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
spiSendBlock(token, src);
|
spiSendBlock(token, src);
|
||||||
spiSend(crc >> 8);
|
spiSend(crc >> 8);
|
||||||
spiSend(crc & 0xFF);
|
spiSend(crc & 0xFF);
|
||||||
|
@ -607,6 +608,8 @@ bool Sd2Card::writeData(const uint8_t token, const uint8_t* src) {
|
||||||
* \return true for success, false for failure.
|
* \return true for success, false for failure.
|
||||||
*/
|
*/
|
||||||
bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) {
|
bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (!cardAcmd(ACMD23, eraseCount)) { // Send pre-erase count
|
if (!cardAcmd(ACMD23, eraseCount)) { // Send pre-erase count
|
||||||
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card
|
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card
|
||||||
|
@ -626,6 +629,8 @@ bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) {
|
||||||
* \return true for success, false for failure.
|
* \return true for success, false for failure.
|
||||||
*/
|
*/
|
||||||
bool Sd2Card::writeStop() {
|
bool Sd2Card::writeStop() {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
chipSelect();
|
chipSelect();
|
||||||
if (waitNotBusy(SD_WRITE_TIMEOUT)) {
|
if (waitNotBusy(SD_WRITE_TIMEOUT)) {
|
||||||
|
|
|
@ -47,6 +47,8 @@ void (*SdBaseFile::dateTime_)(uint16_t* date, uint16_t* time) = 0;
|
||||||
|
|
||||||
// add a cluster to a file
|
// add a cluster to a file
|
||||||
bool SdBaseFile::addCluster() {
|
bool SdBaseFile::addCluster() {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
if (!vol_->allocContiguous(1, &curCluster_)) return false;
|
if (!vol_->allocContiguous(1, &curCluster_)) return false;
|
||||||
|
|
||||||
// if first cluster of file link to directory entry
|
// if first cluster of file link to directory entry
|
||||||
|
@ -60,6 +62,8 @@ bool SdBaseFile::addCluster() {
|
||||||
// Add a cluster to a directory file and zero the cluster.
|
// Add a cluster to a directory file and zero the cluster.
|
||||||
// return with first block of cluster in the cache
|
// return with first block of cluster in the cache
|
||||||
bool SdBaseFile::addDirCluster() {
|
bool SdBaseFile::addDirCluster() {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
uint32_t block;
|
uint32_t block;
|
||||||
// max folder size
|
// max folder size
|
||||||
if (fileSize_ / sizeof(dir_t) >= 0xFFFF) return false;
|
if (fileSize_ / sizeof(dir_t) >= 0xFFFF) return false;
|
||||||
|
@ -153,6 +157,8 @@ bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool SdBaseFile::createContiguous(SdBaseFile* dirFile, const char* path, uint32_t size) {
|
bool SdBaseFile::createContiguous(SdBaseFile* dirFile, const char* path, uint32_t size) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
// don't allow zero length file
|
// don't allow zero length file
|
||||||
if (size == 0) return false;
|
if (size == 0) return false;
|
||||||
|
@ -419,6 +425,8 @@ bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) {
|
||||||
* directory, \a path is invalid or already exists in \a parent.
|
* directory, \a path is invalid or already exists in \a parent.
|
||||||
*/
|
*/
|
||||||
bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) {
|
bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
uint8_t dname[11];
|
uint8_t dname[11];
|
||||||
SdBaseFile dir1, dir2;
|
SdBaseFile dir1, dir2;
|
||||||
SdBaseFile* sub = &dir1;
|
SdBaseFile* sub = &dir1;
|
||||||
|
@ -449,6 +457,8 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
|
bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
uint32_t block;
|
uint32_t block;
|
||||||
dir_t d;
|
dir_t d;
|
||||||
dir_t* p;
|
dir_t* p;
|
||||||
|
@ -632,7 +642,7 @@ bool SdBaseFile::open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t ofla
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// don't create unless O_CREAT and O_WRITE
|
// don't create unless O_CREAT and O_WRITE
|
||||||
if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) return false;
|
if ((oflag & (O_CREAT | O_WRITE)) != (O_CREAT | O_WRITE)) return false;
|
||||||
if (emptyFound) {
|
if (emptyFound) {
|
||||||
index = dirIndex_;
|
index = dirIndex_;
|
||||||
p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||||
|
@ -716,8 +726,14 @@ bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) {
|
||||||
|
|
||||||
// open a cached directory entry. Assumes vol_ is initialized
|
// open a cached directory entry. Assumes vol_ is initialized
|
||||||
bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
|
bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
|
||||||
|
dir_t* p;
|
||||||
|
|
||||||
|
#if ENABLED(SDCARD_READONLY)
|
||||||
|
if (oflag & (O_WRITE | O_CREAT | O_TRUNC)) goto FAIL;
|
||||||
|
#endif
|
||||||
|
|
||||||
// location of entry in cache
|
// location of entry in cache
|
||||||
dir_t* p = &vol_->cache()->dir[dirIndex];
|
p = &vol_->cache()->dir[dirIndex];
|
||||||
|
|
||||||
// write or truncate is an error for a directory or read-only file
|
// write or truncate is an error for a directory or read-only file
|
||||||
if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) {
|
if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) {
|
||||||
|
@ -1135,6 +1151,8 @@ dir_t* SdBaseFile::readDirCache() {
|
||||||
* or an I/O error occurred.
|
* or an I/O error occurred.
|
||||||
*/
|
*/
|
||||||
bool SdBaseFile::remove() {
|
bool SdBaseFile::remove() {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
dir_t* d;
|
dir_t* d;
|
||||||
// free any clusters - will fail if read-only or directory
|
// free any clusters - will fail if read-only or directory
|
||||||
if (!truncate(0)) return false;
|
if (!truncate(0)) return false;
|
||||||
|
@ -1172,6 +1190,8 @@ bool SdBaseFile::remove() {
|
||||||
* or an I/O error occurred.
|
* or an I/O error occurred.
|
||||||
*/
|
*/
|
||||||
bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) {
|
bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
SdBaseFile file;
|
SdBaseFile file;
|
||||||
return file.open(dirFile, path, O_WRITE) ? file.remove() : false;
|
return file.open(dirFile, path, O_WRITE) ? file.remove() : false;
|
||||||
}
|
}
|
||||||
|
@ -1187,6 +1207,8 @@ bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) {
|
||||||
* file, newPath is invalid or already exists, or an I/O error occurs.
|
* file, newPath is invalid or already exists, or an I/O error occurs.
|
||||||
*/
|
*/
|
||||||
bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) {
|
bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
dir_t entry;
|
dir_t entry;
|
||||||
uint32_t dirCluster = 0;
|
uint32_t dirCluster = 0;
|
||||||
SdBaseFile file;
|
SdBaseFile file;
|
||||||
|
@ -1279,6 +1301,8 @@ restore:
|
||||||
* directory, is not empty, or an I/O error occurred.
|
* directory, is not empty, or an I/O error occurred.
|
||||||
*/
|
*/
|
||||||
bool SdBaseFile::rmdir() {
|
bool SdBaseFile::rmdir() {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
// must be open subdirectory
|
// must be open subdirectory
|
||||||
if (!isSubDir()) return false;
|
if (!isSubDir()) return false;
|
||||||
|
|
||||||
|
@ -1317,6 +1341,8 @@ bool SdBaseFile::rmdir() {
|
||||||
* \return true for success, false for failure.
|
* \return true for success, false for failure.
|
||||||
*/
|
*/
|
||||||
bool SdBaseFile::rmRfStar() {
|
bool SdBaseFile::rmRfStar() {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
SdBaseFile f;
|
SdBaseFile f;
|
||||||
rewind();
|
rewind();
|
||||||
|
@ -1424,7 +1450,7 @@ void SdBaseFile::setpos(filepos_t* pos) {
|
||||||
*/
|
*/
|
||||||
bool SdBaseFile::sync() {
|
bool SdBaseFile::sync() {
|
||||||
// only allow open files and directories
|
// only allow open files and directories
|
||||||
if (!isOpen()) goto FAIL;
|
if (ENABLED(SDCARD_READONLY) || !isOpen()) goto FAIL;
|
||||||
|
|
||||||
if (flags_ & F_FILE_DIR_DIRTY) {
|
if (flags_ & F_FILE_DIR_DIRTY) {
|
||||||
dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||||
|
@ -1524,6 +1550,8 @@ bool SdBaseFile::timestamp(SdBaseFile* file) {
|
||||||
*/
|
*/
|
||||||
bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|
bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|
||||||
uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
|
uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
uint16_t dirDate, dirTime;
|
uint16_t dirDate, dirTime;
|
||||||
dir_t* d;
|
dir_t* d;
|
||||||
|
|
||||||
|
@ -1575,6 +1603,8 @@ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|
||||||
* \a length is greater than the current file size or an I/O error occurs.
|
* \a length is greater than the current file size or an I/O error occurs.
|
||||||
*/
|
*/
|
||||||
bool SdBaseFile::truncate(uint32_t length) {
|
bool SdBaseFile::truncate(uint32_t length) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
uint32_t newPos;
|
uint32_t newPos;
|
||||||
// error if not a normal file or read-only
|
// error if not a normal file or read-only
|
||||||
if (!isFile() || !(flags_ & O_WRITE)) return false;
|
if (!isFile() || !(flags_ & O_WRITE)) return false;
|
||||||
|
@ -1636,6 +1666,10 @@ bool SdBaseFile::truncate(uint32_t length) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
|
int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
|
||||||
|
#if ENABLED(SDCARD_READONLY)
|
||||||
|
writeError = true; return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
// convert void* to uint8_t* - must be before goto statements
|
// convert void* to uint8_t* - must be before goto statements
|
||||||
const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
|
const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
|
|
||||||
// find a contiguous group of clusters
|
// find a contiguous group of clusters
|
||||||
bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
|
bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
// start of group
|
// start of group
|
||||||
uint32_t bgnCluster;
|
uint32_t bgnCluster;
|
||||||
// end of group
|
// end of group
|
||||||
|
@ -117,18 +119,20 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SdVolume::cacheFlush() {
|
bool SdVolume::cacheFlush() {
|
||||||
if (cacheDirty_) {
|
#if DISABLED(SDCARD_READONLY)
|
||||||
if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data))
|
if (cacheDirty_) {
|
||||||
return false;
|
if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data))
|
||||||
|
|
||||||
// mirror FAT tables
|
|
||||||
if (cacheMirrorBlock_) {
|
|
||||||
if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data))
|
|
||||||
return false;
|
return false;
|
||||||
cacheMirrorBlock_ = 0;
|
|
||||||
|
// mirror FAT tables
|
||||||
|
if (cacheMirrorBlock_) {
|
||||||
|
if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data))
|
||||||
|
return false;
|
||||||
|
cacheMirrorBlock_ = 0;
|
||||||
|
}
|
||||||
|
cacheDirty_ = 0;
|
||||||
}
|
}
|
||||||
cacheDirty_ = 0;
|
#endif
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +194,8 @@ bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) {
|
||||||
|
|
||||||
// Store a FAT entry
|
// Store a FAT entry
|
||||||
bool SdVolume::fatPut(uint32_t cluster, uint32_t value) {
|
bool SdVolume::fatPut(uint32_t cluster, uint32_t value) {
|
||||||
|
if (ENABLED(SDCARD_READONLY)) return false;
|
||||||
|
|
||||||
uint32_t lba;
|
uint32_t lba;
|
||||||
// error if reserved cluster
|
// error if reserved cluster
|
||||||
if (cluster < 2) return false;
|
if (cluster < 2) return false;
|
||||||
|
|
|
@ -446,8 +446,8 @@ void CardReader::endFilePrint(TERN_(SD_RESORT, const bool re_sort/*=false*/)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::openLogFile(char * const path) {
|
void CardReader::openLogFile(char * const path) {
|
||||||
flag.logging = true;
|
flag.logging = DISABLED(SDCARD_READONLY);
|
||||||
openFileWrite(path);
|
TERN(SDCARD_READONLY,,openFileWrite(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -573,15 +573,19 @@ void CardReader::openFileWrite(char * const path) {
|
||||||
const char * const fname = diveToFile(false, curDir, path);
|
const char * const fname = diveToFile(false, curDir, path);
|
||||||
if (!fname) return;
|
if (!fname) return;
|
||||||
|
|
||||||
if (file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
|
#if ENABLED(SDCARD_READONLY)
|
||||||
flag.saving = true;
|
|
||||||
selectFileByName(fname);
|
|
||||||
TERN_(EMERGENCY_PARSER, emergency_parser.disable());
|
|
||||||
echo_write_to_file(fname);
|
|
||||||
ui.set_status(fname);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
openFailed(fname);
|
openFailed(fname);
|
||||||
|
#else
|
||||||
|
if (file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
|
||||||
|
flag.saving = true;
|
||||||
|
selectFileByName(fname);
|
||||||
|
TERN_(EMERGENCY_PARSER, emergency_parser.disable());
|
||||||
|
echo_write_to_file(fname);
|
||||||
|
ui.set_status(fname);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
openFailed(fname);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -596,13 +600,17 @@ void CardReader::removeFile(const char * const name) {
|
||||||
const char * const fname = diveToFile(false, curDir, name);
|
const char * const fname = diveToFile(false, curDir, name);
|
||||||
if (!fname) return;
|
if (!fname) return;
|
||||||
|
|
||||||
if (file.remove(curDir, fname)) {
|
#if ENABLED(SDCARD_READONLY)
|
||||||
SERIAL_ECHOLNPAIR("File deleted:", fname);
|
SERIAL_ECHOLNPAIR("Deletion failed (read-only), File: ", fname, ".");
|
||||||
sdpos = 0;
|
#else
|
||||||
TERN_(SDCARD_SORT_ALPHA, presort());
|
if (file.remove(curDir, fname)) {
|
||||||
}
|
SERIAL_ECHOLNPAIR("File deleted:", fname);
|
||||||
else
|
sdpos = 0;
|
||||||
SERIAL_ECHOLNPAIR("Deletion failed, File: ", fname, ".");
|
TERN_(SDCARD_SORT_ALPHA, presort());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SERIAL_ECHOLNPAIR("Deletion failed, File: ", fname, ".");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::report_status() {
|
void CardReader::report_status() {
|
||||||
|
|
|
@ -15,8 +15,7 @@ set -e
|
||||||
|
|
||||||
restore_configs
|
restore_configs
|
||||||
opt_set MOTHERBOARD BOARD_RAMPS_14_RE_ARM_EFB
|
opt_set MOTHERBOARD BOARD_RAMPS_14_RE_ARM_EFB
|
||||||
opt_enable VIKI2 SDSUPPORT SERIAL_PORT_2 NEOPIXEL_LED
|
opt_enable VIKI2 SDSUPPORT SDCARD_READONLY SERIAL_PORT_2 NEOPIXEL_LED
|
||||||
|
|
||||||
opt_set NEOPIXEL_PIN P1_16
|
opt_set NEOPIXEL_PIN P1_16
|
||||||
exec_test $1 $2 "ReARM EFB VIKI2, SDSUPPORT, 2 Serial ports (USB CDC + UART0), NeoPixel"
|
exec_test $1 $2 "ReARM EFB VIKI2, SDSUPPORT, 2 Serial ports (USB CDC + UART0), NeoPixel"
|
||||||
|
|
||||||
|
|
Reference in a new issue