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

525 lines
15KB

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