Browse Source

More carefully balance chip select low/high

main
PaulStoffregen 8 years ago
parent
commit
4ae02baf25
2 changed files with 10 additions and 38 deletions
  1. +10
    -36
      utility/Sd2Card.cpp
  2. +0
    -2
      utility/Sd2Card.h

+ 10
- 36
utility/Sd2Card.cpp View File

//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// send command and return error code. Return zero for OK // send command and return error code. Return zero for OK
uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg)
{ {
// select card
chipSelectLow();
// wait up to 300 ms if busy // wait up to 300 ms if busy
waitNotBusy(300); waitNotBusy(300);
} }
// check SD version // check SD version
if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) { if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
type(SD_CARD_TYPE_SD1);
type_ = SD_CARD_TYPE_SD1;
} else { } else {
// only need last byte of r7 response // only need last byte of r7 response
for (uint8_t i = 0; i < 4; i++) status_ = spiRec(); for (uint8_t i = 0; i < 4; i++) status_ = spiRec();
if (status_ != 0XAA) { if (status_ != 0XAA) {
goto fail; // SD_CARD_ERROR_CMD8 goto fail; // SD_CARD_ERROR_CMD8
} }
type(SD_CARD_TYPE_SD2);
type_ = SD_CARD_TYPE_SD2;
} }
// initialize card and send host supports SDHC if SD2 // initialize card and send host supports SDHC if SD2
arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;
arg = (type_ == SD_CARD_TYPE_SD2) ? 0X40000000 : 0;
while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) { while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
// check for timeout // check for timeout
} }
} }
// if SD2 read OCR register to check for SDHC card // if SD2 read OCR register to check for SDHC card
if (type() == SD_CARD_TYPE_SD2) {
if (type_ == SD_CARD_TYPE_SD2) {
if (cardCommand(CMD58, 0)) { if (cardCommand(CMD58, 0)) {
goto fail; // SD_CARD_ERROR_CMD58 goto fail; // SD_CARD_ERROR_CMD58
} }
if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC);
if ((spiRec() & 0XC0) == 0XC0) type_ = SD_CARD_TYPE_SDHC;
// discard rest of ocr - contains allowed voltage range // discard rest of ocr - contains allowed voltage range
for (uint8_t i = 0; i < 3; i++) spiRec(); for (uint8_t i = 0; i < 3; i++) spiRec();
} }
chipSelectHigh(); chipSelectHigh();
return setSckRate(sckRateID); return setSckRate(sckRateID);
fail:
fail:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst) uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst)
{ {
// use address if not SDHC card // use address if not SDHC card
if (type() != SD_CARD_TYPE_SDHC) block <<= 9;
if (type_ != SD_CARD_TYPE_SDHC) block <<= 9;
chipSelectLow();
if (cardCommand(CMD17, block)) { if (cardCommand(CMD17, block)) {
goto fail; // SD_CARD_ERROR_CMD17 goto fail; // SD_CARD_ERROR_CMD17
} }
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** read CID or CSR register */
uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {
uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
if (cardCommand(cmd, 0)) {
goto fail; // SD_CARD_ERROR_READ_REG
}
if (!waitStartBlock()) goto fail;
// transfer data
for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec();
spiRec(); // get first crc byte
spiRec(); // get second crc byte
chipSelectHigh();
return true;
fail:
chipSelectHigh();
return false;
}
//------------------------------------------------------------------------------
/** /**
* Set the SPI clock rate. * Set the SPI clock rate.
* *
#endif // SD_PROTECT_BLOCK_ZERO #endif // SD_PROTECT_BLOCK_ZERO
// use address if not SDHC card // use address if not SDHC card
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
if (type_ != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
chipSelectLow();
if (cardCommand(CMD24, blockNumber)) { if (cardCommand(CMD24, blockNumber)) {
goto fail; // SD_CARD_ERROR_CMD24 goto fail; // SD_CARD_ERROR_CMD24
} }
status_ = spiRec(); status_ = spiRec();
if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
chipSelectHigh();
return false; // SD_CARD_ERROR_WRITE return false; // SD_CARD_ERROR_WRITE
} }
return true; return true;

+ 0
- 2
utility/Sd2Card.h View File

return cardCommand(cmd, arg); return cardCommand(cmd, arg);
} }
uint8_t cardCommand(uint8_t cmd, uint32_t arg); uint8_t cardCommand(uint8_t cmd, uint32_t arg);
uint8_t readRegister(uint8_t cmd, void* buf);
uint8_t sendWriteCommand(uint32_t blockNumber, uint32_t eraseCount); uint8_t sendWriteCommand(uint32_t blockNumber, uint32_t eraseCount);
void chipSelectHigh(void); void chipSelectHigh(void);
void chipSelectLow(void); void chipSelectLow(void);
void type(uint8_t value) {type_ = value;}
uint8_t waitNotBusy(uint16_t timeoutMillis); uint8_t waitNotBusy(uint16_t timeoutMillis);
uint8_t writeData(uint8_t token, const uint8_t* src); uint8_t writeData(uint8_t token, const uint8_t* src);
uint8_t waitStartBlock(void); uint8_t waitStartBlock(void);

Loading…
Cancel
Save