Browse Source

updated to sdfatlib2010902

Bernhard Kubicek 13 years ago
parent
commit
64f2121ab1

+ 3
- 3
Marlin/Configuration.h View File

@@ -4,8 +4,8 @@
4 4
 
5 5
 
6 6
 // This determines the communication speed of the printer
7
-#define BAUDRATE 250000
8
-//#define BAUDRATE 115200
7
+//#define BAUDRATE 250000
8
+#define BAUDRATE 115200
9 9
 //#define BAUDRATE 230400
10 10
 
11 11
 
@@ -277,7 +277,7 @@ const bool ENDSTOPS_INVERTING = true; // set to true to invert the logic of the
277 277
 
278 278
 #define ULTIPANEL
279 279
 #ifdef ULTIPANEL
280
-//  #define NEWPANEL  //enable this if you have a click-encoder panel
280
+  #define NEWPANEL  //enable this if you have a click-encoder panel
281 281
   #define SDSUPPORT
282 282
   #define ULTRA_LCD
283 283
   #define LCD_WIDTH 20

+ 16
- 4
Marlin/Marlin.pde View File

@@ -26,6 +26,7 @@
26 26
  */
27 27
 
28 28
 #include <EEPROM.h>
29
+
29 30
 #include "EEPROMwrite.h"
30 31
 #include "fastio.h"
31 32
 #include "Configuration.h"
@@ -391,9 +392,15 @@ inline void get_command()
391 392
   while( !card.eof()  && buflen < BUFSIZE) {
392 393
     int16_t n=card.get();
393 394
     serial_char = (char)n;
395
+//     Serial.print((char)serial_char);
396
+//     Serial.print(" ");
397
+//     Serial.println((int)serial_count);
394 398
     if(serial_char == '\n' || serial_char == '\r' || serial_char == ':' || serial_count >= (MAX_CMD_SIZE - 1)||n==-1) 
395 399
     {
396
-     
400
+//       if(serial_char == '\n' || serial_char == '\r' )
401
+//         Serial.println("newline or :");
402
+//       if(serial_count >= (MAX_CMD_SIZE - 1))
403
+//         Serial.println("too long line");
397 404
       if(card.eof()){
398 405
         card.sdprinting = false;
399 406
         SERIAL_PROTOCOLLNPGM("Done printing file");
@@ -409,15 +416,20 @@ inline void get_command()
409 416
         LCD_MESSAGE(time);
410 417
         card.checkautostart(true);
411 418
       }
412
-      if(!serial_count) 
413
-	return; //if empty line
419
+      if(serial_char=='\n')
420
+         comment_mode = false; //for new command
421
+      if(!serial_count)
422
+      {
423
+// 	Serial.println("empty line");
424
+        return; //if empty line
425
+      }
414 426
       cmdbuffer[bufindw][serial_count] = 0; //terminate string
415 427
       if(!comment_mode){
416 428
         fromsd[bufindw] = true;
417 429
         buflen += 1;
418 430
         bufindw = (bufindw + 1)%BUFSIZE;
419 431
       }
420
-      comment_mode = false; //for new command
432
+     
421 433
       serial_count = 0; //clear buffer
422 434
     }
423 435
     else

+ 217
- 218
Marlin/Sd2Card.cpp View File

@@ -17,28 +17,77 @@
17 17
  * along with the Arduino Sd2Card Library.  If not, see
18 18
  * <http://www.gnu.org/licenses/>.
19 19
  */
20
+#if ARDUINO < 100
20 21
 #include <WProgram.h>
22
+#else  // ARDUINO
23
+#include <Arduino.h>
24
+#endif  // ARDUINO
21 25
 #include "Sd2Card.h"
22 26
 //------------------------------------------------------------------------------
23 27
 #ifndef SOFTWARE_SPI
24 28
 // functions for hardware SPI
25
-/** Send a byte to the card */
29
+//------------------------------------------------------------------------------
30
+// make sure SPCR rate is in expected bits
31
+#if (SPR0 != 0 || SPR1 != 1)
32
+#error unexpected SPCR bits
33
+#endif
34
+/**
35
+ * Initialize hardware SPI
36
+ * Set SCK rate to F_CPU/pow(2, 1 + spiRate) for spiRate [0,6]
37
+ */
38
+static void spiInit(uint8_t spiRate) {
39
+  // See avr processor documentation
40
+  SPCR = (1 << SPE) | (1 << MSTR) | (spiRate >> 1);
41
+  SPSR = spiRate & 1 || spiRate == 6 ? 0 : 1 << SPI2X;
42
+}
43
+//------------------------------------------------------------------------------
44
+/** SPI receive a byte */
45
+static uint8_t spiRec() {
46
+  SPDR = 0XFF;
47
+  while (!(SPSR & (1 << SPIF)));
48
+  return SPDR;
49
+}
50
+//------------------------------------------------------------------------------
51
+/** SPI read data - only one call so force inline */
52
+static inline __attribute__((always_inline))
53
+  void spiRead(uint8_t* buf, uint16_t nbyte) {
54
+  if (nbyte-- == 0) return;
55
+  SPDR = 0XFF;
56
+  for (uint16_t i = 0; i < nbyte; i++) {
57
+    while (!(SPSR & (1 << SPIF)));
58
+    buf[i] = SPDR;
59
+    SPDR = 0XFF;
60
+  }
61
+  while (!(SPSR & (1 << SPIF)));
62
+  buf[nbyte] = SPDR;
63
+}
64
+//------------------------------------------------------------------------------
65
+/** SPI send a byte */
26 66
 static void spiSend(uint8_t b) {
27 67
   SPDR = b;
28 68
   while (!(SPSR & (1 << SPIF)));
29 69
 }
30
-/** Receive a byte from the card */
31
-static  uint8_t spiRec(void) {
32
-  spiSend(0XFF);
33
-  return SPDR;
70
+//------------------------------------------------------------------------------
71
+/** SPI send block - only one call so force inline */
72
+static inline __attribute__((always_inline))
73
+  void spiSendBlock(uint8_t token, const uint8_t* buf) {
74
+  SPDR = token;
75
+  for (uint16_t i = 0; i < 512; i += 2) {
76
+    while (!(SPSR & (1 << SPIF)));
77
+    SPDR = buf[i];
78
+    while (!(SPSR & (1 << SPIF)));
79
+    SPDR = buf[i + 1];
80
+  }
81
+  while (!(SPSR & (1 << SPIF)));
34 82
 }
83
+//------------------------------------------------------------------------------
35 84
 #else  // SOFTWARE_SPI
36 85
 //------------------------------------------------------------------------------
37 86
 /** nop to tune soft SPI timing */
38 87
 #define nop asm volatile ("nop\n\t")
39 88
 //------------------------------------------------------------------------------
40
-/** Soft SPI receive */
41
-uint8_t spiRec(void) {
89
+/** Soft SPI receive byte */
90
+static uint8_t spiRec() {
42 91
   uint8_t data = 0;
43 92
   // no interrupts during byte receive - about 8 us
44 93
   cli();
@@ -63,8 +112,15 @@ uint8_t spiRec(void) {
63 112
   return data;
64 113
 }
65 114
 //------------------------------------------------------------------------------
66
-/** Soft SPI send */
67
-void spiSend(uint8_t data) {
115
+/** Soft SPI read data */
116
+static void spiRead(uint8_t* buf, uint16_t nbyte) {
117
+  for (uint16_t i = 0; i < nbyte; i++) {
118
+    buf[i] = spiRec();
119
+  }
120
+}
121
+//------------------------------------------------------------------------------
122
+/** Soft SPI send byte */
123
+static void spiSend(uint8_t data) {
68 124
   // no interrupts during byte send - about 8 us
69 125
   cli();
70 126
   for (uint8_t i = 0; i < 8; i++) {
@@ -86,13 +142,18 @@ void spiSend(uint8_t data) {
86 142
   // enable interrupts
87 143
   sei();
88 144
 }
145
+//------------------------------------------------------------------------------
146
+/** Soft SPI send block */
147
+  void spiSendBlock(uint8_t token, const uint8_t* buf) {
148
+  spiSend(token);
149
+  for (uint16_t i = 0; i < 512; i++) {
150
+    spiSend(buf[i]);
151
+  }
152
+}
89 153
 #endif  // SOFTWARE_SPI
90 154
 //------------------------------------------------------------------------------
91 155
 // send command and return error code.  Return zero for OK
92 156
 uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
93
-  // end read if in partialBlockRead mode
94
-  readEnd();
95
-
96 157
   // select card
97 158
   chipSelectLow();
98 159
 
@@ -111,6 +172,9 @@ uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
111 172
   if (cmd == CMD8) crc = 0X87;  // correct crc for CMD8 with arg 0X1AA
112 173
   spiSend(crc);
113 174
 
175
+  // skip stuff byte for stop read
176
+  if (cmd == CMD12) spiRec();
177
+
114 178
   // wait for response
115 179
   for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++);
116 180
   return status_;
@@ -122,7 +186,7 @@ uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
122 186
  * \return The number of 512 byte data blocks in the card
123 187
  *         or zero if an error occurs.
124 188
  */
125
-uint32_t Sd2Card::cardSize(void) {
189
+uint32_t Sd2Card::cardSize() {
126 190
   csd_t csd;
127 191
   if (!readCSD(&csd)) return 0;
128 192
   if (csd.v1.csd_ver == 0) {
@@ -142,11 +206,14 @@ uint32_t Sd2Card::cardSize(void) {
142 206
   }
143 207
 }
144 208
 //------------------------------------------------------------------------------
145
-void Sd2Card::chipSelectHigh(void) {
209
+void Sd2Card::chipSelectHigh() {
146 210
   digitalWrite(chipSelectPin_, HIGH);
147 211
 }
148 212
 //------------------------------------------------------------------------------
149
-void Sd2Card::chipSelectLow(void) {
213
+void Sd2Card::chipSelectLow() {
214
+#ifndef SOFTWARE_SPI
215
+  spiInit(spiRate_);
216
+#endif  // SOFTWARE_SPI
150 217
   digitalWrite(chipSelectPin_, LOW);
151 218
 }
152 219
 //------------------------------------------------------------------------------
@@ -163,10 +230,18 @@ void Sd2Card::chipSelectLow(void) {
163 230
  * \return The value one, true, is returned for success and
164 231
  * the value zero, false, is returned for failure.
165 232
  */
166
-uint8_t Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
167
-  if (!eraseSingleBlockEnable()) {
168
-    error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK);
169
-    goto fail;
233
+bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
234
+  csd_t csd;
235
+  if (!readCSD(&csd)) goto fail;
236
+  // check for single block erase
237
+  if (!csd.v1.erase_blk_en) {
238
+    // erase size mask
239
+    uint8_t m = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low;
240
+    if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) {
241
+      // error card can't erase specified area
242
+      error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK);
243
+      goto fail;
244
+    }
170 245
   }
171 246
   if (type_ != SD_CARD_TYPE_SDHC) {
172 247
     firstBlock <<= 9;
@@ -195,9 +270,9 @@ uint8_t Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
195 270
  * \return The value one, true, is returned if single block erase is supported.
196 271
  * The value zero, false, is returned if single block erase is not supported.
197 272
  */
198
-uint8_t Sd2Card::eraseSingleBlockEnable(void) {
273
+bool Sd2Card::eraseSingleBlockEnable() {
199 274
   csd_t csd;
200
-  return readCSD(&csd) ? csd.v1.erase_blk_en : 0;
275
+  return readCSD(&csd) ? csd.v1.erase_blk_en : false;
201 276
 }
202 277
 //------------------------------------------------------------------------------
203 278
 /**
@@ -210,8 +285,8 @@ uint8_t Sd2Card::eraseSingleBlockEnable(void) {
210 285
  * the value zero, false, is returned for failure.  The reason for failure
211 286
  * can be determined by calling errorCode() and errorData().
212 287
  */
213
-uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
214
-  errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;
288
+bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
289
+  errorCode_ = type_ = 0;
215 290
   chipSelectPin_ = chipSelectPin;
216 291
   // 16-bit init start time allows over a minute
217 292
   uint16_t t0 = (uint16_t)millis();
@@ -227,17 +302,18 @@ uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
227 302
 #ifndef SOFTWARE_SPI
228 303
   // SS must be in output mode even it is not chip select
229 304
   pinMode(SS_PIN, OUTPUT);
230
-  // Enable SPI, Master, clock rate f_osc/128
231
-  SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
232
-  // clear double speed
233
-  SPSR &= ~(1 << SPI2X);
305
+  // set SS high - may be chip select for another SPI device
306
+#if SET_SPI_SS_HIGH
307
+  digitalWrite(SS_PIN, HIGH);
308
+#endif  // SET_SPI_SS_HIGH
309
+  // set SCK rate for initialization commands
310
+  spiRate_ = SPI_SD_INIT_RATE;
311
+  spiInit(spiRate_);
234 312
 #endif  // SOFTWARE_SPI
235 313
 
236 314
   // must supply min of 74 clock cycles with CS high.
237 315
   for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
238 316
 
239
-  chipSelectLow();
240
-
241 317
   // command to go idle in SPI mode
242 318
   while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
243 319
     if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
@@ -291,105 +367,60 @@ uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
291 367
 }
292 368
 //------------------------------------------------------------------------------
293 369
 /**
294
- * Enable or disable partial block reads.
295
- *
296
- * Enabling partial block reads improves performance by allowing a block
297
- * to be read over the SPI bus as several sub-blocks.  Errors may occur
298
- * if the time between reads is too long since the SD card may timeout.
299
- * The SPI SS line will be held low until the entire block is read or
300
- * readEnd() is called.
370
+ * Read a 512 byte block from an SD card.
301 371
  *
302
- * Use this for applications like the Adafruit Wave Shield.
303
- *
304
- * \param[in] value The value TRUE (non-zero) or FALSE (zero).)
305
- */
306
-void Sd2Card::partialBlockRead(uint8_t value) {
307
-  readEnd();
308
-  partialBlockRead_ = value;
309
-}
310
-//------------------------------------------------------------------------------
311
-/**
312
- * Read a 512 byte block from an SD card device.
313
- *
314
- * \param[in] block Logical block to be read.
372
+ * \param[in] blockNumber Logical block to be read.
315 373
  * \param[out] dst Pointer to the location that will receive the data.
316 374
 
317 375
  * \return The value one, true, is returned for success and
318 376
  * the value zero, false, is returned for failure.
319 377
  */
320
-uint8_t Sd2Card::readBlock(uint32_t block, uint8_t* dst) {
321
-  return readData(block, 0, 512, dst);
378
+bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
379
+  // use address if not SDHC card
380
+  if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9;
381
+  if (cardCommand(CMD17, blockNumber)) {
382
+    error(SD_CARD_ERROR_CMD17);
383
+    goto fail;
384
+  }
385
+  return readData(dst, 512);
386
+
387
+ fail:
388
+  chipSelectHigh();
389
+  return false;
322 390
 }
323 391
 //------------------------------------------------------------------------------
324
-/**
325
- * Read part of a 512 byte block from an SD card.
392
+/** Read one data block in a multiple block read sequence
393
+ *
394
+ * \param[in] dst Pointer to the location for the data to be read.
326 395
  *
327
- * \param[in] block Logical block to be read.
328
- * \param[in] offset Number of bytes to skip at start of block
329
- * \param[out] dst Pointer to the location that will receive the data.
330
- * \param[in] count Number of bytes to read
331 396
  * \return The value one, true, is returned for success and
332 397
  * the value zero, false, is returned for failure.
333 398
  */
334
-uint8_t Sd2Card::readData(uint32_t block,
335
-        uint16_t offset, uint16_t count, uint8_t* dst) {
336
-  uint16_t n;
337
-  if (count == 0) return true;
338
-  if ((count + offset) > 512) {
339
-    goto fail;
340
-  }
341
-  if (!inBlock_ || block != block_ || offset < offset_) {
342
-    block_ = block;
343
-    // use address if not SDHC card
344
-    if (type()!= SD_CARD_TYPE_SDHC) block <<= 9;
345
-    if (cardCommand(CMD17, block)) {
346
-      error(SD_CARD_ERROR_CMD17);
347
-      goto fail;
348
-    }
349
-    if (!waitStartBlock()) {
399
+bool Sd2Card::readData(uint8_t *dst) {
400
+  chipSelectLow();
401
+  return readData(dst, 512);
402
+}
403
+//------------------------------------------------------------------------------
404
+bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
405
+  // wait for start block token
406
+  uint16_t t0 = millis();
407
+  while ((status_ = spiRec()) == 0XFF) {
408
+    if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) {
409
+      error(SD_CARD_ERROR_READ_TIMEOUT);
350 410
       goto fail;
351 411
     }
352
-    offset_ = 0;
353
-    inBlock_ = 1;
354
-  }
355
-
356
-#ifdef OPTIMIZE_HARDWARE_SPI
357
-  // start first spi transfer
358
-  SPDR = 0XFF;
359
-
360
-  // skip data before offset
361
-  for (;offset_ < offset; offset_++) {
362
-    while (!(SPSR & (1 << SPIF)));
363
-    SPDR = 0XFF;
364
-  }
365
-  // transfer data
366
-  n = count - 1;
367
-  for (uint16_t i = 0; i < n; i++) {
368
-    while (!(SPSR & (1 << SPIF)));
369
-    dst[i] = SPDR;
370
-    SPDR = 0XFF;
371 412
   }
372
-  // wait for last byte
373
-  while (!(SPSR & (1 << SPIF)));
374
-  dst[n] = SPDR;
375
-
376
-#else  // OPTIMIZE_HARDWARE_SPI
377
-
378
-  // skip data before offset
379
-  for (;offset_ < offset; offset_++) {
380
-    spiRec();
413
+  if (status_ != DATA_START_BLOCK) {
414
+    error(SD_CARD_ERROR_READ);
415
+    goto fail;
381 416
   }
382 417
   // transfer data
383
-  for (uint16_t i = 0; i < count; i++) {
384
-    dst[i] = spiRec();
385
-  }
386
-#endif  // OPTIMIZE_HARDWARE_SPI
418
+  spiRead(dst, count);
387 419
 
388
-  offset_ += count;
389
-  if (!partialBlockRead_ || offset_ >= 512) {
390
-    // read rest of data, checksum and set chip select high
391
-    readEnd();
392
-  }
420
+  // discard CRC
421
+  spiRec();
422
+  spiRec();
423
+  chipSelectHigh();
393 424
   return true;
394 425
 
395 426
  fail:
@@ -397,39 +428,55 @@ uint8_t Sd2Card::readData(uint32_t block,
397 428
   return false;
398 429
 }
399 430
 //------------------------------------------------------------------------------
400
-/** Skip remaining data in a block when in partial block read mode. */
401
-void Sd2Card::readEnd(void) {
402
-  if (inBlock_) {
403
-      // skip data and crc
404
-#ifdef OPTIMIZE_HARDWARE_SPI
405
-    // optimize skip for hardware
406
-    SPDR = 0XFF;
407
-    while (offset_++ < 513) {
408
-      while (!(SPSR & (1 << SPIF)));
409
-      SPDR = 0XFF;
410
-    }
411
-    // wait for last crc byte
412
-    while (!(SPSR & (1 << SPIF)));
413
-#else  // OPTIMIZE_HARDWARE_SPI
414
-    while (offset_++ < 514) spiRec();
415
-#endif  // OPTIMIZE_HARDWARE_SPI
416
-    chipSelectHigh();
417
-    inBlock_ = 0;
418
-  }
419
-}
420
-//------------------------------------------------------------------------------
421 431
 /** read CID or CSR register */
422
-uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {
432
+bool Sd2Card::readRegister(uint8_t cmd, void* buf) {
423 433
   uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
424 434
   if (cardCommand(cmd, 0)) {
425 435
     error(SD_CARD_ERROR_READ_REG);
426 436
     goto fail;
427 437
   }
428
-  if (!waitStartBlock()) goto fail;
429
-  // transfer data
430
-  for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec();
431
-  spiRec();  // get first crc byte
432
-  spiRec();  // get second crc byte
438
+  return readData(dst, 16);
439
+
440
+ fail:
441
+  chipSelectHigh();
442
+  return false;
443
+}
444
+//------------------------------------------------------------------------------
445
+/** Start a read multiple blocks sequence.
446
+ *
447
+ * \param[in] blockNumber Address of first block in sequence.
448
+ *
449
+ * \note This function is used with readData() and readStop() for optimized
450
+ * multiple block reads.  SPI chipSelect must be low for the entire sequence.
451
+ *
452
+ * \return The value one, true, is returned for success and
453
+ * the value zero, false, is returned for failure.
454
+ */
455
+bool Sd2Card::readStart(uint32_t blockNumber) {
456
+  if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9;
457
+  if (cardCommand(CMD18, blockNumber)) {
458
+    error(SD_CARD_ERROR_CMD18);
459
+    goto fail;
460
+  }
461
+  chipSelectHigh();
462
+  return true;
463
+
464
+ fail:
465
+  chipSelectHigh();
466
+  return false;
467
+}
468
+//------------------------------------------------------------------------------
469
+/** End a read multiple blocks sequence.
470
+ *
471
+* \return The value one, true, is returned for success and
472
+ * the value zero, false, is returned for failure.
473
+ */
474
+bool Sd2Card::readStop() {
475
+  chipSelectLow();
476
+  if (cardCommand(CMD12, 0)) {
477
+    error(SD_CARD_ERROR_CMD12);
478
+    goto fail;
479
+  }
433 480
   chipSelectHigh();
434 481
   return true;
435 482
 
@@ -450,50 +497,24 @@ uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {
450 497
  * \return The value one, true, is returned for success and the value zero,
451 498
  * false, is returned for an invalid value of \a sckRateID.
452 499
  */
453
-uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {
500
+bool Sd2Card::setSckRate(uint8_t sckRateID) {
454 501
   if (sckRateID > 6) {
455 502
     error(SD_CARD_ERROR_SCK_RATE);
456 503
     return false;
457 504
   }
458
-  // see avr processor datasheet for SPI register bit definitions
459
-  if ((sckRateID & 1) || sckRateID == 6) {
460
-    SPSR &= ~(1 << SPI2X);
461
-  } else {
462
-    SPSR |= (1 << SPI2X);
463
-  }
464
-  SPCR &= ~((1 <<SPR1) | (1 << SPR0));
465
-  SPCR |= (sckRateID & 4 ? (1 << SPR1) : 0)
466
-    | (sckRateID & 2 ? (1 << SPR0) : 0);
505
+  spiRate_ = sckRateID;
467 506
   return true;
468 507
 }
469 508
 //------------------------------------------------------------------------------
470 509
 // wait for card to go not busy
471
-uint8_t Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
510
+bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
472 511
   uint16_t t0 = millis();
473
-  do {
474
-    if (spiRec() == 0XFF) return true;
475
-  }
476
-  while (((uint16_t)millis() - t0) < timeoutMillis);
477
-  return false;
478
-}
479
-//------------------------------------------------------------------------------
480
-/** Wait for start block token */
481
-uint8_t Sd2Card::waitStartBlock(void) {
482
-  uint16_t t0 = millis();
483
-  while ((status_ = spiRec()) == 0XFF) {
484
-    if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) {
485
-      error(SD_CARD_ERROR_READ_TIMEOUT);
486
-      goto fail;
487
-    }
488
-  }
489
-  if (status_ != DATA_START_BLOCK) {
490
-    error(SD_CARD_ERROR_READ);
491
-    goto fail;
512
+  while (spiRec() != 0XFF) {
513
+    if (((uint16_t)millis() - t0) >= timeoutMillis) goto fail;
492 514
   }
493 515
   return true;
494 516
 
495 517
  fail:
496
-  chipSelectHigh();
497 518
   return false;
498 519
 }
499 520
 //------------------------------------------------------------------------------
@@ -505,15 +526,7 @@ uint8_t Sd2Card::waitStartBlock(void) {
505 526
  * \return The value one, true, is returned for success and
506 527
  * the value zero, false, is returned for failure.
507 528
  */
508
-uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
509
-#if SD_PROTECT_BLOCK_ZERO
510
-  // don't allow write to first block
511
-  if (blockNumber == 0) {
512
-    error(SD_CARD_ERROR_WRITE_BLOCK_ZERO);
513
-    goto fail;
514
-  }
515
-#endif  // SD_PROTECT_BLOCK_ZERO
516
-
529
+bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
517 530
   // use address if not SDHC card
518 531
   if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
519 532
   if (cardCommand(CMD24, blockNumber)) {
@@ -540,51 +553,42 @@ uint8_t Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
540 553
   return false;
541 554
 }
542 555
 //------------------------------------------------------------------------------
543
-/** Write one data block in a multiple block write sequence */
544
-uint8_t Sd2Card::writeData(const uint8_t* src) {
556
+/** Write one data block in a multiple block write sequence
557
+ * \param[in] src Pointer to the location of the data to be written.
558
+ * \return The value one, true, is returned for success and
559
+ * the value zero, false, is returned for failure.
560
+ */
561
+bool Sd2Card::writeData(const uint8_t* src) {
562
+  chipSelectLow();
545 563
   // wait for previous write to finish
546
-  if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
547
-    error(SD_CARD_ERROR_WRITE_MULTIPLE);
548
-    chipSelectHigh();
549
-    return false;
550
-  }
551
-  return writeData(WRITE_MULTIPLE_TOKEN, src);
564
+  if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
565
+  if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto fail;
566
+  chipSelectHigh();
567
+  return true;
568
+
569
+ fail:
570
+  error(SD_CARD_ERROR_WRITE_MULTIPLE);
571
+  chipSelectHigh();
572
+  return false;
552 573
 }
553 574
 //------------------------------------------------------------------------------
554 575
 // send one block of data for write block or write multiple blocks
555
-uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) {
556
-#ifdef OPTIMIZE_HARDWARE_SPI
557
-
558
-  // send data - optimized loop
559
-  SPDR = token;
560
-
561
-  // send two byte per iteration
562
-  for (uint16_t i = 0; i < 512; i += 2) {
563
-    while (!(SPSR & (1 << SPIF)));
564
-    SPDR = src[i];
565
-    while (!(SPSR & (1 << SPIF)));
566
-    SPDR = src[i+1];
567
-  }
568
-
569
-  // wait for last data byte
570
-  while (!(SPSR & (1 << SPIF)));
576
+bool Sd2Card::writeData(uint8_t token, const uint8_t* src) {
577
+  spiSendBlock(token, src);
571 578
 
572
-#else  // OPTIMIZE_HARDWARE_SPI
573
-  spiSend(token);
574
-  for (uint16_t i = 0; i < 512; i++) {
575
-    spiSend(src[i]);
576
-  }
577
-#endif  // OPTIMIZE_HARDWARE_SPI
578 579
   spiSend(0xff);  // dummy crc
579 580
   spiSend(0xff);  // dummy crc
580 581
 
581 582
   status_ = spiRec();
582 583
   if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
583 584
     error(SD_CARD_ERROR_WRITE);
584
-    chipSelectHigh();
585
-    return false;
585
+    goto fail;
586 586
   }
587 587
   return true;
588
+
589
+ fail:
590
+  chipSelectHigh();
591
+  return false;
588 592
 }
589 593
 //------------------------------------------------------------------------------
590 594
 /** Start a write multiple blocks sequence.
@@ -598,14 +602,7 @@ uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) {
598 602
  * \return The value one, true, is returned for success and
599 603
  * the value zero, false, is returned for failure.
600 604
  */
601
-uint8_t Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
602
-#if SD_PROTECT_BLOCK_ZERO
603
-  // don't allow write to first block
604
-  if (blockNumber == 0) {
605
-    error(SD_CARD_ERROR_WRITE_BLOCK_ZERO);
606
-    goto fail;
607
-  }
608
-#endif  // SD_PROTECT_BLOCK_ZERO
605
+bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
609 606
   // send pre-erase count
610 607
   if (cardAcmd(ACMD23, eraseCount)) {
611 608
     error(SD_CARD_ERROR_ACMD23);
@@ -617,6 +614,7 @@ uint8_t Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
617 614
     error(SD_CARD_ERROR_CMD25);
618 615
     goto fail;
619 616
   }
617
+  chipSelectHigh();
620 618
   return true;
621 619
 
622 620
  fail:
@@ -629,7 +627,8 @@ uint8_t Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
629 627
 * \return The value one, true, is returned for success and
630 628
  * the value zero, false, is returned for failure.
631 629
  */
632
-uint8_t Sd2Card::writeStop(void) {
630
+bool Sd2Card::writeStop() {
631
+  chipSelectLow();
633 632
   if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
634 633
   spiSend(STOP_TRAN_TOKEN);
635 634
   if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;

+ 127
- 126
Marlin/Sd2Card.h View File

@@ -21,67 +21,24 @@
21 21
 #define Sd2Card_h
22 22
 /**
23 23
  * \file
24
- * Sd2Card class
24
+ * \brief Sd2Card class for V2 SD/SDHC cards
25 25
  */
26
+#include "SdFatConfig.h"
26 27
 #include "Sd2PinMap.h"
27 28
 #include "SdInfo.h"
29
+//------------------------------------------------------------------------------
30
+// SPI speed is F_CPU/2^(1 + index), 0 <= index <= 6
28 31
 /** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */
29 32
 uint8_t const SPI_FULL_SPEED = 0;
30 33
 /** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */
31 34
 uint8_t const SPI_HALF_SPEED = 1;
32
-/** Set SCK rate to F_CPU/8. Sd2Card::setSckRate(). */
35
+/** Set SCK rate to F_CPU/8. See Sd2Card::setSckRate(). */
33 36
 uint8_t const SPI_QUARTER_SPEED = 2;
34
-/**
35
- * Define MEGA_SOFT_SPI non-zero to use software SPI on Mega Arduinos.
36
- * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13.
37
- *
38
- * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used
39
- * on Mega Arduinos.  Software SPI works well with GPS Shield V1.1
40
- * but many SD cards will fail with GPS Shield V1.0.
41
- */
42
-#define MEGA_SOFT_SPI 0
43
-//------------------------------------------------------------------------------
44
-#if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__))
45
-#define SOFTWARE_SPI
46
-#endif  // MEGA_SOFT_SPI
47
-//------------------------------------------------------------------------------
48
-// SPI pin definitions
49
-//
50
-#ifndef SOFTWARE_SPI
51
-// hardware pin defs
52
-/**
53
- * SD Chip Select pin
54
- *
55
- * Warning if this pin is redefined the hardware SS will pin will be enabled
56
- * as an output by init().  An avr processor will not function as an SPI
57
- * master unless SS is set to output mode.
58
- */
59
-/** The default chip select pin for the SD card is SS. */
60
-uint8_t const  SD_CHIP_SELECT_PIN = SS_PIN;
61
-// The following three pins must not be redefined for hardware SPI.
62
-/** SPI Master Out Slave In pin */
63
-uint8_t const  SPI_MOSI_PIN = MOSI_PIN;
64
-/** SPI Master In Slave Out pin */
65
-uint8_t const  SPI_MISO_PIN = MISO_PIN;
66
-/** SPI Clock pin */
67
-uint8_t const  SPI_SCK_PIN = SCK_PIN;
68
-/** optimize loops for hardware SPI */
69
-#define OPTIMIZE_HARDWARE_SPI
70
-
71
-#else  // SOFTWARE_SPI
72
-// define software SPI pins so Mega can use unmodified GPS Shield
73
-/** SPI chip select pin */
74
-uint8_t const SD_CHIP_SELECT_PIN = 10;
75
-/** SPI Master Out Slave In pin */
76
-uint8_t const SPI_MOSI_PIN = 11;
77
-/** SPI Master In Slave Out pin */
78
-uint8_t const SPI_MISO_PIN = 12;
79
-/** SPI Clock pin */
80
-uint8_t const SPI_SCK_PIN = 13;
81
-#endif  // SOFTWARE_SPI
37
+/** Set SCK rate to F_CPU/16. See Sd2Card::setSckRate(). */
38
+uint8_t const SPI_EIGHTH_SPEED = 3;
39
+/** Set SCK rate to F_CPU/32. See Sd2Card::setSckRate(). */
40
+uint8_t const SPI_SIXTEENTH_SPEED = 4;
82 41
 //------------------------------------------------------------------------------
83
-/** Protect block zero from write if nonzero */
84
-#define SD_PROTECT_BLOCK_ZERO 1
85 42
 /** init timeout ms */
86 43
 uint16_t const SD_INIT_TIMEOUT = 2000;
87 44
 /** erase timeout ms */
@@ -92,58 +49,99 @@ uint16_t const SD_READ_TIMEOUT = 300;
92 49
 uint16_t const SD_WRITE_TIMEOUT = 600;
93 50
 //------------------------------------------------------------------------------
94 51
 // SD card errors
95
-/** timeout error for command CMD0 */
52
+/** timeout error for command CMD0 (initialize card in SPI mode) */
96 53
 uint8_t const SD_CARD_ERROR_CMD0 = 0X1;
97 54
 /** CMD8 was not accepted - not a valid SD card*/
98 55
 uint8_t const SD_CARD_ERROR_CMD8 = 0X2;
56
+/** card returned an error response for CMD12 (write stop) */
57
+uint8_t const SD_CARD_ERROR_CMD12 = 0X3;
99 58
 /** card returned an error response for CMD17 (read block) */
100
-uint8_t const SD_CARD_ERROR_CMD17 = 0X3;
59
+uint8_t const SD_CARD_ERROR_CMD17 = 0X4;
60
+/** card returned an error response for CMD18 (read multiple block) */
61
+uint8_t const SD_CARD_ERROR_CMD18 = 0X5;
101 62
 /** card returned an error response for CMD24 (write block) */
102
-uint8_t const SD_CARD_ERROR_CMD24 = 0X4;
63
+uint8_t const SD_CARD_ERROR_CMD24 = 0X6;
103 64
 /**  WRITE_MULTIPLE_BLOCKS command failed */
104
-uint8_t const SD_CARD_ERROR_CMD25 = 0X05;
65
+uint8_t const SD_CARD_ERROR_CMD25 = 0X7;
105 66
 /** card returned an error response for CMD58 (read OCR) */
106
-uint8_t const SD_CARD_ERROR_CMD58 = 0X06;
67
+uint8_t const SD_CARD_ERROR_CMD58 = 0X8;
107 68
 /** SET_WR_BLK_ERASE_COUNT failed */
108
-uint8_t const SD_CARD_ERROR_ACMD23 = 0X07;
109
-/** card's ACMD41 initialization process timeout */
110
-uint8_t const SD_CARD_ERROR_ACMD41 = 0X08;
69
+uint8_t const SD_CARD_ERROR_ACMD23 = 0X9;
70
+/** ACMD41 initialization process timeout */
71
+uint8_t const SD_CARD_ERROR_ACMD41 = 0XA;
111 72
 /** card returned a bad CSR version field */
112
-uint8_t const SD_CARD_ERROR_BAD_CSD = 0X09;
73
+uint8_t const SD_CARD_ERROR_BAD_CSD = 0XB;
113 74
 /** erase block group command failed */
114
-uint8_t const SD_CARD_ERROR_ERASE = 0X0A;
75
+uint8_t const SD_CARD_ERROR_ERASE = 0XC;
115 76
 /** card not capable of single block erase */
116
-uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0X0B;
77
+uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0XD;
117 78
 /** Erase sequence timed out */
118
-uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0X0C;
79
+uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0XE;
119 80
 /** card returned an error token instead of read data */
120
-uint8_t const SD_CARD_ERROR_READ = 0X0D;
81
+uint8_t const SD_CARD_ERROR_READ = 0XF;
121 82
 /** read CID or CSD failed */
122
-uint8_t const SD_CARD_ERROR_READ_REG = 0X0E;
83
+uint8_t const SD_CARD_ERROR_READ_REG = 0X10;
123 84
 /** timeout while waiting for start of read data */
124
-uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X0F;
85
+uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X11;
125 86
 /** card did not accept STOP_TRAN_TOKEN */
126
-uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X10;
87
+uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X12;
127 88
 /** card returned an error token as a response to a write operation */
128
-uint8_t const SD_CARD_ERROR_WRITE = 0X11;
89
+uint8_t const SD_CARD_ERROR_WRITE = 0X13;
129 90
 /** attempt to write protected block zero */
130
-uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X12;
91
+uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X14;  // REMOVE - not used
131 92
 /** card did not go ready for a multiple block write */
132
-uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X13;
93
+uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X15;
133 94
 /** card returned an error to a CMD13 status check after a write */
134
-uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X14;
95
+uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X16;
135 96
 /** timeout occurred during write programming */
136
-uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X15;
97
+uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X17;
137 98
 /** incorrect rate selected */
138
-uint8_t const SD_CARD_ERROR_SCK_RATE = 0X16;
99
+uint8_t const SD_CARD_ERROR_SCK_RATE = 0X18;
100
+/** init() not called */
101
+uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0X19;
139 102
 //------------------------------------------------------------------------------
140 103
 // card types
141 104
 /** Standard capacity V1 SD card */
142
-uint8_t const SD_CARD_TYPE_SD1 = 1;
105
+uint8_t const SD_CARD_TYPE_SD1  = 1;
143 106
 /** Standard capacity V2 SD card */
144
-uint8_t const SD_CARD_TYPE_SD2 = 2;
107
+uint8_t const SD_CARD_TYPE_SD2  = 2;
145 108
 /** High Capacity SD card */
146 109
 uint8_t const SD_CARD_TYPE_SDHC = 3;
110
+/**
111
+ * define SOFTWARE_SPI to use bit-bang SPI
112
+ */
113
+//------------------------------------------------------------------------------
114
+#if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__))
115
+#define SOFTWARE_SPI
116
+#elif USE_SOFTWARE_SPI
117
+#define SOFTWARE_SPI
118
+#endif  // MEGA_SOFT_SPI
119
+//------------------------------------------------------------------------------
120
+// SPI pin definitions - do not edit here - change in SdFatConfig.h
121
+//
122
+#ifndef SOFTWARE_SPI
123
+// hardware pin defs
124
+/** The default chip select pin for the SD card is SS. */
125
+uint8_t const  SD_CHIP_SELECT_PIN = SS_PIN;
126
+// The following three pins must not be redefined for hardware SPI.
127
+/** SPI Master Out Slave In pin */
128
+uint8_t const  SPI_MOSI_PIN = MOSI_PIN;
129
+/** SPI Master In Slave Out pin */
130
+uint8_t const  SPI_MISO_PIN = MISO_PIN;
131
+/** SPI Clock pin */
132
+uint8_t const  SPI_SCK_PIN = SCK_PIN;
133
+
134
+#else  // SOFTWARE_SPI
135
+
136
+/** SPI chip select pin */
137
+uint8_t const SD_CHIP_SELECT_PIN = SOFT_SPI_CS_PIN;
138
+/** SPI Master Out Slave In pin */
139
+uint8_t const SPI_MOSI_PIN = SOFT_SPI_MOSI_PIN;
140
+/** SPI Master In Slave Out pin */
141
+uint8_t const SPI_MISO_PIN = SOFT_SPI_MISO_PIN;
142
+/** SPI Clock pin */
143
+uint8_t const SPI_SCK_PIN = SOFT_SPI_SCK_PIN;
144
+#endif  // SOFTWARE_SPI
147 145
 //------------------------------------------------------------------------------
148 146
 /**
149 147
  * \class Sd2Card
@@ -152,66 +150,70 @@ uint8_t const SD_CARD_TYPE_SDHC = 3;
152 150
 class Sd2Card {
153 151
  public:
154 152
   /** Construct an instance of Sd2Card. */
155
-  Sd2Card(void) : errorCode_(0), inBlock_(0), partialBlockRead_(0), type_(0) {}
156
-  uint32_t cardSize(void);
157
-  uint8_t erase(uint32_t firstBlock, uint32_t lastBlock);
158
-  uint8_t eraseSingleBlockEnable(void);
153
+  Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {}
154
+  uint32_t cardSize();
155
+  bool erase(uint32_t firstBlock, uint32_t lastBlock);
156
+  bool eraseSingleBlockEnable();
157
+  /**
158
+   *  Set SD error code.
159
+   *  \param[in] code value for error code.
160
+   */
161
+  void error(uint8_t code) {errorCode_ = code;}
159 162
   /**
160 163
    * \return error code for last error. See Sd2Card.h for a list of error codes.
161 164
    */
162
-  uint8_t errorCode(void) const {return errorCode_;}
165
+  int errorCode() const {return errorCode_;}
163 166
   /** \return error data for last error. */
164
-  uint8_t errorData(void) const {return status_;}
167
+  int errorData() const {return status_;}
165 168
   /**
166 169
    * Initialize an SD flash memory card with default clock rate and chip
167 170
    * select pin.  See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin).
171
+   *
172
+   * \return true for success or false for failure.
168 173
    */
169
-  uint8_t init(void) {
170
-    return init(SPI_FULL_SPEED, SD_CHIP_SELECT_PIN);
171
-  }
174
+  bool init(uint8_t sckRateID = SPI_FULL_SPEED,
175
+    uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
176
+  bool readBlock(uint32_t block, uint8_t* dst);
172 177
   /**
173
-   * Initialize an SD flash memory card with the selected SPI clock rate
174
-   * and the default SD chip select pin.
175
-   * See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin).
176
-   */
177
-  uint8_t init(uint8_t sckRateID) {
178
-    return init(sckRateID, SD_CHIP_SELECT_PIN);
179
-  }
180
-  uint8_t init(uint8_t sckRateID, uint8_t chipSelectPin);
181
-  void partialBlockRead(uint8_t value);
182
-  /** Returns the current value, true or false, for partial block read. */
183
-  uint8_t partialBlockRead(void) const {return partialBlockRead_;}
184
-  uint8_t readBlock(uint32_t block, uint8_t* dst);
185
-  uint8_t readData(uint32_t block,
186
-          uint16_t offset, uint16_t count, uint8_t* dst);
187
-  /**
188
-   * Read a cards CID register. The CID contains card identification
178
+   * Read a card's CID register. The CID contains card identification
189 179
    * information such as Manufacturer ID, Product name, Product serial
190
-   * number and Manufacturing date. */
191
-  uint8_t readCID(cid_t* cid) {
180
+   * number and Manufacturing date. 
181
+   *
182
+   * \param[out] cid pointer to area for returned data.
183
+   *
184
+   * \return true for success or false for failure.
185
+   */
186
+  bool readCID(cid_t* cid) {
192 187
     return readRegister(CMD10, cid);
193 188
   }
194 189
   /**
195
-   * Read a cards CSD register. The CSD contains Card-Specific Data that
196
-   * provides information regarding access to the card's contents. */
197
-  uint8_t readCSD(csd_t* csd) {
190
+   * Read a card's CSD register. The CSD contains Card-Specific Data that
191
+   * provides information regarding access to the card's contents.
192
+   *
193
+   * \param[out] csd pointer to area for returned data.
194
+   *
195
+   * \return true for success or false for failure.
196
+   */
197
+  bool readCSD(csd_t* csd) {
198 198
     return readRegister(CMD9, csd);
199 199
   }
200
-  void readEnd(void);
201
-  uint8_t setSckRate(uint8_t sckRateID);
202
-  /** Return the card type: SD V1, SD V2 or SDHC */
203
-  uint8_t type(void) const {return type_;}
204
-  uint8_t writeBlock(uint32_t blockNumber, const uint8_t* src);
205
-  uint8_t writeData(const uint8_t* src);
206
-  uint8_t writeStart(uint32_t blockNumber, uint32_t eraseCount);
207
-  uint8_t writeStop(void);
200
+  bool readData(uint8_t *dst);
201
+  bool readStart(uint32_t blockNumber);
202
+  bool readStop();
203
+  bool setSckRate(uint8_t sckRateID);
204
+  /** Return the card type: SD V1, SD V2 or SDHC
205
+   * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC.
206
+   */
207
+  int type() const {return type_;}
208
+  bool writeBlock(uint32_t blockNumber, const uint8_t* src);
209
+  bool writeData(const uint8_t* src);
210
+  bool writeStart(uint32_t blockNumber, uint32_t eraseCount);
211
+  bool writeStop();
208 212
  private:
209
-  uint32_t block_;
213
+  //----------------------------------------------------------------------------
210 214
   uint8_t chipSelectPin_;
211 215
   uint8_t errorCode_;
212
-  uint8_t inBlock_;
213
-  uint16_t offset_;
214
-  uint8_t partialBlockRead_;
216
+  uint8_t spiRate_;
215 217
   uint8_t status_;
216 218
   uint8_t type_;
217 219
   // private functions
@@ -220,14 +222,13 @@ class Sd2Card {
220 222
     return cardCommand(cmd, arg);
221 223
   }
222 224
   uint8_t cardCommand(uint8_t cmd, uint32_t arg);
223
-  void error(uint8_t code) {errorCode_ = code;}
224
-  uint8_t readRegister(uint8_t cmd, void* buf);
225
-  uint8_t sendWriteCommand(uint32_t blockNumber, uint32_t eraseCount);
226
-  void chipSelectHigh(void);
227
-  void chipSelectLow(void);
225
+
226
+  bool readData(uint8_t* dst, uint16_t count);
227
+  bool readRegister(uint8_t cmd, void* buf);
228
+  void chipSelectHigh();
229
+  void chipSelectLow();
228 230
   void type(uint8_t value) {type_ = value;}
229
-  uint8_t waitNotBusy(uint16_t timeoutMillis);
230
-  uint8_t writeData(uint8_t token, const uint8_t* src);
231
-  uint8_t waitStartBlock(void);
231
+  bool waitNotBusy(uint16_t timeoutMillis);
232
+  bool writeData(uint8_t token, const uint8_t* src);
232 233
 };
233 234
 #endif  // Sd2Card_h

+ 45
- 38
Marlin/Sd2PinMap.h View File

@@ -21,7 +21,6 @@
21 21
 #ifndef Sd2PinMap_h
22 22
 #define Sd2PinMap_h
23 23
 #include <avr/io.h>
24
-
25 24
 //------------------------------------------------------------------------------
26 25
 /** struct for mapping digital pins */
27 26
 struct pin_map_t {
@@ -31,18 +30,19 @@ struct pin_map_t {
31 30
   uint8_t bit;
32 31
 };
33 32
 //------------------------------------------------------------------------------
34
-#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
33
+#if defined(__AVR_ATmega1280__)\
34
+|| defined(__AVR_ATmega2560__)
35 35
 // Mega
36 36
 
37 37
 // Two Wire (aka I2C) ports
38
-uint8_t const SDA_PIN = 20;
39
-uint8_t const SCL_PIN = 21;
38
+uint8_t const SDA_PIN = 20;  // D1
39
+uint8_t const SCL_PIN = 21;  // D0
40 40
 
41 41
 // SPI port
42
-uint8_t const SS_PIN = 53;
43
-uint8_t const MOSI_PIN = 51;
44
-uint8_t const MISO_PIN = 50;
45
-uint8_t const SCK_PIN = 52;
42
+uint8_t const SS_PIN = 53;    // B0
43
+uint8_t const MOSI_PIN = 51;  // B2
44
+uint8_t const MISO_PIN = 50;  // B3
45
+uint8_t const SCK_PIN = 52;   // B1
46 46
 
47 47
 static const pin_map_t digitalPinMap[] = {
48 48
   {&DDRE, &PINE, &PORTE, 0},  // E0  0
@@ -117,18 +117,20 @@ static const pin_map_t digitalPinMap[] = {
117 117
   {&DDRK, &PINK, &PORTK, 7}   // K7 69
118 118
 };
119 119
 //------------------------------------------------------------------------------
120
-#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
120
+#elif defined(__AVR_ATmega644P__)\
121
+|| defined(__AVR_ATmega644__)\
122
+|| defined(__AVR_ATmega1284P__)
121 123
 // Sanguino
122 124
 
123 125
 // Two Wire (aka I2C) ports
124
-uint8_t const SDA_PIN = 17;
125
-uint8_t const SCL_PIN = 18;
126
+uint8_t const SDA_PIN = 17;  // C1
127
+uint8_t const SCL_PIN = 18;  // C2
126 128
 
127 129
 // SPI port
128
-uint8_t const SS_PIN = 4;
129
-uint8_t const MOSI_PIN = 5;
130
-uint8_t const MISO_PIN = 6;
131
-uint8_t const SCK_PIN = 7;
130
+uint8_t const SS_PIN = 4;    // B4
131
+uint8_t const MOSI_PIN = 5;  // B5
132
+uint8_t const MISO_PIN = 6;  // B6
133
+uint8_t const SCK_PIN = 7;   // B7
132 134
 
133 135
 static const pin_map_t digitalPinMap[] = {
134 136
   {&DDRB, &PINB, &PORTB, 0},  // B0  0
@@ -169,14 +171,14 @@ static const pin_map_t digitalPinMap[] = {
169 171
 // Teensy 2.0
170 172
 
171 173
 // Two Wire (aka I2C) ports
172
-uint8_t const SDA_PIN = 6;
173
-uint8_t const SCL_PIN = 5;
174
+uint8_t const SDA_PIN = 6;  // D1
175
+uint8_t const SCL_PIN = 5;  // D0
174 176
 
175 177
 // SPI port
176
-uint8_t const SS_PIN = 0;
177
-uint8_t const MOSI_PIN = 2;
178
-uint8_t const MISO_PIN = 3;
179
-uint8_t const SCK_PIN = 1;
178
+uint8_t const SS_PIN = 0;    // B0
179
+uint8_t const MOSI_PIN = 2;  // B2
180
+uint8_t const MISO_PIN = 3;  // B3
181
+uint8_t const SCK_PIN = 1;   // B1
180 182
 
181 183
 static const pin_map_t digitalPinMap[] = {
182 184
   {&DDRB, &PINB, &PORTB, 0},  // B0  0
@@ -206,18 +208,19 @@ static const pin_map_t digitalPinMap[] = {
206 208
   {&DDRE, &PINE, &PORTE, 6}   // E6 24
207 209
 };
208 210
 //------------------------------------------------------------------------------
209
-#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
211
+#elif defined(__AVR_AT90USB646__)\
212
+|| defined(__AVR_AT90USB1286__)
210 213
 // Teensy++ 1.0 & 2.0
211 214
 
212 215
 // Two Wire (aka I2C) ports
213
-uint8_t const SDA_PIN = 1;
214
-uint8_t const SCL_PIN = 0;
216
+uint8_t const SDA_PIN = 1;  // D1
217
+uint8_t const SCL_PIN = 0;  // D0
215 218
 
216 219
 // SPI port
217
-uint8_t const SS_PIN = 20;
218
-uint8_t const MOSI_PIN = 22;
219
-uint8_t const MISO_PIN = 23;
220
-uint8_t const SCK_PIN = 21;
220
+uint8_t const SS_PIN = 20;    // B0
221
+uint8_t const MOSI_PIN = 22;  // B2
222
+uint8_t const MISO_PIN = 23;  // B3
223
+uint8_t const SCK_PIN = 21;   // B1
221 224
 
222 225
 static const pin_map_t digitalPinMap[] = {
223 226
   {&DDRD, &PIND, &PORTD, 0},  // D0  0
@@ -268,18 +271,20 @@ static const pin_map_t digitalPinMap[] = {
268 271
   {&DDRF, &PINF, &PORTF, 7}   // F7 45
269 272
 };
270 273
 //------------------------------------------------------------------------------
271
-#else  // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
274
+#elif defined(__AVR_ATmega168__)\
275
+||defined(__AVR_ATmega168P__)\
276
+||defined(__AVR_ATmega328P__)
272 277
 // 168 and 328 Arduinos
273 278
 
274 279
 // Two Wire (aka I2C) ports
275
-uint8_t const SDA_PIN = 18;
276
-uint8_t const SCL_PIN = 19;
280
+uint8_t const SDA_PIN = 18;  // C4
281
+uint8_t const SCL_PIN = 19;  // C5
277 282
 
278 283
 // SPI port
279
-uint8_t const SS_PIN = 10;
280
-uint8_t const MOSI_PIN = 11;
281
-uint8_t const MISO_PIN = 12;
282
-uint8_t const SCK_PIN = 13;
284
+uint8_t const SS_PIN = 10;    // B2
285
+uint8_t const MOSI_PIN = 11;  // B3
286
+uint8_t const MISO_PIN = 12;  // B4
287
+uint8_t const SCK_PIN = 13;   // B5
283 288
 
284 289
 static const pin_map_t digitalPinMap[] = {
285 290
   {&DDRD, &PIND, &PORTD, 0},  // D0  0
@@ -303,7 +308,9 @@ static const pin_map_t digitalPinMap[] = {
303 308
   {&DDRC, &PINC, &PORTC, 4},  // C4 18
304 309
   {&DDRC, &PINC, &PORTC, 5}   // C5 19
305 310
 };
306
-#endif  // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
311
+#else  // defined(__AVR_ATmega1280__)
312
+#error unknown chip
313
+#endif  // defined(__AVR_ATmega1280__)
307 314
 //------------------------------------------------------------------------------
308 315
 static const uint8_t digitalPinCount = sizeof(digitalPinMap)/sizeof(pin_map_t);
309 316
 
@@ -311,7 +318,7 @@ uint8_t badPinNumber(void)
311 318
   __attribute__((error("Pin number is too large or not a constant")));
312 319
 
313 320
 static inline __attribute__((always_inline))
314
-  uint8_t getPinMode(uint8_t pin) {
321
+  bool getPinMode(uint8_t pin) {
315 322
   if (__builtin_constant_p(pin) && pin < digitalPinCount) {
316 323
     return (*digitalPinMap[pin].ddr >> digitalPinMap[pin].bit) & 1;
317 324
   } else {
@@ -331,7 +338,7 @@ static inline __attribute__((always_inline))
331 338
   }
332 339
 }
333 340
 static inline __attribute__((always_inline))
334
-  uint8_t fastDigitalRead(uint8_t pin) {
341
+  bool fastDigitalRead(uint8_t pin) {
335 342
   if (__builtin_constant_p(pin) && pin < digitalPinCount) {
336 343
     return (*digitalPinMap[pin].pin >> digitalPinMap[pin].bit) & 1;
337 344
   } else {

+ 1818
- 0
Marlin/SdBaseFile.cpp
File diff suppressed because it is too large
View File


+ 489
- 0
Marlin/SdBaseFile.h View File

@@ -0,0 +1,489 @@
1
+/* Arduino SdFat Library
2
+ * Copyright (C) 2009 by William Greiman
3
+ *
4
+ * This file is part of the Arduino SdFat 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 SdFat Library.  If not, see
18
+ * <http://www.gnu.org/licenses/>.
19
+ */
20
+#ifndef SdBaseFile_h
21
+#define SdBaseFile_h
22
+/**
23
+ * \file
24
+ * \brief SdBaseFile class
25
+ */
26
+#include <avr/pgmspace.h>
27
+#if ARDUINO < 100
28
+#include <WProgram.h>
29
+#else  // ARDUINO
30
+#include <Arduino.h>
31
+#endif  // ARDUINO
32
+#include "SdFatConfig.h"
33
+#include "SdVolume.h"
34
+//------------------------------------------------------------------------------
35
+/**
36
+ * \struct fpos_t
37
+ * \brief internal type for istream
38
+ * do not use in user apps
39
+ */
40
+struct fpos_t {
41
+  /** stream position */
42
+  uint32_t position;
43
+  /** cluster for position */
44
+  uint32_t cluster;
45
+  fpos_t() : position(0), cluster(0) {}
46
+};
47
+
48
+// use the gnu style oflag in open()
49
+/** open() oflag for reading */
50
+uint8_t const O_READ = 0X01;
51
+/** open() oflag - same as O_IN */
52
+uint8_t const O_RDONLY = O_READ;
53
+/** open() oflag for write */
54
+uint8_t const O_WRITE = 0X02;
55
+/** open() oflag - same as O_WRITE */
56
+uint8_t const O_WRONLY = O_WRITE;
57
+/** open() oflag for reading and writing */
58
+uint8_t const O_RDWR = (O_READ | O_WRITE);
59
+/** open() oflag mask for access modes */
60
+uint8_t const O_ACCMODE = (O_READ | O_WRITE);
61
+/** The file offset shall be set to the end of the file prior to each write. */
62
+uint8_t const O_APPEND = 0X04;
63
+/** synchronous writes - call sync() after each write */
64
+uint8_t const O_SYNC = 0X08;
65
+/** truncate the file to zero length */
66
+uint8_t const O_TRUNC = 0X10;
67
+/** set the initial position at the end of the file */
68
+uint8_t const O_AT_END = 0X20;
69
+/** create the file if nonexistent */
70
+uint8_t const O_CREAT = 0X40;
71
+/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
72
+uint8_t const O_EXCL = 0X80;
73
+
74
+// SdBaseFile class static and const definitions
75
+// flags for ls()
76
+/** ls() flag to print modify date */
77
+uint8_t const LS_DATE = 1;
78
+/** ls() flag to print file size */
79
+uint8_t const LS_SIZE = 2;
80
+/** ls() flag for recursive list of subdirectories */
81
+uint8_t const LS_R = 4;
82
+
83
+
84
+// flags for timestamp
85
+/** set the file's last access date */
86
+uint8_t const T_ACCESS = 1;
87
+/** set the file's creation date and time */
88
+uint8_t const T_CREATE = 2;
89
+/** Set the file's write date and time */
90
+uint8_t const T_WRITE = 4;
91
+// values for type_
92
+/** This file has not been opened. */
93
+uint8_t const FAT_FILE_TYPE_CLOSED = 0;
94
+/** A normal file */
95
+uint8_t const FAT_FILE_TYPE_NORMAL = 1;
96
+/** A FAT12 or FAT16 root directory */
97
+uint8_t const FAT_FILE_TYPE_ROOT_FIXED = 2;
98
+/** A FAT32 root directory */
99
+uint8_t const FAT_FILE_TYPE_ROOT32 = 3;
100
+/** A subdirectory file*/
101
+uint8_t const FAT_FILE_TYPE_SUBDIR = 4;
102
+/** Test value for directory type */
103
+uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED;
104
+
105
+/** date field for FAT directory entry
106
+ * \param[in] year [1980,2107]
107
+ * \param[in] month [1,12]
108
+ * \param[in] day [1,31]
109
+ *
110
+ * \return Packed date for dir_t entry.
111
+ */
112
+static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) {
113
+  return (year - 1980) << 9 | month << 5 | day;
114
+}
115
+/** year part of FAT directory date field
116
+ * \param[in] fatDate Date in packed dir format.
117
+ *
118
+ * \return Extracted year [1980,2107]
119
+ */
120
+static inline uint16_t FAT_YEAR(uint16_t fatDate) {
121
+  return 1980 + (fatDate >> 9);
122
+}
123
+/** month part of FAT directory date field
124
+ * \param[in] fatDate Date in packed dir format.
125
+ *
126
+ * \return Extracted month [1,12]
127
+ */
128
+static inline uint8_t FAT_MONTH(uint16_t fatDate) {
129
+  return (fatDate >> 5) & 0XF;
130
+}
131
+/** day part of FAT directory date field
132
+ * \param[in] fatDate Date in packed dir format.
133
+ *
134
+ * \return Extracted day [1,31]
135
+ */
136
+static inline uint8_t FAT_DAY(uint16_t fatDate) {
137
+  return fatDate & 0X1F;
138
+}
139
+/** time field for FAT directory entry
140
+ * \param[in] hour [0,23]
141
+ * \param[in] minute [0,59]
142
+ * \param[in] second [0,59]
143
+ *
144
+ * \return Packed time for dir_t entry.
145
+ */
146
+static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) {
147
+  return hour << 11 | minute << 5 | second >> 1;
148
+}
149
+/** hour part of FAT directory time field
150
+ * \param[in] fatTime Time in packed dir format.
151
+ *
152
+ * \return Extracted hour [0,23]
153
+ */
154
+static inline uint8_t FAT_HOUR(uint16_t fatTime) {
155
+  return fatTime >> 11;
156
+}
157
+/** minute part of FAT directory time field
158
+ * \param[in] fatTime Time in packed dir format.
159
+ *
160
+ * \return Extracted minute [0,59]
161
+ */
162
+static inline uint8_t FAT_MINUTE(uint16_t fatTime) {
163
+  return(fatTime >> 5) & 0X3F;
164
+}
165
+/** second part of FAT directory time field
166
+ * Note second/2 is stored in packed time.
167
+ *
168
+ * \param[in] fatTime Time in packed dir format.
169
+ *
170
+ * \return Extracted second [0,58]
171
+ */
172
+static inline uint8_t FAT_SECOND(uint16_t fatTime) {
173
+  return 2*(fatTime & 0X1F);
174
+}
175
+/** Default date for file timestamps is 1 Jan 2000 */
176
+uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1;
177
+/** Default time for file timestamp is 1 am */
178
+uint16_t const FAT_DEFAULT_TIME = (1 << 11);
179
+//------------------------------------------------------------------------------
180
+/**
181
+ * \class SdBaseFile
182
+ * \brief Base class for SdFile with Print and C++ streams.
183
+ */
184
+class SdBaseFile {
185
+ public:
186
+  /** Create an instance. */
187
+  SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {}
188
+  SdBaseFile(const char* path, uint8_t oflag);
189
+  ~SdBaseFile() {if(isOpen()) close();}
190
+  /**
191
+   * writeError is set to true if an error occurs during a write().
192
+   * Set writeError to false before calling print() and/or write() and check
193
+   * for true after calls to print() and/or write().
194
+   */
195
+  bool writeError;
196
+  //----------------------------------------------------------------------------
197
+  // helpers for stream classes
198
+  /** get position for streams
199
+   * \param[out] pos struct to receive position
200
+   */
201
+  void getpos(fpos_t* pos);
202
+  /** set position for streams
203
+   * \param[out] pos struct with value for new position
204
+   */
205
+  void setpos(fpos_t* pos);
206
+  //----------------------------------------------------------------------------
207
+  bool close();
208
+  bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
209
+  bool createContiguous(SdBaseFile* dirFile,
210
+          const char* path, uint32_t size);
211
+  /** \return The current cluster number for a file or directory. */
212
+  uint32_t curCluster() const {return curCluster_;}
213
+  /** \return The current position for a file or directory. */
214
+  uint32_t curPosition() const {return curPosition_;}
215
+  /** \return Current working directory */
216
+  static SdBaseFile* cwd() {return cwd_;}
217
+  /** Set the date/time callback function
218
+   *
219
+   * \param[in] dateTime The user's call back function.  The callback
220
+   * function is of the form:
221
+   *
222
+   * \code
223
+   * void dateTime(uint16_t* date, uint16_t* time) {
224
+   *   uint16_t year;
225
+   *   uint8_t month, day, hour, minute, second;
226
+   *
227
+   *   // User gets date and time from GPS or real-time clock here
228
+   *
229
+   *   // return date using FAT_DATE macro to format fields
230
+   *   *date = FAT_DATE(year, month, day);
231
+   *
232
+   *   // return time using FAT_TIME macro to format fields
233
+   *   *time = FAT_TIME(hour, minute, second);
234
+   * }
235
+   * \endcode
236
+   *
237
+   * Sets the function that is called when a file is created or when
238
+   * a file's directory entry is modified by sync(). All timestamps,
239
+   * access, creation, and modify, are set when a file is created.
240
+   * sync() maintains the last access date and last modify date/time.
241
+   *
242
+   * See the timestamp() function.
243
+   */
244
+  static void dateTimeCallback(
245
+    void (*dateTime)(uint16_t* date, uint16_t* time)) {
246
+    dateTime_ = dateTime;
247
+  }
248
+  /**  Cancel the date/time callback function. */
249
+  static void dateTimeCallbackCancel() {dateTime_ = 0;}
250
+  bool dirEntry(dir_t* dir);
251
+  static void dirName(const dir_t& dir, char* name);
252
+  bool exists(const char* name);
253
+  int16_t fgets(char* str, int16_t num, char* delim = 0);
254
+  /** \return The total number of bytes in a file or directory. */
255
+  uint32_t fileSize() const {return fileSize_;}
256
+  /** \return The first cluster number for a file or directory. */
257
+  uint32_t firstCluster() const {return firstCluster_;}
258
+  bool getFilename(char* name);
259
+  /** \return True if this is a directory else false. */
260
+  bool isDir() const {return type_ >= FAT_FILE_TYPE_MIN_DIR;}
261
+  /** \return True if this is a normal file else false. */
262
+  bool isFile() const {return type_ == FAT_FILE_TYPE_NORMAL;}
263
+  /** \return True if this is an open file/directory else false. */
264
+  bool isOpen() const {return type_ != FAT_FILE_TYPE_CLOSED;}
265
+  /** \return True if this is a subdirectory else false. */
266
+  bool isSubDir() const {return type_ == FAT_FILE_TYPE_SUBDIR;}
267
+  /** \return True if this is the root directory. */
268
+  bool isRoot() const {
269
+    return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32;
270
+  }
271
+  void ls(Print* pr, uint8_t flags = 0, uint8_t indent = 0);
272
+  void ls(uint8_t flags = 0);
273
+  bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true);
274
+  // alias for backward compactability
275
+  bool makeDir(SdBaseFile* dir, const char* path) {
276
+    return mkdir(dir, path, false);
277
+  }
278
+  bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag);
279
+  bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag);
280
+  bool open(const char* path, uint8_t oflag = O_READ);
281
+  bool openNext(SdBaseFile* dirFile, uint8_t oflag);
282
+  bool openRoot(SdVolume* vol);
283
+  int peek();
284
+  static void printFatDate(uint16_t fatDate);
285
+  static void printFatDate(Print* pr, uint16_t fatDate);
286
+  static void printFatTime(uint16_t fatTime);
287
+  static void printFatTime(Print* pr, uint16_t fatTime);
288
+  bool printName();
289
+  int16_t read();
290
+  int16_t read(void* buf, uint16_t nbyte);
291
+  int8_t readDir(dir_t* dir);
292
+  static bool remove(SdBaseFile* dirFile, const char* path);
293
+  bool remove();
294
+  /** Set the file's current position to zero. */
295
+  void rewind() {seekSet(0);}
296
+  bool rename(SdBaseFile* dirFile, const char* newPath);
297
+  bool rmdir();
298
+  // for backward compatibility
299
+  bool rmDir() {return rmdir();}
300
+  bool rmRfStar();
301
+  /** Set the files position to current position + \a pos. See seekSet().
302
+   * \param[in] offset The new position in bytes from the current position.
303
+   * \return true for success or false for failure.
304
+   */
305
+  bool seekCur(int32_t offset) {
306
+    return seekSet(curPosition_ + offset);
307
+  }
308
+  /** Set the files position to end-of-file + \a offset. See seekSet().
309
+   * \param[in] offset The new position in bytes from end-of-file.
310
+   * \return true for success or false for failure.
311
+   */
312
+  bool seekEnd(int32_t offset = 0) {return seekSet(fileSize_ + offset);}
313
+  bool seekSet(uint32_t pos);
314
+  bool sync();
315
+  bool timestamp(SdBaseFile* file);
316
+  bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day,
317
+          uint8_t hour, uint8_t minute, uint8_t second);
318
+  /** Type of file.  You should use isFile() or isDir() instead of type()
319
+   * if possible.
320
+   *
321
+   * \return The file or directory type.
322
+   */
323
+  uint8_t type() const {return type_;}
324
+  bool truncate(uint32_t size);
325
+  /** \return SdVolume that contains this file. */
326
+  SdVolume* volume() const {return vol_;}
327
+  int16_t write(const void* buf, uint16_t nbyte);
328
+//------------------------------------------------------------------------------
329
+ private:
330
+  // allow SdFat to set cwd_
331
+  friend class SdFat;
332
+  // global pointer to cwd dir
333
+  static SdBaseFile* cwd_;
334
+  // data time callback function
335
+  static void (*dateTime_)(uint16_t* date, uint16_t* time);
336
+  // bits defined in flags_
337
+  // should be 0X0F
338
+  static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC);
339
+  // sync of directory entry required
340
+  static uint8_t const F_FILE_DIR_DIRTY = 0X80;
341
+
342
+  // private data
343
+  uint8_t   flags_;         // See above for definition of flags_ bits
344
+  uint8_t   fstate_;        // error and eof indicator
345
+  uint8_t   type_;          // type of file see above for values
346
+  uint32_t  curCluster_;    // cluster for current file position
347
+  uint32_t  curPosition_;   // current file position in bytes from beginning
348
+  uint32_t  dirBlock_;      // block for this files directory entry
349
+  uint8_t   dirIndex_;      // index of directory entry in dirBlock
350
+  uint32_t  fileSize_;      // file size in bytes
351
+  uint32_t  firstCluster_;  // first cluster of file
352
+  SdVolume* vol_;           // volume where file is located
353
+
354
+  /** experimental don't use */
355
+  bool openParent(SdBaseFile* dir);
356
+  // private functions
357
+  bool addCluster();
358
+  bool addDirCluster();
359
+  dir_t* cacheDirEntry(uint8_t action);
360
+  int8_t lsPrintNext(Print *pr, uint8_t flags, uint8_t indent);
361
+  static bool make83Name(const char* str, uint8_t* name, const char** ptr);
362
+  bool mkdir(SdBaseFile* parent, const uint8_t dname[11]);
363
+  bool open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag);
364
+  bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags);
365
+  dir_t* readDirCache();
366
+//------------------------------------------------------------------------------
367
+// to be deleted
368
+  static void printDirName(const dir_t& dir,
369
+    uint8_t width, bool printSlash);
370
+  static void printDirName(Print* pr, const dir_t& dir,
371
+    uint8_t width, bool printSlash);
372
+//------------------------------------------------------------------------------
373
+// Deprecated functions  - suppress cpplint warnings with NOLINT comment
374
+#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN)
375
+ public:
376
+  /** \deprecated Use:
377
+   * bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
378
+   * \param[out] bgnBlock the first block address for the file.
379
+   * \param[out] endBlock the last  block address for the file.
380
+   * \return true for success or false for failure.
381
+   */
382
+  bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) {  // NOLINT
383
+    return contiguousRange(&bgnBlock, &endBlock);
384
+  }
385
+ /** \deprecated Use:
386
+   * bool createContiguous(SdBaseFile* dirFile,
387
+   *   const char* path, uint32_t size)
388
+   * \param[in] dirFile The directory where the file will be created.
389
+   * \param[in] path A path with a valid DOS 8.3 file name.
390
+   * \param[in] size The desired file size.
391
+   * \return true for success or false for failure.
392
+   */
393
+  bool createContiguous(SdBaseFile& dirFile,  // NOLINT
394
+    const char* path, uint32_t size) {
395
+    return createContiguous(&dirFile, path, size);
396
+  }
397
+  /** \deprecated Use:
398
+   * static void dateTimeCallback(
399
+   *   void (*dateTime)(uint16_t* date, uint16_t* time));
400
+   * \param[in] dateTime The user's call back function.
401
+   */
402
+  static void dateTimeCallback(
403
+    void (*dateTime)(uint16_t& date, uint16_t& time)) {  // NOLINT
404
+    oldDateTime_ = dateTime;
405
+    dateTime_ = dateTime ? oldToNew : 0;
406
+  }
407
+  /** \deprecated Use: bool dirEntry(dir_t* dir);
408
+   * \param[out] dir Location for return of the file's directory entry.
409
+   * \return true for success or false for failure.
410
+   */
411
+  bool dirEntry(dir_t& dir) {return dirEntry(&dir);}  // NOLINT
412
+  /** \deprecated Use:
413
+   * bool mkdir(SdBaseFile* dir, const char* path);
414
+   * \param[in] dir An open SdFat instance for the directory that will contain
415
+   * the new directory.
416
+   * \param[in] path A path with a valid 8.3 DOS name for the new directory.
417
+   * \return true for success or false for failure.
418
+   */
419
+  bool mkdir(SdBaseFile& dir, const char* path) {  // NOLINT
420
+    return mkdir(&dir, path);
421
+  }
422
+  /** \deprecated Use:
423
+   * bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag);
424
+   * \param[in] dirFile An open SdFat instance for the directory containing the
425
+   * file to be opened.
426
+   * \param[in] path A path with a valid 8.3 DOS name for the file.
427
+   * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
428
+   * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC.
429
+   * \return true for success or false for failure.
430
+   */
431
+  bool open(SdBaseFile& dirFile, // NOLINT
432
+    const char* path, uint8_t oflag) {
433
+    return open(&dirFile, path, oflag);
434
+  }
435
+  /** \deprecated  Do not use in new apps
436
+   * \param[in] dirFile An open SdFat instance for the directory containing the
437
+   * file to be opened.
438
+   * \param[in] path A path with a valid 8.3 DOS name for a file to be opened.
439
+   * \return true for success or false for failure.
440
+   */
441
+  bool open(SdBaseFile& dirFile, const char* path) {  // NOLINT
442
+    return open(dirFile, path, O_RDWR);
443
+  }
444
+  /** \deprecated Use:
445
+   * bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag);
446
+   * \param[in] dirFile An open SdFat instance for the directory.
447
+   * \param[in] index The \a index of the directory entry for the file to be
448
+   * opened.  The value for \a index is (directory file position)/32.
449
+   * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
450
+   * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC.
451
+   * \return true for success or false for failure.
452
+   */
453
+  bool open(SdBaseFile& dirFile, uint16_t index, uint8_t oflag) {  // NOLINT
454
+    return open(&dirFile, index, oflag);
455
+  }
456
+  /** \deprecated Use: bool openRoot(SdVolume* vol);
457
+   * \param[in] vol The FAT volume containing the root directory to be opened.
458
+   * \return true for success or false for failure.
459
+   */
460
+  bool openRoot(SdVolume& vol) {return openRoot(&vol);}  // NOLINT
461
+  /** \deprecated Use: int8_t readDir(dir_t* dir);
462
+   * \param[out] dir The dir_t struct that will receive the data.
463
+   * \return bytes read for success zero for eof or -1 for failure.
464
+   */
465
+  int8_t readDir(dir_t& dir) {return readDir(&dir);}  // NOLINT
466
+  /** \deprecated Use:
467
+   * static uint8_t remove(SdBaseFile* dirFile, const char* path);
468
+   * \param[in] dirFile The directory that contains the file.
469
+   * \param[in] path The name of the file to be removed.
470
+   * \return true for success or false for failure.
471
+   */
472
+  static bool remove(SdBaseFile& dirFile, const char* path) {  // NOLINT
473
+    return remove(&dirFile, path);
474
+  }
475
+//------------------------------------------------------------------------------
476
+// rest are private
477
+ private:
478
+  static void (*oldDateTime_)(uint16_t& date, uint16_t& time);  // NOLINT
479
+  static void oldToNew(uint16_t* date, uint16_t* time) {
480
+    uint16_t d;
481
+    uint16_t t;
482
+    oldDateTime_(d, t);
483
+    *date = d;
484
+    *time = t;
485
+  }
486
+#endif  // ALLOW_DEPRECATED_FUNCTIONS
487
+};
488
+
489
+#endif  // SdBaseFile_h

+ 329
- 0
Marlin/SdFat.cpp View File

@@ -0,0 +1,329 @@
1
+/* Arduino SdFat Library
2
+ * Copyright (C) 2009 by William Greiman
3
+ *
4
+ * This file is part of the Arduino SdFat 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 SdFat Library.  If not, see
18
+ * <http://www.gnu.org/licenses/>.
19
+ */
20
+#include "SdFat.h"
21
+#include "SdFatUtil.h"
22
+//------------------------------------------------------------------------------
23
+/** Change a volume's working directory to root
24
+ *
25
+ * Changes the volume's working directory to the SD's root directory.
26
+ * Optionally set the current working directory to the volume's
27
+ * working directory.
28
+ *
29
+ * \param[in] set_cwd Set the current working directory to this volume's
30
+ *  working directory if true.
31
+ *
32
+ * \return The value one, true, is returned for success and
33
+ * the value zero, false, is returned for failure.
34
+ */
35
+bool SdFat::chdir(bool set_cwd) {
36
+  if (set_cwd) SdBaseFile::cwd_ = &vwd_;
37
+  vwd_.close();
38
+  return vwd_.openRoot(&vol_);
39
+}
40
+//------------------------------------------------------------------------------
41
+/** Change a volume's working directory
42
+ *
43
+ * Changes the volume working directory to the \a path subdirectory.
44
+ * Optionally set the current working directory to the volume's
45
+ * working directory.
46
+ *
47
+ * Example: If the volume's working directory is "/DIR", chdir("SUB")
48
+ * will change the volume's working directory from "/DIR" to "/DIR/SUB".
49
+ *
50
+ * If path is "/", the volume's working directory will be changed to the
51
+ * root directory
52
+ *
53
+ * \param[in] path The name of the subdirectory.
54
+ *
55
+ * \param[in] set_cwd Set the current working directory to this volume's
56
+ *  working directory if true.
57
+ *
58
+ * \return The value one, true, is returned for success and
59
+ * the value zero, false, is returned for failure.
60
+ */
61
+bool SdFat::chdir(const char *path, bool set_cwd) {
62
+  SdBaseFile dir;
63
+  if (path[0] == '/' && path[1] == '\0') return chdir(set_cwd);
64
+  if (!dir.open(&vwd_, path, O_READ)) goto fail;
65
+  if (!dir.isDir()) goto fail;
66
+  vwd_ = dir;
67
+  if (set_cwd) SdBaseFile::cwd_ = &vwd_;
68
+  return true;
69
+
70
+ fail:
71
+  return false;
72
+}
73
+//------------------------------------------------------------------------------
74
+/** Set the current working directory to a volume's working directory.
75
+ *
76
+ * This is useful with multiple SD cards.
77
+ *
78
+ * The current working directory is changed to this volume's working directory.
79
+ *
80
+ * This is like the Windows/DOS \<drive letter>: command.
81
+ */
82
+void SdFat::chvol() {
83
+  SdBaseFile::cwd_ = &vwd_;
84
+}
85
+//------------------------------------------------------------------------------
86
+/** %Print any SD error code and halt. */
87
+void SdFat::errorHalt() {
88
+  errorPrint();
89
+  while (1);
90
+}
91
+//------------------------------------------------------------------------------
92
+/** %Print msg, any SD error code, and halt.
93
+ *
94
+ * \param[in] msg Message to print.
95
+ */
96
+void SdFat::errorHalt(char const* msg) {
97
+  errorPrint(msg);
98
+  while (1);
99
+}
100
+//------------------------------------------------------------------------------
101
+/** %Print msg, any SD error code, and halt.
102
+ *
103
+ * \param[in] msg Message in program space (flash memory) to print.
104
+ */
105
+void SdFat::errorHalt_P(PGM_P msg) {
106
+  errorPrint_P(msg);
107
+  while (1);
108
+}
109
+//------------------------------------------------------------------------------
110
+/** %Print any SD error code. */
111
+void SdFat::errorPrint() {
112
+  if (!card_.errorCode()) return;
113
+  PgmPrint("SD errorCode: 0X");
114
+  Serial.println(card_.errorCode(), HEX);
115
+}
116
+//------------------------------------------------------------------------------
117
+/** %Print msg, any SD error code.
118
+ *
119
+ * \param[in] msg Message to print.
120
+ */
121
+void SdFat::errorPrint(char const* msg) {
122
+  PgmPrint("error: ");
123
+  Serial.println(msg);
124
+  errorPrint();
125
+}
126
+//------------------------------------------------------------------------------
127
+/** %Print msg, any SD error code.
128
+ *
129
+ * \param[in] msg Message in program space (flash memory) to print.
130
+ */
131
+void SdFat::errorPrint_P(PGM_P msg) {
132
+  PgmPrint("error: ");
133
+  SerialPrintln_P(msg);
134
+  errorPrint();
135
+}
136
+//------------------------------------------------------------------------------
137
+/**
138
+ * Test for the existence of a file.
139
+ *
140
+ * \param[in] name Name of the file to be tested for.
141
+ *
142
+ * \return true if the file exists else false.
143
+ */
144
+bool SdFat::exists(const char* name) {
145
+  return vwd_.exists(name);
146
+}
147
+//------------------------------------------------------------------------------
148
+/**
149
+ * Initialize an SdFat object.
150
+ *
151
+ * Initializes the SD card, SD volume, and root directory.
152
+ *
153
+ * \param[in] sckRateID value for SPI SCK rate. See Sd2Card::init().
154
+ * \param[in] chipSelectPin SD chip select pin. See Sd2Card::init().
155
+ *
156
+ * \return The value one, true, is returned for success and
157
+ * the value zero, false, is returned for failure.
158
+ */
159
+bool SdFat::init(uint8_t sckRateID, uint8_t chipSelectPin) {
160
+  return card_.init(sckRateID, chipSelectPin) && vol_.init(&card_) && chdir(1);
161
+}
162
+//------------------------------------------------------------------------------
163
+/** %Print error details and halt after SdFat::init() fails. */
164
+void SdFat::initErrorHalt() {
165
+  initErrorPrint();
166
+  while (1);
167
+}
168
+//------------------------------------------------------------------------------
169
+/**Print message, error details, and halt after SdFat::init() fails.
170
+ *
171
+ * \param[in] msg Message to print.
172
+ */
173
+void SdFat::initErrorHalt(char const *msg) {
174
+  Serial.println(msg);
175
+  initErrorHalt();
176
+}
177
+//------------------------------------------------------------------------------
178
+/**Print message, error details, and halt after SdFat::init() fails.
179
+ *
180
+ * \param[in] msg Message in program space (flash memory) to print.
181
+ */
182
+void SdFat::initErrorHalt_P(PGM_P msg) {
183
+  SerialPrintln_P(msg);
184
+  initErrorHalt();
185
+}
186
+//------------------------------------------------------------------------------
187
+/** Print error details after SdFat::init() fails. */
188
+void SdFat::initErrorPrint() {
189
+  if (card_.errorCode()) {
190
+    PgmPrintln("Can't access SD card. Do not reformat.");
191
+    if (card_.errorCode() == SD_CARD_ERROR_CMD0) {
192
+      PgmPrintln("No card, wrong chip select pin, or SPI problem?");
193
+    }
194
+    errorPrint();
195
+  } else if (vol_.fatType() == 0) {
196
+    PgmPrintln("Invalid format, reformat SD.");
197
+  } else if (!vwd_.isOpen()) {
198
+    PgmPrintln("Can't open root directory.");
199
+  } else {
200
+    PgmPrintln("No error found.");
201
+  }
202
+}
203
+//------------------------------------------------------------------------------
204
+/**Print message and error details and halt after SdFat::init() fails.
205
+ *
206
+ * \param[in] msg Message to print.
207
+ */
208
+void SdFat::initErrorPrint(char const *msg) {
209
+  Serial.println(msg);
210
+  initErrorPrint();
211
+}
212
+//------------------------------------------------------------------------------
213
+/**Print message and error details after SdFat::init() fails.
214
+ *
215
+ * \param[in] msg Message in program space (flash memory) to print.
216
+ */
217
+void SdFat::initErrorPrint_P(PGM_P msg) {
218
+  SerialPrintln_P(msg);
219
+  initErrorHalt();
220
+}
221
+//------------------------------------------------------------------------------
222
+/** List the directory contents of the volume working directory to Serial.
223
+ *
224
+ * \param[in] flags The inclusive OR of
225
+ *
226
+ * LS_DATE - %Print file modification date
227
+ *
228
+ * LS_SIZE - %Print file size.
229
+ *
230
+ * LS_R - Recursive list of subdirectories.
231
+ */
232
+void SdFat::ls(uint8_t flags) {
233
+  vwd_.ls(&Serial, flags);
234
+}
235
+//------------------------------------------------------------------------------
236
+/** List the directory contents of the volume working directory to Serial.
237
+ *
238
+ * \param[in] pr Print stream for list.
239
+ *
240
+ * \param[in] flags The inclusive OR of
241
+ *
242
+ * LS_DATE - %Print file modification date
243
+ *
244
+ * LS_SIZE - %Print file size.
245
+ *
246
+ * LS_R - Recursive list of subdirectories.
247
+ */
248
+void SdFat::ls(Print* pr, uint8_t flags) {
249
+  vwd_.ls(pr, flags);
250
+}
251
+//------------------------------------------------------------------------------
252
+/** Make a subdirectory in the volume working directory.
253
+ *
254
+ * \param[in] path A path with a valid 8.3 DOS name for the subdirectory.
255
+ *
256
+ * \param[in] pFlag Create missing parent directories if true.
257
+ *
258
+ * \return The value one, true, is returned for success and
259
+ * the value zero, false, is returned for failure.
260
+ */
261
+bool SdFat::mkdir(const char* path, bool pFlag) {
262
+  SdBaseFile sub;
263
+  return sub.mkdir(&vwd_, path, pFlag);
264
+}
265
+//------------------------------------------------------------------------------
266
+/** Remove a file from the volume working directory.
267
+*
268
+* \param[in] path A path with a valid 8.3 DOS name for the file.
269
+*
270
+* \return The value one, true, is returned for success and
271
+* the value zero, false, is returned for failure.
272
+*/
273
+bool SdFat::remove(const char* path) {
274
+  return SdBaseFile::remove(&vwd_, path);
275
+}
276
+//------------------------------------------------------------------------------
277
+/** Rename a file or subdirectory.
278
+ *
279
+ * \param[in] oldPath Path name to the file or subdirectory to be renamed.
280
+ *
281
+ * \param[in] newPath New path name of the file or subdirectory.
282
+ *
283
+ * The \a newPath object must not exist before the rename call.
284
+ *
285
+ * The file to be renamed must not be open.  The directory entry may be
286
+ * moved and file system corruption could occur if the file is accessed by
287
+ * a file object that was opened before the rename() call.
288
+ *
289
+ * \return The value one, true, is returned for success and
290
+ * the value zero, false, is returned for failure.
291
+ */
292
+bool SdFat::rename(const char *oldPath, const char *newPath) {
293
+  SdBaseFile file;
294
+  if (!file.open(oldPath, O_READ)) return false;
295
+  return file.rename(&vwd_, newPath);
296
+}
297
+//------------------------------------------------------------------------------
298
+/** Remove a subdirectory from the volume's working directory.
299
+ *
300
+ * \param[in] path A path with a valid 8.3 DOS name for the subdirectory.
301
+ *
302
+ * The subdirectory file will be removed only if it is empty.
303
+ *
304
+ * \return The value one, true, is returned for success and
305
+ * the value zero, false, is returned for failure.
306
+ */
307
+bool SdFat::rmdir(const char* path) {
308
+  SdBaseFile sub;
309
+  if (!sub.open(path, O_READ)) return false;
310
+  return sub.rmdir();
311
+}
312
+//------------------------------------------------------------------------------
313
+/** Truncate a file to a specified length.  The current file position
314
+ * will be maintained if it is less than or equal to \a length otherwise
315
+ * it will be set to end of file.
316
+ *
317
+ * \param[in] path A path with a valid 8.3 DOS name for the file.
318
+ * \param[in] length The desired length for the file.
319
+ *
320
+ * \return The value one, true, is returned for success and
321
+ * the value zero, false, is returned for failure.
322
+ * Reasons for failure include file is read only, file is a directory,
323
+ * \a length is greater than the current file size or an I/O error occurs.
324
+ */
325
+bool SdFat::truncate(const char* path, uint32_t length) {
326
+  SdBaseFile file;
327
+  if (!file.open(path, O_WRITE)) return false;
328
+  return file.truncate(length);
329
+}

+ 44
- 515
Marlin/SdFat.h View File

@@ -21,527 +21,56 @@
21 21
 #define SdFat_h
22 22
 /**
23 23
  * \file
24
- * SdFile and SdVolume classes
24
+ * \brief SdFat class
25 25
  */
26
-#include <avr/pgmspace.h>
27
-#include "Sd2Card.h"
28
-#include "FatStructs.h"
29
-#include "Print.h"
26
+#include "SdFile.h"
27
+//#include <SdStream.h>
28
+//#include <ArduinoStream.h>
30 29
 //------------------------------------------------------------------------------
31
-/**
32
- * Allow use of deprecated functions if non-zero
33
- */
34
-#define ALLOW_DEPRECATED_FUNCTIONS 1
35
-//------------------------------------------------------------------------------
36
-// forward declaration since SdVolume is used in SdFile
37
-class SdVolume;
38
-//==============================================================================
39
-// SdFile class
40
-
41
-// flags for ls()
42
-/** ls() flag to print modify date */
43
-uint8_t const LS_DATE = 1;
44
-/** ls() flag to print file size */
45
-uint8_t const LS_SIZE = 2;
46
-/** ls() flag for recursive list of subdirectories */
47
-uint8_t const LS_R = 4;
48
-
49
-// use the gnu style oflag in open()
50
-/** open() oflag for reading */
51
-uint8_t const O_READ = 0X01;
52
-/** open() oflag - same as O_READ */
53
-uint8_t const O_RDONLY = O_READ;
54
-/** open() oflag for write */
55
-uint8_t const O_WRITE = 0X02;
56
-/** open() oflag - same as O_WRITE */
57
-uint8_t const O_WRONLY = O_WRITE;
58
-/** open() oflag for reading and writing */
59
-uint8_t const O_RDWR = (O_READ | O_WRITE);
60
-/** open() oflag mask for access modes */
61
-uint8_t const O_ACCMODE = (O_READ | O_WRITE);
62
-/** The file offset shall be set to the end of the file prior to each write. */
63
-uint8_t const O_APPEND = 0X04;
64
-/** synchronous writes - call sync() after each write */
65
-uint8_t const O_SYNC = 0X08;
66
-/** create the file if nonexistent */
67
-uint8_t const O_CREAT = 0X10;
68
-/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
69
-uint8_t const O_EXCL = 0X20;
70
-/** truncate the file to zero length */
71
-uint8_t const O_TRUNC = 0X40;
72
-
73
-// flags for timestamp
74
-/** set the file's last access date */
75
-uint8_t const T_ACCESS = 1;
76
-/** set the file's creation date and time */
77
-uint8_t const T_CREATE = 2;
78
-/** Set the file's write date and time */
79
-uint8_t const T_WRITE = 4;
80
-// values for type_
81
-/** This SdFile has not been opened. */
82
-uint8_t const FAT_FILE_TYPE_CLOSED = 0;
83
-/** SdFile for a file */
84
-uint8_t const FAT_FILE_TYPE_NORMAL = 1;
85
-/** SdFile for a FAT16 root directory */
86
-uint8_t const FAT_FILE_TYPE_ROOT16 = 2;
87
-/** SdFile for a FAT32 root directory */
88
-uint8_t const FAT_FILE_TYPE_ROOT32 = 3;
89
-/** SdFile for a subdirectory */
90
-uint8_t const FAT_FILE_TYPE_SUBDIR = 4;
91
-/** Test value for directory type */
92
-uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT16;
93
-
94
-/** date field for FAT directory entry */
95
-static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) {
96
-  return (year - 1980) << 9 | month << 5 | day;
97
-}
98
-/** year part of FAT directory date field */
99
-static inline uint16_t FAT_YEAR(uint16_t fatDate) {
100
-  return 1980 + (fatDate >> 9);
101
-}
102
-/** month part of FAT directory date field */
103
-static inline uint8_t FAT_MONTH(uint16_t fatDate) {
104
-  return (fatDate >> 5) & 0XF;
105
-}
106
-/** day part of FAT directory date field */
107
-static inline uint8_t FAT_DAY(uint16_t fatDate) {
108
-  return fatDate & 0X1F;
109
-}
110
-/** time field for FAT directory entry */
111
-static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) {
112
-  return hour << 11 | minute << 5 | second >> 1;
113
-}
114
-/** hour part of FAT directory time field */
115
-static inline uint8_t FAT_HOUR(uint16_t fatTime) {
116
-  return fatTime >> 11;
117
-}
118
-/** minute part of FAT directory time field */
119
-static inline uint8_t FAT_MINUTE(uint16_t fatTime) {
120
-  return(fatTime >> 5) & 0X3F;
121
-}
122
-/** second part of FAT directory time field */
123
-static inline uint8_t FAT_SECOND(uint16_t fatTime) {
124
-  return 2*(fatTime & 0X1F);
125
-}
126
-/** Default date for file timestamps is 1 Jan 2000 */
127
-uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1;
128
-/** Default time for file timestamp is 1 am */
129
-uint16_t const FAT_DEFAULT_TIME = (1 << 11);
30
+/** SdFat version YYYYMMDD */
31
+#define SD_FAT_VERSION 20110902
130 32
 //------------------------------------------------------------------------------
131 33
 /**
132
- * \class SdFile
133
- * \brief Access FAT16 and FAT32 files on SD and SDHC cards.
34
+ * \class SdFat
35
+ * \brief Integration class for the %SdFat library.
134 36
  */
135
-class SdFile : public Print {
37
+class SdFat {
136 38
  public:
137
-  /** Create an instance of SdFile. */
138
-  SdFile(void) : type_(FAT_FILE_TYPE_CLOSED) {}
139
-  /**
140
-   * writeError is set to true if an error occurs during a write().
141
-   * Set writeError to false before calling print() and/or write() and check
142
-   * for true after calls to print() and/or write().
143
-   */
144
-  bool writeError;
145
-  /**
146
-   * Cancel unbuffered reads for this file.
147
-   * See setUnbufferedRead()
148
-   */
149
-  void clearUnbufferedRead(void) {
150
-    flags_ &= ~F_FILE_UNBUFFERED_READ;
151
-  }
152
-  uint8_t close(void);
153
-  uint8_t contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
154
-  uint8_t createContiguous(SdFile* dirFile,
155
-          const char* fileName, uint32_t size);
156
-  /** \return The current cluster number for a file or directory. */
157
-  uint32_t curCluster(void) const {return curCluster_;}
158
-  /** \return The current position for a file or directory. */
159
-  uint32_t curPosition(void) const {return curPosition_;}
160
-  /**
161
-   * Set the date/time callback function
162
-   *
163
-   * \param[in] dateTime The user's call back function.  The callback
164
-   * function is of the form:
165
-   *
166
-   * \code
167
-   * void dateTime(uint16_t* date, uint16_t* time) {
168
-   *   uint16_t year;
169
-   *   uint8_t month, day, hour, minute, second;
170
-   *
171
-   *   // User gets date and time from GPS or real-time clock here
172
-   *
173
-   *   // return date using FAT_DATE macro to format fields
174
-   *   *date = FAT_DATE(year, month, day);
175
-   *
176
-   *   // return time using FAT_TIME macro to format fields
177
-   *   *time = FAT_TIME(hour, minute, second);
178
-   * }
179
-   * \endcode
180
-   *
181
-   * Sets the function that is called when a file is created or when
182
-   * a file's directory entry is modified by sync(). All timestamps,
183
-   * access, creation, and modify, are set when a file is created.
184
-   * sync() maintains the last access date and last modify date/time.
185
-   *
186
-   * See the timestamp() function.
187
-   */
188
-  static void dateTimeCallback(
189
-    void (*dateTime)(uint16_t* date, uint16_t* time)) {
190
-    dateTime_ = dateTime;
191
-  }
192
-  /**
193
-   * Cancel the date/time callback function.
194
-   */
195
-  static void dateTimeCallbackCancel(void) {
196
-    // use explicit zero since NULL is not defined for Sanguino
197
-    dateTime_ = 0;
198
-  }
199
-  /** \return Address of the block that contains this file's directory. */
200
-  uint32_t dirBlock(void) const {return dirBlock_;}
201
-  uint8_t dirEntry(dir_t* dir);
202
-  /** \return Index of this file's directory in the block dirBlock. */
203
-  uint8_t dirIndex(void) const {return dirIndex_;}
204
-  static void dirName(const dir_t& dir, char* name);
205
-  /** \return The total number of bytes in a file or directory. */
206
-  uint32_t fileSize(void) const {return fileSize_;}
207
-  /** \return The first cluster number for a file or directory. */
208
-  uint32_t firstCluster(void) const {return firstCluster_;}
209
-  /** \return True if this is a SdFile for a directory else false. */
210
-  uint8_t isDir(void) const {return type_ >= FAT_FILE_TYPE_MIN_DIR;}
211
-  /** \return True if this is a SdFile for a file else false. */
212
-  uint8_t isFile(void) const {return type_ == FAT_FILE_TYPE_NORMAL;}
213
-  /** \return True if this is a SdFile for an open file/directory else false. */
214
-  uint8_t isOpen(void) const {return type_ != FAT_FILE_TYPE_CLOSED;}
215
-  /** \return True if this is a SdFile for a subdirectory else false. */
216
-  uint8_t isSubDir(void) const {return type_ == FAT_FILE_TYPE_SUBDIR;}
217
-  /** \return True if this is a SdFile for the root directory. */
218
-  uint8_t isRoot(void) const {
219
-    return type_ == FAT_FILE_TYPE_ROOT16 || type_ == FAT_FILE_TYPE_ROOT32;
220
-  }
221
-  void ls(uint8_t flags = 0, uint8_t indent = 0);
222
-  uint8_t makeDir(SdFile* dir, const char* dirName);
223
-  uint8_t open(SdFile* dirFile, uint16_t index, uint8_t oflag);
224
-  uint8_t open(SdFile* dirFile, const char* fileName, uint8_t oflag);
225
-
226
-  uint8_t openRoot(SdVolume* vol);
227
-  static void printDirName(const dir_t& dir, uint8_t width);
228
-  static void printFatDate(uint16_t fatDate);
229
-  static void printFatTime(uint16_t fatTime);
230
-  static void printTwoDigits(uint8_t v);
231
-  /**
232
-   * Read the next byte from a file.
233
-   *
234
-   * \return For success read returns the next byte in the file as an int.
235
-   * If an error occurs or end of file is reached -1 is returned.
236
-   */
237
-  int16_t read(void) {
238
-    uint8_t b;
239
-    return read(&b, 1) == 1 ? b : -1;
240
-  }
241
-  int16_t read(void* buf, uint16_t nbyte);
242
-  int8_t readDir(dir_t* dir);
243
-  static uint8_t remove(SdFile* dirFile, const char* fileName);
244
-  uint8_t remove(void);
245
-  /** Set the file's current position to zero. */
246
-  void rewind(void) {
247
-    curPosition_ = curCluster_ = 0;
248
-  }
249
-  uint8_t rmDir(void);
250
-  uint8_t rmRfStar(void);
251
-  /** Set the files position to current position + \a pos. See seekSet(). */
252
-  uint8_t seekCur(uint32_t pos) {
253
-    return seekSet(curPosition_ + pos);
254
-  }
255
-  /**
256
-   *  Set the files current position to end of file.  Useful to position
257
-   *  a file for append. See seekSet().
258
-   */
259
-  uint8_t seekEnd(void) {return seekSet(fileSize_);}
260
-  uint8_t seekSet(uint32_t pos);
261
-  /**
262
-   * Use unbuffered reads to access this file.  Used with Wave
263
-   * Shield ISR.  Used with Sd2Card::partialBlockRead() in WaveRP.
264
-   *
265
-   * Not recommended for normal applications.
266
-   */
267
-  void setUnbufferedRead(void) {
268
-    if (isFile()) flags_ |= F_FILE_UNBUFFERED_READ;
269
-  }
270
-  uint8_t timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day,
271
-          uint8_t hour, uint8_t minute, uint8_t second);
272
-  uint8_t sync(void);
273
-  /** Type of this SdFile.  You should use isFile() or isDir() instead of type()
274
-   * if possible.
275
-   *
276
-   * \return The file or directory type.
277
-   */
278
-  uint8_t type(void) const {return type_;}
279
-  uint8_t truncate(uint32_t size);
280
-  /** \return Unbuffered read flag. */
281
-  uint8_t unbufferedRead(void) const {
282
-    return flags_ & F_FILE_UNBUFFERED_READ;
283
-  }
284
-  /** \return SdVolume that contains this file. */
285
-  SdVolume* volume(void) const {return vol_;}
286
-  void write(uint8_t b);
287
-  int16_t write(const void* buf, uint16_t nbyte);
288
-  void write(const char* str);
289
-  void write_P(PGM_P str);
290
-  void writeln_P(PGM_P str);
291
-//------------------------------------------------------------------------------
292
-#if ALLOW_DEPRECATED_FUNCTIONS
293
-// Deprecated functions  - suppress cpplint warnings with NOLINT comment
294
-  /** \deprecated Use:
295
-   * uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
296
-   */
297
-  uint8_t contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) {  // NOLINT
298
-    return contiguousRange(&bgnBlock, &endBlock);
299
-  }
300
- /** \deprecated Use:
301
-   * uint8_t SdFile::createContiguous(SdFile* dirFile,
302
-   *   const char* fileName, uint32_t size)
303
-   */
304
-  uint8_t createContiguous(SdFile& dirFile,  // NOLINT
305
-    const char* fileName, uint32_t size) {
306
-    return createContiguous(&dirFile, fileName, size);
307
-  }
308
-
309
-  /**
310
-   * \deprecated Use:
311
-   * static void SdFile::dateTimeCallback(
312
-   *   void (*dateTime)(uint16_t* date, uint16_t* time));
313
-   */
314
-  static void dateTimeCallback(
315
-    void (*dateTime)(uint16_t& date, uint16_t& time)) {  // NOLINT
316
-    oldDateTime_ = dateTime;
317
-    dateTime_ = dateTime ? oldToNew : 0;
318
-  }
319
-  /** \deprecated Use: uint8_t SdFile::dirEntry(dir_t* dir); */
320
-  uint8_t dirEntry(dir_t& dir) {return dirEntry(&dir);}  // NOLINT
321
-  /** \deprecated Use:
322
-   * uint8_t SdFile::makeDir(SdFile* dir, const char* dirName);
323
-   */
324
-  uint8_t makeDir(SdFile& dir, const char* dirName) {  // NOLINT
325
-    return makeDir(&dir, dirName);
326
-  }
327
-  /** \deprecated Use:
328
-   * uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag);
329
-   */
330
-  uint8_t open(SdFile& dirFile, // NOLINT
331
-    const char* fileName, uint8_t oflag) {
332
-    return open(&dirFile, fileName, oflag);
333
-  }
334
-  /** \deprecated  Do not use in new apps */
335
-  uint8_t open(SdFile& dirFile, const char* fileName) {  // NOLINT
336
-    return open(dirFile, fileName, O_RDWR);
337
-  }
338
-  /** \deprecated Use:
339
-   * uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag);
340
-   */
341
-  uint8_t open(SdFile& dirFile, uint16_t index, uint8_t oflag) {  // NOLINT
342
-    return open(&dirFile, index, oflag);
343
-  }
344
-  /** \deprecated Use: uint8_t SdFile::openRoot(SdVolume* vol); */
345
-  uint8_t openRoot(SdVolume& vol) {return openRoot(&vol);}  // NOLINT
346
-
347
-  /** \deprecated Use: int8_t SdFile::readDir(dir_t* dir); */
348
-  int8_t readDir(dir_t& dir) {return readDir(&dir);}  // NOLINT
349
-  /** \deprecated Use:
350
-   * static uint8_t SdFile::remove(SdFile* dirFile, const char* fileName);
351
-   */
352
-  static uint8_t remove(SdFile& dirFile, const char* fileName) {  // NOLINT
353
-    return remove(&dirFile, fileName);
354
-  }
355
-//------------------------------------------------------------------------------
356
-// rest are private
357
- private:
358
-  static void (*oldDateTime_)(uint16_t& date, uint16_t& time);  // NOLINT
359
-  static void oldToNew(uint16_t* date, uint16_t* time) {
360
-    uint16_t d;
361
-    uint16_t t;
362
-    oldDateTime_(d, t);
363
-    *date = d;
364
-    *time = t;
365
-  }
366
-#endif  // ALLOW_DEPRECATED_FUNCTIONS
39
+  SdFat() {}
40
+  /** \return a pointer to the Sd2Card object. */
41
+  Sd2Card* card() {return &card_;}
42
+  bool chdir(bool set_cwd = false);
43
+  bool chdir(const char* path, bool set_cwd = false);
44
+  void chvol();
45
+  void errorHalt();
46
+  void errorHalt_P(PGM_P msg);
47
+  void errorHalt(char const *msg);
48
+  void errorPrint();
49
+  void errorPrint_P(PGM_P msg);
50
+  void errorPrint(char const *msg);
51
+  bool exists(const char* name);
52
+  bool init(uint8_t sckRateID = SPI_FULL_SPEED,
53
+    uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
54
+  void initErrorHalt();
55
+  void initErrorHalt(char const *msg);
56
+  void initErrorHalt_P(PGM_P msg);
57
+  void initErrorPrint();
58
+  void initErrorPrint(char const *msg);
59
+  void initErrorPrint_P(PGM_P msg);
60
+  void ls(uint8_t flags = 0);
61
+  void ls(Print* pr, uint8_t flags = 0);
62
+  bool mkdir(const char* path, bool pFlag = true);
63
+  bool remove(const char* path);
64
+  bool rename(const char *oldPath, const char *newPath);
65
+  bool rmdir(const char* path);
66
+  bool truncate(const char* path, uint32_t length);
67
+  /** \return a pointer to the SdVolume object. */
68
+  SdVolume* vol() {return &vol_;}
69
+  /** \return a pointer to the volume working directory. */
70
+  SdBaseFile* vwd() {return &vwd_;}
367 71
  private:
368
-  // bits defined in flags_
369
-  // should be 0XF
370
-  static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC);
371
-  // available bits
372
-  static uint8_t const F_UNUSED = 0X30;
373
-  // use unbuffered SD read
374
-  static uint8_t const F_FILE_UNBUFFERED_READ = 0X40;
375
-  // sync of directory entry required
376
-  static uint8_t const F_FILE_DIR_DIRTY = 0X80;
377
-
378
-// make sure F_OFLAG is ok
379
-#if ((F_UNUSED | F_FILE_UNBUFFERED_READ | F_FILE_DIR_DIRTY) & F_OFLAG)
380
-#error flags_ bits conflict
381
-#endif  // flags_ bits
382
-
383
-  // private data
384
-  uint8_t   flags_;         // See above for definition of flags_ bits
385
-  uint8_t   type_;          // type of file see above for values
386
-  uint32_t  curCluster_;    // cluster for current file position
387
-  uint32_t  curPosition_;   // current file position in bytes from beginning
388
-  uint32_t  dirBlock_;      // SD block that contains directory entry for file
389
-  uint8_t   dirIndex_;      // index of entry in dirBlock 0 <= dirIndex_ <= 0XF
390
-  uint32_t  fileSize_;      // file size in bytes
391
-  uint32_t  firstCluster_;  // first cluster of file
392
-  SdVolume* vol_;           // volume where file is located
393
-
394
-  // private functions
395
-  uint8_t addCluster(void);
396
-  uint8_t addDirCluster(void);
397
-  dir_t* cacheDirEntry(uint8_t action);
398
-  static void (*dateTime_)(uint16_t* date, uint16_t* time);
399
-  static uint8_t make83Name(const char* str, uint8_t* name);
400
-  uint8_t openCachedEntry(uint8_t cacheIndex, uint8_t oflags);
401
-  dir_t* readDirCache(void);
402
-};
403
-//==============================================================================
404
-// SdVolume class
405
-/**
406
- * \brief Cache for an SD data block
407
- */
408
-union cache_t {
409
-           /** Used to access cached file data blocks. */
410
-  uint8_t  data[512];
411
-           /** Used to access cached FAT16 entries. */
412
-  uint16_t fat16[256];
413
-           /** Used to access cached FAT32 entries. */
414
-  uint32_t fat32[128];
415
-           /** Used to access cached directory entries. */
416
-  dir_t    dir[16];
417
-           /** Used to access a cached MasterBoot Record. */
418
-  mbr_t    mbr;
419
-           /** Used to access to a cached FAT boot sector. */
420
-  fbs_t    fbs;
421
-};
422
-//------------------------------------------------------------------------------
423
-/**
424
- * \class SdVolume
425
- * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards.
426
- */
427
-class SdVolume {
428
- public:
429
-  /** Create an instance of SdVolume */
430
-  SdVolume(void) :allocSearchStart_(2), fatType_(0) {}
431
-  /** Clear the cache and returns a pointer to the cache.  Used by the WaveRP
432
-   *  recorder to do raw write to the SD card.  Not for normal apps.
433
-   */
434
-  static uint8_t* cacheClear(void) {
435
-    cacheFlush();
436
-    cacheBlockNumber_ = 0XFFFFFFFF;
437
-    return cacheBuffer_.data;
438
-  }
439
-  /**
440
-   * Initialize a FAT volume.  Try partition one first then try super
441
-   * floppy format.
442
-   *
443
-   * \param[in] dev The Sd2Card where the volume is located.
444
-   *
445
-   * \return The value one, true, is returned for success and
446
-   * the value zero, false, is returned for failure.  Reasons for
447
-   * failure include not finding a valid partition, not finding a valid
448
-   * FAT file system or an I/O error.
449
-   */
450
-  uint8_t init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);}
451
-  uint8_t init(Sd2Card* dev, uint8_t part);
452
-
453
-  // inline functions that return volume info
454
-  /** \return The volume's cluster size in blocks. */
455
-  uint8_t blocksPerCluster(void) const {return blocksPerCluster_;}
456
-  /** \return The number of blocks in one FAT. */
457
-  uint32_t blocksPerFat(void)  const {return blocksPerFat_;}
458
-  /** \return The total number of clusters in the volume. */
459
-  uint32_t clusterCount(void) const {return clusterCount_;}
460
-  /** \return The shift count required to multiply by blocksPerCluster. */
461
-  uint8_t clusterSizeShift(void) const {return clusterSizeShift_;}
462
-  /** \return The logical block number for the start of file data. */
463
-  uint32_t dataStartBlock(void) const {return dataStartBlock_;}
464
-  /** \return The number of FAT structures on the volume. */
465
-  uint8_t fatCount(void) const {return fatCount_;}
466
-  /** \return The logical block number for the start of the first FAT. */
467
-  uint32_t fatStartBlock(void) const {return fatStartBlock_;}
468
-  /** \return The FAT type of the volume. Values are 12, 16 or 32. */
469
-  uint8_t fatType(void) const {return fatType_;}
470
-  /** \return The number of entries in the root directory for FAT16 volumes. */
471
-  uint32_t rootDirEntryCount(void) const {return rootDirEntryCount_;}
472
-  /** \return The logical block number for the start of the root directory
473
-       on FAT16 volumes or the first cluster number on FAT32 volumes. */
474
-  uint32_t rootDirStart(void) const {return rootDirStart_;}
475
-  /** return a pointer to the Sd2Card object for this volume */
476
-  static Sd2Card* sdCard(void) {return sdCard_;}
477
-//------------------------------------------------------------------------------
478
-#if ALLOW_DEPRECATED_FUNCTIONS
479
-  // Deprecated functions  - suppress cpplint warnings with NOLINT comment
480
-  /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev); */
481
-  uint8_t init(Sd2Card& dev) {return init(&dev);}  // NOLINT
482
-
483
-  /** \deprecated Use: uint8_t SdVolume::init(Sd2Card* dev, uint8_t vol); */
484
-  uint8_t init(Sd2Card& dev, uint8_t part) {  // NOLINT
485
-    return init(&dev, part);
486
-  }
487
-#endif  // ALLOW_DEPRECATED_FUNCTIONS
488
-//------------------------------------------------------------------------------
489
-  private:
490
-  // Allow SdFile access to SdVolume private data.
491
-  friend class SdFile;
492
-
493
-  // value for action argument in cacheRawBlock to indicate read from cache
494
-  static uint8_t const CACHE_FOR_READ = 0;
495
-  // value for action argument in cacheRawBlock to indicate cache dirty
496
-  static uint8_t const CACHE_FOR_WRITE = 1;
497
-
498
-  static cache_t cacheBuffer_;        // 512 byte cache for device blocks
499
-  static uint32_t cacheBlockNumber_;  // Logical number of block in the cache
500
-  static Sd2Card* sdCard_;            // Sd2Card object for cache
501
-  static uint8_t cacheDirty_;         // cacheFlush() will write block if true
502
-  static uint32_t cacheMirrorBlock_;  // block number for mirror FAT
503
-//
504
-  uint32_t allocSearchStart_;   // start cluster for alloc search
505
-  uint8_t blocksPerCluster_;    // cluster size in blocks
506
-  uint32_t blocksPerFat_;       // FAT size in blocks
507
-  uint32_t clusterCount_;       // clusters in one FAT
508
-  uint8_t clusterSizeShift_;    // shift to convert cluster count to block count
509
-  uint32_t dataStartBlock_;     // first data block number
510
-  uint8_t fatCount_;            // number of FATs on volume
511
-  uint32_t fatStartBlock_;      // start block for first FAT
512
-  uint8_t fatType_;             // volume type (12, 16, OR 32)
513
-  uint16_t rootDirEntryCount_;  // number of entries in FAT16 root dir
514
-  uint32_t rootDirStart_;       // root start block for FAT16, cluster for FAT32
515
-  //----------------------------------------------------------------------------
516
-  uint8_t allocContiguous(uint32_t count, uint32_t* curCluster);
517
-  uint8_t blockOfCluster(uint32_t position) const {
518
-          return (position >> 9) & (blocksPerCluster_ - 1);}
519
-  uint32_t clusterStartBlock(uint32_t cluster) const {
520
-           return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);}
521
-  uint32_t blockNumber(uint32_t cluster, uint32_t position) const {
522
-           return clusterStartBlock(cluster) + blockOfCluster(position);}
523
-  static uint8_t cacheFlush(void);
524
-  static uint8_t cacheRawBlock(uint32_t blockNumber, uint8_t action);
525
-  static void cacheSetDirty(void) {cacheDirty_ |= CACHE_FOR_WRITE;}
526
-  static uint8_t cacheZeroBlock(uint32_t blockNumber);
527
-  uint8_t chainSize(uint32_t beginCluster, uint32_t* size) const;
528
-  uint8_t fatGet(uint32_t cluster, uint32_t* value) const;
529
-  uint8_t fatPut(uint32_t cluster, uint32_t value);
530
-  uint8_t fatPutEOC(uint32_t cluster) {
531
-    return fatPut(cluster, 0x0FFFFFFF);
532
-  }
533
-  uint8_t freeChain(uint32_t cluster);
534
-  uint8_t isEOC(uint32_t cluster) const {
535
-    return  cluster >= (fatType_ == 16 ? FAT16EOC_MIN : FAT32EOC_MIN);
536
-  }
537
-  uint8_t readBlock(uint32_t block, uint8_t* dst) {
538
-    return sdCard_->readBlock(block, dst);}
539
-  uint8_t readData(uint32_t block, uint16_t offset,
540
-    uint16_t count, uint8_t* dst) {
541
-      return sdCard_->readData(block, offset, count, dst);
542
-  }
543
-  uint8_t writeBlock(uint32_t block, const uint8_t* dst) {
544
-    return sdCard_->writeBlock(block, dst);
545
-  }
72
+  Sd2Card card_;
73
+  SdVolume vol_;
74
+  SdBaseFile vwd_;
546 75
 };
547 76
 #endif  // SdFat_h

+ 108
- 0
Marlin/SdFatConfig.h View File

@@ -0,0 +1,108 @@
1
+/* Arduino SdFat Library
2
+ * Copyright (C) 2009 by William Greiman
3
+ *
4
+ * This file is part of the Arduino SdFat 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 SdFat Library.  If not, see
18
+ * <http://www.gnu.org/licenses/>.
19
+ */
20
+/**
21
+ * \file
22
+ * \brief configuration definitions
23
+ */
24
+#ifndef SdFatConfig_h
25
+#define SdFatConfig_h
26
+#include <stdint.h>
27
+//------------------------------------------------------------------------------
28
+/**
29
+ * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero.
30
+ *
31
+ * Using multiple cards costs 400 - 500  bytes of flash.
32
+ *
33
+ * Each card requires about 550 bytes of SRAM so use of a Mega is recommended.
34
+ */
35
+#define USE_MULTIPLE_CARDS 0
36
+//------------------------------------------------------------------------------
37
+/**
38
+ * Call flush for endl if ENDL_CALLS_FLUSH is nonzero
39
+ *
40
+ * The standard for iostreams is to call flush.  This is very costly for
41
+ * SdFat.  Each call to flush causes 2048 bytes of I/O to the SD.
42
+ *
43
+ * SdFat has a single 512 byte buffer for SD I/O so it must write the current
44
+ * data block to the SD, read the directory block from the SD, update the
45
+ * directory entry, write the directory block to the SD and read the data
46
+ * block back into the buffer.
47
+ *
48
+ * The SD flash memory controller is not designed for this many rewrites
49
+ * so performance may be reduced by more than a factor of 100.
50
+ *
51
+ * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force
52
+ * all data to be written to the SD.
53
+ */
54
+#define ENDL_CALLS_FLUSH 0
55
+//------------------------------------------------------------------------------
56
+/**
57
+ * Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero
58
+ */
59
+#define ALLOW_DEPRECATED_FUNCTIONS 1
60
+//------------------------------------------------------------------------------
61
+/**
62
+ * Allow FAT12 volumes if FAT12_SUPPORT is nonzero.
63
+ * FAT12 has not been well tested.
64
+ */
65
+#define FAT12_SUPPORT 0
66
+//------------------------------------------------------------------------------
67
+/**
68
+ * SPI init rate for SD initialization commands. Must be 5 (F_CPU/64)
69
+ * or 6 (F_CPU/128).
70
+ */
71
+#define SPI_SD_INIT_RATE 5
72
+//------------------------------------------------------------------------------
73
+/**
74
+ * Set the SS pin high for hardware SPI.  If SS is chip select for another SPI
75
+ * device this will disable that device during the SD init phase.
76
+ */
77
+#define SET_SPI_SS_HIGH 1
78
+//------------------------------------------------------------------------------
79
+/**
80
+ * Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos.
81
+ * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13.
82
+ *
83
+ * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used
84
+ * on Mega Arduinos.  Software SPI works well with GPS Shield V1.1
85
+ * but many SD cards will fail with GPS Shield V1.0.
86
+ */
87
+#define MEGA_SOFT_SPI 0
88
+//------------------------------------------------------------------------------
89
+/**
90
+ * Set USE_SOFTWARE_SPI nonzero to always use software SPI.
91
+ */
92
+#define USE_SOFTWARE_SPI 0
93
+// define software SPI pins so Mega can use unmodified 168/328 shields
94
+/** Software SPI chip select pin for the SD */
95
+uint8_t const SOFT_SPI_CS_PIN = 10;
96
+/** Software SPI Master Out Slave In pin */
97
+uint8_t const SOFT_SPI_MOSI_PIN = 11;
98
+/** Software SPI Master In Slave Out pin */
99
+uint8_t const SOFT_SPI_MISO_PIN = 12;
100
+/** Software SPI Clock pin */
101
+uint8_t const SOFT_SPI_SCK_PIN = 13;
102
+//------------------------------------------------------------------------------
103
+/**
104
+ * The __cxa_pure_virtual function is an error handler that is invoked when
105
+ * a pure virtual function is called.
106
+ */
107
+#define USE_CXA_PURE_VIRTUAL 1
108
+#endif  // SdFatConfig_h

Marlin/SdFatStructs.h
File diff suppressed because it is too large
View File


+ 74
- 0
Marlin/SdFatUtil.cpp View File

@@ -0,0 +1,74 @@
1
+/* Arduino SdFat Library
2
+ * Copyright (C) 2008 by William Greiman
3
+ *
4
+ * This file is part of the Arduino SdFat 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 SdFat Library.  If not, see
18
+ * <http://www.gnu.org/licenses/>.
19
+ */
20
+#include "SdFatUtil.h"
21
+//------------------------------------------------------------------------------
22
+/** Amount of free RAM
23
+ * \return The number of free bytes.
24
+ */
25
+int SdFatUtil::FreeRam() {
26
+  extern int  __bss_end;
27
+  extern int* __brkval;
28
+  int free_memory;
29
+  if (reinterpret_cast<int>(__brkval) == 0) {
30
+    // if no heap use from end of bss section
31
+    free_memory = reinterpret_cast<int>(&free_memory)
32
+                  - reinterpret_cast<int>(&__bss_end);
33
+  } else {
34
+    // use from top of stack to heap
35
+    free_memory = reinterpret_cast<int>(&free_memory)
36
+                  - reinterpret_cast<int>(__brkval);
37
+  }
38
+  return free_memory;
39
+}
40
+//------------------------------------------------------------------------------
41
+/** %Print a string in flash memory.
42
+ *
43
+ * \param[in] pr Print object for output.
44
+ * \param[in] str Pointer to string stored in flash memory.
45
+ */
46
+void SdFatUtil::print_P(Print* pr, PGM_P str) {
47
+  for (uint8_t c; (c = pgm_read_byte(str)); str++) pr->write(c);
48
+}
49
+//------------------------------------------------------------------------------
50
+/** %Print a string in flash memory followed by a CR/LF.
51
+ *
52
+ * \param[in] pr Print object for output.
53
+ * \param[in] str Pointer to string stored in flash memory.
54
+ */
55
+void SdFatUtil::println_P(Print* pr, PGM_P str) {
56
+  print_P(pr, str);
57
+  pr->println();
58
+}
59
+//------------------------------------------------------------------------------
60
+/** %Print a string in flash memory to Serial.
61
+ *
62
+ * \param[in] str Pointer to string stored in flash memory.
63
+ */
64
+void SdFatUtil::SerialPrint_P(PGM_P str) {
65
+  print_P(&Serial, str);
66
+}
67
+//------------------------------------------------------------------------------
68
+/** %Print a string in flash memory to Serial followed by a CR/LF.
69
+ *
70
+ * \param[in] str Pointer to string stored in flash memory.
71
+ */
72
+void SdFatUtil::SerialPrintln_P(PGM_P str) {
73
+  println_P(&Serial, str);
74
+}

+ 15
- 39
Marlin/SdFatUtil.h View File

@@ -21,50 +21,26 @@
21 21
 #define SdFatUtil_h
22 22
 /**
23 23
  * \file
24
- * Useful utility functions.
24
+ * \brief Useful utility functions.
25 25
  */
26
-#include <WProgram.h>
27 26
 #include <avr/pgmspace.h>
27
+#if ARDUINO < 100
28
+#include <WProgram.h>
29
+#else  // ARDUINO
30
+#include <Arduino.h>
31
+#endif  // ARDUINO
28 32
 /** Store and print a string in flash memory.*/
29 33
 #define PgmPrint(x) SerialPrint_P(PSTR(x))
30 34
 /** Store and print a string in flash memory followed by a CR/LF.*/
31 35
 #define PgmPrintln(x) SerialPrintln_P(PSTR(x))
32
-/** Defined so doxygen works for function definitions. */
33
-#define NOINLINE __attribute__((noinline))
34
-//------------------------------------------------------------------------------
35
-/** Return the number of bytes currently free in RAM. */
36
-static int FreeRam(void) {
37
-  extern int  __bss_end;
38
-  extern int* __brkval;
39
-  int free_memory;
40
-  if (reinterpret_cast<int>(__brkval) == 0) {
41
-    // if no heap use from end of bss section
42
-    free_memory = reinterpret_cast<int>(&free_memory)
43
-                  - reinterpret_cast<int>(&__bss_end);
44
-  } else {
45
-    // use from top of stack to heap
46
-    free_memory = reinterpret_cast<int>(&free_memory)
47
-                  - reinterpret_cast<int>(__brkval);
48
-  }
49
-  return free_memory;
50
-}
51
-//------------------------------------------------------------------------------
52
-/**
53
- * %Print a string in flash memory to the serial port.
54
- *
55
- * \param[in] str Pointer to string stored in flash memory.
56
- */
57
-static NOINLINE void SerialPrint_P(PGM_P str) {
58
-  for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.print(c);
59
-}
60
-//------------------------------------------------------------------------------
61
-/**
62
- * %Print a string in flash memory followed by a CR/LF.
63
- *
64
- * \param[in] str Pointer to string stored in flash memory.
65
- */
66
-static NOINLINE void SerialPrintln_P(PGM_P str) {
67
-  SerialPrint_P(str);
68
-  Serial.println();
36
+
37
+namespace SdFatUtil {
38
+  int FreeRam();
39
+  void print_P(Print* pr, PGM_P str);
40
+  void println_P(Print* pr, PGM_P str);
41
+  void SerialPrint_P(PGM_P str);
42
+  void SerialPrintln_P(PGM_P str);
69 43
 }
44
+
45
+using namespace SdFatUtil;  // NOLINT
70 46
 #endif  // #define SdFatUtil_h

+ 0
- 202
Marlin/SdFatmainpage.h View File

@@ -1,202 +0,0 @@
1
-/* Arduino SdFat Library
2
- * Copyright (C) 2009 by William Greiman
3
- *  
4
- * This file is part of the Arduino SdFat 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 SdFat Library.  If not, see
18
- * <http://www.gnu.org/licenses/>.
19
- */
20
-
21
-/**
22
-\mainpage Arduino SdFat Library
23
-<CENTER>Copyright &copy; 2009 by William Greiman
24
-</CENTER>
25
-
26
-\section Intro Introduction
27
-The Arduino SdFat Library is a minimal implementation of FAT16 and FAT32
28
-file systems on SD flash memory cards.  Standard SD and high capacity
29
-SDHC cards are supported.
30
-
31
-The SdFat only supports short 8.3 names.
32
-
33
-The main classes in SdFat are Sd2Card, SdVolume, and SdFile.
34
-
35
-The Sd2Card class supports access to standard SD cards and SDHC cards.  Most
36
-applications will only need to call the Sd2Card::init() member function.
37
-
38
-The SdVolume class supports FAT16 and FAT32 partitions.  Most applications
39
-will only need to call the SdVolume::init() member function.
40
-
41
-The SdFile class provides file access functions such as open(), read(),
42
-remove(), write(), close() and sync(). This class supports access to the root
43
-directory and subdirectories.
44
-
45
-A number of example are provided in the SdFat/examples folder.  These were
46
-developed to test SdFat and illustrate its use.
47
-
48
-SdFat was developed for high speed data recording.  SdFat was used to implement
49
-an audio record/play class, WaveRP, for the Adafruit Wave Shield.  This
50
-application uses special Sd2Card calls to write to contiguous files in raw mode.
51
-These functions reduce write latency so that audio can be recorded with the
52
-small amount of RAM in the Arduino.
53
-
54
-\section SDcard SD\SDHC Cards
55
-
56
-Arduinos access SD cards using the cards SPI protocol.  PCs, Macs, and
57
-most consumer devices use the 4-bit parallel SD protocol.  A card that
58
-functions well on A PC or Mac may not work well on the Arduino.
59
-
60
-Most cards have good SPI read performance but cards vary widely in SPI
61
-write performance.  Write performance is limited by how efficiently the
62
-card manages internal erase/remapping operations.  The Arduino cannot
63
-optimize writes to reduce erase operations because of its limit RAM.
64
-
65
-SanDisk cards generally have good write performance.  They seem to have
66
-more internal RAM buffering than other cards and therefore can limit
67
-the number of flash erase operations that the Arduino forces due to its
68
-limited RAM.
69
-
70
-\section Hardware Hardware Configuration
71
-
72
-SdFat was developed using an
73
-<A HREF = "http://www.adafruit.com/"> Adafruit Industries</A> 
74
-<A HREF = "http://www.ladyada.net/make/waveshield/"> Wave Shield</A>.
75
-
76
-The hardware interface to the SD card should not use a resistor based level
77
-shifter.  SdFat sets the SPI bus frequency to 8 MHz which results in signal
78
-rise times that are too slow for the edge detectors in many newer SD card
79
-controllers when resistor voltage dividers are used.
80
-
81
-The 5 to 3.3 V level shifter for 5 V Arduinos should be IC based like the
82
-74HC4050N based circuit shown in the file SdLevel.png.  The Adafruit Wave Shield
83
-uses a 74AHC125N.  Gravitech sells SD and MicroSD Card Adapters based on the
84
-74LCX245.
85
-
86
-If you are using a resistor based level shifter and are having problems try
87
-setting the SPI bus frequency to 4 MHz.  This can be done by using 
88
-card.init(SPI_HALF_SPEED) to initialize the SD card.
89
-
90
-\section comment Bugs and Comments
91
-
92
-If you wish to report bugs or have comments, send email to fat16lib@sbcglobal.net.
93
-
94
-\section SdFatClass SdFat Usage
95
-
96
-SdFat uses a slightly restricted form of short names.
97
-Only printable ASCII characters are supported. No characters with code point
98
-values greater than 127 are allowed.  Space is not allowed even though space
99
-was allowed in the API of early versions of DOS.
100
-
101
-Short names are limited to 8 characters followed by an optional period (.)
102
-and extension of up to 3 characters.  The characters may be any combination
103
-of letters and digits.  The following special characters are also allowed:
104
-
105
-$ % ' - _ @ ~ ` ! ( ) { } ^ # &
106
-
107
-Short names are always converted to upper case and their original case
108
-value is lost.
109
-
110
-\note
111
-  The Arduino Print class uses character
112
-at a time writes so it was necessary to use a \link SdFile::sync() sync() \endlink
113
-function to control when data is written to the SD card.
114
-
115
-\par
116
-An application which writes to a file using \link Print::print() print()\endlink,
117
-\link Print::println() println() \endlink
118
-or \link SdFile::write write() \endlink must call \link SdFile::sync() sync() \endlink
119
-at the appropriate time to force data and directory information to be written
120
-to the SD Card.  Data and directory information are also written to the SD card
121
-when \link SdFile::close() close() \endlink is called.
122
-
123
-\par
124
-Applications must use care calling \link SdFile::sync() sync() \endlink
125
-since 2048 bytes of I/O is required to update file and
126
-directory information.  This includes writing the current data block, reading
127
-the block that contains the directory entry for update, writing the directory
128
-block back and reading back the current data block.
129
-
130
-It is possible to open a file with two or more instances of SdFile.  A file may
131
-be corrupted if data is written to the file by more than one instance of SdFile.
132
-
133
-\section HowTo How to format SD Cards as FAT Volumes
134
-
135
-You should use a freshly formatted SD card for best performance.  FAT
136
-file systems become slower if many files have been created and deleted.
137
-This is because the directory entry for a deleted file is marked as deleted,
138
-but is not deleted.  When a new file is created, these entries must be scanned
139
-before creating the file, a flaw in the FAT design.  Also files can become
140
-fragmented which causes reads and writes to be slower.
141
-
142
-Microsoft operating systems support removable media formatted with a
143
-Master Boot Record, MBR, or formatted as a super floppy with a FAT Boot Sector
144
-in block zero.
145
-
146
-Microsoft operating systems expect MBR formatted removable media
147
-to have only one partition. The first partition should be used.
148
-
149
-Microsoft operating systems do not support partitioning SD flash cards.
150
-If you erase an SD card with a program like KillDisk, Most versions of
151
-Windows will format the card as a super floppy.
152
-
153
-The best way to restore an SD card's format is to use SDFormatter
154
-which can be downloaded from:
155
-
156
-http://www.sdcard.org/consumers/formatter/
157
-
158
-SDFormatter aligns flash erase boundaries with file
159
-system structures which reduces write latency and file system overhead.
160
-
161
-SDFormatter does not have an option for FAT type so it may format
162
-small cards as FAT12.
163
-
164
-After the MBR is restored by SDFormatter you may need to reformat small
165
-cards that have been formatted FAT12 to force the volume type to be FAT16.
166
-
167
-If you reformat the SD card with an OS utility, choose a cluster size that
168
-will result in:
169
-
170
-4084 < CountOfClusters && CountOfClusters < 65525
171
-
172
-The volume will then be FAT16.
173
-
174
-If you are formatting an SD card on OS X or Linux, be sure to use the first
175
-partition. Format this partition with a cluster count in above range.
176
-
177
-\section  References References
178
-
179
-Adafruit Industries:
180
-
181
-http://www.adafruit.com/
182
-
183
-http://www.ladyada.net/make/waveshield/
184
-
185
-The Arduino site:
186
-
187
-http://www.arduino.cc/
188
-
189
-For more information about FAT file systems see:
190
-
191
-http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
192
-
193
-For information about using SD cards as SPI devices see:
194
-
195
-http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf
196
-
197
-The ATmega328 datasheet:
198
-
199
-http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf
200
- 
201
-
202
- */  

+ 22
- 1193
Marlin/SdFile.cpp
File diff suppressed because it is too large
View File


+ 42
- 0
Marlin/SdFile.h View File

@@ -0,0 +1,42 @@
1
+/* Arduino SdFat Library
2
+ * Copyright (C) 2009 by William Greiman
3
+ *
4
+ * This file is part of the Arduino SdFat 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 SdFat Library.  If not, see
18
+ * <http://www.gnu.org/licenses/>.
19
+ */
20
+/**
21
+ * \file
22
+ * \brief SdFile class
23
+ */
24
+#include "SdBaseFile.h"
25
+#ifndef SdFile_h
26
+#define SdFile_h
27
+//------------------------------------------------------------------------------
28
+/**
29
+ * \class SdFile
30
+ * \brief SdBaseFile with Print.
31
+ */
32
+class SdFile : public SdBaseFile, public Print {
33
+ public:
34
+  SdFile() {}
35
+  SdFile(const char* name, uint8_t oflag);
36
+  void write(uint8_t b);
37
+  int16_t write(const void* buf, uint16_t nbyte);
38
+  void write(const char* str);
39
+  void write_P(PGM_P str);
40
+  void writeln_P(PGM_P str);
41
+};
42
+#endif  // SdFile_h

+ 140
- 97
Marlin/SdInfo.h View File

@@ -26,10 +26,10 @@
26 26
 // Part 1
27 27
 // Physical Layer
28 28
 // Simplified Specification
29
-// Version 2.00
30
-// September 25, 2006
29
+// Version 3.01
30
+// May 18, 2010
31 31
 //
32
-// www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf
32
+// http://www.sdcard.org/developers/tech/sdcard/pls/simplified_specs
33 33
 //------------------------------------------------------------------------------
34 34
 // SD card commands
35 35
 /** GO_IDLE_STATE - init card in spi mode if CS low */
@@ -40,10 +40,14 @@ uint8_t const CMD8 = 0X08;
40 40
 uint8_t const CMD9 = 0X09;
41 41
 /** SEND_CID - read the card identification information (CID register) */
42 42
 uint8_t const CMD10 = 0X0A;
43
+/** STOP_TRANSMISSION - end multiple block read sequence */
44
+uint8_t const CMD12 = 0X0C;
43 45
 /** SEND_STATUS - read the card status register */
44 46
 uint8_t const CMD13 = 0X0D;
45
-/** READ_BLOCK - read a single data block from the card */
47
+/** READ_SINGLE_BLOCK - read a single data block from the card */
46 48
 uint8_t const CMD17 = 0X11;
49
+/** READ_MULTIPLE_BLOCK - read a multiple data blocks from the card */
50
+uint8_t const CMD18 = 0X12;
47 51
 /** WRITE_BLOCK - write a single data block to the card */
48 52
 uint8_t const CMD24 = 0X18;
49 53
 /** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */
@@ -83,148 +87,187 @@ uint8_t const DATA_RES_MASK = 0X1F;
83 87
 /** write data accepted token */
84 88
 uint8_t const DATA_RES_ACCEPTED = 0X05;
85 89
 //------------------------------------------------------------------------------
90
+/** Card IDentification (CID) register */
86 91
 typedef struct CID {
87 92
   // byte 0
88
-  uint8_t mid;  // Manufacturer ID
93
+  /** Manufacturer ID */
94
+  unsigned char mid;
89 95
   // byte 1-2
90
-  char oid[2];  // OEM/Application ID
96
+  /** OEM/Application ID */
97
+  char oid[2];
91 98
   // byte 3-7
92
-  char pnm[5];  // Product name
99
+  /** Product name */
100
+  char pnm[5];
93 101
   // byte 8
94
-  unsigned prv_m : 4;  // Product revision n.m
95
-  unsigned prv_n : 4;
102
+  /** Product revision least significant digit */
103
+  unsigned char prv_m : 4;
104
+  /** Product revision most significant digit */
105
+  unsigned char prv_n : 4;
96 106
   // byte 9-12
97
-  uint32_t psn;  // Product serial number
107
+  /** Product serial number */
108
+  uint32_t psn;
98 109
   // byte 13
99
-  unsigned mdt_year_high : 4;  // Manufacturing date
100
-  unsigned reserved : 4;
110
+  /** Manufacturing date year low digit */
111
+  unsigned char mdt_year_high : 4;
112
+  /** not used */
113
+  unsigned char reserved : 4;
101 114
   // byte 14
102
-  unsigned mdt_month : 4;
103
-  unsigned mdt_year_low :4;
115
+  /** Manufacturing date month */
116
+  unsigned char mdt_month : 4;
117
+  /** Manufacturing date year low digit */
118
+  unsigned char mdt_year_low :4;
104 119
   // byte 15
105
-  unsigned always1 : 1;
106
-  unsigned crc : 7;
120
+  /** not used always 1 */
121
+  unsigned char always1 : 1;
122
+  /** CRC7 checksum */
123
+  unsigned char crc : 7;
107 124
 }cid_t;
108 125
 //------------------------------------------------------------------------------
109
-// CSD for version 1.00 cards
126
+/** CSD for version 1.00 cards */
110 127
 typedef struct CSDV1 {
111 128
   // byte 0
112
-  unsigned reserved1 : 6;
113
-  unsigned csd_ver : 2;
129
+  unsigned char reserved1 : 6;
130
+  unsigned char csd_ver : 2;
114 131
   // byte 1
115
-  uint8_t taac;
132
+  unsigned char taac;
116 133
   // byte 2
117
-  uint8_t nsac;
134
+  unsigned char nsac;
118 135
   // byte 3
119
-  uint8_t tran_speed;
136
+  unsigned char tran_speed;
120 137
   // byte 4
121
-  uint8_t ccc_high;
138
+  unsigned char ccc_high;
122 139
   // byte 5
123
-  unsigned read_bl_len : 4;
124
-  unsigned ccc_low : 4;
140
+  unsigned char read_bl_len : 4;
141
+  unsigned char ccc_low : 4;
125 142
   // byte 6
126
-  unsigned c_size_high : 2;
127
-  unsigned reserved2 : 2;
128
-  unsigned dsr_imp : 1;
129
-  unsigned read_blk_misalign :1;
130
-  unsigned write_blk_misalign : 1;
131
-  unsigned read_bl_partial : 1;
143
+  unsigned char c_size_high : 2;
144
+  unsigned char reserved2 : 2;
145
+  unsigned char dsr_imp : 1;
146
+  unsigned char read_blk_misalign :1;
147
+  unsigned char write_blk_misalign : 1;
148
+  unsigned char read_bl_partial : 1;
132 149
   // byte 7
133
-  uint8_t c_size_mid;
150
+  unsigned char c_size_mid;
134 151
   // byte 8
135
-  unsigned vdd_r_curr_max : 3;
136
-  unsigned vdd_r_curr_min : 3;
137
-  unsigned c_size_low :2;
152
+  unsigned char vdd_r_curr_max : 3;
153
+  unsigned char vdd_r_curr_min : 3;
154
+  unsigned char c_size_low :2;
138 155
   // byte 9
139
-  unsigned c_size_mult_high : 2;
140
-  unsigned vdd_w_cur_max : 3;
141
-  unsigned vdd_w_curr_min : 3;
156
+  unsigned char c_size_mult_high : 2;
157
+  unsigned char vdd_w_cur_max : 3;
158
+  unsigned char vdd_w_curr_min : 3;
142 159
   // byte 10
143
-  unsigned sector_size_high : 6;
144
-  unsigned erase_blk_en : 1;
145
-  unsigned c_size_mult_low : 1;
160
+  unsigned char sector_size_high : 6;
161
+  unsigned char erase_blk_en : 1;
162
+  unsigned char c_size_mult_low : 1;
146 163
   // byte 11
147
-  unsigned wp_grp_size : 7;
148
-  unsigned sector_size_low : 1;
164
+  unsigned char wp_grp_size : 7;
165
+  unsigned char sector_size_low : 1;
149 166
   // byte 12
150
-  unsigned write_bl_len_high : 2;
151
-  unsigned r2w_factor : 3;
152
-  unsigned reserved3 : 2;
153
-  unsigned wp_grp_enable : 1;
167
+  unsigned char write_bl_len_high : 2;
168
+  unsigned char r2w_factor : 3;
169
+  unsigned char reserved3 : 2;
170
+  unsigned char wp_grp_enable : 1;
154 171
   // byte 13
155
-  unsigned reserved4 : 5;
156
-  unsigned write_partial : 1;
157
-  unsigned write_bl_len_low : 2;
172
+  unsigned char reserved4 : 5;
173
+  unsigned char write_partial : 1;
174
+  unsigned char write_bl_len_low : 2;
158 175
   // byte 14
159
-  unsigned reserved5: 2;
160
-  unsigned file_format : 2;
161
-  unsigned tmp_write_protect : 1;
162
-  unsigned perm_write_protect : 1;
163
-  unsigned copy : 1;
164
-  unsigned file_format_grp : 1;
176
+  unsigned char reserved5: 2;
177
+  unsigned char file_format : 2;
178
+  unsigned char tmp_write_protect : 1;
179
+  unsigned char perm_write_protect : 1;
180
+  unsigned char copy : 1;
181
+  /** Indicates the file format on the card */
182
+  unsigned char file_format_grp : 1;
165 183
   // byte 15
166
-  unsigned always1 : 1;
167
-  unsigned crc : 7;
184
+  unsigned char always1 : 1;
185
+  unsigned char crc : 7;
168 186
 }csd1_t;
169 187
 //------------------------------------------------------------------------------
170
-// CSD for version 2.00 cards
188
+/** CSD for version 2.00 cards */
171 189
 typedef struct CSDV2 {
172 190
   // byte 0
173
-  unsigned reserved1 : 6;
174
-  unsigned csd_ver : 2;
191
+  unsigned char reserved1 : 6;
192
+  unsigned char csd_ver : 2;
175 193
   // byte 1
176
-  uint8_t taac;
194
+  /** fixed to 0X0E */
195
+  unsigned char taac;
177 196
   // byte 2
178
-  uint8_t nsac;
197
+  /** fixed to 0 */
198
+  unsigned char nsac;
179 199
   // byte 3
180
-  uint8_t tran_speed;
200
+  unsigned char tran_speed;
181 201
   // byte 4
182
-  uint8_t ccc_high;
202
+  unsigned char ccc_high;
183 203
   // byte 5
184
-  unsigned read_bl_len : 4;
185
-  unsigned ccc_low : 4;
204
+  /** This field is fixed to 9h, which indicates READ_BL_LEN=512 Byte */
205
+  unsigned char read_bl_len : 4;
206
+  unsigned char ccc_low : 4;
186 207
   // byte 6
187
-  unsigned reserved2 : 4;
188
-  unsigned dsr_imp : 1;
189
-  unsigned read_blk_misalign :1;
190
-  unsigned write_blk_misalign : 1;
191
-  unsigned read_bl_partial : 1;
208
+  /** not used */
209
+  unsigned char reserved2 : 4;
210
+  unsigned char dsr_imp : 1;
211
+  /** fixed to 0 */
212
+  unsigned char read_blk_misalign :1;
213
+  /** fixed to 0 */
214
+  unsigned char write_blk_misalign : 1;
215
+  /** fixed to 0 - no partial read */
216
+  unsigned char read_bl_partial : 1;
192 217
   // byte 7
193
-  unsigned reserved3 : 2;
194
-  unsigned c_size_high : 6;
218
+  /** not used */
219
+  unsigned char reserved3 : 2;
220
+  /** high part of card size */
221
+  unsigned char c_size_high : 6;
195 222
   // byte 8
196
-  uint8_t c_size_mid;
223
+  /** middle part of card size */
224
+  unsigned char c_size_mid;
197 225
   // byte 9
198
-  uint8_t c_size_low;
226
+  /** low part of card size */
227
+  unsigned char c_size_low;
199 228
   // byte 10
200
-  unsigned sector_size_high : 6;
201
-  unsigned erase_blk_en : 1;
202
-  unsigned reserved4 : 1;
229
+  /** sector size is fixed at 64 KB */
230
+  unsigned char sector_size_high : 6;
231
+  /** fixed to 1 - erase single is supported */
232
+  unsigned char erase_blk_en : 1;
233
+  /** not used */
234
+  unsigned char reserved4 : 1;
203 235
   // byte 11
204
-  unsigned wp_grp_size : 7;
205
-  unsigned sector_size_low : 1;
236
+  unsigned char wp_grp_size : 7;
237
+  /** sector size is fixed at 64 KB */
238
+  unsigned char sector_size_low : 1;
206 239
   // byte 12
207
-  unsigned write_bl_len_high : 2;
208
-  unsigned r2w_factor : 3;
209
-  unsigned reserved5 : 2;
210
-  unsigned wp_grp_enable : 1;
240
+  /** write_bl_len fixed for 512 byte blocks */
241
+  unsigned char write_bl_len_high : 2;
242
+  /** fixed value of 2 */
243
+  unsigned char r2w_factor : 3;
244
+  /** not used */
245
+  unsigned char reserved5 : 2;
246
+  /** fixed value of 0 - no write protect groups */
247
+  unsigned char wp_grp_enable : 1;
211 248
   // byte 13
212
-  unsigned reserved6 : 5;
213
-  unsigned write_partial : 1;
214
-  unsigned write_bl_len_low : 2;
249
+  unsigned char reserved6 : 5;
250
+  /** always zero - no partial block read*/
251
+  unsigned char write_partial : 1;
252
+  /** write_bl_len fixed for 512 byte blocks */
253
+  unsigned char write_bl_len_low : 2;
215 254
   // byte 14
216
-  unsigned reserved7: 2;
217
-  unsigned file_format : 2;
218
-  unsigned tmp_write_protect : 1;
219
-  unsigned perm_write_protect : 1;
220
-  unsigned copy : 1;
221
-  unsigned file_format_grp : 1;
255
+  unsigned char reserved7: 2;
256
+  /** Do not use always 0 */
257
+  unsigned char file_format : 2;
258
+  unsigned char tmp_write_protect : 1;
259
+  unsigned char perm_write_protect : 1;
260
+  unsigned char copy : 1;
261
+  /** Do not use always 0 */
262
+  unsigned char file_format_grp : 1;
222 263
   // byte 15
223
-  unsigned always1 : 1;
224
-  unsigned crc : 7;
264
+  /** not used always 1 */
265
+  unsigned char always1 : 1;
266
+  /** checksum */
267
+  unsigned char crc : 7;
225 268
 }csd2_t;
226 269
 //------------------------------------------------------------------------------
227
-// union of old and new style CSD register
270
+/** union of old and new style CSD register */
228 271
 union csd_t {
229 272
   csd1_t v1;
230 273
   csd2_t v2;

+ 192
- 86
Marlin/SdVolume.cpp View File

@@ -17,23 +17,28 @@
17 17
  * along with the Arduino SdFat Library.  If not, see
18 18
  * <http://www.gnu.org/licenses/>.
19 19
  */
20
-#include "SdFat.h"
20
+#include "SdVolume.h"
21 21
 //------------------------------------------------------------------------------
22
+#if !USE_MULTIPLE_CARDS
22 23
 // raw block cache
23
-// init cacheBlockNumber_to invalid SD block number
24
-uint32_t SdVolume::cacheBlockNumber_ = 0XFFFFFFFF;
25
-cache_t  SdVolume::cacheBuffer_;     // 512 byte cache for Sd2Card
26
-Sd2Card* SdVolume::sdCard_;          // pointer to SD card object
27
-uint8_t  SdVolume::cacheDirty_ = 0;  // cacheFlush() will write block if true
28
-uint32_t SdVolume::cacheMirrorBlock_ = 0;  // mirror  block for second FAT
24
+uint32_t SdVolume::cacheBlockNumber_;  // current block number
25
+cache_t  SdVolume::cacheBuffer_;       // 512 byte cache for Sd2Card
26
+Sd2Card* SdVolume::sdCard_;            // pointer to SD card object
27
+bool     SdVolume::cacheDirty_;        // cacheFlush() will write block if true
28
+uint32_t SdVolume::cacheMirrorBlock_;  // mirror  block for second FAT
29
+#endif  // USE_MULTIPLE_CARDS
29 30
 //------------------------------------------------------------------------------
30 31
 // find a contiguous group of clusters
31
-uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
32
+bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
32 33
   // start of group
33 34
   uint32_t bgnCluster;
35
+  // end of group
36
+  uint32_t endCluster;
37
+  // last cluster of FAT
38
+  uint32_t fatEnd = clusterCount_ + 1;
34 39
 
35 40
   // flag to save place to start next search
36
-  uint8_t setStart;
41
+  bool setStart;
37 42
 
38 43
   // set search start cluster
39 44
   if (*curCluster) {
@@ -47,25 +52,22 @@ uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
47 52
     bgnCluster = allocSearchStart_;
48 53
 
49 54
     // save next search start if one cluster
50
-    setStart = 1 == count;
55
+    setStart = count == 1;
51 56
   }
52 57
   // end of group
53
-  uint32_t endCluster = bgnCluster;
54
-
55
-  // last cluster of FAT
56
-  uint32_t fatEnd = clusterCount_ + 1;
58
+  endCluster = bgnCluster;
57 59
 
58 60
   // search the FAT for free clusters
59 61
   for (uint32_t n = 0;; n++, endCluster++) {
60 62
     // can't find space checked all clusters
61
-    if (n >= clusterCount_) return false;
63
+    if (n >= clusterCount_) goto fail;
62 64
 
63 65
     // past end - start from beginning of FAT
64 66
     if (endCluster > fatEnd) {
65 67
       bgnCluster = endCluster = 2;
66 68
     }
67 69
     uint32_t f;
68
-    if (!fatGet(endCluster, &f)) return false;
70
+    if (!fatGet(endCluster, &f)) goto fail;
69 71
 
70 72
     if (f != 0) {
71 73
       // cluster in use try next cluster as bgnCluster
@@ -76,16 +78,16 @@ uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
76 78
     }
77 79
   }
78 80
   // mark end of chain
79
-  if (!fatPutEOC(endCluster)) return false;
81
+  if (!fatPutEOC(endCluster)) goto fail;
80 82
 
81 83
   // link clusters
82 84
   while (endCluster > bgnCluster) {
83
-    if (!fatPut(endCluster - 1, endCluster)) return false;
85
+    if (!fatPut(endCluster - 1, endCluster)) goto fail;
84 86
     endCluster--;
85 87
   }
86 88
   if (*curCluster != 0) {
87 89
     // connect chains
88
-    if (!fatPut(*curCluster, bgnCluster)) return false;
90
+    if (!fatPut(*curCluster, bgnCluster)) goto fail;
89 91
   }
90 92
   // return first cluster number to caller
91 93
   *curCluster = bgnCluster;
@@ -94,66 +96,87 @@ uint8_t SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
94 96
   if (setStart) allocSearchStart_ = bgnCluster + 1;
95 97
 
96 98
   return true;
99
+
100
+ fail:
101
+  return false;
97 102
 }
98 103
 //------------------------------------------------------------------------------
99
-uint8_t SdVolume::cacheFlush(void) {
104
+bool SdVolume::cacheFlush() {
100 105
   if (cacheDirty_) {
101 106
     if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) {
102
-      return false;
107
+      goto fail;
103 108
     }
104 109
     // mirror FAT tables
105 110
     if (cacheMirrorBlock_) {
106 111
       if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) {
107
-        return false;
112
+        goto fail;
108 113
       }
109 114
       cacheMirrorBlock_ = 0;
110 115
     }
111 116
     cacheDirty_ = 0;
112 117
   }
113 118
   return true;
119
+
120
+ fail:
121
+  return false;
114 122
 }
115 123
 //------------------------------------------------------------------------------
116
-uint8_t SdVolume::cacheRawBlock(uint32_t blockNumber, uint8_t action) {
124
+bool SdVolume::cacheRawBlock(uint32_t blockNumber, bool dirty) {
117 125
   if (cacheBlockNumber_ != blockNumber) {
118
-    if (!cacheFlush()) return false;
119
-    if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) return false;
126
+    if (!cacheFlush()) goto fail;
127
+    if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) goto fail;
120 128
     cacheBlockNumber_ = blockNumber;
121 129
   }
122
-  cacheDirty_ |= action;
130
+  if (dirty) cacheDirty_ = true;
123 131
   return true;
124
-}
125
-//------------------------------------------------------------------------------
126
-// cache a zero block for blockNumber
127
-uint8_t SdVolume::cacheZeroBlock(uint32_t blockNumber) {
128
-  if (!cacheFlush()) return false;
129 132
 
130
-  // loop take less flash than memset(cacheBuffer_.data, 0, 512);
131
-  for (uint16_t i = 0; i < 512; i++) {
132
-    cacheBuffer_.data[i] = 0;
133
-  }
134
-  cacheBlockNumber_ = blockNumber;
135
-  cacheSetDirty();
136
-  return true;
133
+ fail:
134
+  return false;
137 135
 }
138 136
 //------------------------------------------------------------------------------
139 137
 // return the size in bytes of a cluster chain
140
-uint8_t SdVolume::chainSize(uint32_t cluster, uint32_t* size) const {
138
+bool SdVolume::chainSize(uint32_t cluster, uint32_t* size) {
141 139
   uint32_t s = 0;
142 140
   do {
143
-    if (!fatGet(cluster, &cluster)) return false;
141
+    if (!fatGet(cluster, &cluster)) goto fail;
144 142
     s += 512UL << clusterSizeShift_;
145 143
   } while (!isEOC(cluster));
146 144
   *size = s;
147 145
   return true;
146
+
147
+ fail:
148
+  return false;
148 149
 }
149 150
 //------------------------------------------------------------------------------
150 151
 // Fetch a FAT entry
151
-uint8_t SdVolume::fatGet(uint32_t cluster, uint32_t* value) const {
152
-  if (cluster > (clusterCount_ + 1)) return false;
153
-  uint32_t lba = fatStartBlock_;
154
-  lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7;
152
+bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) {
153
+  uint32_t lba;
154
+  if (cluster > (clusterCount_ + 1)) goto fail;
155
+  if (FAT12_SUPPORT && fatType_ == 12) {
156
+    uint16_t index = cluster;
157
+    index += index >> 1;
158
+    lba = fatStartBlock_ + (index >> 9);
159
+    if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto fail;
160
+    index &= 0X1FF;
161
+    uint16_t tmp = cacheBuffer_.data[index];
162
+    index++;
163
+    if (index == 512) {
164
+      if (!cacheRawBlock(lba + 1, CACHE_FOR_READ)) goto fail;
165
+      index = 0;
166
+    }
167
+    tmp |= cacheBuffer_.data[index] << 8;
168
+    *value = cluster & 1 ? tmp >> 4 : tmp & 0XFFF;
169
+    return true;
170
+  }
171
+  if (fatType_ == 16) {
172
+    lba = fatStartBlock_ + (cluster >> 8);
173
+  } else if (fatType_ == 32) {
174
+    lba = fatStartBlock_ + (cluster >> 7);
175
+  } else {
176
+    goto fail;
177
+  }
155 178
   if (lba != cacheBlockNumber_) {
156
-    if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false;
179
+    if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto fail;
157 180
   }
158 181
   if (fatType_ == 16) {
159 182
     *value = cacheBuffer_.fat16[cluster & 0XFF];
@@ -161,56 +184,127 @@ uint8_t SdVolume::fatGet(uint32_t cluster, uint32_t* value) const {
161 184
     *value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK;
162 185
   }
163 186
   return true;
187
+
188
+ fail:
189
+  return false;
164 190
 }
165 191
 //------------------------------------------------------------------------------
166 192
 // Store a FAT entry
167
-uint8_t SdVolume::fatPut(uint32_t cluster, uint32_t value) {
193
+bool SdVolume::fatPut(uint32_t cluster, uint32_t value) {
194
+  uint32_t lba;
168 195
   // error if reserved cluster
169
-  if (cluster < 2) return false;
196
+  if (cluster < 2) goto fail;
170 197
 
171 198
   // error if not in FAT
172
-  if (cluster > (clusterCount_ + 1)) return false;
199
+  if (cluster > (clusterCount_ + 1)) goto fail;
173 200
 
174
-  // calculate block address for entry
175
-  uint32_t lba = fatStartBlock_;
176
-  lba += fatType_ == 16 ? cluster >> 8 : cluster >> 7;
177
-
178
-  if (lba != cacheBlockNumber_) {
179
-    if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false;
201
+  if (FAT12_SUPPORT && fatType_ == 12) {
202
+    uint16_t index = cluster;
203
+    index += index >> 1;
204
+    lba = fatStartBlock_ + (index >> 9);
205
+    if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail;
206
+    // mirror second FAT
207
+    if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
208
+    index &= 0X1FF;
209
+    uint8_t tmp = value;
210
+    if (cluster & 1) {
211
+      tmp = (cacheBuffer_.data[index] & 0XF) | tmp << 4;
212
+    }
213
+    cacheBuffer_.data[index] = tmp;
214
+    index++;
215
+    if (index == 512) {
216
+      lba++;
217
+      index = 0;
218
+      if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail;
219
+      // mirror second FAT
220
+      if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
221
+    }
222
+    tmp = value >> 4;
223
+    if (!(cluster & 1)) {
224
+      tmp = ((cacheBuffer_.data[index] & 0XF0)) | tmp >> 4;
225
+    }
226
+    cacheBuffer_.data[index] = tmp;
227
+    return true;
180 228
   }
229
+  if (fatType_ == 16) {
230
+    lba = fatStartBlock_ + (cluster >> 8);
231
+  } else if (fatType_ == 32) {
232
+    lba = fatStartBlock_ + (cluster >> 7);
233
+  } else {
234
+    goto fail;
235
+  }
236
+  if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail;
181 237
   // store entry
182 238
   if (fatType_ == 16) {
183 239
     cacheBuffer_.fat16[cluster & 0XFF] = value;
184 240
   } else {
185 241
     cacheBuffer_.fat32[cluster & 0X7F] = value;
186 242
   }
187
-  cacheSetDirty();
188
-
189 243
   // mirror second FAT
190 244
   if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
191 245
   return true;
246
+
247
+ fail:
248
+  return false;
192 249
 }
193 250
 //------------------------------------------------------------------------------
194 251
 // free a cluster chain
195
-uint8_t SdVolume::freeChain(uint32_t cluster) {
252
+bool SdVolume::freeChain(uint32_t cluster) {
253
+  uint32_t next;
254
+
196 255
   // clear free cluster location
197 256
   allocSearchStart_ = 2;
198 257
 
199 258
   do {
200
-    uint32_t next;
201
-    if (!fatGet(cluster, &next)) return false;
259
+    if (!fatGet(cluster, &next)) goto fail;
202 260
 
203 261
     // free cluster
204
-    if (!fatPut(cluster, 0)) return false;
262
+    if (!fatPut(cluster, 0)) goto fail;
205 263
 
206 264
     cluster = next;
207 265
   } while (!isEOC(cluster));
208 266
 
209 267
   return true;
268
+
269
+ fail:
270
+  return false;
271
+}
272
+//------------------------------------------------------------------------------
273
+/** Volume free space in clusters.
274
+ *
275
+ * \return Count of free clusters for success or -1 if an error occurs.
276
+ */
277
+int32_t SdVolume::freeClusterCount() {
278
+  uint32_t free = 0;
279
+  uint16_t n;
280
+  uint32_t todo = clusterCount_ + 2;
281
+
282
+  if (fatType_ == 16) {
283
+    n = 256;
284
+  } else if (fatType_ == 32) {
285
+    n = 128;
286
+  } else {
287
+    // put FAT12 here
288
+    return -1;
289
+  }
290
+
291
+  for (uint32_t lba = fatStartBlock_; todo; todo -= n, lba++) {
292
+    if (!cacheRawBlock(lba, CACHE_FOR_READ)) return -1;
293
+    if (todo < n) n = todo;
294
+    if (fatType_ == 16) {
295
+      for (uint16_t i = 0; i < n; i++) {
296
+        if (cacheBuffer_.fat16[i] == 0) free++;
297
+      }
298
+    } else {
299
+      for (uint16_t i = 0; i < n; i++) {
300
+        if (cacheBuffer_.fat32[i] == 0) free++;
301
+      }
302
+    }
303
+  }
304
+  return free;
210 305
 }
211 306
 //------------------------------------------------------------------------------
212
-/**
213
- * Initialize a FAT volume.
307
+/** Initialize a FAT volume.
214 308
  *
215 309
  * \param[in] dev The SD card where the volume is located.
216 310
  *
@@ -224,58 +318,66 @@ uint8_t SdVolume::freeChain(uint32_t cluster) {
224 318
  * failure include not finding a valid partition, not finding a valid
225 319
  * FAT file system in the specified partition or an I/O error.
226 320
  */
227
-uint8_t SdVolume::init(Sd2Card* dev, uint8_t part) {
321
+bool SdVolume::init(Sd2Card* dev, uint8_t part) {
322
+  uint32_t totalBlocks;
228 323
   uint32_t volumeStartBlock = 0;
324
+  fat32_boot_t* fbs;
325
+
229 326
   sdCard_ = dev;
327
+  fatType_ = 0;
328
+  allocSearchStart_ = 2;
329
+  cacheDirty_ = 0;  // cacheFlush() will write block if true
330
+  cacheMirrorBlock_ = 0;
331
+  cacheBlockNumber_ = 0XFFFFFFFF;
332
+
230 333
   // if part == 0 assume super floppy with FAT boot sector in block zero
231 334
   // if part > 0 assume mbr volume with partition table
232 335
   if (part) {
233
-    if (part > 4)return false;
234
-    if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false;
336
+    if (part > 4)goto fail;
337
+    if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail;
235 338
     part_t* p = &cacheBuffer_.mbr.part[part-1];
236 339
     if ((p->boot & 0X7F) !=0  ||
237 340
       p->totalSectors < 100 ||
238 341
       p->firstSector == 0) {
239 342
       // not a valid partition
240
-      return false;
343
+      goto fail;
241 344
     }
242 345
     volumeStartBlock = p->firstSector;
243 346
   }
244
-  if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false;
245
-  bpb_t* bpb = &cacheBuffer_.fbs.bpb;
246
-  if (bpb->bytesPerSector != 512 ||
247
-    bpb->fatCount == 0 ||
248
-    bpb->reservedSectorCount == 0 ||
249
-    bpb->sectorsPerCluster == 0) {
347
+  if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail;
348
+  fbs = &cacheBuffer_.fbs32;
349
+  if (fbs->bytesPerSector != 512 ||
350
+    fbs->fatCount == 0 ||
351
+    fbs->reservedSectorCount == 0 ||
352
+    fbs->sectorsPerCluster == 0) {
250 353
        // not valid FAT volume
251
-      return false;
354
+      goto fail;
252 355
   }
253
-  fatCount_ = bpb->fatCount;
254
-  blocksPerCluster_ = bpb->sectorsPerCluster;
255
-
356
+  fatCount_ = fbs->fatCount;
357
+  blocksPerCluster_ = fbs->sectorsPerCluster;
256 358
   // determine shift that is same as multiply by blocksPerCluster_
257 359
   clusterSizeShift_ = 0;
258 360
   while (blocksPerCluster_ != (1 << clusterSizeShift_)) {
259 361
     // error if not power of 2
260
-    if (clusterSizeShift_++ > 7) return false;
362
+    if (clusterSizeShift_++ > 7) goto fail;
261 363
   }
262
-  blocksPerFat_ = bpb->sectorsPerFat16 ?
263
-                    bpb->sectorsPerFat16 : bpb->sectorsPerFat32;
364
+  blocksPerFat_ = fbs->sectorsPerFat16 ?
365
+                    fbs->sectorsPerFat16 : fbs->sectorsPerFat32;
264 366
 
265
-  fatStartBlock_ = volumeStartBlock + bpb->reservedSectorCount;
367
+  fatStartBlock_ = volumeStartBlock + fbs->reservedSectorCount;
266 368
 
267 369
   // count for FAT16 zero for FAT32
268
-  rootDirEntryCount_ = bpb->rootDirEntryCount;
370
+  rootDirEntryCount_ = fbs->rootDirEntryCount;
269 371
 
270 372
   // directory start for FAT16 dataStart for FAT32
271
-  rootDirStart_ = fatStartBlock_ + bpb->fatCount * blocksPerFat_;
373
+  rootDirStart_ = fatStartBlock_ + fbs->fatCount * blocksPerFat_;
272 374
 
273 375
   // data start for FAT16 and FAT32
274
-  dataStartBlock_ = rootDirStart_ + ((32 * bpb->rootDirEntryCount + 511)/512);
376
+  dataStartBlock_ = rootDirStart_ + ((32 * fbs->rootDirEntryCount + 511)/512);
275 377
 
276 378
   // total blocks for FAT16 or FAT32
277
-  uint32_t totalBlocks = bpb->totalSectors16 ?
278
-                           bpb->totalSectors16 : bpb->totalSectors32;
379
+  totalBlocks = fbs->totalSectors16 ?
380
+                           fbs->totalSectors16 : fbs->totalSectors32;
279 381
   // total data blocks
280 382
   clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock);
281 383
 
@@ -285,11 +387,15 @@ uint8_t SdVolume::init(Sd2Card* dev, uint8_t part) {
285 387
   // FAT type is determined by cluster count
286 388
   if (clusterCount_ < 4085) {
287 389
     fatType_ = 12;
390
+    if (!FAT12_SUPPORT) goto fail;
288 391
   } else if (clusterCount_ < 65525) {
289 392
     fatType_ = 16;
290 393
   } else {
291
-    rootDirStart_ = bpb->fat32RootCluster;
394
+    rootDirStart_ = fbs->fat32RootCluster;
292 395
     fatType_ = 32;
293 396
   }
294 397
   return true;
398
+
399
+ fail:
400
+  return false;
295 401
 }

+ 211
- 0
Marlin/SdVolume.h View File

@@ -0,0 +1,211 @@
1
+/* Arduino SdFat Library
2
+ * Copyright (C) 2009 by William Greiman
3
+ *
4
+ * This file is part of the Arduino SdFat 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 SdFat Library.  If not, see
18
+ * <http://www.gnu.org/licenses/>.
19
+ */
20
+#ifndef SdVolume_h
21
+#define SdVolume_h
22
+/**
23
+ * \file
24
+ * \brief SdVolume class
25
+ */
26
+#include "SdFatConfig.h"
27
+#include "Sd2Card.h"
28
+#include "SdFatStructs.h"
29
+
30
+//==============================================================================
31
+// SdVolume class
32
+/**
33
+ * \brief Cache for an SD data block
34
+ */
35
+union cache_t {
36
+           /** Used to access cached file data blocks. */
37
+  uint8_t  data[512];
38
+           /** Used to access cached FAT16 entries. */
39
+  uint16_t fat16[256];
40
+           /** Used to access cached FAT32 entries. */
41
+  uint32_t fat32[128];
42
+           /** Used to access cached directory entries. */
43
+  dir_t    dir[16];
44
+           /** Used to access a cached Master Boot Record. */
45
+  mbr_t    mbr;
46
+           /** Used to access to a cached FAT boot sector. */
47
+  fat_boot_t fbs;
48
+           /** Used to access to a cached FAT32 boot sector. */
49
+  fat32_boot_t fbs32;
50
+           /** Used to access to a cached FAT32 FSINFO sector. */
51
+  fat32_fsinfo_t fsinfo;
52
+};
53
+//------------------------------------------------------------------------------
54
+/**
55
+ * \class SdVolume
56
+ * \brief Access FAT16 and FAT32 volumes on SD and SDHC cards.
57
+ */
58
+class SdVolume {
59
+ public:
60
+  /** Create an instance of SdVolume */
61
+  SdVolume() : fatType_(0) {}
62
+  /** Clear the cache and returns a pointer to the cache.  Used by the WaveRP
63
+   * recorder to do raw write to the SD card.  Not for normal apps.
64
+   * \return A pointer to the cache buffer or zero if an error occurs.
65
+   */
66
+  cache_t* cacheClear() {
67
+    if (!cacheFlush()) return 0;
68
+    cacheBlockNumber_ = 0XFFFFFFFF;
69
+    return &cacheBuffer_;
70
+  }
71
+  /** Initialize a FAT volume.  Try partition one first then try super
72
+   * floppy format.
73
+   *
74
+   * \param[in] dev The Sd2Card where the volume is located.
75
+   *
76
+   * \return The value one, true, is returned for success and
77
+   * the value zero, false, is returned for failure.  Reasons for
78
+   * failure include not finding a valid partition, not finding a valid
79
+   * FAT file system or an I/O error.
80
+   */
81
+  bool init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);}
82
+  bool init(Sd2Card* dev, uint8_t part);
83
+
84
+  // inline functions that return volume info
85
+  /** \return The volume's cluster size in blocks. */
86
+  uint8_t blocksPerCluster() const {return blocksPerCluster_;}
87
+  /** \return The number of blocks in one FAT. */
88
+  uint32_t blocksPerFat()  const {return blocksPerFat_;}
89
+  /** \return The total number of clusters in the volume. */
90
+  uint32_t clusterCount() const {return clusterCount_;}
91
+  /** \return The shift count required to multiply by blocksPerCluster. */
92
+  uint8_t clusterSizeShift() const {return clusterSizeShift_;}
93
+  /** \return The logical block number for the start of file data. */
94
+  uint32_t dataStartBlock() const {return dataStartBlock_;}
95
+  /** \return The number of FAT structures on the volume. */
96
+  uint8_t fatCount() const {return fatCount_;}
97
+  /** \return The logical block number for the start of the first FAT. */
98
+  uint32_t fatStartBlock() const {return fatStartBlock_;}
99
+  /** \return The FAT type of the volume. Values are 12, 16 or 32. */
100
+  uint8_t fatType() const {return fatType_;}
101
+  int32_t freeClusterCount();
102
+  /** \return The number of entries in the root directory for FAT16 volumes. */
103
+  uint32_t rootDirEntryCount() const {return rootDirEntryCount_;}
104
+  /** \return The logical block number for the start of the root directory
105
+       on FAT16 volumes or the first cluster number on FAT32 volumes. */
106
+  uint32_t rootDirStart() const {return rootDirStart_;}
107
+  /** Sd2Card object for this volume
108
+   * \return pointer to Sd2Card object.
109
+   */
110
+  Sd2Card* sdCard() {return sdCard_;}
111
+  /** Debug access to FAT table
112
+   *
113
+   * \param[in] n cluster number.
114
+   * \param[out] v value of entry
115
+   * \return true for success or false for failure
116
+   */
117
+  bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);}
118
+//------------------------------------------------------------------------------
119
+ private:
120
+  // Allow SdBaseFile access to SdVolume private data.
121
+  friend class SdBaseFile;
122
+
123
+  // value for dirty argument in cacheRawBlock to indicate read from cache
124
+  static bool const CACHE_FOR_READ = false;
125
+  // value for dirty argument in cacheRawBlock to indicate write to cache
126
+  static bool const CACHE_FOR_WRITE = true;
127
+
128
+#if USE_MULTIPLE_CARDS
129
+  cache_t cacheBuffer_;        // 512 byte cache for device blocks
130
+  uint32_t cacheBlockNumber_;  // Logical number of block in the cache
131
+  Sd2Card* sdCard_;            // Sd2Card object for cache
132
+  bool cacheDirty_;            // cacheFlush() will write block if true
133
+  uint32_t cacheMirrorBlock_;  // block number for mirror FAT
134
+#else  // USE_MULTIPLE_CARDS
135
+  static cache_t cacheBuffer_;        // 512 byte cache for device blocks
136
+  static uint32_t cacheBlockNumber_;  // Logical number of block in the cache
137
+  static Sd2Card* sdCard_;            // Sd2Card object for cache
138
+  static bool cacheDirty_;            // cacheFlush() will write block if true
139
+  static uint32_t cacheMirrorBlock_;  // block number for mirror FAT
140
+#endif  // USE_MULTIPLE_CARDS
141
+  uint32_t allocSearchStart_;   // start cluster for alloc search
142
+  uint8_t blocksPerCluster_;    // cluster size in blocks
143
+  uint32_t blocksPerFat_;       // FAT size in blocks
144
+  uint32_t clusterCount_;       // clusters in one FAT
145
+  uint8_t clusterSizeShift_;    // shift to convert cluster count to block count
146
+  uint32_t dataStartBlock_;     // first data block number
147
+  uint8_t fatCount_;            // number of FATs on volume
148
+  uint32_t fatStartBlock_;      // start block for first FAT
149
+  uint8_t fatType_;             // volume type (12, 16, OR 32)
150
+  uint16_t rootDirEntryCount_;  // number of entries in FAT16 root dir
151
+  uint32_t rootDirStart_;       // root start block for FAT16, cluster for FAT32
152
+  //----------------------------------------------------------------------------
153
+  bool allocContiguous(uint32_t count, uint32_t* curCluster);
154
+  uint8_t blockOfCluster(uint32_t position) const {
155
+          return (position >> 9) & (blocksPerCluster_ - 1);}
156
+  uint32_t clusterStartBlock(uint32_t cluster) const {
157
+           return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);}
158
+  uint32_t blockNumber(uint32_t cluster, uint32_t position) const {
159
+           return clusterStartBlock(cluster) + blockOfCluster(position);}
160
+  cache_t *cache() {return &cacheBuffer_;}
161
+  uint32_t cacheBlockNumber() {return cacheBlockNumber_;}
162
+#if USE_MULTIPLE_CARDS
163
+  bool cacheFlush();
164
+  bool cacheRawBlock(uint32_t blockNumber, bool dirty);
165
+#else  // USE_MULTIPLE_CARDS
166
+  static bool cacheFlush();
167
+  static bool cacheRawBlock(uint32_t blockNumber, bool dirty);
168
+#endif  // USE_MULTIPLE_CARDS
169
+  // used by SdBaseFile write to assign cache to SD location
170
+  void cacheSetBlockNumber(uint32_t blockNumber, bool dirty) {
171
+    cacheDirty_ = dirty;
172
+    cacheBlockNumber_  = blockNumber;
173
+  }
174
+  void cacheSetDirty() {cacheDirty_ |= CACHE_FOR_WRITE;}
175
+  bool chainSize(uint32_t beginCluster, uint32_t* size);
176
+  bool fatGet(uint32_t cluster, uint32_t* value);
177
+  bool fatPut(uint32_t cluster, uint32_t value);
178
+  bool fatPutEOC(uint32_t cluster) {
179
+    return fatPut(cluster, 0x0FFFFFFF);
180
+  }
181
+  bool freeChain(uint32_t cluster);
182
+  bool isEOC(uint32_t cluster) const {
183
+    if (FAT12_SUPPORT && fatType_ == 12) return  cluster >= FAT12EOC_MIN;
184
+    if (fatType_ == 16) return cluster >= FAT16EOC_MIN;
185
+    return  cluster >= FAT32EOC_MIN;
186
+  }
187
+  bool readBlock(uint32_t block, uint8_t* dst) {
188
+    return sdCard_->readBlock(block, dst);}
189
+  bool writeBlock(uint32_t block, const uint8_t* dst) {
190
+    return sdCard_->writeBlock(block, dst);
191
+  }
192
+//------------------------------------------------------------------------------
193
+  // Deprecated functions  - suppress cpplint warnings with NOLINT comment
194
+#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN)
195
+ public:
196
+  /** \deprecated Use: bool SdVolume::init(Sd2Card* dev);
197
+   * \param[in] dev The SD card where the volume is located.
198
+   * \return true for success or false for failure.
199
+   */
200
+  bool init(Sd2Card& dev) {return init(&dev);}  // NOLINT
201
+  /** \deprecated Use: bool SdVolume::init(Sd2Card* dev, uint8_t vol);
202
+   * \param[in] dev The SD card where the volume is located.
203
+   * \param[in] part The partition to be used.
204
+   * \return true for success or false for failure.
205
+   */
206
+  bool init(Sd2Card& dev, uint8_t part) {  // NOLINT
207
+    return init(&dev, part);
208
+  }
209
+#endif  // ALLOW_DEPRECATED_FUNCTIONS
210
+};
211
+#endif  // SdVolume

+ 1
- 0
Marlin/cardreader.h View File

@@ -3,6 +3,7 @@
3 3
 
4 4
 #ifdef SDSUPPORT
5 5
  
6
+
6 7
 #include "SdFat.h"
7 8
 
8 9
 class CardReader

+ 0
- 58
merging still needs.txt View File

@@ -1,58 +0,0 @@
1
-files to compare manually:
2
-planner.cpp
3
-stepper.cpp
4
-temperature.cpp
5
-
6
----
7
-things that changed:
8
-* planner.cpp
9
-estimate_acc_distance now works with floats.
10
-in calculate_trapezoid:for_block
11
- long acceleration_rate=(long)((float)acceleration*8.388608) is gone
12
- so is block_>acceleration_rate
13
-void planner_reverse_pass:
14
- some stuff I don't understand right now changed
15
-in planner_forward_pass:
16
- done: BLOCK_BUFFER_SIZE is now necessarily power of 2 (aka 8 16, 32). Inportant to document this somewhere.
17
-no more inline in void plan_discard_current_block()
18
-no more inline in plan_get_current_block()
19
-in plan_buffer_line(...)
20
- the long target[4]; and calculations of thoose should go after the while(block_buffer_tail==..). if the axis_steps_per_unit are changed from the gcode (M92) the calculation for the currently planned buffer move will be corrupt, because Target is calculated with one value, and the stuff afterwards with another. At least this solved the problem I had with the M92 E* changes in the code. Very sure about this, I took me 20min to find this as the solution for the bug I was hunting.
21
-around if(feed_rate<minimumfeedrate) this only should be done if it is not a pure extrusion. I think there is a bug right now.
22
-~line 447 blockcount= 
23
- not sure if this also works if the difference is negative, as it would happen if the ringbuffer runs over the end and start at 0.
24
-~line 507 tmp_aceleration. not sure whats going on, but a lot changed.
25
-
26
-
27
-* stepper.cpp
28
-~214: if (busy) should be a echoln, maybe
29
-~331: great, The Z_M_PIN checks are in :)
30
-
31
-*temperature.cpp
32
-done: enum for heater, bed,
33
-manage_heater() is seriously different.
34
-  done: if tem_meas_ready ==true->!true+return?
35
-done #define K1 0.95 maybe in the configuration.h?
36
-semi-done: PID-C checking needed. Untested but added.
37
-----
38
-
39
-still needed to finish the merge, before testin!
40
-
41
- manage_heater
42
- ISR
43
- movement planner
44
-
45
-TODO:
46
-
47
-remove traveling at maxpseed
48
-remove Simplelcd
49
-
50
-remove DEBUG_STEPS?
51
-
52
-block_t
53
-pid_dt ->0.1  whats the changes to the PID, checking needed
54
-
55
-
56
-----
57
-second merge saturday morning:
58
-done: PID_dt->0.1

Loading…
Cancel
Save