return false; | 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 */ | /** read CID or CSR register */ | ||||
bool Sd2Card::readRegister(uint8_t cmd, void* buf) { | bool Sd2Card::readRegister(uint8_t cmd, void* buf) { | ||||
uint8_t* dst = reinterpret_cast<uint8_t*>(buf); | uint8_t* dst = reinterpret_cast<uint8_t*>(buf); |
return readRegister(CMD9, csd); | return readRegister(CMD9, csd); | ||||
} | } | ||||
bool readData(uint8_t *dst); | bool readData(uint8_t *dst); | ||||
bool readOCR(uint32_t* ocr); | |||||
bool readStart(uint32_t blockNumber); | bool readStart(uint32_t blockNumber); | ||||
bool readStop(); | bool readStop(); | ||||
/** Return SCK divisor. | /** Return SCK divisor. |
* successfully opened and is not read only, its length shall be truncated to 0. | * 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 | * 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 | * \note Directory files must be opened read only. Write and truncation is | ||||
* not allowed for directory files. | * not allowed for directory files. |
#define DBG_FAIL_MACRO // Serial.print(__FILE__);Serial.println(__LINE__) | #define DBG_FAIL_MACRO // Serial.print(__FILE__);Serial.println(__LINE__) | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** SdFat version YYYYMMDD */ | /** SdFat version YYYYMMDD */ | ||||
#define SD_FAT_VERSION 20140824 | |||||
#define SD_FAT_VERSION 20141023 | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** error if old IDE */ | /** error if old IDE */ | ||||
#if !defined(ARDUINO) || ARDUINO < 100 | #if !defined(ARDUINO) || ARDUINO < 100 |
*/ | */ | ||||
#if defined(RAMEND) && RAMEND < 3000 | #if defined(RAMEND) && RAMEND < 3000 | ||||
#define USE_MULTI_BLOCK_SD_IO 0 | #define USE_MULTI_BLOCK_SD_IO 0 | ||||
#else | |||||
#else // RAMEND | |||||
#define USE_MULTI_BLOCK_SD_IO 1 | #define USE_MULTI_BLOCK_SD_IO 1 | ||||
#endif | |||||
#endif // RAMEND | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** | /** |
* \file | * \file | ||||
* \brief SdFile class | * \brief SdFile class | ||||
*/ | */ | ||||
#include <SdBaseFile.h> | |||||
#ifndef SdFile_h | #ifndef SdFile_h | ||||
#define SdFile_h | #define SdFile_h | ||||
#include <limits.h> | |||||
#include <SdBaseFile.h> | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** | /** | ||||
* \class SdFile | * \class SdFile | ||||
* \brief SdBaseFile with Print. | * \brief SdBaseFile with Print. | ||||
*/ | */ | ||||
class SdFile : public SdBaseFile, public Print { | |||||
class SdFile : public SdBaseFile, public Stream { | |||||
public: | public: | ||||
SdFile() {} | SdFile() {} | ||||
SdFile(const char* name, uint8_t oflag); | SdFile(const char* name, uint8_t oflag); | ||||
#if DESTRUCTOR_CLOSES_FILE | #if DESTRUCTOR_CLOSES_FILE | ||||
~SdFile() {} | ~SdFile() {} | ||||
#endif // DESTRUCTOR_CLOSES_FILE | #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 */ | /** \return value of writeError */ | ||||
bool getWriteError() {return SdBaseFile::getWriteError();} | bool getWriteError() {return SdBaseFile::getWriteError();} | ||||
/** Set writeError to zero */ | /** Set writeError to zero */ |
sdErrorMsg("read MBR failed"); | sdErrorMsg("read MBR failed"); | ||||
return false; | 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("\nSD Partition Table\n"); | ||||
cout << pstr("part,boot,type,start,length\n"); | cout << pstr("part,boot,type,start,length\n"); | ||||
for (uint8_t ip = 1; ip < 5; ip++) { | for (uint8_t ip = 1; ip < 5; ip++) { | ||||
} | } | ||||
if (!cidDmp()) return; | if (!cidDmp()) return; | ||||
if (!csdDmp()) 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 (!partDmp()) return; | ||||
if (!vol.init(&card)) { | if (!vol.init(&card)) { | ||||
sdErrorMsg("\nvol.init failed"); | sdErrorMsg("\nvol.init failed"); |
* \return the stream | * \return the stream | ||||
*/ | */ | ||||
ostream &operator<< (long arg) { // NOLINT | ostream &operator<< (long arg) { // NOLINT | ||||
putNum(arg); | |||||
putNum((int32_t)arg); | |||||
return *this; | return *this; | ||||
} | } | ||||
/** Output unsigned long | /** Output unsigned long | ||||
* \return the stream | * \return the stream | ||||
*/ | */ | ||||
ostream &operator<< (unsigned long arg) { // NOLINT | ostream &operator<< (unsigned long arg) { // NOLINT | ||||
putNum(arg); | |||||
putNum((uint32_t)arg); | |||||
return *this; | return *this; | ||||
} | } | ||||
/** Output pointer | /** Output pointer |