QuickStart.ino 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // Quick hardware test for SPI card access.
  2. //
  3. #include <SPI.h>
  4. #include "SdFat.h"
  5. #include "sdios.h"
  6. // SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
  7. // 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
  8. #define SD_FAT_TYPE 3
  9. //
  10. // Set DISABLE_CHIP_SELECT to disable a second SPI device.
  11. // For example, with the Ethernet shield, set DISABLE_CHIP_SELECT
  12. // to 10 to disable the Ethernet controller.
  13. const int8_t DISABLE_CHIP_SELECT = -1;
  14. //
  15. // Test with reduced SPI speed for breadboards. SD_SCK_MHZ(4) will select
  16. // the highest speed supported by the board that is not over 4 MHz.
  17. // Change SPI_SPEED to SD_SCK_MHZ(50) for best performance.
  18. #define SPI_SPEED SD_SCK_MHZ(4)
  19. //------------------------------------------------------------------------------
  20. #if SD_FAT_TYPE == 0
  21. SdFat sd;
  22. File file;
  23. #elif SD_FAT_TYPE == 1
  24. SdFat32 sd;
  25. File32 file;
  26. #elif SD_FAT_TYPE == 2
  27. SdExFat sd;
  28. ExFile file;
  29. #elif SD_FAT_TYPE == 3
  30. SdFs sd;
  31. FsFile file;
  32. #else // SD_FAT_TYPE
  33. #error Invalid SD_FAT_TYPE
  34. #endif // SD_FAT_TYPE
  35. // Serial streams
  36. ArduinoOutStream cout(Serial);
  37. // input buffer for line
  38. char cinBuf[40];
  39. ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf));
  40. // SD card chip select
  41. int chipSelect;
  42. void cardOrSpeed() {
  43. cout << F("Try another SD card or reduce the SPI bus speed.\n");
  44. cout << F("Edit SPI_SPEED in this program to change it.\n");
  45. }
  46. void clearSerialInput() {
  47. uint32_t m = micros();
  48. do {
  49. if (Serial.read() >= 0) {
  50. m = micros();
  51. }
  52. } while (micros() - m < 10000);
  53. }
  54. void reformatMsg() {
  55. cout << F("Try reformatting the card. For best results use\n");
  56. cout << F("the SdFormatter program in SdFat/examples or download\n");
  57. cout << F("and use SDFormatter from www.sdcard.org/downloads.\n");
  58. }
  59. void setup() {
  60. Serial.begin(9600);
  61. // Wait for USB Serial
  62. while (!Serial) {
  63. yield();
  64. }
  65. cout << F("\nSPI pins:\n");
  66. cout << F("MISO: ") << int(MISO) << endl;
  67. cout << F("MOSI: ") << int(MOSI) << endl;
  68. cout << F("SCK: ") << int(SCK) << endl;
  69. cout << F("SS: ") << int(SS) << endl;
  70. #ifdef SDCARD_SS_PIN
  71. cout << F("SDCARD_SS_PIN: ") << int(SDCARD_SS_PIN) << endl;
  72. #endif // SDCARD_SS_PIN
  73. if (DISABLE_CHIP_SELECT < 0) {
  74. cout << F(
  75. "\nBe sure to edit DISABLE_CHIP_SELECT if you have\n"
  76. "a second SPI device. For example, with the Ethernet\n"
  77. "shield, DISABLE_CHIP_SELECT should be set to 10\n"
  78. "to disable the Ethernet controller.\n");
  79. }
  80. cout << F(
  81. "\nSD chip select is the key hardware option.\n"
  82. "Common values are:\n"
  83. "Arduino Ethernet shield, pin 4\n"
  84. "Sparkfun SD shield, pin 8\n"
  85. "Adafruit SD shields and modules, pin 10\n");
  86. }
  87. bool firstTry = true;
  88. void loop() {
  89. // Read any existing Serial data.
  90. clearSerialInput();
  91. if (!firstTry) {
  92. cout << F("\nRestarting\n");
  93. }
  94. firstTry = false;
  95. cout << F("\nEnter the chip select pin number: ");
  96. while (!Serial.available()) {
  97. yield();
  98. }
  99. cin.readline();
  100. if (cin >> chipSelect) {
  101. cout << chipSelect << endl;
  102. } else {
  103. cout << F("\nInvalid pin number\n");
  104. return;
  105. }
  106. if (DISABLE_CHIP_SELECT < 0) {
  107. cout << F(
  108. "\nAssuming the SD is the only SPI device.\n"
  109. "Edit DISABLE_CHIP_SELECT to disable another device.\n");
  110. } else {
  111. cout << F("\nDisabling SPI device on pin ");
  112. cout << int(DISABLE_CHIP_SELECT) << endl;
  113. pinMode(DISABLE_CHIP_SELECT, OUTPUT);
  114. digitalWrite(DISABLE_CHIP_SELECT, HIGH);
  115. }
  116. if (!sd.begin(chipSelect, SPI_SPEED)) {
  117. if (sd.card()->errorCode()) {
  118. cout << F(
  119. "\nSD initialization failed.\n"
  120. "Do not reformat the card!\n"
  121. "Is the card correctly inserted?\n"
  122. "Is chipSelect set to the correct value?\n"
  123. "Does another SPI device need to be disabled?\n"
  124. "Is there a wiring/soldering problem?\n");
  125. cout << F("\nerrorCode: ") << hex << showbase;
  126. cout << int(sd.card()->errorCode());
  127. cout << F(", errorData: ") << int(sd.card()->errorData());
  128. cout << dec << noshowbase << endl;
  129. return;
  130. }
  131. cout << F("\nCard successfully initialized.\n");
  132. if (sd.vol()->fatType() == 0) {
  133. cout << F("Can't find a valid FAT16/FAT32 partition.\n");
  134. reformatMsg();
  135. return;
  136. }
  137. cout << F("Can't determine error type\n");
  138. return;
  139. }
  140. cout << F("\nCard successfully initialized.\n");
  141. cout << endl;
  142. uint32_t size = sd.card()->sectorCount();
  143. if (size == 0) {
  144. cout << F("Can't determine the card size.\n");
  145. cardOrSpeed();
  146. return;
  147. }
  148. uint32_t sizeMB = 0.000512 * size + 0.5;
  149. cout << F("Card size: ") << sizeMB;
  150. cout << F(" MB (MB = 1,000,000 bytes)\n");
  151. cout << endl;
  152. cout << F("Volume is FAT") << int(sd.vol()->fatType());
  153. cout << F(", Cluster size (bytes): ") << sd.vol()->bytesPerCluster();
  154. cout << endl << endl;
  155. cout << F("Files found (date time size name):\n");
  156. sd.ls(LS_R | LS_DATE | LS_SIZE);
  157. if ((sizeMB > 1100 && sd.vol()->sectorsPerCluster() < 64) ||
  158. (sizeMB < 2200 && sd.vol()->fatType() == 32)) {
  159. cout << F("\nThis card should be reformatted for best performance.\n");
  160. cout << F("Use a cluster size of 32 KB for cards larger than 1 GB.\n");
  161. cout << F("Only cards larger than 2 GB should be formatted FAT32.\n");
  162. reformatMsg();
  163. return;
  164. }
  165. // Read any extra Serial data.
  166. clearSerialInput();
  167. cout << F("\nSuccess! Type any character to restart.\n");
  168. while (!Serial.available()) {
  169. yield();
  170. }
  171. }