From 01acf005f8e3f731a07c20f5f779f73d89c31ee0 Mon Sep 17 00:00:00 2001 From: Martin Turski Date: Sat, 4 Feb 2023 18:23:32 +0100 Subject: [PATCH 1/9] - added SD card reliability update --- Marlin/src/HAL/STM32/msc_sd.cpp | 52 +++++++++++++++----- Marlin/src/sd/Sd2Card.cpp | 87 ++++++++++++++++++++++++++------- 2 files changed, 110 insertions(+), 29 deletions(-) diff --git a/Marlin/src/HAL/STM32/msc_sd.cpp b/Marlin/src/HAL/STM32/msc_sd.cpp index a40bec9d644d..b6e2ec6dee1e 100644 --- a/Marlin/src/HAL/STM32/msc_sd.cpp +++ b/Marlin/src/HAL/STM32/msc_sd.cpp @@ -33,6 +33,10 @@ #define BLOCK_SIZE 512 #define PRODUCT_ID 0x29 +#ifndef SD_MULTIBLOCK_READ_RETRY_CNT + #define SD_MULTIBLOCK_READ_RETRY_CNT 1 +#endif + class Sd2CardUSBMscHandler : public USBMscHandler { public: DiskIODriver* diskIODriver() { @@ -58,19 +62,32 @@ class Sd2CardUSBMscHandler : public USBMscHandler { // single block if (blkLen == 1) { hal.watchdog_refresh(); - sd2card->writeBlock(blkAddr, pBuf); - return true; + return sd2card->writeBlock(blkAddr, pBuf); } // multi block optimization - sd2card->writeStart(blkAddr, blkLen); - while (blkLen--) { + uint32_t multi_retry_cnt = SD_MULTIBLOCK_READ_RETRY_CNT; + + RETRY_MULTI: + uint32 i = blkLen; + uint8_t *cBuf = pBuf; + sd2card->writeStart(blkAddr); + while (i--) { hal.watchdog_refresh(); - sd2card->writeData(pBuf); - pBuf += BLOCK_SIZE; + if (sd2card->writeData(cBuf) == false) + { + sd2card->writeStop(); + if (--multi_retry_cnt == 0) + goto FAIL; + multi_retry_cnt--; + goto RETRY_MULTI: + } + cBuf += BLOCK_SIZE; } sd2card->writeStop(); return true; + FAIL: + return false; } bool Read(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) { @@ -78,19 +95,32 @@ class Sd2CardUSBMscHandler : public USBMscHandler { // single block if (blkLen == 1) { hal.watchdog_refresh(); - sd2card->readBlock(blkAddr, pBuf); - return true; + return sd2card->readBlock(blkAddr, pBuf); } // multi block optimization + uint32_t multi_retry_cnt = SD_MULTIBLOCK_READ_RETRY_CNT; + + RETRY_MULTI: + uint32 i = blkLen; + uint8_t *cBuf = pBuf; sd2card->readStart(blkAddr); - while (blkLen--) { + while (i--) { hal.watchdog_refresh(); - sd2card->readData(pBuf); - pBuf += BLOCK_SIZE; + if (sd2card->readData(cBuf) == false) + { + sd2card->readStop(); + if (--multi_retry_cnt == 0) + goto FAIL; + multi_retry_cnt--; + goto RETRY_MULTI: + } + cBuf += BLOCK_SIZE; } sd2card->readStop(); return true; + FAIL: + return false; } bool IsReady() { diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp index 2d84c95a3d19..df28b5e4b90b 100644 --- a/Marlin/src/sd/Sd2Card.cpp +++ b/Marlin/src/sd/Sd2Card.cpp @@ -40,6 +40,10 @@ #include "../MarlinCore.h" +#ifndef SD_RETRY_COUNT + #define SD_RETRY_COUNT 3 +#endif + #if ENABLED(SD_CHECK_AND_RETRY) static bool crcSupported = true; @@ -97,8 +101,10 @@ uint8_t DiskIODriver_SPI_SD::cardCommand(const uint8_t cmd, const uint32_t arg) // Select card chipSelect(); +#ifdef SD_WRITE_TIMEOUT // Wait up to 300 ms if busy waitNotBusy(SD_WRITE_TIMEOUT); +#endif uint8_t *pa = (uint8_t *)(&arg); @@ -204,10 +210,14 @@ bool DiskIODriver_SPI_SD::erase(uint32_t firstBlock, uint32_t lastBlock) { error(SD_CARD_ERROR_ERASE); goto FAIL; } +#ifdef SD_ERASE_TIMEOUT if (!waitNotBusy(SD_ERASE_TIMEOUT)) { error(SD_CARD_ERROR_ERASE_TIMEOUT); goto FAIL; } +#else + while (spiRec() != 0xFF) {} +#endif chipDeselect(); return true; FAIL: @@ -246,7 +256,9 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi errorCode_ = type_ = 0; chipSelectPin_ = chipSelectPin; // 16-bit init start time allows over a minute +#ifdef SD_INIT_TIMEOUT const millis_t init_timeout = millis() + SD_INIT_TIMEOUT; +#endif uint32_t arg; hal.watchdog_refresh(); // In case init takes too long @@ -274,10 +286,12 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi // Command to go idle in SPI mode while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) { +#ifdef SD_INIT_TIMEOUT if (ELAPSED(millis(), init_timeout)) { error(SD_CARD_ERROR_CMD0); goto FAIL; } +#endif } #if ENABLED(SD_CHECK_AND_RETRY) @@ -300,10 +314,12 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi break; } +#ifdef SD_INIT_TIMEOUT if (ELAPSED(millis(), init_timeout)) { error(SD_CARD_ERROR_CMD8); goto FAIL; } +#endif } hal.watchdog_refresh(); // In case init takes too long @@ -311,11 +327,13 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi // Initialize card and send host supports SDHC if SD2 arg = type() == SD_CARD_TYPE_SD2 ? 0x40000000 : 0; while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) { +#ifdef SD_INIT_TIMEOUT // Check for timeout if (ELAPSED(millis(), init_timeout)) { error(SD_CARD_ERROR_ACMD41); goto FAIL; } +#endif } // If SD2 read OCR register to check for SDHC card if (type() == SD_CARD_TYPE_SD2) { @@ -353,7 +371,7 @@ bool DiskIODriver_SPI_SD::readBlock(uint32_t blockNumber, uint8_t *dst) { if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card #if ENABLED(SD_CHECK_AND_RETRY) - uint8_t retryCnt = 3; + uint8_t retryCnt = SD_RETRY_COUNT; for (;;) { if (cardCommand(CMD17, blockNumber)) error(SD_CARD_ERROR_CMD17); @@ -458,18 +476,22 @@ bool DiskIODriver_SPI_SD::readData(uint8_t *dst) { bool DiskIODriver_SPI_SD::readData(uint8_t *dst, const uint16_t count) { bool success = false; +#ifdef SD_READ_TIMEOUT const millis_t read_timeout = millis() + SD_READ_TIMEOUT; +#endif while ((status_ = spiRec()) == 0xFF) { // Wait for start block token +#ifdef SD_READ_TIMEOUT if (ELAPSED(millis(), read_timeout)) { error(SD_CARD_ERROR_READ_TIMEOUT); goto FAIL; } +#endif } if (status_ == DATA_START_BLOCK) { spiRead(dst, count); // Transfer data - const uint16_t recvCrc = (spiRec() << 8) | spiRec(); + const uint16_t recvCrc = ((uint16_t)spiRec() << 8) | (uint16_t)spiRec(); #if ENABLED(SD_CHECK_AND_RETRY) success = !crcSupported || recvCrc == CRC_CCITT(dst, count); if (!success) error(SD_CARD_ERROR_READ_CRC); @@ -481,7 +503,9 @@ bool DiskIODriver_SPI_SD::readData(uint8_t *dst, const uint16_t count) { else error(SD_CARD_ERROR_READ); +#ifdef SD_READ_TIMEOUT FAIL: +#endif chipDeselect(); return success; } @@ -578,12 +602,18 @@ bool DiskIODriver_SPI_SD::writeBlock(uint32_t blockNumber, const uint8_t *src) { if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card if (!cardCommand(CMD24, blockNumber)) { if (writeData(DATA_START_BLOCK, src)) { - if (waitNotBusy(SD_WRITE_TIMEOUT)) { // Wait for flashing to complete +#ifdef SD_WRITE_TIMEOUT + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { // Wait for flashing to complete + error(SD_CARD_ERROR_WRITE_TIMEOUT); + } + else +#else + while (spiRec() != 0xFF) {} +#endif + { success = !(cardCommand(CMD13, 0) || spiRec()); // Response is r2 so get and check two bytes for nonzero if (!success) error(SD_CARD_ERROR_WRITE_PROGRAMMING); } - else - error(SD_CARD_ERROR_WRITE_TIMEOUT); } } else @@ -601,15 +631,22 @@ bool DiskIODriver_SPI_SD::writeBlock(uint32_t blockNumber, const uint8_t *src) { bool DiskIODriver_SPI_SD::writeData(const uint8_t *src) { if (ENABLED(SDCARD_READONLY)) return false; - bool success = true; chipSelect(); // Wait for previous write to finish - if (!waitNotBusy(SD_WRITE_TIMEOUT) || !writeData(WRITE_MULTIPLE_TOKEN, src)) { - error(SD_CARD_ERROR_WRITE_MULTIPLE); - success = false; - } +#ifdef SD_WRITE_TIMEOUT + if (!waitNotBusy(SD_WRITE_TIMEOUT)) + goto FAIL; +#else + while (spiRec() != 0xFF) {} +#endif + if (!writeData(WRITE_MULTIPLE_TOKEN, src)) + goto FAIL; chipDeselect(); - return success; + return true; +FAIL: + chipDeselect(); + error(SD_CARD_ERROR_WRITE_MULTIPLE); + return false; } // Send one block of data for write block or write multiple blocks @@ -665,17 +702,31 @@ bool DiskIODriver_SPI_SD::writeStart(uint32_t blockNumber, const uint32_t eraseC bool DiskIODriver_SPI_SD::writeStop() { if (ENABLED(SDCARD_READONLY)) return false; - bool success = false; chipSelect(); - if (waitNotBusy(SD_WRITE_TIMEOUT)) { - spiSend(STOP_TRAN_TOKEN); - success = waitNotBusy(SD_WRITE_TIMEOUT); - } - else +#ifdef SD_WRITE_TIMEOUT + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { error(SD_CARD_ERROR_STOP_TRAN); + goto FAIL; + } +#else + while (spiRec() != 0xFF) {} +#endif + spiSend(STOP_TRAN_TOKEN); +#ifdef SD_WRITE_TIMEOUT + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { + goto FAIL; + } +#else + while (spiRec() != 0xFF) {} +#endif chipDeselect(); - return success; + return true; +#ifdef SD_WRITE_TIMEOUT +FAIL: + chipDeselect(); + return false; +#endif } #endif // NEED_SD2CARD_SPI From 42087fceda1c761608c66c94d0688334a0439b3c Mon Sep 17 00:00:00 2001 From: Martin Turski Date: Sat, 4 Feb 2023 19:14:05 +0100 Subject: [PATCH 2/9] - follow-up improvement --- Marlin/src/sd/Sd2Card.cpp | 8 ++++++-- Marlin/src/sd/Sd2Card.h | 30 ++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp index df28b5e4b90b..0c0fae2c9e50 100644 --- a/Marlin/src/sd/Sd2Card.cpp +++ b/Marlin/src/sd/Sd2Card.cpp @@ -40,8 +40,12 @@ #include "../MarlinCore.h" -#ifndef SD_RETRY_COUNT - #define SD_RETRY_COUNT 3 +#if ENABLED(SD_CHECK_AND_RETRY) + #ifndef SD_RETRY_COUNT + #define SD_RETRY_COUNT 3 + #elif SD_RETRY_COUNT < 1 + #error "SD_RETRY_COUNT has to be at least 1" + #endif #endif #if ENABLED(SD_CHECK_AND_RETRY) diff --git a/Marlin/src/sd/Sd2Card.h b/Marlin/src/sd/Sd2Card.h index e0dce02a0236..06548288bedf 100644 --- a/Marlin/src/sd/Sd2Card.h +++ b/Marlin/src/sd/Sd2Card.h @@ -39,10 +39,32 @@ #include -uint16_t const SD_INIT_TIMEOUT = 2000, // (ms) Init timeout - SD_ERASE_TIMEOUT = 10000, // (ms) Erase timeout - SD_READ_TIMEOUT = 300, // (ms) Read timeout - SD_WRITE_TIMEOUT = 600; // (ms) Write timeout +#ifndef SD_NO_DEFAULT_TIMEOUT + #ifndef SD_INIT_TIMEOUT + // (ms) Init timeout + #define SD_INIT_TIMEOUT 2000u + #elif SD_INIT_TIMEOUT < 0 + #error "SD_INIT_TIMEOUT has to be at least 0" + #endif + #ifndef SD_ERASE_TIMEOUT + // (ms) Erase timeout + #define SD_ERASE_TIMEOUT 10000u + #elif SD_ERASE_TIMEOUT < 0 + #error "SD_ERASE_TIMEOUT has to be at least 0" + #endif + #ifndef SD_READ_TIMEOUT + // (ms) Read timeout + #define SD_READ_TIMEOUT 300u + #elif SD_READ_TIMEOUT < 0 + #error "SD_READ_TIMEOUT has to be at least 0" + #endif + #ifndef SD_WRITE_TIMEOUT + // (ms) Write timeout + #define SD_WRITE_TIMEOUT 600u + #elif SD_WRITE_TIMEOUT < 0 + #error "SD_WRITE_TIMEOUT has to be at least 0" + #endif +#endif //SD_NO_DEFAULT_TIMEOUT // SD card errors typedef enum : uint8_t { From be8729742506a512f3912a1c9cd1a6cfbd85801f Mon Sep 17 00:00:00 2001 From: Martin Turski Date: Sat, 4 Feb 2023 20:27:33 +0100 Subject: [PATCH 3/9] - further support maintainability improvements --- Marlin/src/HAL/STM32/msc_sd.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Marlin/src/HAL/STM32/msc_sd.cpp b/Marlin/src/HAL/STM32/msc_sd.cpp index b6e2ec6dee1e..4d7f05857234 100644 --- a/Marlin/src/HAL/STM32/msc_sd.cpp +++ b/Marlin/src/HAL/STM32/msc_sd.cpp @@ -33,8 +33,10 @@ #define BLOCK_SIZE 512 #define PRODUCT_ID 0x29 -#ifndef SD_MULTIBLOCK_READ_RETRY_CNT - #define SD_MULTIBLOCK_READ_RETRY_CNT 1 +#ifndef SD_MULTIBLOCK_RETRY_CNT + #define SD_MULTIBLOCK_RETRY_CNT 1 +#elif SD_MULTIBLOCK_RETRY_CNT < 1 + #error "SD_MULTIBLOCK_RETRY_CNT has to be at least 1" #endif class Sd2CardUSBMscHandler : public USBMscHandler { @@ -66,7 +68,7 @@ class Sd2CardUSBMscHandler : public USBMscHandler { } // multi block optimization - uint32_t multi_retry_cnt = SD_MULTIBLOCK_READ_RETRY_CNT; + uint32_t multi_retry_cnt = SD_MULTIBLOCK_RETRY_CNT; RETRY_MULTI: uint32 i = blkLen; @@ -99,7 +101,7 @@ class Sd2CardUSBMscHandler : public USBMscHandler { } // multi block optimization - uint32_t multi_retry_cnt = SD_MULTIBLOCK_READ_RETRY_CNT; + uint32_t multi_retry_cnt = SD_MULTIBLOCK_RETRY_CNT; RETRY_MULTI: uint32 i = blkLen; From 39d1970120c2d925f4f92bd7434ebc281ff75a67 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 12 Feb 2023 01:11:25 -0600 Subject: [PATCH 4/9] avoiding goto --- Marlin/src/HAL/STM32/msc_sd.cpp | 80 +++++++++++++++------------------ 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/Marlin/src/HAL/STM32/msc_sd.cpp b/Marlin/src/HAL/STM32/msc_sd.cpp index 4d7f05857234..bcab5fb1d9f7 100644 --- a/Marlin/src/HAL/STM32/msc_sd.cpp +++ b/Marlin/src/HAL/STM32/msc_sd.cpp @@ -68,28 +68,26 @@ class Sd2CardUSBMscHandler : public USBMscHandler { } // multi block optimization - uint32_t multi_retry_cnt = SD_MULTIBLOCK_RETRY_CNT; - - RETRY_MULTI: - uint32 i = blkLen; - uint8_t *cBuf = pBuf; - sd2card->writeStart(blkAddr); - while (i--) { - hal.watchdog_refresh(); - if (sd2card->writeData(cBuf) == false) - { - sd2card->writeStop(); - if (--multi_retry_cnt == 0) - goto FAIL; - multi_retry_cnt--; - goto RETRY_MULTI: + uint16_t rcount = SD_MULTIBLOCK_RETRY_CNT; + bool done = false; + while (!done && rcount--) { + uint8_t *cBuf = pBuf; + sd2card->writeStart(blkAddr); + bool okay = true; // Assume success + for (uint32 i = blkLen; i--;) { + hal.watchdog_refresh(); + if (!sd2card->writeData(cBuf)) { // Write. Did it fail? + sd2card->writeStop(); // writeStop for new writeStart + okay = false; // Failed, so retry + break; // Go to while... below + } + cBuf += BLOCK_SIZE; } - cBuf += BLOCK_SIZE; + done = okay; // Done if no error occurred } - sd2card->writeStop(); - return true; - FAIL: - return false; + + if (done) sd2card->writeStop(); + return done; } bool Read(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) { @@ -101,33 +99,29 @@ class Sd2CardUSBMscHandler : public USBMscHandler { } // multi block optimization - uint32_t multi_retry_cnt = SD_MULTIBLOCK_RETRY_CNT; - - RETRY_MULTI: - uint32 i = blkLen; - uint8_t *cBuf = pBuf; - sd2card->readStart(blkAddr); - while (i--) { - hal.watchdog_refresh(); - if (sd2card->readData(cBuf) == false) - { - sd2card->readStop(); - if (--multi_retry_cnt == 0) - goto FAIL; - multi_retry_cnt--; - goto RETRY_MULTI: + uint16_t rcount = SD_MULTIBLOCK_RETRY_CNT; + bool done = false; + while (!done && rcount--) { + uint8_t *cBuf = pBuf; + sd2card->readStart(blkAddr); + bool okay = true; // Assume success + for (uint32 i = blkLen; i--;) { + hal.watchdog_refresh(); + if (!sd2card->readData(cBuf)) { // Read. Did it fail? + sd2card->readStop(); // readStop for new readStart + okay = false; // Failed, so retry + break; // Go to while... below + } + cBuf += BLOCK_SIZE; } - cBuf += BLOCK_SIZE; + done = okay; // Done if no error occurred } - sd2card->readStop(); - return true; - FAIL: - return false; - } - bool IsReady() { - return diskIODriver()->isReady(); + if (done) sd2card->readStop(); + return done; } + + bool IsReady() { return diskIODriver()->isReady(); } }; Sd2CardUSBMscHandler usbMscHandler; From 2d223afb9645de23a33945eb7732282f2fc42eb6 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 12 Feb 2023 01:22:42 -0600 Subject: [PATCH 5/9] adjust indent --- Marlin/src/HAL/STM32/msc_sd.cpp | 2 +- Marlin/src/sd/Sd2Card.cpp | 183 ++++++++++++++++---------------- Marlin/src/sd/Sd2Card.h | 22 ++-- 3 files changed, 104 insertions(+), 103 deletions(-) diff --git a/Marlin/src/HAL/STM32/msc_sd.cpp b/Marlin/src/HAL/STM32/msc_sd.cpp index bcab5fb1d9f7..97c766eaf5d9 100644 --- a/Marlin/src/HAL/STM32/msc_sd.cpp +++ b/Marlin/src/HAL/STM32/msc_sd.cpp @@ -36,7 +36,7 @@ #ifndef SD_MULTIBLOCK_RETRY_CNT #define SD_MULTIBLOCK_RETRY_CNT 1 #elif SD_MULTIBLOCK_RETRY_CNT < 1 - #error "SD_MULTIBLOCK_RETRY_CNT has to be at least 1" + #error "SD_MULTIBLOCK_RETRY_CNT must be greater than or equal to 1." #endif class Sd2CardUSBMscHandler : public USBMscHandler { diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp index 0c0fae2c9e50..44cc9f299578 100644 --- a/Marlin/src/sd/Sd2Card.cpp +++ b/Marlin/src/sd/Sd2Card.cpp @@ -44,7 +44,7 @@ #ifndef SD_RETRY_COUNT #define SD_RETRY_COUNT 3 #elif SD_RETRY_COUNT < 1 - #error "SD_RETRY_COUNT has to be at least 1" + #error "SD_RETRY_COUNT must be greater than or equal to 1." #endif #endif @@ -105,17 +105,16 @@ uint8_t DiskIODriver_SPI_SD::cardCommand(const uint8_t cmd, const uint32_t arg) // Select card chipSelect(); -#ifdef SD_WRITE_TIMEOUT - // Wait up to 300 ms if busy - waitNotBusy(SD_WRITE_TIMEOUT); -#endif + #ifdef SD_WRITE_TIMEOUT + waitNotBusy(SD_WRITE_TIMEOUT); // Wait up to 300 ms if busy + #endif uint8_t *pa = (uint8_t *)(&arg); #if ENABLED(SD_CHECK_AND_RETRY) // Form message - uint8_t d[6] = {(uint8_t) (cmd | 0x40), pa[3], pa[2], pa[1], pa[0] }; + uint8_t d[6] = { uint8_t(cmd | 0x40), pa[3], pa[2], pa[1], pa[0] }; // Add crc d[5] = CRC7(d, 5); @@ -203,7 +202,7 @@ bool DiskIODriver_SPI_SD::erase(uint32_t firstBlock, uint32_t lastBlock) { if (!csd.v1.erase_blk_en) { // erase size mask uint8_t m = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; - if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) { + if ((firstBlock & m) || ((lastBlock + 1) & m)) { // error card can't erase specified area error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); goto FAIL; @@ -214,16 +213,18 @@ bool DiskIODriver_SPI_SD::erase(uint32_t firstBlock, uint32_t lastBlock) { error(SD_CARD_ERROR_ERASE); goto FAIL; } -#ifdef SD_ERASE_TIMEOUT - if (!waitNotBusy(SD_ERASE_TIMEOUT)) { - error(SD_CARD_ERROR_ERASE_TIMEOUT); - goto FAIL; - } -#else - while (spiRec() != 0xFF) {} -#endif + #ifdef SD_ERASE_TIMEOUT + if (!waitNotBusy(SD_ERASE_TIMEOUT)) { + error(SD_CARD_ERROR_ERASE_TIMEOUT); + goto FAIL; + } + #else + while (spiRec() != 0xFF) {} + #endif + chipDeselect(); return true; + FAIL: chipDeselect(); return false; @@ -260,9 +261,9 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi errorCode_ = type_ = 0; chipSelectPin_ = chipSelectPin; // 16-bit init start time allows over a minute -#ifdef SD_INIT_TIMEOUT - const millis_t init_timeout = millis() + SD_INIT_TIMEOUT; -#endif + #ifdef SD_INIT_TIMEOUT + const millis_t init_timeout = millis() + SD_INIT_TIMEOUT; + #endif uint32_t arg; hal.watchdog_refresh(); // In case init takes too long @@ -290,12 +291,12 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi // Command to go idle in SPI mode while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) { -#ifdef SD_INIT_TIMEOUT - if (ELAPSED(millis(), init_timeout)) { - error(SD_CARD_ERROR_CMD0); - goto FAIL; - } -#endif + #ifdef SD_INIT_TIMEOUT + if (ELAPSED(millis(), init_timeout)) { + error(SD_CARD_ERROR_CMD0); + goto FAIL; + } + #endif } #if ENABLED(SD_CHECK_AND_RETRY) @@ -318,12 +319,12 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi break; } -#ifdef SD_INIT_TIMEOUT - if (ELAPSED(millis(), init_timeout)) { - error(SD_CARD_ERROR_CMD8); - goto FAIL; - } -#endif + #ifdef SD_INIT_TIMEOUT + if (ELAPSED(millis(), init_timeout)) { + error(SD_CARD_ERROR_CMD8); + goto FAIL; + } + #endif } hal.watchdog_refresh(); // In case init takes too long @@ -331,13 +332,13 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi // Initialize card and send host supports SDHC if SD2 arg = type() == SD_CARD_TYPE_SD2 ? 0x40000000 : 0; while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) { -#ifdef SD_INIT_TIMEOUT - // Check for timeout - if (ELAPSED(millis(), init_timeout)) { - error(SD_CARD_ERROR_ACMD41); - goto FAIL; - } -#endif + #ifdef SD_INIT_TIMEOUT + // Check for timeout + if (ELAPSED(millis(), init_timeout)) { + error(SD_CARD_ERROR_ACMD41); + goto FAIL; + } + #endif } // If SD2 read OCR register to check for SDHC card if (type() == SD_CARD_TYPE_SD2) { @@ -480,16 +481,17 @@ bool DiskIODriver_SPI_SD::readData(uint8_t *dst) { bool DiskIODriver_SPI_SD::readData(uint8_t *dst, const uint16_t count) { bool success = false; -#ifdef SD_READ_TIMEOUT - const millis_t read_timeout = millis() + SD_READ_TIMEOUT; -#endif + #ifdef SD_READ_TIMEOUT + const millis_t read_timeout = millis() + SD_READ_TIMEOUT; + #endif + while ((status_ = spiRec()) == 0xFF) { // Wait for start block token -#ifdef SD_READ_TIMEOUT - if (ELAPSED(millis(), read_timeout)) { - error(SD_CARD_ERROR_READ_TIMEOUT); - goto FAIL; - } -#endif + #ifdef SD_READ_TIMEOUT + if (ELAPSED(millis(), read_timeout)) { + error(SD_CARD_ERROR_READ_TIMEOUT); + goto FAIL; + } + #endif } if (status_ == DATA_START_BLOCK) { @@ -507,9 +509,9 @@ bool DiskIODriver_SPI_SD::readData(uint8_t *dst, const uint16_t count) { else error(SD_CARD_ERROR_READ); -#ifdef SD_READ_TIMEOUT - FAIL: -#endif + #ifdef SD_READ_TIMEOUT + FAIL: + #endif chipDeselect(); return success; } @@ -606,15 +608,16 @@ bool DiskIODriver_SPI_SD::writeBlock(uint32_t blockNumber, const uint8_t *src) { if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card if (!cardCommand(CMD24, blockNumber)) { if (writeData(DATA_START_BLOCK, src)) { -#ifdef SD_WRITE_TIMEOUT - if (!waitNotBusy(SD_WRITE_TIMEOUT)) { // Wait for flashing to complete - error(SD_CARD_ERROR_WRITE_TIMEOUT); - } - else -#else - while (spiRec() != 0xFF) {} -#endif - { + #ifdef SD_WRITE_TIMEOUT + if (!waitNotBusy(SD_WRITE_TIMEOUT)) // Wait for flashing to complete + error(SD_CARD_ERROR_WRITE_TIMEOUT); + else + success = true; + #else + while (spiRec() != 0xFF) {} + success = true; + #endif + if (success) { success = !(cardCommand(CMD13, 0) || spiRec()); // Response is r2 so get and check two bytes for nonzero if (!success) error(SD_CARD_ERROR_WRITE_PROGRAMMING); } @@ -637,17 +640,20 @@ bool DiskIODriver_SPI_SD::writeData(const uint8_t *src) { chipSelect(); // Wait for previous write to finish -#ifdef SD_WRITE_TIMEOUT - if (!waitNotBusy(SD_WRITE_TIMEOUT)) - goto FAIL; -#else - while (spiRec() != 0xFF) {} -#endif - if (!writeData(WRITE_MULTIPLE_TOKEN, src)) - goto FAIL; - chipDeselect(); - return true; -FAIL: + #ifdef SD_WRITE_TIMEOUT + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL; + #else + while (spiRec() != 0xFF) {} + #endif + + if (writeData(WRITE_MULTIPLE_TOKEN, src)) { + chipDeselect(); + return true; + } + + #ifdef SD_WRITE_TIMEOUT + FAIL: + #endif chipDeselect(); error(SD_CARD_ERROR_WRITE_MULTIPLE); return false; @@ -707,30 +713,29 @@ bool DiskIODriver_SPI_SD::writeStop() { if (ENABLED(SDCARD_READONLY)) return false; chipSelect(); -#ifdef SD_WRITE_TIMEOUT - if (!waitNotBusy(SD_WRITE_TIMEOUT)) { - error(SD_CARD_ERROR_STOP_TRAN); - goto FAIL; - } -#else - while (spiRec() != 0xFF) {} -#endif + #ifdef SD_WRITE_TIMEOUT + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { + error(SD_CARD_ERROR_STOP_TRAN); + goto FAIL; + } + #else + while (spiRec() != 0xFF) {} + #endif spiSend(STOP_TRAN_TOKEN); -#ifdef SD_WRITE_TIMEOUT - if (!waitNotBusy(SD_WRITE_TIMEOUT)) { - goto FAIL; - } -#else - while (spiRec() != 0xFF) {} -#endif + #ifdef SD_WRITE_TIMEOUT + if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL; + #else + while (spiRec() != 0xFF) {} + #endif chipDeselect(); return true; -#ifdef SD_WRITE_TIMEOUT -FAIL: - chipDeselect(); - return false; -#endif + + #ifdef SD_WRITE_TIMEOUT + FAIL: + chipDeselect(); + return false; + #endif } #endif // NEED_SD2CARD_SPI diff --git a/Marlin/src/sd/Sd2Card.h b/Marlin/src/sd/Sd2Card.h index 06548288bedf..3762a7de635a 100644 --- a/Marlin/src/sd/Sd2Card.h +++ b/Marlin/src/sd/Sd2Card.h @@ -41,30 +41,26 @@ #ifndef SD_NO_DEFAULT_TIMEOUT #ifndef SD_INIT_TIMEOUT - // (ms) Init timeout - #define SD_INIT_TIMEOUT 2000u + #define SD_INIT_TIMEOUT 2000u // (ms) Init timeout #elif SD_INIT_TIMEOUT < 0 - #error "SD_INIT_TIMEOUT has to be at least 0" + #error "SD_INIT_TIMEOUT must be greater than or equal to 0." #endif #ifndef SD_ERASE_TIMEOUT - // (ms) Erase timeout - #define SD_ERASE_TIMEOUT 10000u + #define SD_ERASE_TIMEOUT 10000u // (ms) Erase timeout #elif SD_ERASE_TIMEOUT < 0 - #error "SD_ERASE_TIMEOUT has to be at least 0" + #error "SD_ERASE_TIMEOUT must be greater than or equal to 0." #endif #ifndef SD_READ_TIMEOUT - // (ms) Read timeout - #define SD_READ_TIMEOUT 300u + #define SD_READ_TIMEOUT 300u // (ms) Read timeout #elif SD_READ_TIMEOUT < 0 - #error "SD_READ_TIMEOUT has to be at least 0" + #error "SD_READ_TIMEOUT must be greater than or equal to 0." #endif #ifndef SD_WRITE_TIMEOUT - // (ms) Write timeout - #define SD_WRITE_TIMEOUT 600u + #define SD_WRITE_TIMEOUT 600u // (ms) Write timeout #elif SD_WRITE_TIMEOUT < 0 - #error "SD_WRITE_TIMEOUT has to be at least 0" + #error "SD_WRITE_TIMEOUT must be greater than or equal to 0." #endif -#endif //SD_NO_DEFAULT_TIMEOUT +#endif // SD_NO_DEFAULT_TIMEOUT // SD card errors typedef enum : uint8_t { From 69bb8ce7eea611405aa11c031a1d39799072012a Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 12 Feb 2023 17:42:15 -0600 Subject: [PATCH 6/9] fewer goto --- Marlin/src/HAL/STM32/msc_sd.cpp | 6 +- Marlin/src/sd/Sd2Card.cpp | 173 +++++++++++++++++--------------- 2 files changed, 92 insertions(+), 87 deletions(-) diff --git a/Marlin/src/HAL/STM32/msc_sd.cpp b/Marlin/src/HAL/STM32/msc_sd.cpp index 97c766eaf5d9..f03f533a7195 100644 --- a/Marlin/src/HAL/STM32/msc_sd.cpp +++ b/Marlin/src/HAL/STM32/msc_sd.cpp @@ -68,9 +68,8 @@ class Sd2CardUSBMscHandler : public USBMscHandler { } // multi block optimization - uint16_t rcount = SD_MULTIBLOCK_RETRY_CNT; bool done = false; - while (!done && rcount--) { + for (uint16_t rcount = SD_MULTIBLOCK_RETRY_CNT; !done && rcount--;) { uint8_t *cBuf = pBuf; sd2card->writeStart(blkAddr); bool okay = true; // Assume success @@ -99,9 +98,8 @@ class Sd2CardUSBMscHandler : public USBMscHandler { } // multi block optimization - uint16_t rcount = SD_MULTIBLOCK_RETRY_CNT; bool done = false; - while (!done && rcount--) { + for (uint16_t rcount = SD_MULTIBLOCK_RETRY_CNT; !done && rcount--;) { uint8_t *cBuf = pBuf; sd2card->readStart(blkAddr); bool okay = true; // Assume success diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp index 44cc9f299578..f58969035081 100644 --- a/Marlin/src/sd/Sd2Card.cpp +++ b/Marlin/src/sd/Sd2Card.cpp @@ -195,39 +195,42 @@ void DiskIODriver_SPI_SD::chipSelect() { bool DiskIODriver_SPI_SD::erase(uint32_t firstBlock, uint32_t lastBlock) { if (ENABLED(SDCARD_READONLY)) return false; - csd_t csd; - if (!readCSD(&csd)) goto FAIL; - - // check for single block erase - if (!csd.v1.erase_blk_en) { - // erase size mask - uint8_t m = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; - if ((firstBlock & m) || ((lastBlock + 1) & m)) { - // error card can't erase specified area - error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); - goto FAIL; + bool success = false; + do { + + csd_t csd; + if (!readCSD(&csd)) break; + + // check for single block erase + if (!csd.v1.erase_blk_en) { + // erase size mask + uint8_t m = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low; + if ((firstBlock & m) || ((lastBlock + 1) & m)) { + // error card can't erase specified area + error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); + break; + } } - } - if (type_ != SD_CARD_TYPE_SDHC) { firstBlock <<= 9; lastBlock <<= 9; } - if (cardCommand(CMD32, firstBlock) || cardCommand(CMD33, lastBlock) || cardCommand(CMD38, 0)) { - error(SD_CARD_ERROR_ERASE); - goto FAIL; - } - #ifdef SD_ERASE_TIMEOUT - if (!waitNotBusy(SD_ERASE_TIMEOUT)) { - error(SD_CARD_ERROR_ERASE_TIMEOUT); - goto FAIL; + if (type_ != SD_CARD_TYPE_SDHC) { firstBlock <<= 9; lastBlock <<= 9; } + if (cardCommand(CMD32, firstBlock) || cardCommand(CMD33, lastBlock) || cardCommand(CMD38, 0)) { + error(SD_CARD_ERROR_ERASE); + break; } - #else - while (spiRec() != 0xFF) {} - #endif + #ifdef SD_ERASE_TIMEOUT + if (!waitNotBusy(SD_ERASE_TIMEOUT)) { + error(SD_CARD_ERROR_ERASE_TIMEOUT); + break; + } + #else + while (spiRec() != 0xFF) {} + #endif - chipDeselect(); - return true; + success = true; + + } while (0); - FAIL: chipDeselect(); - return false; + return success; } /** @@ -340,6 +343,7 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi } #endif } + // If SD2 read OCR register to check for SDHC card if (type() == SD_CARD_TYPE_SD2) { if (cardCommand(CMD58, 0)) { @@ -350,6 +354,7 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi // Discard rest of ocr - contains allowed voltage range LOOP_L_N(i, 3) spiRec(); } + chipDeselect(); ready = true; @@ -604,27 +609,23 @@ bool DiskIODriver_SPI_SD::writeBlock(uint32_t blockNumber, const uint8_t *src) { return 0 == SDHC_CardWriteBlock(src, blockNumber); #endif - bool success = false; - if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card - if (!cardCommand(CMD24, blockNumber)) { - if (writeData(DATA_START_BLOCK, src)) { - #ifdef SD_WRITE_TIMEOUT - if (!waitNotBusy(SD_WRITE_TIMEOUT)) // Wait for flashing to complete - error(SD_CARD_ERROR_WRITE_TIMEOUT); - else - success = true; - #else - while (spiRec() != 0xFF) {} - success = true; - #endif - if (success) { - success = !(cardCommand(CMD13, 0) || spiRec()); // Response is r2 so get and check two bytes for nonzero - if (!success) error(SD_CARD_ERROR_WRITE_PROGRAMMING); - } + if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card + bool success = !cardCommand(CMD24, blockNumber); + if (!success) { + error(SD_CARD_ERROR_CMD24); + } + else if (writeData(DATA_START_BLOCK, src)) { + #ifdef SD_WRITE_TIMEOUT + success = waitNotBusy(SD_WRITE_TIMEOUT); // Wait for flashing to complete + if (!success) error(SD_CARD_ERROR_WRITE_TIMEOUT); + #else + while (spiRec() != 0xFF) {} + #endif + if (success) { + success = !(cardCommand(CMD13, 0) || spiRec()); // Response is r2 so get and check two bytes for nonzero + if (!success) error(SD_CARD_ERROR_WRITE_PROGRAMMING); } } - else - error(SD_CARD_ERROR_CMD24); chipDeselect(); return success; @@ -639,24 +640,26 @@ bool DiskIODriver_SPI_SD::writeData(const uint8_t *src) { if (ENABLED(SDCARD_READONLY)) return false; chipSelect(); - // Wait for previous write to finish - #ifdef SD_WRITE_TIMEOUT - if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL; - #else - while (spiRec() != 0xFF) {} - #endif - if (writeData(WRITE_MULTIPLE_TOKEN, src)) { - chipDeselect(); - return true; - } + bool success = false; + do { + + // Wait for previous write to finish + #ifdef SD_WRITE_TIMEOUT + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { + error(SD_CARD_ERROR_WRITE_MULTIPLE); + break; + } + #else + while (spiRec() != 0xFF) {} + #endif + + success = writeData(WRITE_MULTIPLE_TOKEN, src); + + } while (0); - #ifdef SD_WRITE_TIMEOUT - FAIL: - #endif chipDeselect(); - error(SD_CARD_ERROR_WRITE_MULTIPLE); - return false; + return success; } // Send one block of data for write block or write multiple blocks @@ -713,29 +716,33 @@ bool DiskIODriver_SPI_SD::writeStop() { if (ENABLED(SDCARD_READONLY)) return false; chipSelect(); - #ifdef SD_WRITE_TIMEOUT - if (!waitNotBusy(SD_WRITE_TIMEOUT)) { - error(SD_CARD_ERROR_STOP_TRAN); - goto FAIL; - } - #else - while (spiRec() != 0xFF) {} - #endif - spiSend(STOP_TRAN_TOKEN); - #ifdef SD_WRITE_TIMEOUT - if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL; - #else - while (spiRec() != 0xFF) {} - #endif - chipDeselect(); - return true; + bool success = false; + do { - #ifdef SD_WRITE_TIMEOUT - FAIL: - chipDeselect(); - return false; - #endif + #ifdef SD_WRITE_TIMEOUT + if (!waitNotBusy(SD_WRITE_TIMEOUT)) { + error(SD_CARD_ERROR_STOP_TRAN); + break; + } + #else + while (spiRec() != 0xFF) {} + #endif + + spiSend(STOP_TRAN_TOKEN); + + #ifdef SD_WRITE_TIMEOUT + if (!waitNotBusy(SD_WRITE_TIMEOUT)) break; + #else + while (spiRec() != 0xFF) {} + #endif + + success = true; + + } while(0); + + chipDeselect(); + return success; } #endif // NEED_SD2CARD_SPI From 5e426dc8010eb7a80b5ec8e748bd03a05811fc39 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 12 Feb 2023 18:16:21 -0600 Subject: [PATCH 7/9] Fewer #if blocks --- Marlin/src/sd/Sd2Card.cpp | 58 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp index f58969035081..7fe83d5311fa 100644 --- a/Marlin/src/sd/Sd2Card.cpp +++ b/Marlin/src/sd/Sd2Card.cpp @@ -263,10 +263,15 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi errorCode_ = type_ = 0; chipSelectPin_ = chipSelectPin; + // 16-bit init start time allows over a minute - #ifdef SD_INIT_TIMEOUT + #if SD_INIT_TIMEOUT const millis_t init_timeout = millis() + SD_INIT_TIMEOUT; + #define INIT_TIMEOUT() ELAPSED(millis(), init_timeout) + #else + #define INIT_TIMEOUT() false #endif + uint32_t arg; hal.watchdog_refresh(); // In case init takes too long @@ -294,12 +299,10 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi // Command to go idle in SPI mode while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) { - #ifdef SD_INIT_TIMEOUT - if (ELAPSED(millis(), init_timeout)) { - error(SD_CARD_ERROR_CMD0); - goto FAIL; - } - #endif + if (INIT_TIMEOUT()) { + error(SD_CARD_ERROR_CMD0); + goto FAIL; + } } #if ENABLED(SD_CHECK_AND_RETRY) @@ -322,12 +325,10 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi break; } - #ifdef SD_INIT_TIMEOUT - if (ELAPSED(millis(), init_timeout)) { - error(SD_CARD_ERROR_CMD8); - goto FAIL; - } - #endif + if (INIT_TIMEOUT()) { + error(SD_CARD_ERROR_CMD8); + goto FAIL; + } } hal.watchdog_refresh(); // In case init takes too long @@ -335,13 +336,11 @@ bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPi // Initialize card and send host supports SDHC if SD2 arg = type() == SD_CARD_TYPE_SD2 ? 0x40000000 : 0; while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) { - #ifdef SD_INIT_TIMEOUT - // Check for timeout - if (ELAPSED(millis(), init_timeout)) { - error(SD_CARD_ERROR_ACMD41); - goto FAIL; - } - #endif + // Check for timeout + if (INIT_TIMEOUT()) { + error(SD_CARD_ERROR_ACMD41); + goto FAIL; + } } // If SD2 read OCR register to check for SDHC card @@ -486,17 +485,18 @@ bool DiskIODriver_SPI_SD::readData(uint8_t *dst) { bool DiskIODriver_SPI_SD::readData(uint8_t *dst, const uint16_t count) { bool success = false; - #ifdef SD_READ_TIMEOUT + #if SD_READ_TIMEOUT const millis_t read_timeout = millis() + SD_READ_TIMEOUT; + #define READ_TIMEOUT() ELAPSED(millis(), read_timeout) + #else + #define READ_TIMEOUT() false #endif while ((status_ = spiRec()) == 0xFF) { // Wait for start block token - #ifdef SD_READ_TIMEOUT - if (ELAPSED(millis(), read_timeout)) { - error(SD_CARD_ERROR_READ_TIMEOUT); - goto FAIL; - } - #endif + if (READ_TIMEOUT()) { + error(SD_CARD_ERROR_READ_TIMEOUT); + goto FAIL; + } } if (status_ == DATA_START_BLOCK) { @@ -514,9 +514,7 @@ bool DiskIODriver_SPI_SD::readData(uint8_t *dst, const uint16_t count) { else error(SD_CARD_ERROR_READ); - #ifdef SD_READ_TIMEOUT - FAIL: - #endif + FAIL: chipDeselect(); return success; } From dc318343791d652f0cfc3570781d4eac9cf3171a Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 12 Feb 2023 18:19:36 -0600 Subject: [PATCH 8/9] localize some defines --- Marlin/src/sd/Sd2Card.cpp | 23 +++++++++++++++++++++++ Marlin/src/sd/Sd2Card.h | 23 ----------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp index 7fe83d5311fa..f1baf38a19ac 100644 --- a/Marlin/src/sd/Sd2Card.cpp +++ b/Marlin/src/sd/Sd2Card.cpp @@ -40,6 +40,29 @@ #include "../MarlinCore.h" +#if DISABLED(SD_NO_DEFAULT_TIMEOUT) + #ifndef SD_INIT_TIMEOUT + #define SD_INIT_TIMEOUT 2000u // (ms) Init timeout + #elif SD_INIT_TIMEOUT < 0 + #error "SD_INIT_TIMEOUT must be greater than or equal to 0." + #endif + #ifndef SD_ERASE_TIMEOUT + #define SD_ERASE_TIMEOUT 10000u // (ms) Erase timeout + #elif SD_ERASE_TIMEOUT < 0 + #error "SD_ERASE_TIMEOUT must be greater than or equal to 0." + #endif + #ifndef SD_READ_TIMEOUT + #define SD_READ_TIMEOUT 300u // (ms) Read timeout + #elif SD_READ_TIMEOUT < 0 + #error "SD_READ_TIMEOUT must be greater than or equal to 0." + #endif + #ifndef SD_WRITE_TIMEOUT + #define SD_WRITE_TIMEOUT 600u // (ms) Write timeout + #elif SD_WRITE_TIMEOUT < 0 + #error "SD_WRITE_TIMEOUT must be greater than or equal to 0." + #endif +#endif // SD_NO_DEFAULT_TIMEOUT + #if ENABLED(SD_CHECK_AND_RETRY) #ifndef SD_RETRY_COUNT #define SD_RETRY_COUNT 3 diff --git a/Marlin/src/sd/Sd2Card.h b/Marlin/src/sd/Sd2Card.h index 3762a7de635a..20cc1c9a7ea7 100644 --- a/Marlin/src/sd/Sd2Card.h +++ b/Marlin/src/sd/Sd2Card.h @@ -39,29 +39,6 @@ #include -#ifndef SD_NO_DEFAULT_TIMEOUT - #ifndef SD_INIT_TIMEOUT - #define SD_INIT_TIMEOUT 2000u // (ms) Init timeout - #elif SD_INIT_TIMEOUT < 0 - #error "SD_INIT_TIMEOUT must be greater than or equal to 0." - #endif - #ifndef SD_ERASE_TIMEOUT - #define SD_ERASE_TIMEOUT 10000u // (ms) Erase timeout - #elif SD_ERASE_TIMEOUT < 0 - #error "SD_ERASE_TIMEOUT must be greater than or equal to 0." - #endif - #ifndef SD_READ_TIMEOUT - #define SD_READ_TIMEOUT 300u // (ms) Read timeout - #elif SD_READ_TIMEOUT < 0 - #error "SD_READ_TIMEOUT must be greater than or equal to 0." - #endif - #ifndef SD_WRITE_TIMEOUT - #define SD_WRITE_TIMEOUT 600u // (ms) Write timeout - #elif SD_WRITE_TIMEOUT < 0 - #error "SD_WRITE_TIMEOUT must be greater than or equal to 0." - #endif -#endif // SD_NO_DEFAULT_TIMEOUT - // SD card errors typedef enum : uint8_t { SD_CARD_ERROR_CMD0 = 0x01, // Timeout error for command CMD0 (initialize card in SPI mode) From c07490baaa2e039d8c9d832129b23fd3f5a1f09b Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 13 Feb 2023 16:31:18 -0600 Subject: [PATCH 9/9] Allow 0 for no timeout --- Marlin/src/sd/Sd2Card.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp index f1baf38a19ac..faed61f9f091 100644 --- a/Marlin/src/sd/Sd2Card.cpp +++ b/Marlin/src/sd/Sd2Card.cpp @@ -128,8 +128,8 @@ uint8_t DiskIODriver_SPI_SD::cardCommand(const uint8_t cmd, const uint32_t arg) // Select card chipSelect(); - #ifdef SD_WRITE_TIMEOUT - waitNotBusy(SD_WRITE_TIMEOUT); // Wait up to 300 ms if busy + #if SD_WRITE_TIMEOUT + waitNotBusy(SD_WRITE_TIMEOUT); // Wait up to 600 ms (by default) if busy #endif uint8_t *pa = (uint8_t *)(&arg); @@ -239,7 +239,7 @@ bool DiskIODriver_SPI_SD::erase(uint32_t firstBlock, uint32_t lastBlock) { error(SD_CARD_ERROR_ERASE); break; } - #ifdef SD_ERASE_TIMEOUT + #if SD_ERASE_TIMEOUT if (!waitNotBusy(SD_ERASE_TIMEOUT)) { error(SD_CARD_ERROR_ERASE_TIMEOUT); break; @@ -636,7 +636,7 @@ bool DiskIODriver_SPI_SD::writeBlock(uint32_t blockNumber, const uint8_t *src) { error(SD_CARD_ERROR_CMD24); } else if (writeData(DATA_START_BLOCK, src)) { - #ifdef SD_WRITE_TIMEOUT + #if SD_WRITE_TIMEOUT success = waitNotBusy(SD_WRITE_TIMEOUT); // Wait for flashing to complete if (!success) error(SD_CARD_ERROR_WRITE_TIMEOUT); #else @@ -666,7 +666,7 @@ bool DiskIODriver_SPI_SD::writeData(const uint8_t *src) { do { // Wait for previous write to finish - #ifdef SD_WRITE_TIMEOUT + #if SD_WRITE_TIMEOUT if (!waitNotBusy(SD_WRITE_TIMEOUT)) { error(SD_CARD_ERROR_WRITE_MULTIPLE); break; @@ -741,7 +741,7 @@ bool DiskIODriver_SPI_SD::writeStop() { bool success = false; do { - #ifdef SD_WRITE_TIMEOUT + #if SD_WRITE_TIMEOUT if (!waitNotBusy(SD_WRITE_TIMEOUT)) { error(SD_CARD_ERROR_STOP_TRAN); break; @@ -752,7 +752,7 @@ bool DiskIODriver_SPI_SD::writeStop() { spiSend(STOP_TRAN_TOKEN); - #ifdef SD_WRITE_TIMEOUT + #if SD_WRITE_TIMEOUT if (!waitNotBusy(SD_WRITE_TIMEOUT)) break; #else while (spiRec() != 0xFF) {} @@ -760,7 +760,7 @@ bool DiskIODriver_SPI_SD::writeStop() { success = true; - } while(0); + } while (0); chipDeselect(); return success;