@@ -32,7 +32,7 @@ | |||
#endif // ARDUINO | |||
//------------------------------------------------------------------------------ | |||
/** SdFat version YYYYMMDD */ | |||
#define SD_FAT_VERSION 20160427 | |||
#define SD_FAT_VERSION 20160430 | |||
//============================================================================== | |||
/** | |||
* \class SdBaseFile |
@@ -88,6 +88,8 @@ uint8_t const SD_CARD_ERROR_CMD59 = 0X1A; | |||
uint8_t const SD_CARD_ERROR_READ_CRC = 0X1B; | |||
/** SPI DMA error */ | |||
uint8_t const SD_CARD_ERROR_SPI_DMA = 0X1C; | |||
/** CMD6 not accepted */ | |||
uint8_t const SD_CARD_ERROR_CMD6 = 0X1D; | |||
//------------------------------------------------------------------------------ | |||
// card types | |||
/** Standard capacity V1 SD card */ | |||
@@ -126,6 +128,8 @@ unsigned const SD_WRITE_TIMEOUT = 600; | |||
// SD card commands | |||
/** GO_IDLE_STATE - init card in spi mode if CS low */ | |||
uint8_t const CMD0 = 0X00; | |||
/** SWITCH_FUNC - Switch Function Command */ | |||
uint8_t const CMD6 = 0X06; | |||
/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ | |||
uint8_t const CMD8 = 0X08; | |||
/** SEND_CSD - read the Card Specific Data (CSD register) */ |
@@ -503,6 +503,35 @@ fail: | |||
return false; | |||
} | |||
//------------------------------------------------------------------------------ | |||
bool SdSpiCard::sendCmd6(uint32_t arg, uint8_t* status) { | |||
if (cardCommand(CMD6, arg)) { | |||
error(SD_CARD_ERROR_CMD6); | |||
goto fail; | |||
} | |||
if (!readData(status, 64)) { | |||
goto fail; | |||
} | |||
chipSelectHigh(); | |||
return true; | |||
fail: | |||
chipSelectHigh(); | |||
return false; | |||
} | |||
//------------------------------------------------------------------------------ | |||
bool SdSpiCard::setHighSpeedMode(uint8_t divisor) { | |||
uint8_t status[64]; | |||
uint8_t saveDivisor = m_sckDivisor; | |||
setSckDivisor(128); | |||
if (!sendCmd6(0X00FFFFFF, status) || (2 & status[13]) == 0 || | |||
!sendCmd6(0X80FFFFF1, status) || (status[16] & 0XF) != 1) { | |||
setSckDivisor(saveDivisor); | |||
return false; | |||
} | |||
setSckDivisor(divisor); | |||
return true; | |||
} | |||
//------------------------------------------------------------------------------ | |||
// wait for card to go not busy | |||
bool SdSpiCard::waitNotBusy(uint16_t timeoutMillis) { | |||
unsigned t0 = millis(); |
@@ -193,6 +193,25 @@ class SdSpiCard { | |||
} | |||
/** \return the SD chip select status, true if slected else false. */ | |||
bool selected() {return m_selected;} | |||
/** Send CMD6 - Switch Function Command | |||
* | |||
* param[in] arg 32-bit argument to CMD6. | |||
* param[out] status - 64 byte status returned by CMD6. | |||
* \return true if the command was accepted else false. | |||
*/ | |||
bool sendCmd6(uint32_t arg, uint8_t* status); | |||
/** Set High Speed Bus Mode. | |||
* | |||
* param[in] divisor new value for SPI SCK divisor. | |||
* \return true if successful else false. | |||
*/ | |||
bool setHighSpeedMode(uint8_t divisor); | |||
/** Set SCK divisor. | |||
* param[in] sckDivisor value for divisor. | |||
*/ | |||
void setSckDivisor(uint8_t sckDivisor) { | |||
m_sckDivisor = sckDivisor; | |||
} | |||
/** Return the card type: SD V1, SD V2 or SDHC | |||
* \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. | |||
*/ |