Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

258 lines
7.9KB

  1. /*
  2. * This program attempts to initialize an SD card and analyze its structure.
  3. */
  4. #include "SdFat.h"
  5. #include "sdios.h"
  6. /*
  7. Set DISABLE_CS_PIN to disable a second SPI device.
  8. For example, with the Ethernet shield, set DISABLE_CS_PIN
  9. to 10 to disable the Ethernet controller.
  10. */
  11. const int8_t DISABLE_CS_PIN = -1;
  12. /*
  13. Change the value of SD_CS_PIN if you are using SPI
  14. and your hardware does not use the default value, SS.
  15. Common values are:
  16. Arduino Ethernet shield: pin 4
  17. Sparkfun SD shield: pin 8
  18. Adafruit SD shields and modules: pin 10
  19. */
  20. // SDCARD_SS_PIN is defined for the built-in SD on some boards.
  21. #ifndef SDCARD_SS_PIN
  22. const uint8_t SD_CS_PIN = SS;
  23. #else // SDCARD_SS_PIN
  24. const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
  25. #endif // SDCARD_SS_PIN
  26. // Try to select the best SD card configuration.
  27. #if HAS_SDIO_CLASS
  28. #define SD_CONFIG SdioConfig(FIFO_SDIO)
  29. #elif ENABLE_DEDICATED_SPI
  30. #define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(16))
  31. #else // HAS_SDIO_CLASS
  32. #define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SD_SCK_MHZ(16))
  33. #endif // HAS_SDIO_CLASS
  34. //------------------------------------------------------------------------------
  35. SdFs sd;
  36. cid_t m_cid;
  37. csd_t m_csd;
  38. uint32_t m_eraseSize;
  39. uint32_t m_ocr;
  40. static ArduinoOutStream cout(Serial);
  41. //------------------------------------------------------------------------------
  42. bool cidDmp() {
  43. cout << F("\nManufacturer ID: ");
  44. cout << uppercase << showbase << hex << int(m_cid.mid) << dec << endl;
  45. cout << F("OEM ID: ") << m_cid.oid[0] << m_cid.oid[1] << endl;
  46. cout << F("Product: ");
  47. for (uint8_t i = 0; i < 5; i++) {
  48. cout << m_cid.pnm[i];
  49. }
  50. cout << F("\nVersion: ");
  51. cout << int(m_cid.prv_n) << '.' << int(m_cid.prv_m) << endl;
  52. cout << F("Serial number: ") << hex << m_cid.psn << dec << endl;
  53. cout << F("Manufacturing date: ");
  54. cout << int(m_cid.mdt_month) << '/';
  55. cout << (2000 + m_cid.mdt_year_low + 10 * m_cid.mdt_year_high) << endl;
  56. cout << endl;
  57. return true;
  58. }
  59. //------------------------------------------------------------------------------
  60. bool csdDmp() {
  61. bool eraseSingleBlock;
  62. if (m_csd.v1.csd_ver == 0) {
  63. eraseSingleBlock = m_csd.v1.erase_blk_en;
  64. m_eraseSize = (m_csd.v1.sector_size_high << 1) | m_csd.v1.sector_size_low;
  65. } else if (m_csd.v2.csd_ver == 1) {
  66. eraseSingleBlock = m_csd.v2.erase_blk_en;
  67. m_eraseSize = (m_csd.v2.sector_size_high << 1) | m_csd.v2.sector_size_low;
  68. } else {
  69. cout << F("m_csd version error\n");
  70. return false;
  71. }
  72. m_eraseSize++;
  73. cout << F("cardSize: ") << 0.000512 * sdCardCapacity(&m_csd);
  74. cout << F(" MB (MB = 1,000,000 bytes)\n");
  75. cout << F("flashEraseSize: ") << int(m_eraseSize) << F(" blocks\n");
  76. cout << F("eraseSingleBlock: ");
  77. if (eraseSingleBlock) {
  78. cout << F("true\n");
  79. } else {
  80. cout << F("false\n");
  81. }
  82. return true;
  83. }
  84. //------------------------------------------------------------------------------
  85. void errorPrint() {
  86. if (sd.sdErrorCode()) {
  87. cout << F("SD errorCode: ") << hex << showbase;
  88. printSdErrorSymbol(&Serial, sd.sdErrorCode());
  89. cout << F(" = ") << int(sd.sdErrorCode()) << endl;
  90. cout << F("SD errorData = ") << int(sd.sdErrorData()) << endl;
  91. }
  92. }
  93. //------------------------------------------------------------------------------
  94. bool mbrDmp() {
  95. MbrSector_t mbr;
  96. bool valid = true;
  97. if (!sd.card()->readSector(0, (uint8_t*)&mbr)) {
  98. cout << F("\nread MBR failed.\n");
  99. errorPrint();
  100. return false;
  101. }
  102. cout << F("\nSD Partition Table\n");
  103. cout << F("part,boot,bgnCHS[3],type,endCHS[3],start,length\n");
  104. for (uint8_t ip = 1; ip < 5; ip++) {
  105. MbrPart_t *pt = &mbr.part[ip - 1];
  106. if ((pt->boot != 0 && pt->boot != 0X80) ||
  107. getLe32(pt->relativeSectors) > sdCardCapacity(&m_csd)) {
  108. valid = false;
  109. }
  110. cout << int(ip) << ',' << uppercase << showbase << hex;
  111. cout << int(pt->boot) << ',';
  112. for (int i = 0; i < 3; i++ ) {
  113. cout << int(pt->beginCHS[i]) << ',';
  114. }
  115. cout << int(pt->type) << ',';
  116. for (int i = 0; i < 3; i++ ) {
  117. cout << int(pt->endCHS[i]) << ',';
  118. }
  119. cout << dec << getLe32(pt->relativeSectors) << ',';
  120. cout << getLe32(pt->totalSectors) << endl;
  121. }
  122. if (!valid) {
  123. cout << F("\nMBR not valid, assuming Super Floppy format.\n");
  124. }
  125. return true;
  126. }
  127. //------------------------------------------------------------------------------
  128. void dmpVol() {
  129. cout << F("\nScanning FAT, please wait.\n");
  130. uint32_t freeClusterCount = sd.freeClusterCount();
  131. if (sd.fatType() <= 32) {
  132. cout << F("\nVolume is FAT") << int(sd.fatType()) << endl;
  133. } else {
  134. cout << F("\nVolume is exFAT\n");
  135. }
  136. cout << F("sectorsPerCluster: ") << sd.sectorsPerCluster() << endl;
  137. cout << F("clusterCount: ") << sd.clusterCount() << endl;
  138. cout << F("freeClusterCount: ") << freeClusterCount << endl;
  139. cout << F("fatStartSector: ") << sd.fatStartSector() << endl;
  140. cout << F("dataStartSector: ") << sd.dataStartSector() << endl;
  141. if (sd.dataStartSector() % m_eraseSize) {
  142. cout << F("Data area is not aligned on flash erase boundary!\n");
  143. cout << F("Download and use formatter from www.sdcard.org!\n");
  144. }
  145. }
  146. //------------------------------------------------------------------------------
  147. void printCardType() {
  148. cout << F("\nCard type: ");
  149. switch (sd.card()->type()) {
  150. case SD_CARD_TYPE_SD1:
  151. cout << F("SD1\n");
  152. break;
  153. case SD_CARD_TYPE_SD2:
  154. cout << F("SD2\n");
  155. break;
  156. case SD_CARD_TYPE_SDHC:
  157. if (sdCardCapacity(&m_csd) < 70000000) {
  158. cout << F("SDHC\n");
  159. } else {
  160. cout << F("SDXC\n");
  161. }
  162. break;
  163. default:
  164. cout << F("Unknown\n");
  165. }
  166. }
  167. //------------------------------------------------------------------------------
  168. void printConfig(SdSpiConfig config) {
  169. if (DISABLE_CS_PIN < 0) {
  170. cout << F(
  171. "\nAssuming the SD is the only SPI device.\n"
  172. "Edit DISABLE_CS_PIN to disable an SPI device.\n");
  173. } else {
  174. cout << F("\nDisabling SPI device on pin ");
  175. cout << int(DISABLE_CS_PIN) << endl;
  176. pinMode(DISABLE_CS_PIN, OUTPUT);
  177. digitalWrite(DISABLE_CS_PIN, HIGH);
  178. }
  179. cout << F("\nAssuming the SD chip select pin is: ") << int(config.csPin);
  180. cout << F("\nEdit SD_CS_PIN to change the SD chip select pin.\n");
  181. }
  182. //------------------------------------------------------------------------------
  183. void printConfig(SdioConfig config) {
  184. (void)config;
  185. cout << F("Assuming an SDIO interface.\n");
  186. }
  187. //-----------------------------------------------------------------------------
  188. void setup() {
  189. Serial.begin(9600);
  190. // Wait for USB Serial
  191. while (!Serial) {
  192. SysCall::yield();
  193. }
  194. cout << F("SdFat version: ") << SD_FAT_VERSION << endl;
  195. printConfig(SD_CONFIG);
  196. }
  197. //------------------------------------------------------------------------------
  198. void loop() {
  199. // Read any existing Serial data.
  200. do {
  201. delay(10);
  202. } while (Serial.available() && Serial.read() >= 0);
  203. // F stores strings in flash to save RAM
  204. cout << F("\ntype any character to start\n");
  205. while (!Serial.available()) {
  206. SysCall::yield();
  207. }
  208. uint32_t t = millis();
  209. if (!sd.cardBegin(SD_CONFIG)) {
  210. cout << F(
  211. "\nSD initialization failed.\n"
  212. "Do not reformat the card!\n"
  213. "Is the card correctly inserted?\n"
  214. "Is there a wiring/soldering problem?\n");
  215. if (isSpi(SD_CONFIG)) {
  216. cout << F(
  217. "Is SD_CS_PIN set to the correct value?\n"
  218. "Does another SPI device need to be disabled?\n"
  219. );
  220. }
  221. errorPrint();
  222. return;
  223. }
  224. t = millis() - t;
  225. cout << F("init time: ") << t << " ms" << endl;
  226. if (!sd.card()->readCID(&m_cid) ||
  227. !sd.card()->readCSD(&m_csd) ||
  228. !sd.card()->readOCR(&m_ocr)) {
  229. cout << F("readInfo failed\n");
  230. errorPrint();
  231. return;
  232. }
  233. printCardType();
  234. cidDmp();
  235. csdDmp();
  236. cout << F("\nOCR: ") << uppercase << showbase;
  237. cout << hex << m_ocr << dec << endl;
  238. if (!mbrDmp()) {
  239. return;
  240. }
  241. if (!sd.volumeBegin()) {
  242. cout << F("\nvolumeBegin failed. Is the card formatted?\n");
  243. errorPrint();
  244. return;
  245. }
  246. dmpVol();
  247. }