You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

189 lines
5.5KB

  1. /*
  2. * Example use of three SD cards.
  3. */
  4. #include <SPI.h>
  5. #include <SdFat.h>
  6. #include <SdFatUtil.h>
  7. #if USE_MULTIPLE_SPI_TYPES // Must be nonzero in SdFat/SdFatConfig.h
  8. // SD1 is a microSD on hardware SPI pins 50-52
  9. // Using my fast custom SPI
  10. SdFat sd1;
  11. const uint8_t SD1_CS = 53;
  12. // SD2 is a Catalex shield on hardware SPI pins 50-52
  13. // Using the standard Arduino SPI library
  14. SdFatLibSpi sd2;
  15. const uint8_t SD2_CS = 4;
  16. // SD3 is a Adafruit data logging shield on pins 10-13
  17. // Using Software SPI
  18. SdFatSoftSpi<12, 11, 13> sd3;
  19. const uint8_t SD3_CS = 10;
  20. const uint8_t BUF_DIM = 100;
  21. uint8_t buf[BUF_DIM];
  22. const uint32_t FILE_SIZE = 1000000;
  23. const uint16_t NWRITE = FILE_SIZE/BUF_DIM;
  24. //------------------------------------------------------------------------------
  25. // print error msg, any SD error codes, and halt.
  26. // store messages in flash
  27. #define errorExit(msg) errorHalt(F(msg))
  28. #define initError(msg) initErrorHalt(F(msg))
  29. //------------------------------------------------------------------------------
  30. void list() {
  31. // list current directory on both cards
  32. Serial.println(F("------sd1-------"));
  33. sd1.ls("/", LS_SIZE|LS_R);
  34. Serial.println(F("------sd2-------"));
  35. sd2.ls("/", LS_SIZE|LS_R);
  36. Serial.println(F("------sd3-------"));
  37. sd3.ls("/", LS_SIZE|LS_R);
  38. Serial.println(F("---------------------"));
  39. }
  40. //------------------------------------------------------------------------------
  41. void setup() {
  42. Serial.begin(9600);
  43. while (!Serial) {} // wait for Leonardo
  44. Serial.print(F("FreeRam: "));
  45. Serial.println(FreeRam());
  46. // fill buffer with known data
  47. for (int i = 0; i < sizeof(buf); i++) buf[i] = i;
  48. Serial.println(F("type any character to start"));
  49. while (Serial.read() <= 0) {}
  50. // disable sd2 while initializing sd1
  51. pinMode(SD2_CS, OUTPUT);
  52. digitalWrite(SD2_CS, HIGH);
  53. // initialize the first card
  54. if (!sd1.begin(SD1_CS)) sd1.initError("sd1:");
  55. // initialize the second card
  56. if (!sd2.begin(SD2_CS)) sd2.initError("sd2:");
  57. // initialize the third card
  58. if (!sd3.begin(SD3_CS)) sd3.initError("sd3:");
  59. Serial.println(F("Cards OK - creating directories"));
  60. // create DIR1 on sd1 if it does not exist
  61. if (!sd1.exists("/DIR1")) {
  62. if (!sd1.mkdir("/DIR1")) sd1.errorExit("sd1.mkdir");
  63. }
  64. // make /DIR1 the default directory for sd1
  65. if (!sd1.chdir("/DIR1")) sd1.errorExit("sd1.chdir");
  66. // create DIR2 on sd2 if it does not exist
  67. if (!sd2.exists("/DIR2")) {
  68. if (!sd2.mkdir("/DIR2")) sd2.errorExit("sd2.mkdir");
  69. }
  70. // make /DIR2 the default directory for sd2
  71. if (!sd2.chdir("/DIR2")) sd2.errorExit("sd2.chdir");
  72. // create DIR3 on sd3 if it does not exist
  73. if (!sd3.exists("/DIR3")) {
  74. if (!sd3.mkdir("/DIR3")) sd2.errorExit("sd3.mkdir");
  75. }
  76. // make /DIR3 the default directory for sd3
  77. if (!sd3.chdir("/DIR3")) sd3.errorExit("sd3.chdir");
  78. Serial.println(F("Directories created - removing old files"));
  79. if (sd1.exists("TEST1.BIN")) {
  80. if (!sd1.remove("TEST1.BIN")) sd1.errorExit("sd1.remove");
  81. }
  82. if (sd2.exists("TEST2.BIN")) {
  83. if (!sd2.remove("TEST2.BIN")) sd2.errorExit("sd2.remove");
  84. }
  85. if (sd3.exists("TEST3.BIN")) {
  86. if (!sd3.remove("TEST3.BIN")) sd2.errorExit("sd3.remove");
  87. }
  88. Serial.println("Initial SD directories");
  89. list();
  90. // create or open /DIR1/TEST1.BIN and truncate it to zero length
  91. SdFile file1;
  92. if (!file1.open(&sd1, "TEST1.BIN", O_RDWR | O_CREAT | O_TRUNC)) {
  93. sd1.errorExit("file1");
  94. }
  95. Serial.println(F("Writing SD1:/DIR1/TEST1.BIN"));
  96. // write data to /DIR1/TEST.BIN on sd1
  97. for (int i = 0; i < NWRITE; i++) {
  98. if (file1.write(buf, sizeof(buf)) != sizeof(buf)) {
  99. sd1.errorExit("sd1.write");
  100. }
  101. }
  102. file1.sync();
  103. list();
  104. // create or open /DIR2/TEST2.BIN and truncate it to zero length
  105. SdFile file2;
  106. if (!file2.open(&sd2, "TEST2.BIN", O_RDWR | O_CREAT | O_TRUNC)) {
  107. sd2.errorExit("file2");
  108. }
  109. Serial.println(F("Copying SD1:/DIR1/TEST1.BIN to SD2::/DIR2/TEST2.BIN"));
  110. // copy file1 to file2
  111. file1.rewind();
  112. uint32_t t = millis();
  113. while (1) {
  114. int n = file1.read(buf, sizeof(buf));
  115. if (n < 0) sd1.errorExit("read1");
  116. if (n == 0) break;
  117. if (file2.write(buf, n) != n) sd2.errorExit("write3");
  118. }
  119. t = millis() - t;
  120. file2.sync();
  121. Serial.print(F("File size: "));
  122. Serial.println(file2.fileSize());
  123. Serial.print(F("Copy time: "));
  124. Serial.print(t);
  125. Serial.println(F(" millis"));
  126. list();
  127. // create or open /DIR3/TEST3.BIN and truncate it to zero length
  128. SdFile file3;
  129. if (!file3.open(&sd3, "TEST3.BIN", O_RDWR | O_CREAT | O_TRUNC)) {
  130. sd3.errorExit("file3");
  131. }
  132. file2.rewind();
  133. Serial.println(F("Copying SD2:/DIR2/TEST2.BIN to SD3:/DIR3/TEST3.BIN"));
  134. while (1) {
  135. int n = file2.read(buf, sizeof(buf));
  136. if (n == 0) break;
  137. if (n != sizeof(buf)) sd2.errorExit("read2");
  138. if (file3.write(buf, n) != n) sd3.errorExit("write2");
  139. }
  140. file3.sync();
  141. list();
  142. // Verify content of file3
  143. file3.rewind();
  144. Serial.println(F("Verifying content of TEST3.BIN"));
  145. for (int i = 0; i < NWRITE; i++) {
  146. if (file3.read(buf, sizeof(buf)) != sizeof(buf)) {
  147. sd3.errorExit("sd3.read");
  148. }
  149. for (int j = 0; j < sizeof(buf); j++) {
  150. if (j != buf[j]) sd3.errorExit("Verify error");
  151. }
  152. }
  153. Serial.println(F("Done - Verify OK"));
  154. file1.close();
  155. file2.close();
  156. file3.close();
  157. }
  158. //------------------------------------------------------------------------------
  159. void loop() {}
  160. #else // USE_MULTIPLE_SPI_TYPES
  161. #error USE_MULTIPLE_SPI_TYPES must be set nonzero in SdFat/SdFatConfig.h
  162. #endif //USE_MULTIPLE_SPI_TYPES