Skip to content

Commit

Permalink
🔧 Configurable SD card retry/timeout (MarlinFirmware#25340)
Browse files Browse the repository at this point in the history
Co-authored-by: Scott Lahteine <[email protected]>
  • Loading branch information
2 people authored and EvilGremlin committed Oct 26, 2023
1 parent a5d8d36 commit f179d59
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 86 deletions.
66 changes: 45 additions & 21 deletions Marlin/src/HAL/STM32/msc_sd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
#define BLOCK_SIZE 512
#define PRODUCT_ID 0x29

#ifndef SD_MULTIBLOCK_RETRY_CNT
#define SD_MULTIBLOCK_RETRY_CNT 1
#elif SD_MULTIBLOCK_RETRY_CNT < 1
#error "SD_MULTIBLOCK_RETRY_CNT must be greater than or equal to 1."
#endif

class Sd2CardUSBMscHandler : public USBMscHandler {
public:
DiskIODriver* diskIODriver() {
Expand All @@ -58,44 +64,62 @@ 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--) {
hal.watchdog_refresh();
sd2card->writeData(pBuf);
pBuf += BLOCK_SIZE;
bool done = false;
for (uint16_t rcount = SD_MULTIBLOCK_RETRY_CNT; !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;
}
done = okay; // Done if no error occurred
}
sd2card->writeStop();
return true;

if (done) sd2card->writeStop();
return done;
}

bool Read(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) {
auto sd2card = diskIODriver();
// single block
if (blkLen == 1) {
hal.watchdog_refresh();
sd2card->readBlock(blkAddr, pBuf);
return true;
return sd2card->readBlock(blkAddr, pBuf);
}

// multi block optimization
sd2card->readStart(blkAddr);
while (blkLen--) {
hal.watchdog_refresh();
sd2card->readData(pBuf);
pBuf += BLOCK_SIZE;
bool done = false;
for (uint16_t rcount = SD_MULTIBLOCK_RETRY_CNT; !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;
}
done = okay; // Done if no error occurred
}
sd2card->readStop();
return true;
}

bool IsReady() {
return diskIODriver()->isReady();
if (done) sd2card->readStop();
return done;
}

bool IsReady() { return diskIODriver()->isReady(); }
};

Sd2CardUSBMscHandler usbMscHandler;
Expand Down
Loading

0 comments on commit f179d59

Please sign in to comment.