source: rtos_arduino/trunk/arduino_lib/libraries/SD/src/utility/Sd2Card.cpp@ 260

Last change on this file since 260 was 260, checked in by ertl-honda, 8 years ago

マクロ名を更新.
実行モデルを変更.

File size: 21.8 KB
Line 
1/* Arduino Sd2Card Library
2 * Copyright (C) 2009 by William Greiman
3 *
4 * This file is part of the Arduino Sd2Card Library
5 *
6 * This Library is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This Library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with the Arduino Sd2Card Library. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20#define USE_SPI_LIB
21#include <Arduino.h>
22#include "Sd2Card.h"
23
24#ifdef TOPPERS_WITH_ARDUINO
25#include "r2ca.h"
26#define ENTER_CRITICAL wai_sem(SPI_SEM);
27#define LEAVE_CRITICAL sig_sem(SPI_SEM);
28#else /* !TOPPERS_WITH_ARDUINO */
29#define WAIT_TIMEOUT
30#define ENTER_CRITICAL
31#define LEAVE_CRITICAL
32#endif /* TOPPERS_WITH_ARDUINO */
33
34//------------------------------------------------------------------------------
35#ifndef SOFTWARE_SPI
36#ifdef USE_SPI_LIB
37#include <SPI.h>
38#ifndef ARDUINO_ARCH_SAMD
39static SPISettings settings;
40#endif
41#endif
42// functions for hardware SPI
43/** Send a byte to the card */
44static void spiSend(uint8_t b) {
45#ifndef USE_SPI_LIB
46 SPDR = b;
47 while (!(SPSR & (1 << SPIF)))
48 ;
49#else
50 SPI.transfer(b);
51#endif
52}
53/** Receive a byte from the card */
54static uint8_t spiRec(void) {
55#ifndef USE_SPI_LIB
56 spiSend(0XFF);
57 return SPDR;
58#else
59 return SPI.transfer(0xFF);
60#endif
61}
62#else // SOFTWARE_SPI
63//------------------------------------------------------------------------------
64/** nop to tune soft SPI timing */
65#define nop asm volatile ("nop\n\t")
66//------------------------------------------------------------------------------
67/** Soft SPI receive */
68uint8_t spiRec(void) {
69 uint8_t data = 0;
70 // no interrupts during byte receive - about 8 us
71 cli();
72 // output pin high - like sending 0XFF
73 fastDigitalWrite(SPI_MOSI_PIN, HIGH);
74
75 for (uint8_t i = 0; i < 8; i++) {
76 fastDigitalWrite(SPI_SCK_PIN, HIGH);
77
78 // adjust so SCK is nice
79 nop;
80 nop;
81
82 data <<= 1;
83
84 if (fastDigitalRead(SPI_MISO_PIN)) data |= 1;
85
86 fastDigitalWrite(SPI_SCK_PIN, LOW);
87 }
88 // enable interrupts
89 sei();
90 return data;
91}
92//------------------------------------------------------------------------------
93/** Soft SPI send */
94void spiSend(uint8_t data) {
95 // no interrupts during byte send - about 8 us
96 cli();
97 for (uint8_t i = 0; i < 8; i++) {
98 fastDigitalWrite(SPI_SCK_PIN, LOW);
99
100 fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);
101
102 data <<= 1;
103
104 fastDigitalWrite(SPI_SCK_PIN, HIGH);
105 }
106 // hold SCK high for a few ns
107 nop;
108 nop;
109 nop;
110 nop;
111
112 fastDigitalWrite(SPI_SCK_PIN, LOW);
113 // enable interrupts
114 sei();
115}
116#endif // SOFTWARE_SPI
117//------------------------------------------------------------------------------
118// send command and return error code. Return zero for OK
119uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
120 // end read if in partialBlockRead mode
121 readEnd();
122
123 // select card
124 chipSelectLow();
125
126 // wait up to 300 ms if busy
127 waitNotBusy(300);
128
129 // send command
130 spiSend(cmd | 0x40);
131
132 // send argument
133 for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s);
134
135 // send CRC
136 uint8_t crc = 0XFF;
137 if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0
138 if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA
139 spiSend(crc);
140
141 // wait for response
142 for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++)
143 ;
144 return status_;
145}
146//------------------------------------------------------------------------------
147/**
148 * Determine the size of an SD flash memory card.
149 *
150 * \return The number of 512 byte data blocks in the card
151 * or zero if an error occurs.
152 */
153uint32_t Sd2Card::cardSize(void) {
154 csd_t csd;
155 if (!readCSD(&csd)) return 0;
156 if (csd.v1.csd_ver == 0) {
157 uint8_t read_bl_len = csd.v1.read_bl_len;
158 uint16_t c_size = (csd.v1.c_size_high << 10)
159 | (csd.v1.c_size_mid << 2) | csd.v1.c_size_low;
160 uint8_t c_size_mult = (csd.v1.c_size_mult_high << 1)
161 | csd.v1.c_size_mult_low;
162 return (uint32_t)(c_size + 1) << (c_size_mult + read_bl_len - 7);
163 } else if (csd.v2.csd_ver == 1) {
164 uint32_t c_size = ((uint32_t)csd.v2.c_size_high << 16)
165 | (csd.v2.c_size_mid << 8) | csd.v2.c_size_low;
166 return (c_size + 1) << 10;
167 } else {
168 error(SD_CARD_ERROR_BAD_CSD);
169 return 0;
170 }
171}
172//------------------------------------------------------------------------------
173static uint8_t chip_select_asserted = 0;
174
175void Sd2Card::chipSelectHigh(void) {
176 digitalWrite(chipSelectPin_, HIGH);
177#ifdef USE_SPI_LIB
178 if (chip_select_asserted) {
179 chip_select_asserted = 0;
180 #ifndef ARDUINO_ARCH_SAMD
181 SPI.endTransaction();
182 #endif
183 }
184#endif
185}
186//------------------------------------------------------------------------------
187void Sd2Card::chipSelectLow(void) {
188#ifdef USE_SPI_LIB
189 if (!chip_select_asserted) {
190 chip_select_asserted = 1;
191 #ifndef ARDUINO_ARCH_SAMD
192 SPI.beginTransaction(settings);
193 #endif
194 }
195#endif
196 digitalWrite(chipSelectPin_, LOW);
197}
198//------------------------------------------------------------------------------
199/** Erase a range of blocks.
200 *
201 * \param[in] firstBlock The address of the first block in the range.
202 * \param[in] lastBlock The address of the last block in the range.
203 *
204 * \note This function requests the SD card to do a flash erase for a
205 * range of blocks. The data on the card after an erase operation is
206 * either 0 or 1, depends on the card vendor. The card must support
207 * single block erase.
208 *
209 * \return The value one, true, is returned for success and
210 * the value zero, false, is returned for failure.
211 */
212uint8_t Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
213 ENTER_CRITICAL;
214 if (!eraseSingleBlockEnable()) {
215 error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK);
216 goto fail;
217 }
218 if (type_ != SD_CARD_TYPE_SDHC) {
219 firstBlock <<= 9;
220 lastBlock <<= 9;
221 }
222 if (cardCommand(CMD32, firstBlock)
223 || cardCommand(CMD33, lastBlock)
224 || cardCommand(CMD38, 0)) {
225 error(SD_CARD_ERROR_ERASE);
226 goto fail;
227 }
228 if (!waitNotBusy(SD_ERASE_TIMEOUT)) {
229 error(SD_CARD_ERROR_ERASE_TIMEOUT);
230 goto fail;
231 }
232 chipSelectHigh();
233 LEAVE_CRITICAL;
234 return true;
235
236 fail:
237 chipSelectHigh();
238 LEAVE_CRITICAL;
239 return false;
240}
241//------------------------------------------------------------------------------
242/** Determine if card supports single block erase.
243 *
244 * \return The value one, true, is returned if single block erase is supported.
245 * The value zero, false, is returned if single block erase is not supported.
246 */
247uint8_t Sd2Card::eraseSingleBlockEnable(void) {
248 csd_t csd;
249 return readCSD(&csd) ? csd.v1.erase_blk_en : 0;
250}
251//------------------------------------------------------------------------------
252/**
253 * Initialize an SD flash memory card.
254 *
255 * \param[in] sckRateID SPI clock rate selector. See setSckRate().
256 * \param[in] chipSelectPin SD chip select pin number.
257 *
258 * \return The value one, true, is returned for success and
259 * the value zero, false, is returned for failure. The reason for failure
260 * can be determined by calling errorCode() and errorData().
261 */
262uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
263
264 errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;
265 chipSelectPin_ = chipSelectPin;
266 // 16-bit init start time allows over a minute
267 uint16_t t0 = (uint16_t)millis();
268 uint32_t arg;
269
270 ENTER_CRITICAL;
271 // set pin modes
272 pinMode(chipSelectPin_, OUTPUT);
273 digitalWrite(chipSelectPin_, HIGH);
274#ifndef USE_SPI_LIB
275 pinMode(SPI_MISO_PIN, INPUT);
276 pinMode(SPI_MOSI_PIN, OUTPUT);
277 pinMode(SPI_SCK_PIN, OUTPUT);
278#endif
279
280#ifndef SOFTWARE_SPI
281#ifndef USE_SPI_LIB
282 // SS must be in output mode even it is not chip select
283 pinMode(SS_PIN, OUTPUT);
284 digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin
285 // Enable SPI, Master, clock rate f_osc/128
286 SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
287 // clear double speed
288 SPSR &= ~(1 << SPI2X);
289#else // USE_SPI_LIB
290 SPI.begin();
291 #ifndef ARDUINO_ARCH_SAMD
292 settings = SPISettings(250000, MSBFIRST, SPI_MODE0);
293 #endif
294#endif // USE_SPI_LIB
295#endif // SOFTWARE_SPI
296
297 // must supply min of 74 clock cycles with CS high.
298#ifdef USE_SPI_LIB
299#ifndef ARDUINO_ARCH_SAMD
300 SPI.beginTransaction(settings);
301#endif
302#endif
303 for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
304#ifdef USE_SPI_LIB
305#ifndef ARDUINO_ARCH_SAMD
306 SPI.endTransaction();
307#endif
308#endif
309 chipSelectLow();
310
311 // command to go idle in SPI mode
312 while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
313 if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
314 error(SD_CARD_ERROR_CMD0);
315 goto fail;
316 }
317 }
318 // check SD version
319 if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
320 type(SD_CARD_TYPE_SD1);
321 } else {
322 // only need last byte of r7 response
323 for (uint8_t i = 0; i < 4; i++) status_ = spiRec();
324 if (status_ != 0XAA) {
325 error(SD_CARD_ERROR_CMD8);
326 goto fail;
327 }
328 type(SD_CARD_TYPE_SD2);
329 }
330 // initialize card and send host supports SDHC if SD2
331 arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;
332
333 while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
334 // check for timeout
335 if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
336 error(SD_CARD_ERROR_ACMD41);
337 goto fail;
338 }
339 }
340 // if SD2 read OCR register to check for SDHC card
341 if (type() == SD_CARD_TYPE_SD2) {
342 if (cardCommand(CMD58, 0)) {
343 error(SD_CARD_ERROR_CMD58);
344 goto fail;
345 }
346 if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC);
347 // discard rest of ocr - contains allowed voltage range
348 for (uint8_t i = 0; i < 3; i++) spiRec();
349 }
350 chipSelectHigh();
351 LEAVE_CRITICAL;
352#ifndef SOFTWARE_SPI
353 return setSckRate(sckRateID);
354#else // SOFTWARE_SPI
355 return true;
356#endif // SOFTWARE_SPI
357
358 fail:
359 chipSelectHigh();
360 LEAVE_CRITICAL;
361 return false;
362}
363//------------------------------------------------------------------------------
364/**
365 * Enable or disable partial block reads.
366 *
367 * Enabling partial block reads improves performance by allowing a block
368 * to be read over the SPI bus as several sub-blocks. Errors may occur
369 * if the time between reads is too long since the SD card may timeout.
370 * The SPI SS line will be held low until the entire block is read or
371 * readEnd() is called.
372 *
373 * Use this for applications like the Adafruit Wave Shield.
374 *
375 * \param[in] value The value TRUE (non-zero) or FALSE (zero).)
376 */
377void Sd2Card::partialBlockRead(uint8_t value) {
378 ENTER_CRITICAL;
379 readEnd();
380 partialBlockRead_ = value;
381 LEAVE_CRITICAL;
382}
383//------------------------------------------------------------------------------
384/**
385 * Read a 512 byte block from an SD card device.
386 *
387 * \param[in] block Logical block to be read.
388 * \param[out] dst Pointer to the location that will receive the data.
389
390 * \return The value one, true, is returned for success and
391 * the value zero, false, is returned for failure.
392 */
393uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst) {
394 return readData(block, 0, 512, dst);
395}
396//------------------------------------------------------------------------------
397/**
398 * Read part of a 512 byte block from an SD card.
399 *
400 * \param[in] block Logical block to be read.
401 * \param[in] offset Number of bytes to skip at start of block
402 * \param[out] dst Pointer to the location that will receive the data.
403 * \param[in] count Number of bytes to read
404 * \return The value one, true, is returned for success and
405 * the value zero, false, is returned for failure.
406 */
407uint8_t Sd2Card::readData(uint32_t block,
408 uint16_t offset, uint16_t count, uint8_t* dst) {
409 uint16_t n;
410 if (count == 0) return true;
411 ENTER_CRITICAL;
412 if ((count + offset) > 512) {
413 goto fail;
414 }
415 if (!inBlock_ || block != block_ || offset < offset_) {
416 block_ = block;
417 // use address if not SDHC card
418 if (type()!= SD_CARD_TYPE_SDHC) block <<= 9;
419 if (cardCommand(CMD17, block)) {
420 error(SD_CARD_ERROR_CMD17);
421 goto fail;
422 }
423 if (!waitStartBlock()) {
424 goto fail;
425 }
426 offset_ = 0;
427 inBlock_ = 1;
428 }
429
430#ifdef OPTIMIZE_HARDWARE_SPI
431 // start first spi transfer
432 SPDR = 0XFF;
433
434 // skip data before offset
435 for (;offset_ < offset; offset_++) {
436 while (!(SPSR & (1 << SPIF)))
437 ;
438 SPDR = 0XFF;
439 }
440 // transfer data
441 n = count - 1;
442 for (uint16_t i = 0; i < n; i++) {
443 while (!(SPSR & (1 << SPIF)))
444 ;
445 dst[i] = SPDR;
446 SPDR = 0XFF;
447 }
448 // wait for last byte
449 while (!(SPSR & (1 << SPIF)))
450 ;
451 dst[n] = SPDR;
452
453#else // OPTIMIZE_HARDWARE_SPI
454
455 // skip data before offset
456 for (;offset_ < offset; offset_++) {
457 spiRec();
458 }
459 // transfer data
460 for (uint16_t i = 0; i < count; i++) {
461 dst[i] = spiRec();
462 }
463#endif // OPTIMIZE_HARDWARE_SPI
464
465 offset_ += count;
466 if (!partialBlockRead_ || offset_ >= 512) {
467 // read rest of data, checksum and set chip select high
468 readEnd();
469 }
470 LEAVE_CRITICAL;
471 return true;
472
473 fail:
474 LEAVE_CRITICAL;
475 chipSelectHigh();
476 return false;
477}
478//------------------------------------------------------------------------------
479/** Skip remaining data in a block when in partial block read mode. */
480void Sd2Card::readEnd(void) {
481 if (inBlock_) {
482 // skip data and crc
483#ifdef OPTIMIZE_HARDWARE_SPI
484 // optimize skip for hardware
485 SPDR = 0XFF;
486 while (offset_++ < 513) {
487 while (!(SPSR & (1 << SPIF)))
488 ;
489 SPDR = 0XFF;
490 }
491 // wait for last crc byte
492 while (!(SPSR & (1 << SPIF)))
493 ;
494#else // OPTIMIZE_HARDWARE_SPI
495 while (offset_++ < 514) spiRec();
496#endif // OPTIMIZE_HARDWARE_SPI
497 chipSelectHigh();
498 inBlock_ = 0;
499 }
500}
501//------------------------------------------------------------------------------
502/** read CID or CSR register */
503uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {
504 uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
505 ENTER_CRITICAL;
506 if (cardCommand(cmd, 0)) {
507 error(SD_CARD_ERROR_READ_REG);
508 goto fail;
509 }
510 if (!waitStartBlock()) goto fail;
511 // transfer data
512 for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec();
513 spiRec(); // get first crc byte
514 spiRec(); // get second crc byte
515 chipSelectHigh();
516 LEAVE_CRITICAL;
517 return true;
518
519 fail:
520 chipSelectHigh();
521 LEAVE_CRITICAL;
522 return false;
523}
524//------------------------------------------------------------------------------
525/**
526 * Set the SPI clock rate.
527 *
528 * \param[in] sckRateID A value in the range [0, 6].
529 *
530 * The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum
531 * SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128
532 * for \a scsRateID = 6.
533 *
534 * \return The value one, true, is returned for success and the value zero,
535 * false, is returned for an invalid value of \a sckRateID.
536 */
537uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {
538 if (sckRateID > 6) {
539 error(SD_CARD_ERROR_SCK_RATE);
540 return false;
541 }
542#ifndef USE_SPI_LIB
543 // see avr processor datasheet for SPI register bit definitions
544 if ((sckRateID & 1) || sckRateID == 6) {
545 SPSR &= ~(1 << SPI2X);
546 } else {
547 SPSR |= (1 << SPI2X);
548 }
549 SPCR &= ~((1 <<SPR1) | (1 << SPR0));
550 SPCR |= (sckRateID & 4 ? (1 << SPR1) : 0)
551 | (sckRateID & 2 ? (1 << SPR0) : 0);
552#else // USE_SPI_LIB
553 #if defined(ARDUINO_ARCH_SAM)
554 switch (sckRateID) {
555 case 0: settings = SPISettings(25000000, MSBFIRST, SPI_MODE0); break;
556 case 1: settings = SPISettings(4000000, MSBFIRST, SPI_MODE0); break;
557 case 2: settings = SPISettings(2000000, MSBFIRST, SPI_MODE0); break;
558 case 3: settings = SPISettings(1000000, MSBFIRST, SPI_MODE0); break;
559 case 4: settings = SPISettings(500000, MSBFIRST, SPI_MODE0); break;
560 case 5: settings = SPISettings(250000, MSBFIRST, SPI_MODE0); break;
561 default: settings = SPISettings(125000, MSBFIRST, SPI_MODE0);
562 }
563 #endif
564#endif // USE_SPI_LIB
565 return true;
566}
567//------------------------------------------------------------------------------
568// wait for card to go not busy
569uint8_t Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
570 uint16_t t0 = millis();
571 do {
572 if (spiRec() == 0XFF) return true;
573 }
574 while (((uint16_t)millis() - t0) < timeoutMillis);
575 return false;
576}
577//------------------------------------------------------------------------------
578/** Wait for start block token */
579uint8_t Sd2Card::waitStartBlock(void) {
580 uint16_t t0 = millis();
581 while ((status_ = spiRec()) == 0XFF) {
582 if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) {
583 error(SD_CARD_ERROR_READ_TIMEOUT);
584 goto fail;
585 }
586 }
587 if (status_ != DATA_START_BLOCK) {
588 error(SD_CARD_ERROR_READ);
589 goto fail;
590 }
591 return true;
592
593 fail:
594 chipSelectHigh();
595 return false;
596}
597//------------------------------------------------------------------------------
598/**
599 * Writes a 512 byte block to an SD card.
600 *
601 * \param[in] blockNumber Logical block to be written.
602 * \param[in] src Pointer to the location of the data to be written.
603 * \return The value one, true, is returned for success and
604 * the value zero, false, is returned for failure.
605 */
606uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
607 ENTER_CRITICAL;
608#if SD_PROTECT_BLOCK_ZERO
609 // don't allow write to first block
610 if (blockNumber == 0) {
611 error(SD_CARD_ERROR_WRITE_BLOCK_ZERO);
612 goto fail;
613 }
614#endif // SD_PROTECT_BLOCK_ZERO
615
616 // use address if not SDHC card
617 if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
618 if (cardCommand(CMD24, blockNumber)) {
619 error(SD_CARD_ERROR_CMD24);
620 goto fail;
621 }
622 if (!writeData(DATA_START_BLOCK, src)) goto fail;
623
624 // wait for flash programming to complete
625 if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
626 error(SD_CARD_ERROR_WRITE_TIMEOUT);
627 goto fail;
628 }
629 // response is r2 so get and check two bytes for nonzero
630 if (cardCommand(CMD13, 0) || spiRec()) {
631 error(SD_CARD_ERROR_WRITE_PROGRAMMING);
632 goto fail;
633 }
634 chipSelectHigh();
635 LEAVE_CRITICAL;
636 return true;
637
638 fail:
639 chipSelectHigh();
640 LEAVE_CRITICAL;
641 return false;
642}
643//------------------------------------------------------------------------------
644/** Write one data block in a multiple block write sequence */
645uint8_t Sd2Card::writeData(const uint8_t* src) {
646 uint8_t ret;
647 ENTER_CRITICAL;
648 // wait for previous write to finish
649 if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
650 error(SD_CARD_ERROR_WRITE_MULTIPLE);
651 chipSelectHigh();
652 ret = false;
653 }
654 else {
655 ret = writeData(WRITE_MULTIPLE_TOKEN, src);
656 }
657 LEAVE_CRITICAL;
658 return ret;
659}
660//------------------------------------------------------------------------------
661// send one block of data for write block or write multiple blocks
662uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) {
663#ifdef OPTIMIZE_HARDWARE_SPI
664
665 // send data - optimized loop
666 SPDR = token;
667
668 // send two byte per iteration
669 for (uint16_t i = 0; i < 512; i += 2) {
670 while (!(SPSR & (1 << SPIF)))
671 ;
672 SPDR = src[i];
673 while (!(SPSR & (1 << SPIF)))
674 ;
675 SPDR = src[i+1];
676 }
677
678 // wait for last data byte
679 while (!(SPSR & (1 << SPIF)))
680 ;
681
682#else // OPTIMIZE_HARDWARE_SPI
683 spiSend(token);
684 for (uint16_t i = 0; i < 512; i++) {
685 spiSend(src[i]);
686 }
687#endif // OPTIMIZE_HARDWARE_SPI
688 spiSend(0xff); // dummy crc
689 spiSend(0xff); // dummy crc
690
691 status_ = spiRec();
692 if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
693 error(SD_CARD_ERROR_WRITE);
694 chipSelectHigh();
695 return false;
696 }
697 return true;
698}
699//------------------------------------------------------------------------------
700/** Start a write multiple blocks sequence.
701 *
702 * \param[in] blockNumber Address of first block in sequence.
703 * \param[in] eraseCount The number of blocks to be pre-erased.
704 *
705 * \note This function is used with writeData() and writeStop()
706 * for optimized multiple block writes.
707 *
708 * \return The value one, true, is returned for success and
709 * the value zero, false, is returned for failure.
710 */
711uint8_t Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
712 ENTER_CRITICAL;
713#if SD_PROTECT_BLOCK_ZERO
714 // don't allow write to first block
715 if (blockNumber == 0) {
716 error(SD_CARD_ERROR_WRITE_BLOCK_ZERO);
717 goto fail;
718 }
719#endif // SD_PROTECT_BLOCK_ZERO
720 // send pre-erase count
721 if (cardAcmd(ACMD23, eraseCount)) {
722 error(SD_CARD_ERROR_ACMD23);
723 goto fail;
724 }
725 // use address if not SDHC card
726 if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
727 if (cardCommand(CMD25, blockNumber)) {
728 error(SD_CARD_ERROR_CMD25);
729 goto fail;
730 }
731 LEAVE_CRITICAL;
732 return true;
733
734 fail:
735 chipSelectHigh();
736 LEAVE_CRITICAL;
737 return false;
738}
739//------------------------------------------------------------------------------
740/** End a write multiple blocks sequence.
741 *
742* \return The value one, true, is returned for success and
743 * the value zero, false, is returned for failure.
744 */
745uint8_t Sd2Card::writeStop(void) {
746 ENTER_CRITICAL;
747 if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
748 spiSend(STOP_TRAN_TOKEN);
749 if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
750 chipSelectHigh();
751 LEAVE_CRITICAL;
752 return true;
753
754 fail:
755 error(SD_CARD_ERROR_STOP_TRAN);
756 chipSelectHigh();
757 LEAVE_CRITICAL;
758 return false;
759}
Note: See TracBrowser for help on using the repository browser.