| @@ -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 | |||