/* * This sketch is a test of subdirectory and file creation. * It also tests allocation of clusters to directories. * * It will create two subdirectories and create enough files * to force the allocation of a cluster to each directory. * * More than 3000 files may be created on a FAT32 volume. * * Note: Some cards may 'stutter' others just get slow due * to the number of flash erases this program causes. */ #include #include Sd2Card card; SdVolume volume; SdFile root; // store error strings in flash to save RAM #define error(s) error_P(PSTR(s)) void error_P(const char* str) { PgmPrint("error: "); SerialPrintln_P(str); if (card.errorCode()) { PgmPrint("SD error: "); Serial.print(card.errorCode(), HEX); Serial.print(','); Serial.println(card.errorData(), HEX); } while(1); } /* * create enough files to force a cluster to be allocated to dir. */ void dirAllocTest(SdFile &dir) { char buf[13], name[13]; SdFile file; uint16_t n; uint32_t size = dir.fileSize(); // create files and write name to file for (n = 0; ; n++){ // make file name sprintf(name, "%u.TXT", n); // open start time uint32_t t0 = millis(); if (!file.open(&dir, name, O_WRITE | O_CREAT | O_EXCL)) { error("open for write failed"); } // open end time and write start time uint32_t t1 = millis(); // write file name to file file.print(name); if (!file.close()) error("close write"); // write end time uint32_t t2 = millis(); PgmPrint("WR "); Serial.print(n); Serial.print(' '); // print time to create file Serial.print(t1 - t0); Serial.print(' '); // print time to write file Serial.println(t2 - t1); // directory size will change when a cluster is added if (dir.fileSize() != size) break; } // read files and check content for (uint16_t i = 0; i <= n; i++) { sprintf(name, "%u.TXT", i); // open start time uint32_t t0 = millis(); if (!file.open(&dir, name, O_READ)) { error("open for read failed"); } // open end time and read start time uint32_t t1 = millis(); int16_t nr = file.read(buf, 13); if (nr < 5) error("file.read failed"); // read end time uint32_t t2 = millis(); // check file content if (strlen(name) != nr || strncmp(name, buf, nr)) { error("content compare failed"); } if (!file.close()) error("close read failed"); PgmPrint("RD "); Serial.print(i); Serial.print(' '); // print open time Serial.print(t1 - t0); Serial.print(' '); // print read time Serial.println(t2 - t1); } } void setup() { Serial.begin(9600); PgmPrintln("Type any character to start"); while (!Serial.available()); // initialize the SD card at SPI_FULL_SPEED for best performance. // try SPI_HALF_SPEED if bus errors occur. if (!card.init(SPI_FULL_SPEED)) error("card.init failed"); // initialize a FAT volume if (!volume.init(&card)) error("volume.init failed"); // open the root directory if (!root.openRoot(&volume)) error("openRoot failed"); // write files to root if FAT32 if (volume.fatType() == 32) { PgmPrintln("Writing files to root"); dirAllocTest(root); } // create sub1 and write files SdFile sub1; if (!sub1.makeDir(&root, "SUB1")) error("makdeDir SUB1 failed"); PgmPrintln("Writing files to SUB1"); dirAllocTest(sub1); // create sub2 and write files SdFile sub2; if (!sub2.makeDir(&sub1, "SUB2")) error("makeDir SUB2 failed"); PgmPrintln("Writing files to SUB2"); dirAllocTest(sub2); PgmPrintln("Done"); } void loop() { }