Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Sd2Card.cpp
00001 /* Arduino Sd2Card Library 00002 * Copyright (C) 2009 by William Greiman 00003 * 00004 * This file is part of the Arduino Sd2Card Library 00005 * 00006 * This Library is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This Library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with the Arduino Sd2Card Library. If not, see 00018 * <http://www.gnu.org/licenses/>. 00019 */ 00020 #include "mbed.h" 00021 #include "Sd2Card.h" 00022 #include "pins_config.h" 00023 //------------------------------------------------------------------------------ 00024 #ifndef SOFTWARE_SPI 00025 // functions for hardware SPI 00026 /** Send a byte to the card */ 00027 static void spiSend(uint8_t b) { 00028 SPDR = b; 00029 while (!(SPSR & (1 << SPIF))); 00030 } 00031 /** Receive a byte from the card */ 00032 static uint8_t spiRec(void) { 00033 spiSend(0XFF); 00034 return SPDR; 00035 } 00036 #else // SOFTWARE_SPI 00037 //------------------------------------------------------------------------------ 00038 /** nop to tune soft SPI timing */ 00039 #define nop asm volatile ("nop\n\t") 00040 //------------------------------------------------------------------------------ 00041 /** Soft SPI receive */ 00042 uint8_t spiRec(void) { 00043 uint8_t data = 0; 00044 // no interrupts during byte receive - about 8 us 00045 cli(); 00046 // output pin high - like sending 0XFF 00047 fastDigitalWrite(SPI_MOSI_PIN, HIGH); 00048 00049 for (uint8_t i = 0; i < 8; i++) { 00050 fastDigitalWrite(SPI_SCK_PIN, HIGH); 00051 00052 // adjust so SCK is nice 00053 nop; 00054 nop; 00055 00056 data <<= 1; 00057 00058 if (fastDigitalRead(SPI_MISO_PIN)) data |= 1; 00059 00060 fastDigitalWrite(SPI_SCK_PIN, LOW); 00061 } 00062 // enable interrupts 00063 sei(); 00064 return data; 00065 } 00066 //------------------------------------------------------------------------------ 00067 /** Soft SPI send */ 00068 void spiSend(uint8_t data) { 00069 // no interrupts during byte send - about 8 us 00070 cli(); 00071 for (uint8_t i = 0; i < 8; i++) { 00072 fastDigitalWrite(SPI_SCK_PIN, LOW); 00073 00074 fastDigitalWrite(SPI_MOSI_PIN, data & 0X80); 00075 00076 data <<= 1; 00077 00078 fastDigitalWrite(SPI_SCK_PIN, HIGH); 00079 } 00080 // hold SCK high for a few ns 00081 nop; 00082 nop; 00083 nop; 00084 nop; 00085 00086 fastDigitalWrite(SPI_SCK_PIN, LOW); 00087 // enable interrupts 00088 sei(); 00089 } 00090 #endif // SOFTWARE_SPI 00091 //------------------------------------------------------------------------------ 00092 // send command and return error code. Return zero for OK 00093 uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { 00094 // end read if in partialBlockRead mode 00095 readEnd(); 00096 00097 // select card 00098 chipSelectLow(); 00099 00100 // wait up to 300 ms if busy 00101 waitNotBusy(300); 00102 00103 // send command 00104 spiSend(cmd | 0x40); 00105 00106 // send argument 00107 for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s); 00108 00109 // send CRC 00110 uint8_t crc = 0XFF; 00111 if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0 00112 if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA 00113 spiSend(crc); 00114 00115 // wait for response 00116 for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++); 00117 return status_; 00118 } 00119 //------------------------------------------------------------------------------ 00120 /** 00121 * Determine the size of an SD flash memory card. 00122 * 00123 * \return The number of 512 byte data blocks in the card 00124 * or zero if an error occurs. 00125 */ 00126 uint32_t Sd2Card::cardSize(void) { 00127 csd_t csd; 00128 if (!readCSD(&csd)) return 0; 00129 if (csd.v1.csd_ver == 0) { 00130 uint8_t read_bl_len = csd.v1.read_bl_len; 00131 uint16_t c_size = (csd.v1.c_size_high << 10) 00132 | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low; 00133 uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1) 00134 | csd.v1.c_size_mult_low; 00135 return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7); 00136 } else if (csd.v2.csd_ver == 1) { 00137 uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16) 00138 | (csd.v2.c_size_mid << 8) | csd.v2.c_size_low; 00139 return (c_size + 1) << 10; 00140 } else { 00141 error(SD_CARD_ERROR_BAD_CSD); 00142 return 0; 00143 } 00144 } 00145 //------------------------------------------------------------------------------ 00146 void Sd2Card::chipSelectHigh(void) { 00147 DigitalOut CS(chipSelectPin_,HIGH); 00148 //digitalWrite(chipSelectPin_, HIGH); 00149 } 00150 //------------------------------------------------------------------------------ 00151 void Sd2Card::chipSelectLow(void) { 00152 DigitalOut CS(chipSelectPin_,LOW); 00153 //digitalWrite(chipSelectPin_, LOW); 00154 } 00155 //------------------------------------------------------------------------------ 00156 /** Erase a range of blocks. 00157 * 00158 * \param[in] firstBlock The address of the first block in the range. 00159 * \param[in] lastBlock The address of the last block in the range. 00160 * 00161 * \note This function requests the SD card to do a flash erase for a 00162 * range of blocks. The data on the card after an erase operation is 00163 * either 0 or 1, depends on the card vendor. The card must support 00164 * single block erase. 00165 * 00166 * \return The value one, true, is returned for success and 00167 * the value zero, false, is returned for failure. 00168 */ 00169 uint8_t Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) { 00170 if (!eraseSingleBlockEnable()) { 00171 error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK); 00172 goto fail; 00173 } 00174 if (type_ != SD_CARD_TYPE_SDHC) { 00175 firstBlock <<= 9; 00176 lastBlock <<= 9; 00177 } 00178 if (cardCommand(CMD32, firstBlock) 00179 || cardCommand(CMD33, lastBlock) 00180 || cardCommand(CMD38, 0)) { 00181 error(SD_CARD_ERROR_ERASE); 00182 goto fail; 00183 } 00184 if (!waitNotBusy(SD_ERASE_TIMEOUT)) { 00185 error(SD_CARD_ERROR_ERASE_TIMEOUT); 00186 goto fail; 00187 } 00188 chipSelectHigh(); 00189 return true; 00190 00191 fail: 00192 chipSelectHigh(); 00193 return false; 00194 } 00195 //------------------------------------------------------------------------------ 00196 /** Determine if card supports single block erase. 00197 * 00198 * \return The value one, true, is returned if single block erase is supported. 00199 * The value zero, false, is returned if single block erase is not supported. 00200 */ 00201 uint8_t Sd2Card::eraseSingleBlockEnable(void) { 00202 csd_t csd; 00203 return readCSD(&csd) ? csd.v1.erase_blk_en : 0; 00204 } 00205 //------------------------------------------------------------------------------ 00206 /** 00207 * Initialize an SD flash memory card. 00208 * 00209 * \param[in] sckRateID SPI clock rate selector. See setSckRate(). 00210 * \param[in] chipSelectPin SD chip select pin number. 00211 * 00212 * \return The value one, true, is returned for success and 00213 * the value zero, false, is returned for failure. The reason for failure 00214 * can be determined by calling errorCode() and errorData(). 00215 */ 00216 uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) { 00217 errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0; 00218 chipSelectPin_ = chipSelectPin; 00219 // 16-bit init start time allows over a minute 00220 uint16_t t0 = (uint16_t)millis(); 00221 uint32_t arg; 00222 00223 // set pin modes 00224 pinMode(chipSelectPin_, OUTPUT); 00225 chipSelectHigh(); 00226 pinMode(SPI_MISO_PIN, INPUT); 00227 pinMode(SPI_MOSI_PIN, OUTPUT); 00228 pinMode(SPI_SCK_PIN, OUTPUT); 00229 00230 #ifndef SOFTWARE_SPI 00231 // SS must be in output mode even it is not chip select 00232 pinMode(SS_PIN, OUTPUT); 00233 digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin 00234 // Enable SPI, Master, clock rate f_osc/128 00235 SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); 00236 // clear double speed 00237 SPSR &= ~(1 << SPI2X); 00238 #endif // SOFTWARE_SPI 00239 00240 // must supply min of 74 clock cycles with CS high. 00241 for (uint8_t i = 0; i < 10; i++) spiSend(0XFF); 00242 00243 chipSelectLow(); 00244 00245 // command to go idle in SPI mode 00246 while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) { 00247 if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { 00248 error(SD_CARD_ERROR_CMD0); 00249 goto fail; 00250 } 00251 } 00252 // check SD version 00253 if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) { 00254 type(SD_CARD_TYPE_SD1); 00255 } else { 00256 // only need last byte of r7 response 00257 for (uint8_t i = 0; i < 4; i++) status_ = spiRec(); 00258 if (status_ != 0XAA) { 00259 error(SD_CARD_ERROR_CMD8); 00260 goto fail; 00261 } 00262 type(SD_CARD_TYPE_SD2); 00263 } 00264 // initialize card and send host supports SDHC if SD2 00265 arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0; 00266 00267 while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) { 00268 // check for timeout 00269 if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { 00270 error(SD_CARD_ERROR_ACMD41); 00271 goto fail; 00272 } 00273 } 00274 // if SD2 read OCR register to check for SDHC card 00275 if (type() == SD_CARD_TYPE_SD2) { 00276 if (cardCommand(CMD58, 0)) { 00277 error(SD_CARD_ERROR_CMD58); 00278 goto fail; 00279 } 00280 if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC); 00281 // discard rest of ocr - contains allowed voltage range 00282 for (uint8_t i = 0; i < 3; i++) spiRec(); 00283 } 00284 chipSelectHigh(); 00285 00286 #ifndef SOFTWARE_SPI 00287 return setSckRate(sckRateID); 00288 #else // SOFTWARE_SPI 00289 return true; 00290 #endif // SOFTWARE_SPI 00291 00292 fail: 00293 chipSelectHigh(); 00294 return false; 00295 } 00296 //------------------------------------------------------------------------------ 00297 /** 00298 * Enable or disable partial block reads. 00299 * 00300 * Enabling partial block reads improves performance by allowing a block 00301 * to be read over the SPI bus as several sub-blocks. Errors may occur 00302 * if the time between reads is too long since the SD card may timeout. 00303 * The SPI SS line will be held low until the entire block is read or 00304 * readEnd() is called. 00305 * 00306 * Use this for applications like the Adafruit Wave Shield. 00307 * 00308 * \param[in] value The value TRUE (non-zero) or FALSE (zero).) 00309 */ 00310 void Sd2Card::partialBlockRead(uint8_t value) { 00311 readEnd(); 00312 partialBlockRead_ = value; 00313 } 00314 //------------------------------------------------------------------------------ 00315 /** 00316 * Read a 512 byte block from an SD card device. 00317 * 00318 * \param[in] block Logical block to be read. 00319 * \param[out] dst Pointer to the location that will receive the data. 00320 00321 * \return The value one, true, is returned for success and 00322 * the value zero, false, is returned for failure. 00323 */ 00324 uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst) { 00325 return readData(block, 0, 512, dst); 00326 } 00327 //------------------------------------------------------------------------------ 00328 /** 00329 * Read part of a 512 byte block from an SD card. 00330 * 00331 * \param[in] block Logical block to be read. 00332 * \param[in] offset Number of bytes to skip at start of block 00333 * \param[out] dst Pointer to the location that will receive the data. 00334 * \param[in] count Number of bytes to read 00335 * \return The value one, true, is returned for success and 00336 * the value zero, false, is returned for failure. 00337 */ 00338 uint8_t Sd2Card::readData(uint32_t block, 00339 uint16_t offset, uint16_t count, uint8_t* dst) { 00340 uint16_t n; 00341 if (count == 0) return true; 00342 if ((count + offset) > 512) { 00343 goto fail; 00344 } 00345 if (!inBlock_ || block != block_ || offset < offset_) { 00346 block_ = block; 00347 // use address if not SDHC card 00348 if (type()!= SD_CARD_TYPE_SDHC) block <<= 9; 00349 if (cardCommand(CMD17, block)) { 00350 error(SD_CARD_ERROR_CMD17); 00351 goto fail; 00352 } 00353 if (!waitStartBlock()) { 00354 goto fail; 00355 } 00356 offset_ = 0; 00357 inBlock_ = 1; 00358 } 00359 00360 #ifdef OPTIMIZE_HARDWARE_SPI 00361 // start first spi transfer 00362 SPDR = 0XFF; 00363 00364 // skip data before offset 00365 for (;offset_ < offset; offset_++) { 00366 while (!(SPSR & (1 << SPIF))); 00367 SPDR = 0XFF; 00368 } 00369 // transfer data 00370 n = count - 1; 00371 for (uint16_t i = 0; i < n; i++) { 00372 while (!(SPSR & (1 << SPIF))); 00373 dst[i] = SPDR; 00374 SPDR = 0XFF; 00375 } 00376 // wait for last byte 00377 while (!(SPSR & (1 << SPIF))); 00378 dst[n] = SPDR; 00379 00380 #else // OPTIMIZE_HARDWARE_SPI 00381 00382 // skip data before offset 00383 for (;offset_ < offset; offset_++) { 00384 spiRec(); 00385 } 00386 // transfer data 00387 for (uint16_t i = 0; i < count; i++) { 00388 dst[i] = spiRec(); 00389 } 00390 #endif // OPTIMIZE_HARDWARE_SPI 00391 00392 offset_ += count; 00393 if (!partialBlockRead_ || offset_ >= 512) { 00394 // read rest of data, checksum and set chip select high 00395 readEnd(); 00396 } 00397 return true; 00398 00399 fail: 00400 chipSelectHigh(); 00401 return false; 00402 } 00403 //------------------------------------------------------------------------------ 00404 /** Skip remaining data in a block when in partial block read mode. */ 00405 void Sd2Card::readEnd(void) { 00406 if (inBlock_) { 00407 // skip data and crc 00408 #ifdef OPTIMIZE_HARDWARE_SPI 00409 // optimize skip for hardware 00410 SPDR = 0XFF; 00411 while (offset_++ < 513) { 00412 while (!(SPSR & (1 << SPIF))); 00413 SPDR = 0XFF; 00414 } 00415 // wait for last crc byte 00416 while (!(SPSR & (1 << SPIF))); 00417 #else // OPTIMIZE_HARDWARE_SPI 00418 while (offset_++ < 514) spiRec(); 00419 #endif // OPTIMIZE_HARDWARE_SPI 00420 chipSelectHigh(); 00421 inBlock_ = 0; 00422 } 00423 } 00424 //------------------------------------------------------------------------------ 00425 /** read CID or CSR register */ 00426 uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) { 00427 uint8_t* dst = reinterpret_cast<uint8_t*>(buf); 00428 if (cardCommand(cmd, 0)) { 00429 error(SD_CARD_ERROR_READ_REG); 00430 goto fail; 00431 } 00432 if (!waitStartBlock()) goto fail; 00433 // transfer data 00434 for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec(); 00435 spiRec(); // get first crc byte 00436 spiRec(); // get second crc byte 00437 chipSelectHigh(); 00438 return true; 00439 00440 fail: 00441 chipSelectHigh(); 00442 return false; 00443 } 00444 //------------------------------------------------------------------------------ 00445 /** 00446 * Set the SPI clock rate. 00447 * 00448 * \param[in] sckRateID A value in the range [0, 6]. 00449 * 00450 * The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum 00451 * SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128 00452 * for \a scsRateID = 6. 00453 * 00454 * \return The value one, true, is returned for success and the value zero, 00455 * false, is returned for an invalid value of \a sckRateID. 00456 */ 00457 uint8_t Sd2Card::setSckRate(uint8_t sckRateID) { 00458 if (sckRateID > 6) { 00459 error(SD_CARD_ERROR_SCK_RATE); 00460 return false; 00461 } 00462 // see avr processor datasheet for SPI register bit definitions 00463 if ((sckRateID & 1) || sckRateID == 6) { 00464 SPSR &= ~(1 << SPI2X); 00465 } else { 00466 SPSR |= (1 << SPI2X); 00467 } 00468 SPCR &= ~((1 <<SPR1) | (1 << SPR0)); 00469 SPCR |= (sckRateID & 4 ? (1 << SPR1) : 0) 00470 | (sckRateID & 2 ? (1 << SPR0) : 0); 00471 return true; 00472 } 00473 //------------------------------------------------------------------------------ 00474 // wait for card to go not busy 00475 uint8_t Sd2Card::waitNotBusy(uint16_t timeoutMillis) { 00476 uint16_t t0 = millis(); 00477 do { 00478 if (spiRec() == 0XFF) return true; 00479 } 00480 while (((uint16_t)millis() - t0) < timeoutMillis); 00481 return false; 00482 } 00483 //------------------------------------------------------------------------------ 00484 /** Wait for start block token */ 00485 uint8_t Sd2Card::waitStartBlock(void) { 00486 uint16_t t0 = millis(); 00487 while ((status_ = spiRec()) == 0XFF) { 00488 if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) { 00489 error(SD_CARD_ERROR_READ_TIMEOUT); 00490 goto fail; 00491 } 00492 } 00493 if (status_ != DATA_START_BLOCK) { 00494 error(SD_CARD_ERROR_READ); 00495 goto fail; 00496 } 00497 return true; 00498 00499 fail: 00500 chipSelectHigh(); 00501 return false; 00502 } 00503 //------------------------------------------------------------------------------ 00504 /** 00505 * Writes a 512 byte block to an SD card. 00506 * 00507 * \param[in] blockNumber Logical block to be written. 00508 * \param[in] src Pointer to the location of the data to be written. 00509 * \return The value one, true, is returned for success and 00510 * the value zero, false, is returned for failure. 00511 */ 00512 uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) { 00513 #if SD_PROTECT_BLOCK_ZERO 00514 // don't allow write to first block 00515 if (blockNumber == 0) { 00516 error(SD_CARD_ERROR_WRITE_BLOCK_ZERO); 00517 goto fail; 00518 } 00519 #endif // SD_PROTECT_BLOCK_ZERO 00520 00521 // use address if not SDHC card 00522 if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; 00523 if (cardCommand(CMD24, blockNumber)) { 00524 error(SD_CARD_ERROR_CMD24); 00525 goto fail; 00526 } 00527 if (!writeData(DATA_START_BLOCK, src)) goto fail; 00528 00529 // wait for flash programming to complete 00530 if (!waitNotBusy(SD_WRITE_TIMEOUT)) { 00531 error(SD_CARD_ERROR_WRITE_TIMEOUT); 00532 goto fail; 00533 } 00534 // response is r2 so get and check two bytes for nonzero 00535 if (cardCommand(CMD13, 0) || spiRec()) { 00536 error(SD_CARD_ERROR_WRITE_PROGRAMMING); 00537 goto fail; 00538 } 00539 chipSelectHigh(); 00540 return true; 00541 00542 fail: 00543 chipSelectHigh(); 00544 return false; 00545 } 00546 //------------------------------------------------------------------------------ 00547 /** Write one data block in a multiple block write sequence */ 00548 uint8_t Sd2Card::writeData(const uint8_t* src) { 00549 // wait for previous write to finish 00550 if (!waitNotBusy(SD_WRITE_TIMEOUT)) { 00551 error(SD_CARD_ERROR_WRITE_MULTIPLE); 00552 chipSelectHigh(); 00553 return false; 00554 } 00555 return writeData(WRITE_MULTIPLE_TOKEN, src); 00556 } 00557 //------------------------------------------------------------------------------ 00558 // send one block of data for write block or write multiple blocks 00559 uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) { 00560 #ifdef OPTIMIZE_HARDWARE_SPI 00561 00562 // send data - optimized loop 00563 SPDR = token; 00564 00565 // send two byte per iteration 00566 for (uint16_t i = 0; i < 512; i += 2) { 00567 while (!(SPSR & (1 << SPIF))); 00568 SPDR = src[i]; 00569 while (!(SPSR & (1 << SPIF))); 00570 SPDR = src[i+1]; 00571 } 00572 00573 // wait for last data byte 00574 while (!(SPSR & (1 << SPIF))); 00575 00576 #else // OPTIMIZE_HARDWARE_SPI 00577 spiSend(token); 00578 for (uint16_t i = 0; i < 512; i++) { 00579 spiSend(src[i]); 00580 } 00581 #endif // OPTIMIZE_HARDWARE_SPI 00582 spiSend(0xff); // dummy crc 00583 spiSend(0xff); // dummy crc 00584 00585 status_ = spiRec(); 00586 if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { 00587 error(SD_CARD_ERROR_WRITE); 00588 chipSelectHigh(); 00589 return false; 00590 } 00591 return true; 00592 } 00593 //------------------------------------------------------------------------------ 00594 /** Start a write multiple blocks sequence. 00595 * 00596 * \param[in] blockNumber Address of first block in sequence. 00597 * \param[in] eraseCount The number of blocks to be pre-erased. 00598 * 00599 * \note This function is used with writeData() and writeStop() 00600 * for optimized multiple block writes. 00601 * 00602 * \return The value one, true, is returned for success and 00603 * the value zero, false, is returned for failure. 00604 */ 00605 uint8_t Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) { 00606 #if SD_PROTECT_BLOCK_ZERO 00607 // don't allow write to first block 00608 if (blockNumber == 0) { 00609 error(SD_CARD_ERROR_WRITE_BLOCK_ZERO); 00610 goto fail; 00611 } 00612 #endif // SD_PROTECT_BLOCK_ZERO 00613 // send pre-erase count 00614 if (cardAcmd(ACMD23, eraseCount)) { 00615 error(SD_CARD_ERROR_ACMD23); 00616 goto fail; 00617 } 00618 // use address if not SDHC card 00619 if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; 00620 if (cardCommand(CMD25, blockNumber)) { 00621 error(SD_CARD_ERROR_CMD25); 00622 goto fail; 00623 } 00624 return true; 00625 00626 fail: 00627 chipSelectHigh(); 00628 return false; 00629 } 00630 //------------------------------------------------------------------------------ 00631 /** End a write multiple blocks sequence. 00632 * 00633 * \return The value one, true, is returned for success and 00634 * the value zero, false, is returned for failure. 00635 */ 00636 uint8_t Sd2Card::writeStop(void) { 00637 if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; 00638 spiSend(STOP_TRAN_TOKEN); 00639 if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; 00640 chipSelectHigh(); 00641 return true; 00642 00643 fail: 00644 error(SD_CARD_ERROR_STOP_TRAN); 00645 chipSelectHigh(); 00646 return false; 00647 }
Generated on Thu Jul 14 2022 02:07:54 by
1.7.2