Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

SdFormatter.ino 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. /*
  2. * This program will format an SD or SDHC card.
  3. * Warning all data will be deleted!
  4. *
  5. * For SD/SDHC cards larger than 64 MB this
  6. * program attempts to match the format
  7. * generated by SDFormatter available here:
  8. *
  9. * http://www.sdcard.org/consumers/formatter/
  10. *
  11. * For smaller cards this program uses FAT16
  12. * and SDFormatter uses FAT12.
  13. */
  14. // Print extra info for debug if DEBUG_PRINT is nonzero
  15. #define DEBUG_PRINT 0
  16. #include <SPI.h>
  17. #include <SdFat.h>
  18. #if DEBUG_PRINT
  19. #include <SdFatUtil.h>
  20. #endif // DEBUG_PRINT
  21. //
  22. // Change the value of chipSelect if your hardware does
  23. // not use the default value, SS. Common values are:
  24. // Arduino Ethernet shield: pin 4
  25. // Sparkfun SD shield: pin 8
  26. // Adafruit SD shields and modules: pin 10
  27. const uint8_t chipSelect = SS;
  28. // Change spiSpeed to SPI_FULL_SPEED for better performance
  29. // Use SPI_QUARTER_SPEED for even slower SPI bus speed
  30. const uint8_t spiSpeed = SPI_HALF_SPEED;
  31. // Serial output stream
  32. ArduinoOutStream cout(Serial);
  33. Sd2Card card;
  34. uint32_t cardSizeBlocks;
  35. uint16_t cardCapacityMB;
  36. // cache for SD block
  37. cache_t cache;
  38. // MBR information
  39. uint8_t partType;
  40. uint32_t relSector;
  41. uint32_t partSize;
  42. // Fake disk geometry
  43. uint8_t numberOfHeads;
  44. uint8_t sectorsPerTrack;
  45. // FAT parameters
  46. uint16_t reservedSectors;
  47. uint8_t sectorsPerCluster;
  48. uint32_t fatStart;
  49. uint32_t fatSize;
  50. uint32_t dataStart;
  51. // constants for file system structure
  52. uint16_t const BU16 = 128;
  53. uint16_t const BU32 = 8192;
  54. // strings needed in file system structures
  55. char noName[] = "NO NAME ";
  56. char fat16str[] = "FAT16 ";
  57. char fat32str[] = "FAT32 ";
  58. //------------------------------------------------------------------------------
  59. #define sdError(msg) sdError_F(F(msg))
  60. void sdError_F(const __FlashStringHelper* str) {
  61. cout << F("error: ");
  62. cout << str << endl;
  63. if (card.errorCode()) {
  64. cout << F("SD error: ") << hex << int(card.errorCode());
  65. cout << ',' << int(card.errorData()) << dec << endl;
  66. }
  67. while (1);
  68. }
  69. //------------------------------------------------------------------------------
  70. #if DEBUG_PRINT
  71. void debugPrint() {
  72. cout << F("FreeRam: ") << FreeRam() << endl;
  73. cout << F("partStart: ") << relSector << endl;
  74. cout << F("partSize: ") << partSize << endl;
  75. cout << F("reserved: ") << reservedSectors << endl;
  76. cout << F("fatStart: ") << fatStart << endl;
  77. cout << F("fatSize: ") << fatSize << endl;
  78. cout << F("dataStart: ") << dataStart << endl;
  79. cout << F("clusterCount: ");
  80. cout << ((relSector + partSize - dataStart)/sectorsPerCluster) << endl;
  81. cout << endl;
  82. cout << F("Heads: ") << int(numberOfHeads) << endl;
  83. cout << F("Sectors: ") << int(sectorsPerTrack) << endl;
  84. cout << F("Cylinders: ");
  85. cout << cardSizeBlocks/(numberOfHeads*sectorsPerTrack) << endl;
  86. }
  87. #endif // DEBUG_PRINT
  88. //------------------------------------------------------------------------------
  89. // write cached block to the card
  90. uint8_t writeCache(uint32_t lbn) {
  91. return card.writeBlock(lbn, cache.data);
  92. }
  93. //------------------------------------------------------------------------------
  94. // initialize appropriate sizes for SD capacity
  95. void initSizes() {
  96. if (cardCapacityMB <= 6) {
  97. sdError("Card is too small.");
  98. } else if (cardCapacityMB <= 16) {
  99. sectorsPerCluster = 2;
  100. } else if (cardCapacityMB <= 32) {
  101. sectorsPerCluster = 4;
  102. } else if (cardCapacityMB <= 64) {
  103. sectorsPerCluster = 8;
  104. } else if (cardCapacityMB <= 128) {
  105. sectorsPerCluster = 16;
  106. } else if (cardCapacityMB <= 1024) {
  107. sectorsPerCluster = 32;
  108. } else if (cardCapacityMB <= 32768) {
  109. sectorsPerCluster = 64;
  110. } else {
  111. // SDXC cards
  112. sectorsPerCluster = 128;
  113. }
  114. cout << F("Blocks/Cluster: ") << int(sectorsPerCluster) << endl;
  115. // set fake disk geometry
  116. sectorsPerTrack = cardCapacityMB <= 256 ? 32 : 63;
  117. if (cardCapacityMB <= 16) {
  118. numberOfHeads = 2;
  119. } else if (cardCapacityMB <= 32) {
  120. numberOfHeads = 4;
  121. } else if (cardCapacityMB <= 128) {
  122. numberOfHeads = 8;
  123. } else if (cardCapacityMB <= 504) {
  124. numberOfHeads = 16;
  125. } else if (cardCapacityMB <= 1008) {
  126. numberOfHeads = 32;
  127. } else if (cardCapacityMB <= 2016) {
  128. numberOfHeads = 64;
  129. } else if (cardCapacityMB <= 4032) {
  130. numberOfHeads = 128;
  131. } else {
  132. numberOfHeads = 255;
  133. }
  134. }
  135. //------------------------------------------------------------------------------
  136. // zero cache and optionally set the sector signature
  137. void clearCache(uint8_t addSig) {
  138. memset(&cache, 0, sizeof(cache));
  139. if (addSig) {
  140. cache.mbr.mbrSig0 = BOOTSIG0;
  141. cache.mbr.mbrSig1 = BOOTSIG1;
  142. }
  143. }
  144. //------------------------------------------------------------------------------
  145. // zero FAT and root dir area on SD
  146. void clearFatDir(uint32_t bgn, uint32_t count) {
  147. clearCache(false);
  148. if (!card.writeStart(bgn, count)) {
  149. sdError("Clear FAT/DIR writeStart failed");
  150. }
  151. for (uint32_t i = 0; i < count; i++) {
  152. if ((i & 0XFF) == 0) {
  153. cout << '.';
  154. }
  155. if (!card.writeData(cache.data)) {
  156. sdError("Clear FAT/DIR writeData failed");
  157. }
  158. }
  159. if (!card.writeStop()) {
  160. sdError("Clear FAT/DIR writeStop failed");
  161. }
  162. cout << endl;
  163. }
  164. //------------------------------------------------------------------------------
  165. // return cylinder number for a logical block number
  166. uint16_t lbnToCylinder(uint32_t lbn) {
  167. return lbn / (numberOfHeads * sectorsPerTrack);
  168. }
  169. //------------------------------------------------------------------------------
  170. // return head number for a logical block number
  171. uint8_t lbnToHead(uint32_t lbn) {
  172. return (lbn % (numberOfHeads * sectorsPerTrack)) / sectorsPerTrack;
  173. }
  174. //------------------------------------------------------------------------------
  175. // return sector number for a logical block number
  176. uint8_t lbnToSector(uint32_t lbn) {
  177. return (lbn % sectorsPerTrack) + 1;
  178. }
  179. //------------------------------------------------------------------------------
  180. // format and write the Master Boot Record
  181. void writeMbr() {
  182. clearCache(true);
  183. part_t* p = cache.mbr.part;
  184. p->boot = 0;
  185. uint16_t c = lbnToCylinder(relSector);
  186. if (c > 1023) {
  187. sdError("MBR CHS");
  188. }
  189. p->beginCylinderHigh = c >> 8;
  190. p->beginCylinderLow = c & 0XFF;
  191. p->beginHead = lbnToHead(relSector);
  192. p->beginSector = lbnToSector(relSector);
  193. p->type = partType;
  194. uint32_t endLbn = relSector + partSize - 1;
  195. c = lbnToCylinder(endLbn);
  196. if (c <= 1023) {
  197. p->endCylinderHigh = c >> 8;
  198. p->endCylinderLow = c & 0XFF;
  199. p->endHead = lbnToHead(endLbn);
  200. p->endSector = lbnToSector(endLbn);
  201. } else {
  202. // Too big flag, c = 1023, h = 254, s = 63
  203. p->endCylinderHigh = 3;
  204. p->endCylinderLow = 255;
  205. p->endHead = 254;
  206. p->endSector = 63;
  207. }
  208. p->firstSector = relSector;
  209. p->totalSectors = partSize;
  210. if (!writeCache(0)) {
  211. sdError("write MBR");
  212. }
  213. }
  214. //------------------------------------------------------------------------------
  215. // generate serial number from card size and micros since boot
  216. uint32_t volSerialNumber() {
  217. return (cardSizeBlocks << 8) + micros();
  218. }
  219. //------------------------------------------------------------------------------
  220. // format the SD as FAT16
  221. void makeFat16() {
  222. uint32_t nc;
  223. for (dataStart = 2 * BU16;; dataStart += BU16) {
  224. nc = (cardSizeBlocks - dataStart)/sectorsPerCluster;
  225. fatSize = (nc + 2 + 255)/256;
  226. uint32_t r = BU16 + 1 + 2 * fatSize + 32;
  227. if (dataStart < r) {
  228. continue;
  229. }
  230. relSector = dataStart - r + BU16;
  231. break;
  232. }
  233. // check valid cluster count for FAT16 volume
  234. if (nc < 4085 || nc >= 65525) {
  235. sdError("Bad cluster count");
  236. }
  237. reservedSectors = 1;
  238. fatStart = relSector + reservedSectors;
  239. partSize = nc * sectorsPerCluster + 2 * fatSize + reservedSectors + 32;
  240. if (partSize < 32680) {
  241. partType = 0X01;
  242. } else if (partSize < 65536) {
  243. partType = 0X04;
  244. } else {
  245. partType = 0X06;
  246. }
  247. // write MBR
  248. writeMbr();
  249. clearCache(true);
  250. fat_boot_t* pb = &cache.fbs;
  251. pb->jump[0] = 0XEB;
  252. pb->jump[1] = 0X00;
  253. pb->jump[2] = 0X90;
  254. for (uint8_t i = 0; i < sizeof(pb->oemId); i++) {
  255. pb->oemId[i] = ' ';
  256. }
  257. pb->bytesPerSector = 512;
  258. pb->sectorsPerCluster = sectorsPerCluster;
  259. pb->reservedSectorCount = reservedSectors;
  260. pb->fatCount = 2;
  261. pb->rootDirEntryCount = 512;
  262. pb->mediaType = 0XF8;
  263. pb->sectorsPerFat16 = fatSize;
  264. pb->sectorsPerTrack = sectorsPerTrack;
  265. pb->headCount = numberOfHeads;
  266. pb->hidddenSectors = relSector;
  267. pb->totalSectors32 = partSize;
  268. pb->driveNumber = 0X80;
  269. pb->bootSignature = EXTENDED_BOOT_SIG;
  270. pb->volumeSerialNumber = volSerialNumber();
  271. memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel));
  272. memcpy(pb->fileSystemType, fat16str, sizeof(pb->fileSystemType));
  273. // write partition boot sector
  274. if (!writeCache(relSector)) {
  275. sdError("FAT16 write PBS failed");
  276. }
  277. // clear FAT and root directory
  278. clearFatDir(fatStart, dataStart - fatStart);
  279. clearCache(false);
  280. cache.fat16[0] = 0XFFF8;
  281. cache.fat16[1] = 0XFFFF;
  282. // write first block of FAT and backup for reserved clusters
  283. if (!writeCache(fatStart)
  284. || !writeCache(fatStart + fatSize)) {
  285. sdError("FAT16 reserve failed");
  286. }
  287. }
  288. //------------------------------------------------------------------------------
  289. // format the SD as FAT32
  290. void makeFat32() {
  291. uint32_t nc;
  292. relSector = BU32;
  293. for (dataStart = 2 * BU32;; dataStart += BU32) {
  294. nc = (cardSizeBlocks - dataStart)/sectorsPerCluster;
  295. fatSize = (nc + 2 + 127)/128;
  296. uint32_t r = relSector + 9 + 2 * fatSize;
  297. if (dataStart >= r) {
  298. break;
  299. }
  300. }
  301. // error if too few clusters in FAT32 volume
  302. if (nc < 65525) {
  303. sdError("Bad cluster count");
  304. }
  305. reservedSectors = dataStart - relSector - 2 * fatSize;
  306. fatStart = relSector + reservedSectors;
  307. partSize = nc * sectorsPerCluster + dataStart - relSector;
  308. // type depends on address of end sector
  309. // max CHS has lbn = 16450560 = 1024*255*63
  310. if ((relSector + partSize) <= 16450560) {
  311. // FAT32
  312. partType = 0X0B;
  313. } else {
  314. // FAT32 with INT 13
  315. partType = 0X0C;
  316. }
  317. writeMbr();
  318. clearCache(true);
  319. fat32_boot_t* pb = &cache.fbs32;
  320. pb->jump[0] = 0XEB;
  321. pb->jump[1] = 0X00;
  322. pb->jump[2] = 0X90;
  323. for (uint8_t i = 0; i < sizeof(pb->oemId); i++) {
  324. pb->oemId[i] = ' ';
  325. }
  326. pb->bytesPerSector = 512;
  327. pb->sectorsPerCluster = sectorsPerCluster;
  328. pb->reservedSectorCount = reservedSectors;
  329. pb->fatCount = 2;
  330. pb->mediaType = 0XF8;
  331. pb->sectorsPerTrack = sectorsPerTrack;
  332. pb->headCount = numberOfHeads;
  333. pb->hidddenSectors = relSector;
  334. pb->totalSectors32 = partSize;
  335. pb->sectorsPerFat32 = fatSize;
  336. pb->fat32RootCluster = 2;
  337. pb->fat32FSInfo = 1;
  338. pb->fat32BackBootBlock = 6;
  339. pb->driveNumber = 0X80;
  340. pb->bootSignature = EXTENDED_BOOT_SIG;
  341. pb->volumeSerialNumber = volSerialNumber();
  342. memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel));
  343. memcpy(pb->fileSystemType, fat32str, sizeof(pb->fileSystemType));
  344. // write partition boot sector and backup
  345. if (!writeCache(relSector)
  346. || !writeCache(relSector + 6)) {
  347. sdError("FAT32 write PBS failed");
  348. }
  349. clearCache(true);
  350. // write extra boot area and backup
  351. if (!writeCache(relSector + 2)
  352. || !writeCache(relSector + 8)) {
  353. sdError("FAT32 PBS ext failed");
  354. }
  355. fat32_fsinfo_t* pf = &cache.fsinfo;
  356. pf->leadSignature = FSINFO_LEAD_SIG;
  357. pf->structSignature = FSINFO_STRUCT_SIG;
  358. pf->freeCount = 0XFFFFFFFF;
  359. pf->nextFree = 0XFFFFFFFF;
  360. // write FSINFO sector and backup
  361. if (!writeCache(relSector + 1)
  362. || !writeCache(relSector + 7)) {
  363. sdError("FAT32 FSINFO failed");
  364. }
  365. clearFatDir(fatStart, 2 * fatSize + sectorsPerCluster);
  366. clearCache(false);
  367. cache.fat32[0] = 0x0FFFFFF8;
  368. cache.fat32[1] = 0x0FFFFFFF;
  369. cache.fat32[2] = 0x0FFFFFFF;
  370. // write first block of FAT and backup for reserved clusters
  371. if (!writeCache(fatStart)
  372. || !writeCache(fatStart + fatSize)) {
  373. sdError("FAT32 reserve failed");
  374. }
  375. }
  376. //------------------------------------------------------------------------------
  377. // flash erase all data
  378. uint32_t const ERASE_SIZE = 262144L;
  379. void eraseCard() {
  380. cout << endl << F("Erasing\n");
  381. uint32_t firstBlock = 0;
  382. uint32_t lastBlock;
  383. uint16_t n = 0;
  384. do {
  385. lastBlock = firstBlock + ERASE_SIZE - 1;
  386. if (lastBlock >= cardSizeBlocks) {
  387. lastBlock = cardSizeBlocks - 1;
  388. }
  389. if (!card.erase(firstBlock, lastBlock)) {
  390. sdError("erase failed");
  391. }
  392. cout << '.';
  393. if ((n++)%32 == 31) {
  394. cout << endl;
  395. }
  396. firstBlock += ERASE_SIZE;
  397. } while (firstBlock < cardSizeBlocks);
  398. cout << endl;
  399. if (!card.readBlock(0, cache.data)) {
  400. sdError("readBlock");
  401. }
  402. cout << hex << showbase << setfill('0') << internal;
  403. cout << F("All data set to ") << setw(4) << int(cache.data[0]) << endl;
  404. cout << dec << noshowbase << setfill(' ') << right;
  405. cout << F("Erase done\n");
  406. }
  407. //------------------------------------------------------------------------------
  408. void formatCard() {
  409. cout << endl;
  410. cout << F("Formatting\n");
  411. initSizes();
  412. if (card.type() != SD_CARD_TYPE_SDHC) {
  413. cout << F("FAT16\n");
  414. makeFat16();
  415. } else {
  416. cout << F("FAT32\n");
  417. makeFat32();
  418. }
  419. #if DEBUG_PRINT
  420. debugPrint();
  421. #endif // DEBUG_PRINT
  422. cout << F("Format done\n");
  423. }
  424. //------------------------------------------------------------------------------
  425. void setup() {
  426. char c;
  427. Serial.begin(9600);
  428. while (!Serial) {} // wait for Leonardo
  429. cout << F(
  430. "\n"
  431. "This program can erase and/or format SD/SDHC cards.\n"
  432. "\n"
  433. "Erase uses the card's fast flash erase command.\n"
  434. "Flash erase sets all data to 0X00 for most cards\n"
  435. "and 0XFF for a few vendor's cards.\n"
  436. "\n"
  437. "Cards larger than 2 GB will be formatted FAT32 and\n"
  438. "smaller cards will be formatted FAT16.\n"
  439. "\n"
  440. "Warning, all data on the card will be erased.\n"
  441. "Enter 'Y' to continue: ");
  442. while (!Serial.available()) {}
  443. delay(400); // catch Due restart problem
  444. c = Serial.read();
  445. cout << c << endl;
  446. if (c != 'Y') {
  447. cout << F("Quiting, you did not enter 'Y'.\n");
  448. return;
  449. }
  450. // read any existing Serial data
  451. while (Serial.read() >= 0) {}
  452. cout << F(
  453. "\n"
  454. "Options are:\n"
  455. "E - erase the card and skip formatting.\n"
  456. "F - erase and then format the card. (recommended)\n"
  457. "Q - quick format the card without erase.\n"
  458. "\n"
  459. "Enter option: ");
  460. while (!Serial.available()) {}
  461. c = Serial.read();
  462. cout << c << endl;
  463. if (!strchr("EFQ", c)) {
  464. cout << F("Quiting, invalid option entered.") << endl;
  465. return;
  466. }
  467. if (!card.begin(chipSelect, spiSpeed)) {
  468. cout << F(
  469. "\nSD initialization failure!\n"
  470. "Is the SD card inserted correctly?\n"
  471. "Is chip select correct at the top of this program?\n");
  472. sdError("card.begin failed");
  473. }
  474. cardSizeBlocks = card.cardSize();
  475. if (cardSizeBlocks == 0) {
  476. sdError("cardSize");
  477. }
  478. cardCapacityMB = (cardSizeBlocks + 2047)/2048;
  479. cout << F("Card Size: ") << cardCapacityMB;
  480. cout << F(" MB, (MB = 1,048,576 bytes)") << endl;
  481. if (c == 'E' || c == 'F') {
  482. eraseCard();
  483. }
  484. if (c == 'F' || c == 'Q') {
  485. formatCard();
  486. }
  487. }
  488. //------------------------------------------------------------------------------
  489. void loop() {}