diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp
index f746a22773..4392c06b28 100644
--- a/Marlin/src/sd/Sd2Card.cpp
+++ b/Marlin/src/sd/Sd2Card.cpp
@@ -23,6 +23,7 @@
 /**
  * Arduino Sd2Card Library
  * Copyright (C) 2009 by William Greiman
+ * Updated with backports of the latest SdFat library from the same author
  *
  * This file is part of the Arduino Sd2Card Library
  */
@@ -31,29 +32,92 @@
 
 #if ENABLED(SDSUPPORT)
 
+/* Enable FAST CRC computations - You can trade speed for FLASH space if
+ * needed by disabling the following define */
+#define FAST_CRC 1
+
 #include "Sd2Card.h"
 
 #include "../Marlin.h"
 
+#if ENABLED(SD_CHECK_AND_RETRY)
+  #ifdef FAST_CRC
+    static const uint8_t crctab7[] PROGMEM = {
+      0x00,0x09,0x12,0x1b,0x24,0x2d,0x36,0x3f,0x48,0x41,0x5a,0x53,0x6c,0x65,0x7e,0x77,
+      0x19,0x10,0x0b,0x02,0x3d,0x34,0x2f,0x26,0x51,0x58,0x43,0x4a,0x75,0x7c,0x67,0x6e,
+      0x32,0x3b,0x20,0x29,0x16,0x1f,0x04,0x0d,0x7a,0x73,0x68,0x61,0x5e,0x57,0x4c,0x45,
+      0x2b,0x22,0x39,0x30,0x0f,0x06,0x1d,0x14,0x63,0x6a,0x71,0x78,0x47,0x4e,0x55,0x5c,
+      0x64,0x6d,0x76,0x7f,0x40,0x49,0x52,0x5b,0x2c,0x25,0x3e,0x37,0x08,0x01,0x1a,0x13,
+      0x7d,0x74,0x6f,0x66,0x59,0x50,0x4b,0x42,0x35,0x3c,0x27,0x2e,0x11,0x18,0x03,0x0a,
+      0x56,0x5f,0x44,0x4d,0x72,0x7b,0x60,0x69,0x1e,0x17,0x0c,0x05,0x3a,0x33,0x28,0x21,
+      0x4f,0x46,0x5d,0x54,0x6b,0x62,0x79,0x70,0x07,0x0e,0x15,0x1c,0x23,0x2a,0x31,0x38,
+      0x41,0x48,0x53,0x5a,0x65,0x6c,0x77,0x7e,0x09,0x00,0x1b,0x12,0x2d,0x24,0x3f,0x36,
+      0x58,0x51,0x4a,0x43,0x7c,0x75,0x6e,0x67,0x10,0x19,0x02,0x0b,0x34,0x3d,0x26,0x2f,
+      0x73,0x7a,0x61,0x68,0x57,0x5e,0x45,0x4c,0x3b,0x32,0x29,0x20,0x1f,0x16,0x0d,0x04,
+      0x6a,0x63,0x78,0x71,0x4e,0x47,0x5c,0x55,0x22,0x2b,0x30,0x39,0x06,0x0f,0x14,0x1d,
+      0x25,0x2c,0x37,0x3e,0x01,0x08,0x13,0x1a,0x6d,0x64,0x7f,0x76,0x49,0x40,0x5b,0x52,
+      0x3c,0x35,0x2e,0x27,0x18,0x11,0x0a,0x03,0x74,0x7d,0x66,0x6f,0x50,0x59,0x42,0x4b,
+      0x17,0x1e,0x05,0x0c,0x33,0x3a,0x21,0x28,0x5f,0x56,0x4d,0x44,0x7b,0x72,0x69,0x60,
+      0x0e,0x07,0x1c,0x15,0x2a,0x23,0x38,0x31,0x46,0x4f,0x54,0x5d,0x62,0x6b,0x70,0x79
+    };
+
+    static uint8_t CRC7(const uint8_t* data, uint8_t n) {
+      uint8_t crc = 0;
+      while ( n > 0 ) {
+        crc = pgm_read_byte(&crctab7[ (crc << 1) ^ *data++ ]);
+        n--;
+      }
+      return (crc << 1) | 1;
+    }
+  #else
+    static uint8_t CRC7(const uint8_t* data, uint8_t n) {
+      uint8_t crc = 0;
+      for (uint8_t i = 0; i < n; i++) {
+        uint8_t d = data[i];
+        d ^= crc << 1;
+        if (d & 0x80) d ^= 9;
+        crc = d ^ (crc & 0x78) ^ (crc << 4) ^ ((crc >> 3) & 15);
+        crc &= 0x7f;
+      }
+      crc = (crc << 1) ^ (crc << 4) ^ (crc & 0x70) ^ ((crc >> 3) & 0x0f);
+      return crc | 1;
+    }
+  #endif
+#endif
+
 // send command and return error code.  Return zero for OK
 uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
   // select card
-  chipSelectLow();
+  chipSelect();
 
   // wait up to 300 ms if busy
-  waitNotBusy(300);
+  waitNotBusy( SD_WRITE_TIMEOUT );
 
+  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] };
+
+  // add crc
+  d[5] = CRC7(d, 5);
+
+  // send message
+  for (uint8_t k = 0; k < 6; k++ )
+    spiSend( d[k] );
+
+#else
   // send command
   spiSend(cmd | 0x40);
 
   // send argument
-  for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s);
+  for( int8_t i = 3; i >= 0; i-- )
+    spiSend( pa[i] );
 
-  // send CRC
-  uint8_t crc = 0xFF;
-  if (cmd == CMD0) crc = 0x95;  // correct crc for CMD0 with arg 0
-  if (cmd == CMD8) crc = 0x87;  // correct crc for CMD8 with arg 0x1AA
-  spiSend(crc);
+  // send CRC - correct for CMD0 with arg zero or CMD8 with arg 0X1AA
+  spiSend( cmd == CMD0 ? 0X95 : 0X87 );
+#endif
 
   // skip stuff byte for stop read
   if (cmd == CMD12) spiRec();
@@ -91,14 +155,15 @@ uint32_t Sd2Card::cardSize() {
   }
 }
 
-void Sd2Card::chipSelectHigh() {
+void Sd2Card::chipDeselect() {
   digitalWrite(chipSelectPin_, HIGH);
+
+  // insure MISO goes high impedance
+  spiSend( 0xFF );
 }
 
-void Sd2Card::chipSelectLow() {
-  #if DISABLED(SOFTWARE_SPI)
-    spiInit(spiRate_);
-  #endif  // SOFTWARE_SPI
+void Sd2Card::chipSelect() {
+  spiInit(spiRate_);
   digitalWrite(chipSelectPin_, LOW);
 }
 
@@ -142,10 +207,10 @@ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
     error(SD_CARD_ERROR_ERASE_TIMEOUT);
     goto FAIL;
   }
-  chipSelectHigh();
+  chipDeselect();
   return true;
   FAIL:
-  chipSelectHigh();
+  chipDeselect();
   return false;
 }
 
@@ -200,22 +265,36 @@ bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) {
       goto FAIL;
     }
   }
-  // check SD version
-  if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
-    type(SD_CARD_TYPE_SD1);
+
+#if ENABLED(SD_CHECK_AND_RETRY)
+  if (cardCommand( CMD59, 1 ) != R1_IDLE_STATE) {
+    error(SD_CARD_ERROR_CMD59);
+    goto FAIL;
   }
-  else {
+#endif
+
+  // check SD version
+  while (1) {
+    if (cardCommand(CMD8, 0x1AA) == (R1_ILLEGAL_COMMAND | R1_IDLE_STATE)) {
+    type(SD_CARD_TYPE_SD1);
+      break;
+  }
+
     // only need last byte of r7 response
     for (uint8_t i = 0; i < 4; i++) status_ = spiRec();
-    if (status_ != 0xAA) {
+    if (status_ == 0xAA) {
+      type(SD_CARD_TYPE_SD2);
+      break;
+    }
+
+    if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
       error(SD_CARD_ERROR_CMD8);
       goto FAIL;
     }
-    type(SD_CARD_TYPE_SD2);
   }
+
   // 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) {
     // check for timeout
     if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
@@ -233,17 +312,12 @@ bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) {
     // discard rest of ocr - contains allowed voltage range
     for (uint8_t i = 0; i < 3; i++) spiRec();
   }
-  chipSelectHigh();
+  chipDeselect();
 
-  #if DISABLED(SOFTWARE_SPI)
-    return setSckRate(sckRateID);
-  #else  // SOFTWARE_SPI
-    UNUSED(sckRateID);
-    return true;
-  #endif  // SOFTWARE_SPI
+  return setSckRate(sckRateID);
 
   FAIL:
-  chipSelectHigh();
+  chipDeselect();
   return false;
 }
 
@@ -268,7 +342,7 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
 
       if (!--retryCnt) break;
 
-      chipSelectHigh();
+      chipDeselect();
       cardCommand(CMD12, 0); // Try sending a stop command, ignore the result.
       errorCode_ = 0;
     }
@@ -279,7 +353,7 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
       return readData(dst, 512);
   #endif
 
-  chipSelectHigh();
+  chipDeselect();
   return false;
 }
 
@@ -291,12 +365,13 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
  * \return true for success, false for failure.
  */
 bool Sd2Card::readData(uint8_t* dst) {
-  chipSelectLow();
+  chipSelect();
   return readData(dst, 512);
 }
 
 #if ENABLED(SD_CHECK_AND_RETRY)
-  static const uint16_t crctab[] PROGMEM = {
+  #ifdef FAST_CRC
+  static const uint16_t crctab16[] PROGMEM = {
     0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
     0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
     0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
@@ -330,13 +405,30 @@ bool Sd2Card::readData(uint8_t* dst) {
     0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
     0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
   };
+    // faster CRC-CCITT
+    // uses the x^16,x^12,x^5,x^1 polynomial.
   static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
     uint16_t crc = 0;
     for (size_t i = 0; i < n; i++) {
-      crc = pgm_read_word(&crctab[(crc >> 8 ^ data[i]) & 0xFF]) ^ (crc << 8);
+      crc = pgm_read_word(&crctab16[(crc >> 8 ^ data[i]) & 0xFF]) ^ (crc << 8);
     }
     return crc;
   }
+  #else
+    // slower CRC-CCITT
+    // uses the x^16,x^12,x^5,x^1 polynomial.
+    static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
+      uint16_t crc = 0;
+      for (size_t i = 0; i < n; i++) {
+        crc = (uint8_t)(crc >> 8) | (crc << 8);
+        crc ^= data[i];
+        crc ^= (uint8_t)(crc & 0xff) >> 4;
+        crc ^= crc << 12;
+        crc ^= (crc & 0xff) << 5;
+      }
+      return crc;
+    }
+  #endif
 #endif // SD_CHECK_AND_RETRY
 
 bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
@@ -357,11 +449,9 @@ bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
 
 #if ENABLED(SD_CHECK_AND_RETRY)
   {
-    uint16_t calcCrc = CRC_CCITT(dst, count);
-    uint16_t recvCrc = spiRec() << 8;
-    recvCrc |= spiRec();
-    if (calcCrc != recvCrc) {
-      error(SD_CARD_ERROR_CRC);
+    uint16_t recvCrc = (spiRec() << 8) | spiRec();
+    if (recvCrc != CRC_CCITT(dst, count)) {
+      error(SD_CARD_ERROR_READ_CRC);
       goto FAIL;
     }
   }
@@ -370,14 +460,10 @@ bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
   spiRec();
   spiRec();
 #endif
-  chipSelectHigh();
-  // Send an additional dummy byte, required by Toshiba Flash Air SD Card
-  spiSend(0xFF);
+  chipDeselect();
   return true;
   FAIL:
-  chipSelectHigh();
-  // Send an additional dummy byte, required by Toshiba Flash Air SD Card
-  spiSend(0xFF);
+  chipDeselect();
   return false;
 }
 
@@ -386,7 +472,7 @@ bool Sd2Card::readRegister(uint8_t cmd, void* buf) {
   uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
   if (cardCommand(cmd, 0)) {
     error(SD_CARD_ERROR_READ_REG);
-    chipSelectHigh();
+    chipDeselect();
     return false;
   }
   return readData(dst, 16);
@@ -406,10 +492,10 @@ bool Sd2Card::readStart(uint32_t blockNumber) {
   if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
   if (cardCommand(CMD18, blockNumber)) {
     error(SD_CARD_ERROR_CMD18);
-    chipSelectHigh();
+    chipDeselect();
     return false;
   }
-  chipSelectHigh();
+  chipDeselect();
   return true;
 }
 
@@ -419,13 +505,13 @@ bool Sd2Card::readStart(uint32_t blockNumber) {
  * \return true for success, false for failure.
  */
 bool Sd2Card::readStop() {
-  chipSelectLow();
+  chipSelect();
   if (cardCommand(CMD12, 0)) {
     error(SD_CARD_ERROR_CMD12);
-    chipSelectHigh();
+    chipDeselect();
     return false;
   }
-  chipSelectHigh();
+  chipDeselect();
   return true;
 }
 
@@ -485,10 +571,10 @@ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
     error(SD_CARD_ERROR_WRITE_PROGRAMMING);
     goto FAIL;
   }
-  chipSelectHigh();
+  chipDeselect();
   return true;
   FAIL:
-  chipSelectHigh();
+  chipDeselect();
   return false;
 }
 
@@ -498,28 +584,33 @@ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
  * \return true for success, false for failure.
  */
 bool Sd2Card::writeData(const uint8_t* src) {
-  chipSelectLow();
+  chipSelect();
   // wait for previous write to finish
   if (!waitNotBusy(SD_WRITE_TIMEOUT) || !writeData(WRITE_MULTIPLE_TOKEN, src)) {
     error(SD_CARD_ERROR_WRITE_MULTIPLE);
-    chipSelectHigh();
+    chipDeselect();
     return false;
   }
-  chipSelectHigh();
+  chipDeselect();
   return true;
 }
 
 // send one block of data for write block or write multiple blocks
 bool Sd2Card::writeData(uint8_t token, const uint8_t* src) {
-  spiSendBlock(token, src);
 
-  spiSend(0xFF);  // dummy crc
-  spiSend(0xFF);  // dummy crc
+#if ENABLED(SD_CHECK_AND_RETRY)
+  uint16_t crc = CRC_CCITT( src, 512 );
+#else  // ENABLED(SD_CHECK_AND_RETRY)
+  uint16_t crc = 0xFFFF;
+#endif  // ENABLED(SD_CHECK_AND_RETRY)
+  spiSendBlock( token, src );
+  spiSend( crc >> 8 );
+  spiSend( crc & 0XFF );
 
   status_ = spiRec();
   if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
     error(SD_CARD_ERROR_WRITE);
-    chipSelectHigh();
+    chipDeselect();
     return false;
   }
   return true;
@@ -548,10 +639,10 @@ bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
     error(SD_CARD_ERROR_CMD25);
     goto FAIL;
   }
-  chipSelectHigh();
+  chipDeselect();
   return true;
   FAIL:
-  chipSelectHigh();
+  chipDeselect();
   return false;
 }
 
@@ -561,15 +652,15 @@ bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
  * \return true for success, false for failure.
  */
 bool Sd2Card::writeStop() {
-  chipSelectLow();
+  chipSelect();
   if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL;
   spiSend(STOP_TRAN_TOKEN);
   if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL;
-  chipSelectHigh();
+  chipDeselect();
   return true;
   FAIL:
   error(SD_CARD_ERROR_STOP_TRAN);
-  chipSelectHigh();
+  chipDeselect();
   return false;
 }
 
diff --git a/Marlin/src/sd/Sd2Card.h b/Marlin/src/sd/Sd2Card.h
index 6187db7016..65633aa8c1 100644
--- a/Marlin/src/sd/Sd2Card.h
+++ b/Marlin/src/sd/Sd2Card.h
@@ -71,7 +71,8 @@ uint8_t const SD_CARD_ERROR_CMD0 = 0x01,                // timeout error for com
               SD_CARD_ERROR_WRITE_TIMEOUT = 0x17,       // timeout occurred during write programming
               SD_CARD_ERROR_SCK_RATE = 0x18,            // incorrect rate selected
               SD_CARD_ERROR_INIT_NOT_CALLED = 0x19,     // init() not called
-              SD_CARD_ERROR_CRC = 0x20;                 // crc check error
+              SD_CARD_ERROR_CMD59 = 0x1A,               // card returned an error for CMD59 (CRC_ON_OFF)
+              SD_CARD_ERROR_READ_CRC = 0x1B;            // invalid read CRC
 
 // card types
 uint8_t const SD_CARD_TYPE_SD1  = 1,                    // Standard capacity V1 SD card
@@ -196,8 +197,8 @@ class Sd2Card {
 
   bool readData(uint8_t* dst, uint16_t count);
   bool readRegister(uint8_t cmd, void* buf);
-  void chipSelectHigh();
-  void chipSelectLow();
+  void chipDeselect();
+  void chipSelect();
   void type(uint8_t value) { type_ = value; }
   bool waitNotBusy(uint16_t timeoutMillis);
   bool writeData(uint8_t token, const uint8_t* src);
diff --git a/Marlin/src/sd/SdInfo.h b/Marlin/src/sd/SdInfo.h
index 9fe121f168..91cb35da9e 100644
--- a/Marlin/src/sd/SdInfo.h
+++ b/Marlin/src/sd/SdInfo.h
@@ -54,12 +54,13 @@ uint8_t const CMD0 = 0x00,    // GO_IDLE_STATE - init card in spi mode if CS low
               CMD24 = 0x18,   // WRITE_BLOCK - write a single data block to the card
               CMD25 = 0x19,   // WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION
               CMD32 = 0x20,   // ERASE_WR_BLK_START - sets the address of the first block to be erased
-              CMD33 = 0x21,   // ERASE_WR_BLK_END - sets the address of the last block of the continuous range to be erased*/
-              CMD38 = 0x26,   // ERASE - erase all previously selected blocks */
-              CMD55 = 0x37,   // APP_CMD - escape for application specific command */
-              CMD58 = 0x3A,   // READ_OCR - read the OCR register of a card */
-              ACMD23 = 0x17,  // SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be pre-erased before writing */
-              ACMD41 = 0x29;  // SD_SEND_OP_COMD - Sends host capacity support information and activates the card's initialization process */
+              CMD33 = 0x21,   // ERASE_WR_BLK_END - sets the address of the last block of the continuous range to be erased
+              CMD38 = 0x26,   // ERASE - erase all previously selected blocks
+              CMD55 = 0x37,   // APP_CMD - escape for application specific command
+              CMD58 = 0x3A,   // READ_OCR - read the OCR register of a card
+              CMD59 = 0x3B,   // CRC_ON_OFF - enable or disable CRC checking
+              ACMD23 = 0x17,  // SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be pre-erased before writing
+              ACMD41 = 0x29;  // SD_SEND_OP_COMD - Sends host capacity support information and activates the card's initialization process
 
 /** status for card in the ready state */
 uint8_t const R1_READY_STATE = 0x00;