1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-01-07 22:46:08 +01:00
Arduino/libraries/SD/utility/examples/SdFatInfo/SdFatInfo.pde
2010-11-13 14:34:49 -05:00

181 lines
4.5 KiB
Plaintext

/*
* This sketch attempts to initialize a SD card and analyze its structure.
*/
#include <SdFat.h>
#include <SdFatUtil.h>
// offset to partition table
#define PART_OFFSET (512-64-2)
Sd2Card card;
SdVolume vol;
//global for card erase sector size
uint32_t sectorSize;
void sdError(void) {
PgmPrintln("SD error");
PgmPrint("errorCode: ");
Serial.println(card.errorCode(), HEX);
PgmPrint("errorData: ");
Serial.println(card.errorData(), HEX);
return;
}
uint8_t cidDmp(void) {
cid_t cid;
if (!card.readCID(&cid)) {
PgmPrint("readCID failed");
sdError();
return false;
}
PgmPrint("\nManufacturer ID: ");
Serial.println(cid.mid, HEX);
PgmPrint("OEM ID: ");
Serial.print(cid.oid[0]);
Serial.println(cid.oid[1]);
PgmPrint("Product: ");
for (uint8_t i = 0; i < 5; i++) {
Serial.print(cid.pnm[i]);
}
PgmPrint("\nVersion: ");
Serial.print(cid.prv_n, DEC);
Serial.print('.');
Serial.println(cid.prv_m, DEC);
PgmPrint("Serial number: ");
Serial.println(cid.psn);
PgmPrint("Manufacturing date: ");
Serial.print(cid.mdt_month);
Serial.print('/');
Serial.println(2000 + cid.mdt_year_low + (cid.mdt_year_high <<4));
Serial.println();
return true;
}
uint8_t csdDmp(void) {
csd_t csd;
uint8_t eraseSingleBlock;
uint32_t cardSize = card.cardSize();
if (cardSize == 0 || !card.readCSD(&csd)) {
PgmPrintln("readCSD failed");
sdError();
return false;
}
if (csd.v1.csd_ver == 0) {
eraseSingleBlock = csd.v1.erase_blk_en;
sectorSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low;
}
else if (csd.v2.csd_ver == 1) {
eraseSingleBlock = csd.v2.erase_blk_en;
sectorSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low;
}
else {
PgmPrintln("csd version error");
return false;
}
sectorSize++;
PgmPrint("cardSize: ");
Serial.print(cardSize);
PgmPrintln(" (512 byte blocks)");
PgmPrint("flashEraseSize: ");
Serial.print(sectorSize, DEC);
PgmPrintln(" blocks");
PgmPrint("eraseSingleBlock: ");
if (eraseSingleBlock) {
PgmPrintln("true");
}
else {
PgmPrintln("false");
}
return true;
}
// print partition table
uint8_t partDmp(void) {
part_t pt;
PgmPrintln("\npart,boot,type,start,length");
for (uint8_t ip = 1; ip < 5; ip++) {
if (!card.readData(0, PART_OFFSET + 16*(ip-1), 16, (uint8_t *)&pt)) {
PgmPrint("read partition table failed");
sdError();
return false;
}
Serial.print(ip, DEC);
Serial.print(',');
Serial.print(pt.boot,HEX);
Serial.print(',');
Serial.print(pt.type, HEX);
Serial.print(',');
Serial.print(pt.firstSector);
Serial.print(',');
Serial.println(pt.totalSectors);
}
return true;
}
void volDmp(void) {
PgmPrint("\nVolume is FAT");
Serial.println(vol.fatType(), DEC);
PgmPrint("blocksPerCluster: ");
Serial.println(vol.blocksPerCluster(), DEC);
PgmPrint("clusterCount: ");
Serial.println(vol.clusterCount());
PgmPrint("fatStartBlock: ");
Serial.println(vol.fatStartBlock());
PgmPrint("fatCount: ");
Serial.println(vol.fatCount(), DEC);
PgmPrint("blocksPerFat: ");
Serial.println(vol.blocksPerFat());
PgmPrint("rootDirStart: ");
Serial.println(vol.rootDirStart());
PgmPrint("dataStartBlock: ");
Serial.println(vol.dataStartBlock());
if (vol.dataStartBlock()%sectorSize) {
PgmPrintln("Data area is not aligned on flash erase boundaries!");
}
}
void setup() {
Serial.begin(9600);
}
void loop() {
PgmPrintln("\ntype any character to start");
while (!Serial.available());
Serial.flush();
uint32_t t = millis();
// initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
// breadboards. use SPI_FULL_SPEED for better performance.
uint8_t r = card.init(SPI_HALF_SPEED);
t = millis() - t;
if (!r) {
PgmPrintln("\ncard.init failed");
sdError();
return;
}
PgmPrint("\ninit time: ");
Serial.println(t);
PgmPrint("\nCard type: ");
switch(card.type()) {
case SD_CARD_TYPE_SD1:
PgmPrintln("SD1");
break;
case SD_CARD_TYPE_SD2:
PgmPrintln("SD2");
break;
case SD_CARD_TYPE_SDHC:
PgmPrintln("SDHC");
break;
default:
PgmPrintln("Unknown");
}
if(!cidDmp()) return;
if(!csdDmp()) return;
if(!partDmp()) return;
if (!vol.init(&card)) {
PgmPrintln("\nvol.init failed");
sdError();
return;
}
volDmp();
}