@@ -444,6 +444,27 @@ bool Sd2Card::readData(uint8_t* dst, size_t count) { | |||
return false; | |||
} | |||
//------------------------------------------------------------------------------ | |||
/** Read OCR register. | |||
* | |||
* \param[out] ocr Value of OCR register. | |||
* \return true for success else false. | |||
*/ | |||
bool Sd2Card::readOCR(uint32_t* ocr) { | |||
uint8_t *p = (uint8_t*)ocr; | |||
if (cardCommand(CMD58, 0)) { | |||
error(SD_CARD_ERROR_CMD58); | |||
goto fail; | |||
} | |||
for (uint8_t i = 0; i < 4; i++) p[3-i] = m_spi.receive(); | |||
chipSelectHigh(); | |||
return true; | |||
fail: | |||
chipSelectHigh(); | |||
return false; | |||
} | |||
//------------------------------------------------------------------------------ | |||
/** read CID or CSR register */ | |||
bool Sd2Card::readRegister(uint8_t cmd, void* buf) { | |||
uint8_t* dst = reinterpret_cast<uint8_t*>(buf); |
@@ -158,6 +158,7 @@ class Sd2Card { | |||
return readRegister(CMD9, csd); | |||
} | |||
bool readData(uint8_t *dst); | |||
bool readOCR(uint32_t* ocr); | |||
bool readStart(uint32_t blockNumber); | |||
bool readStop(); | |||
/** Return SCK divisor. |
@@ -566,7 +566,7 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { | |||
* successfully opened and is not read only, its length shall be truncated to 0. | |||
* | |||
* WARNING: A given file must not be opened by more than one SdBaseFile object | |||
* of file corruption may occur. | |||
* or file corruption may occur. | |||
* | |||
* \note Directory files must be opened read only. Write and truncation is | |||
* not allowed for directory files. |
@@ -28,7 +28,7 @@ | |||
#define DBG_FAIL_MACRO // Serial.print(__FILE__);Serial.println(__LINE__) | |||
//------------------------------------------------------------------------------ | |||
/** SdFat version YYYYMMDD */ | |||
#define SD_FAT_VERSION 20140824 | |||
#define SD_FAT_VERSION 20141023 | |||
//------------------------------------------------------------------------------ | |||
/** error if old IDE */ | |||
#if !defined(ARDUINO) || ARDUINO < 100 |
@@ -44,9 +44,9 @@ | |||
*/ | |||
#if defined(RAMEND) && RAMEND < 3000 | |||
#define USE_MULTI_BLOCK_SD_IO 0 | |||
#else | |||
#else // RAMEND | |||
#define USE_MULTI_BLOCK_SD_IO 1 | |||
#endif | |||
#endif // RAMEND | |||
//------------------------------------------------------------------------------ | |||
/** |
@@ -21,21 +21,42 @@ | |||
* \file | |||
* \brief SdFile class | |||
*/ | |||
#include <SdBaseFile.h> | |||
#ifndef SdFile_h | |||
#define SdFile_h | |||
#include <limits.h> | |||
#include <SdBaseFile.h> | |||
//------------------------------------------------------------------------------ | |||
/** | |||
* \class SdFile | |||
* \brief SdBaseFile with Print. | |||
*/ | |||
class SdFile : public SdBaseFile, public Print { | |||
class SdFile : public SdBaseFile, public Stream { | |||
public: | |||
SdFile() {} | |||
SdFile(const char* name, uint8_t oflag); | |||
#if DESTRUCTOR_CLOSES_FILE | |||
~SdFile() {} | |||
#endif // DESTRUCTOR_CLOSES_FILE | |||
/** \return number of bytes available from the current position to EOF | |||
* or INT_MAX if more than INT_MAX bytes are available. | |||
*/ | |||
int available() { | |||
uint32_t n = SdBaseFile::available(); | |||
return n > INT_MAX ? INT_MAX : n; | |||
} | |||
/** Ensure that any bytes written to the file are saved to the SD card. */ | |||
void flush() {SdBaseFile::sync();} | |||
/** Return the next available byte without consuming it. | |||
* | |||
* \return The byte if no error and not at eof else -1; | |||
*/ | |||
int peek() {return SdBaseFile::peek();} | |||
/** Read the next byte from a file. | |||
* | |||
* \return For success read returns the next byte in the file as an int. | |||
* If an error occurs or end of file is reached -1 is returned. | |||
*/ | |||
int read() {return SdBaseFile::read();} | |||
/** \return value of writeError */ | |||
bool getWriteError() {return SdBaseFile::getWriteError();} | |||
/** Set writeError to zero */ |
@@ -101,6 +101,13 @@ uint8_t partDmp() { | |||
sdErrorMsg("read MBR failed"); | |||
return false; | |||
} | |||
for (uint8_t ip = 1; ip < 5; ip++) { | |||
part_t *pt = &p->mbr.part[ip - 1]; | |||
if ((pt->boot & 0X7F) != 0 || pt->firstSector > cardSize) { | |||
cout << pstr("\nNo MBR. Assuming Super Floppy format.\n"); | |||
return true; | |||
} | |||
} | |||
cout << pstr("\nSD Partition Table\n"); | |||
cout << pstr("part,boot,type,start,length\n"); | |||
for (uint8_t ip = 1; ip < 5; ip++) { | |||
@@ -188,6 +195,12 @@ void loop() { | |||
} | |||
if (!cidDmp()) return; | |||
if (!csdDmp()) return; | |||
uint32_t ocr; | |||
if (!card.readOCR(&ocr)) { | |||
sdErrorMsg("\nreadOCR failed"); | |||
return; | |||
} | |||
cout << pstr("OCR: ") << hex << ocr << dec << endl; | |||
if (!partDmp()) return; | |||
if (!vol.init(&card)) { | |||
sdErrorMsg("\nvol.init failed"); |
@@ -175,7 +175,7 @@ class ostream : public virtual ios { | |||
* \return the stream | |||
*/ | |||
ostream &operator<< (long arg) { // NOLINT | |||
putNum(arg); | |||
putNum((int32_t)arg); | |||
return *this; | |||
} | |||
/** Output unsigned long | |||
@@ -183,7 +183,7 @@ class ostream : public virtual ios { | |||
* \return the stream | |||
*/ | |||
ostream &operator<< (unsigned long arg) { // NOLINT | |||
putNum(arg); | |||
putNum((uint32_t)arg); | |||
return *this; | |||
} | |||
/** Output pointer |