utility
Embed:
(wiki syntax)
Show/hide line numbers
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