/** * Determine the size of an SD flash memory card. * * \return The number of 512 byte data blocks in the card * or zero if an error occurs. */ uint32_t Sd2Card::cardSize(void) { csd_t csd; if (!readCSD(&csd)) return 0; if (csd.v1.csd_ver == 0) { uint8_t read_bl_len = csd.v1.read_bl_len; uint16_t c_size = (csd.v1.c_size_high << 10) | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low; uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1) | csd.v1.c_size_mult_low; return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7); } else if (csd.v2.csd_ver == 1) { uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16) | (csd.v2.c_size_mid << 8) | csd.v2.c_size_low; return (c_size + 1) << 10; } else { error(SD_CARD_ERROR_BAD_CSD); return 0; } }
//------------------------------------------------------------------------------ bool SdSpiCard::erase(uint32_t firstBlock, uint32_t lastBlock) { 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) != 0 || ((lastBlock + 1) & m) != 0) { // error card can't erase specified area error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); goto fail; } } if (m_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; } if (!waitNotBusy(SD_ERASE_TIMEOUT)) { error(SD_CARD_ERROR_ERASE_TIMEOUT); goto fail; } spiStop(); return true; fail: spiStop(); return false; }
/** Determine if card supports single block erase. \return The value one, true, is returned if single block erase is supported. The value zero, false, is returned if single block erase is not supported. */ uint8_t Sd2Card::eraseSingleBlockEnable(void) { csd_t csd; return readCSD(&csd) ? csd.v1.erase_blk_en : 0; }
//------------------------------------------------------------------------------ bool SdSpiCard::eraseSingleBlockEnable() { csd_t csd; return readCSD(&csd) ? csd.v1.erase_blk_en : false; }
//------------------------------------------------------------------------------ uint32_t SdSpiCard::cardSize() { csd_t csd; return readCSD(&csd) ? sdCardCapacity(&csd) : 0; }