Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * This sketch attempts to initialize an SD card and analyze its structure.
  3. */
  4. #include <SPI.h>
  5. #include <SdFat.h>
  6. /*
  7. * SD chip select pin. Common values are:
  8. *
  9. * Arduino Ethernet shield, pin 4.
  10. * SparkFun SD shield, pin 8.
  11. * Adafruit SD shields and modules, pin 10.
  12. * Default SD chip select is the SPI SS pin.
  13. */
  14. const uint8_t SD_CHIP_SELECT = SS;
  15. /*
  16. * Set DISABLE_CHIP_SELECT to disable a second SPI device.
  17. * For example, with the Ethernet shield, set DISABLE_CHIP_SELECT
  18. * to 10 to disable the Ethernet controller.
  19. */
  20. const int8_t DISABLE_CHIP_SELECT = -1;
  21. SdFat sd;
  22. // serial output steam
  23. ArduinoOutStream cout(Serial);
  24. // global for card size
  25. uint32_t cardSize;
  26. // global for card erase size
  27. uint32_t eraseSize;
  28. //------------------------------------------------------------------------------
  29. // store error strings in flash
  30. #define sdErrorMsg(msg) sdErrorMsg_P(PSTR(msg));
  31. void sdErrorMsg_P(const char* str) {
  32. cout << pgm(str) << endl;
  33. if (sd.card()->errorCode()) {
  34. cout << pstr("SD errorCode: ");
  35. cout << hex << int(sd.card()->errorCode()) << endl;
  36. cout << pstr("SD errorData: ");
  37. cout << int(sd.card()->errorData()) << dec << endl;
  38. }
  39. }
  40. //------------------------------------------------------------------------------
  41. uint8_t cidDmp() {
  42. cid_t cid;
  43. if (!sd.card()->readCID(&cid)) {
  44. sdErrorMsg("readCID failed");
  45. return false;
  46. }
  47. cout << pstr("\nManufacturer ID: ");
  48. cout << hex << int(cid.mid) << dec << endl;
  49. cout << pstr("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl;
  50. cout << pstr("Product: ");
  51. for (uint8_t i = 0; i < 5; i++) {
  52. cout << cid.pnm[i];
  53. }
  54. cout << pstr("\nVersion: ");
  55. cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl;
  56. cout << pstr("Serial number: ") << hex << cid.psn << dec << endl;
  57. cout << pstr("Manufacturing date: ");
  58. cout << int(cid.mdt_month) << '/';
  59. cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl;
  60. cout << endl;
  61. return true;
  62. }
  63. //------------------------------------------------------------------------------
  64. uint8_t csdDmp() {
  65. csd_t csd;
  66. uint8_t eraseSingleBlock;
  67. if (!sd.card()->readCSD(&csd)) {
  68. sdErrorMsg("readCSD failed");
  69. return false;
  70. }
  71. if (csd.v1.csd_ver == 0) {
  72. eraseSingleBlock = csd.v1.erase_blk_en;
  73. eraseSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low;
  74. } else if (csd.v2.csd_ver == 1) {
  75. eraseSingleBlock = csd.v2.erase_blk_en;
  76. eraseSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low;
  77. } else {
  78. cout << pstr("csd version error\n");
  79. return false;
  80. }
  81. eraseSize++;
  82. cout << pstr("cardSize: ") << 0.000512*cardSize;
  83. cout << pstr(" MB (MB = 1,000,000 bytes)\n");
  84. cout << pstr("flashEraseSize: ") << int(eraseSize) << pstr(" blocks\n");
  85. cout << pstr("eraseSingleBlock: ");
  86. if (eraseSingleBlock) {
  87. cout << pstr("true\n");
  88. } else {
  89. cout << pstr("false\n");
  90. }
  91. return true;
  92. }
  93. //------------------------------------------------------------------------------
  94. // print partition table
  95. uint8_t partDmp() {
  96. cache_t *p = sd.vol()->cacheClear();
  97. if (!p) {
  98. sdErrorMsg("cacheClear failed");
  99. return false;
  100. }
  101. if (!sd.card()->readBlock(0, p->data)) {
  102. sdErrorMsg("read MBR failed");
  103. return false;
  104. }
  105. for (uint8_t ip = 1; ip < 5; ip++) {
  106. part_t *pt = &p->mbr.part[ip - 1];
  107. if ((pt->boot & 0X7F) != 0 || pt->firstSector > cardSize) {
  108. cout << pstr("\nNo MBR. Assuming Super Floppy format.\n");
  109. return true;
  110. }
  111. }
  112. cout << pstr("\nSD Partition Table\n");
  113. cout << pstr("part,boot,type,start,length\n");
  114. for (uint8_t ip = 1; ip < 5; ip++) {
  115. part_t *pt = &p->mbr.part[ip - 1];
  116. cout << int(ip) << ',' << hex << int(pt->boot) << ',' << int(pt->type);
  117. cout << dec << ',' << pt->firstSector <<',' << pt->totalSectors << endl;
  118. }
  119. return true;
  120. }
  121. //------------------------------------------------------------------------------
  122. void volDmp() {
  123. cout << pstr("\nVolume is FAT") << int(sd.vol()->fatType()) << endl;
  124. cout << pstr("blocksPerCluster: ") << int(sd.vol()->blocksPerCluster()) << endl;
  125. cout << pstr("clusterCount: ") << sd.vol()->clusterCount() << endl;
  126. cout << pstr("freeClusters: ");
  127. uint32_t volFree = sd.vol()->freeClusterCount();
  128. cout << volFree << endl;
  129. float fs = 0.000512*volFree*sd.vol()->blocksPerCluster();
  130. cout << pstr("freeSpace: ") << fs << pstr(" MB (MB = 1,000,000 bytes)\n");
  131. cout << pstr("fatStartBlock: ") << sd.vol()->fatStartBlock() << endl;
  132. cout << pstr("fatCount: ") << int(sd.vol()->fatCount()) << endl;
  133. cout << pstr("blocksPerFat: ") << sd.vol()->blocksPerFat() << endl;
  134. cout << pstr("rootDirStart: ") << sd.vol()->rootDirStart() << endl;
  135. cout << pstr("dataStartBlock: ") << sd.vol()->dataStartBlock() << endl;
  136. if (sd.vol()->dataStartBlock() % eraseSize) {
  137. cout << pstr("Data area is not aligned on flash erase boundaries!\n");
  138. cout << pstr("Download and use formatter from www.sdsd.card()->org/consumer!\n");
  139. }
  140. }
  141. //------------------------------------------------------------------------------
  142. void setup() {
  143. Serial.begin(9600);
  144. while(!Serial) {} // wait for Leonardo
  145. // use uppercase in hex and use 0X base prefix
  146. cout << uppercase << showbase << endl;
  147. // pstr stores strings in flash to save RAM
  148. cout << pstr("SdFat version: ") << SD_FAT_VERSION << endl;
  149. if (DISABLE_CHIP_SELECT < 0) {
  150. cout << pstr(
  151. "\nAssuming the SD is the only SPI device.\n"
  152. "Edit DISABLE_CHIP_SELECT to disable another device.\n");
  153. } else {
  154. cout << pstr("\nDisabling SPI device on pin ");
  155. cout << int(DISABLE_CHIP_SELECT) << endl;
  156. pinMode(DISABLE_CHIP_SELECT, OUTPUT);
  157. digitalWrite(DISABLE_CHIP_SELECT, HIGH);
  158. }
  159. cout << pstr("\nAssuming the SD chip select pin is: ") <<int(SD_CHIP_SELECT);
  160. cout << pstr("\nEdit SD_CHIP_SELECT to change the SD chip select pin.\n");
  161. }
  162. //------------------------------------------------------------------------------
  163. void loop() {
  164. // read any existing Serial data
  165. while (Serial.read() >= 0) {}
  166. // pstr stores strings in flash to save RAM
  167. cout << pstr("\ntype any character to start\n");
  168. while (Serial.read() <= 0) {}
  169. delay(400); // catch Due reset problem
  170. uint32_t t = millis();
  171. // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  172. // breadboards. use SPI_FULL_SPEED for better performance.
  173. if (!sd.cardBegin(SD_CHIP_SELECT, SPI_HALF_SPEED)) {
  174. sdErrorMsg("\ncardBegin failed");
  175. return;
  176. }
  177. t = millis() - t;
  178. cardSize = sd.card()->cardSize();
  179. if (cardSize == 0) {
  180. sdErrorMsg("cardSize failed");
  181. return;
  182. }
  183. cout << pstr("\ninit time: ") << t << " ms" << endl;
  184. cout << pstr("\nCard type: ");
  185. switch (sd.card()->type()) {
  186. case SD_CARD_TYPE_SD1:
  187. cout << pstr("SD1\n");
  188. break;
  189. case SD_CARD_TYPE_SD2:
  190. cout << pstr("SD2\n");
  191. break;
  192. case SD_CARD_TYPE_SDHC:
  193. if (cardSize < 70000000) {
  194. cout << pstr("SDHC\n");
  195. } else {
  196. cout << pstr("SDXC\n");
  197. }
  198. break;
  199. default:
  200. cout << pstr("Unknown\n");
  201. }
  202. if (!cidDmp()) return;
  203. if (!csdDmp()) return;
  204. uint32_t ocr;
  205. if (!sd.card()->readOCR(&ocr)) {
  206. sdErrorMsg("\nreadOCR failed");
  207. return;
  208. }
  209. cout << pstr("OCR: ") << hex << ocr << dec << endl;
  210. if (!partDmp()) return;
  211. if (!sd.fsBegin()) {
  212. sdErrorMsg("\nFile System initialization failed.\n");
  213. return;
  214. }
  215. volDmp();
  216. }