Keep "astyled" elements in SD-related files

This commit is contained in:
Scott Lahteine
2015-10-02 23:15:24 -07:00
parent 2bffd12ebd
commit 4c99327329
14 changed files with 597 additions and 599 deletions

View File

@@ -23,131 +23,129 @@
#include "Sd2Card.h" #include "Sd2Card.h"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if DISABLED(SOFTWARE_SPI) #if DISABLED(SOFTWARE_SPI)
// functions for hardware SPI // functions for hardware SPI
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// make sure SPCR rate is in expected bits // make sure SPCR rate is in expected bits
#if (SPR0 != 0 || SPR1 != 1) #if (SPR0 != 0 || SPR1 != 1)
#error unexpected SPCR bits #error unexpected SPCR bits
#endif #endif
/** /**
* Initialize hardware SPI * Initialize hardware SPI
* Set SCK rate to F_CPU/pow(2, 1 + spiRate) for spiRate [0,6] * Set SCK rate to F_CPU/pow(2, 1 + spiRate) for spiRate [0,6]
*/ */
static void spiInit(uint8_t spiRate) { static void spiInit(uint8_t spiRate) {
// See avr processor documentation // See avr processor documentation
SPCR = BIT(SPE) | BIT(MSTR) | (spiRate >> 1); SPCR = BIT(SPE) | BIT(MSTR) | (spiRate >> 1);
SPSR = spiRate & 1 || spiRate == 6 ? 0 : BIT(SPI2X); SPSR = spiRate & 1 || spiRate == 6 ? 0 : BIT(SPI2X);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** SPI receive a byte */ /** SPI receive a byte */
static uint8_t spiRec() { static uint8_t spiRec() {
SPDR = 0XFF;
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
return SPDR;
}
//------------------------------------------------------------------------------
/** SPI read data - only one call so force inline */
static inline __attribute__((always_inline))
void spiRead(uint8_t* buf, uint16_t nbyte) {
if (nbyte-- == 0) return;
SPDR = 0XFF;
for (uint16_t i = 0; i < nbyte; i++) {
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
buf[i] = SPDR;
SPDR = 0XFF; SPDR = 0XFF;
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
return SPDR;
} }
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } //------------------------------------------------------------------------------
buf[nbyte] = SPDR; /** SPI read data - only one call so force inline */
} static inline __attribute__((always_inline))
//------------------------------------------------------------------------------ void spiRead(uint8_t* buf, uint16_t nbyte) {
/** SPI send a byte */ if (nbyte-- == 0) return;
static void spiSend(uint8_t b) { SPDR = 0XFF;
SPDR = b; for (uint16_t i = 0; i < nbyte; i++) {
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
} buf[i] = SPDR;
//------------------------------------------------------------------------------ SPDR = 0XFF;
/** SPI send block - only one call so force inline */ }
static inline __attribute__((always_inline)) while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
buf[nbyte] = SPDR;
}
//------------------------------------------------------------------------------
/** SPI send a byte */
static void spiSend(uint8_t b) {
SPDR = b;
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
}
//------------------------------------------------------------------------------
/** SPI send block - only one call so force inline */
static inline __attribute__((always_inline))
void spiSendBlock(uint8_t token, const uint8_t* buf) { void spiSendBlock(uint8_t token, const uint8_t* buf) {
SPDR = token; SPDR = token;
for (uint16_t i = 0; i < 512; i += 2) { for (uint16_t i = 0; i < 512; i += 2) {
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
SPDR = buf[i];
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
SPDR = buf[i + 1];
}
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
SPDR = buf[i];
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
SPDR = buf[i + 1];
} }
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } //------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------
#else // SOFTWARE_SPI #else // SOFTWARE_SPI
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** nop to tune soft SPI timing */ /** nop to tune soft SPI timing */
#define nop asm volatile ("nop\n\t") #define nop asm volatile ("nop\n\t")
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Soft SPI receive byte */ /** Soft SPI receive byte */
static uint8_t spiRec() { static uint8_t spiRec() {
uint8_t data = 0; uint8_t data = 0;
// no interrupts during byte receive - about 8 us // no interrupts during byte receive - about 8 us
cli(); cli();
// output pin high - like sending 0XFF // output pin high - like sending 0XFF
fastDigitalWrite(SPI_MOSI_PIN, HIGH); fastDigitalWrite(SPI_MOSI_PIN, HIGH);
for (uint8_t i = 0; i < 8; i++) { for (uint8_t i = 0; i < 8; i++) {
fastDigitalWrite(SPI_SCK_PIN, HIGH); fastDigitalWrite(SPI_SCK_PIN, HIGH);
// adjust so SCK is nice // adjust so SCK is nice
nop;
nop;
data <<= 1;
if (fastDigitalRead(SPI_MISO_PIN)) data |= 1;
fastDigitalWrite(SPI_SCK_PIN, LOW);
}
// enable interrupts
sei();
return data;
}
//------------------------------------------------------------------------------
/** Soft SPI read data */
static void spiRead(uint8_t* buf, uint16_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++)
buf[i] = spiRec();
}
//------------------------------------------------------------------------------
/** Soft SPI send byte */
static void spiSend(uint8_t data) {
// no interrupts during byte send - about 8 us
cli();
for (uint8_t i = 0; i < 8; i++) {
fastDigitalWrite(SPI_SCK_PIN, LOW);
fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);
data <<= 1;
fastDigitalWrite(SPI_SCK_PIN, HIGH);
}
// hold SCK high for a few ns
nop;
nop;
nop; nop;
nop; nop;
data <<= 1;
if (fastDigitalRead(SPI_MISO_PIN)) data |= 1;
fastDigitalWrite(SPI_SCK_PIN, LOW); fastDigitalWrite(SPI_SCK_PIN, LOW);
// enable interrupts
sei();
} }
// enable interrupts //------------------------------------------------------------------------------
sei(); /** Soft SPI send block */
return data;
}
//------------------------------------------------------------------------------
/** Soft SPI read data */
static void spiRead(uint8_t* buf, uint16_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++) {
buf[i] = spiRec();
}
}
//------------------------------------------------------------------------------
/** Soft SPI send byte */
static void spiSend(uint8_t data) {
// no interrupts during byte send - about 8 us
cli();
for (uint8_t i = 0; i < 8; i++) {
fastDigitalWrite(SPI_SCK_PIN, LOW);
fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);
data <<= 1;
fastDigitalWrite(SPI_SCK_PIN, HIGH);
}
// hold SCK high for a few ns
nop;
nop;
nop;
nop;
fastDigitalWrite(SPI_SCK_PIN, LOW);
// enable interrupts
sei();
}
//------------------------------------------------------------------------------
/** Soft SPI send block */
void spiSendBlock(uint8_t token, const uint8_t* buf) { void spiSendBlock(uint8_t token, const uint8_t* buf) {
spiSend(token); spiSend(token);
for (uint16_t i = 0; i < 512; i++) { for (uint16_t i = 0; i < 512; i++)
spiSend(buf[i]); spiSend(buf[i]);
} }
}
#endif // SOFTWARE_SPI #endif // SOFTWARE_SPI
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// send command and return error code. Return zero for OK // send command and return error code. Return zero for OK
@@ -209,9 +207,9 @@ void Sd2Card::chipSelectHigh() {
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void Sd2Card::chipSelectLow() { void Sd2Card::chipSelectLow() {
#if DISABLED(SOFTWARE_SPI) #if DISABLED(SOFTWARE_SPI)
spiInit(spiRate_); spiInit(spiRate_);
#endif // SOFTWARE_SPI #endif // SOFTWARE_SPI
digitalWrite(chipSelectPin_, LOW); digitalWrite(chipSelectPin_, LOW);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -246,10 +244,10 @@ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
lastBlock <<= 9; lastBlock <<= 9;
} }
if (cardCommand(CMD32, firstBlock) if (cardCommand(CMD32, firstBlock)
|| cardCommand(CMD33, lastBlock) || cardCommand(CMD33, lastBlock)
|| cardCommand(CMD38, 0)) { || cardCommand(CMD38, 0)) {
error(SD_CARD_ERROR_ERASE); error(SD_CARD_ERROR_ERASE);
goto fail; goto fail;
} }
if (!waitNotBusy(SD_ERASE_TIMEOUT)) { if (!waitNotBusy(SD_ERASE_TIMEOUT)) {
error(SD_CARD_ERROR_ERASE_TIMEOUT); error(SD_CARD_ERROR_ERASE_TIMEOUT);
@@ -257,8 +255,7 @@ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
} }
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail:
fail:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@@ -297,17 +294,17 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
pinMode(SPI_MOSI_PIN, OUTPUT); pinMode(SPI_MOSI_PIN, OUTPUT);
pinMode(SPI_SCK_PIN, OUTPUT); pinMode(SPI_SCK_PIN, OUTPUT);
#if DISABLED(SOFTWARE_SPI) #if DISABLED(SOFTWARE_SPI)
// SS must be in output mode even it is not chip select // SS must be in output mode even it is not chip select
pinMode(SS_PIN, OUTPUT); pinMode(SS_PIN, OUTPUT);
// set SS high - may be chip select for another SPI device // set SS high - may be chip select for another SPI device
#if SET_SPI_SS_HIGH #if SET_SPI_SS_HIGH
digitalWrite(SS_PIN, HIGH); digitalWrite(SS_PIN, HIGH);
#endif // SET_SPI_SS_HIGH #endif // SET_SPI_SS_HIGH
// set SCK rate for initialization commands // set SCK rate for initialization commands
spiRate_ = SPI_SD_INIT_RATE; spiRate_ = SPI_SD_INIT_RATE;
spiInit(spiRate_); spiInit(spiRate_);
#endif // SOFTWARE_SPI #endif // SOFTWARE_SPI
// must supply min of 74 clock cycles with CS high. // must supply min of 74 clock cycles with CS high.
for (uint8_t i = 0; i < 10; i++) spiSend(0XFF); for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
@@ -322,7 +319,8 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
// check SD version // check SD version
if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) { if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
type(SD_CARD_TYPE_SD1); type(SD_CARD_TYPE_SD1);
} else { }
else {
// only need last byte of r7 response // only need last byte of r7 response
for (uint8_t i = 0; i < 4; i++) status_ = spiRec(); for (uint8_t i = 0; i < 4; i++) status_ = spiRec();
if (status_ != 0XAA) { if (status_ != 0XAA) {
@@ -353,13 +351,13 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
} }
chipSelectHigh(); chipSelectHigh();
#if DISABLED(SOFTWARE_SPI) #if DISABLED(SOFTWARE_SPI)
return setSckRate(sckRateID); return setSckRate(sckRateID);
#else // SOFTWARE_SPI #else // SOFTWARE_SPI
return true; return true;
#endif // SOFTWARE_SPI #endif // SOFTWARE_SPI
fail: fail:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@@ -376,28 +374,27 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
#if ENABLED(SD_CHECK_AND_RETRY) #if ENABLED(SD_CHECK_AND_RETRY)
uint8_t retryCnt = 3; uint8_t retryCnt = 3;
// use address if not SDHC card // use address if not SDHC card
if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9; if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
retry2: retry2:
retryCnt --; retryCnt --;
if (cardCommand(CMD17, blockNumber)) { if (cardCommand(CMD17, blockNumber)) {
error(SD_CARD_ERROR_CMD17); error(SD_CARD_ERROR_CMD17);
if (retryCnt > 0) goto retry; if (retryCnt > 0) goto retry;
goto fail; goto fail;
} }
if (!readData(dst, 512)) if (!readData(dst, 512)) {
{
if (retryCnt > 0) goto retry; if (retryCnt > 0) goto retry;
goto fail; goto fail;
} }
return true; return true;
retry: retry:
chipSelectHigh(); chipSelectHigh();
cardCommand(CMD12, 0);//Try sending a stop command, but ignore the result. cardCommand(CMD12, 0);//Try sending a stop command, but ignore the result.
errorCode_ = 0; errorCode_ = 0;
goto retry2; goto retry2;
#else #else
// use address if not SDHC card // use address if not SDHC card
if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9; if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
if (cardCommand(CMD17, blockNumber)) { if (cardCommand(CMD17, blockNumber)) {
error(SD_CARD_ERROR_CMD17); error(SD_CARD_ERROR_CMD17);
goto fail; goto fail;
@@ -405,7 +402,7 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
return readData(dst, 512); return readData(dst, 512);
#endif #endif
fail: fail:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@@ -417,7 +414,7 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
* \return The value one, true, is returned for success and * \return The value one, true, is returned for success and
* the value zero, false, is returned for failure. * the value zero, false, is returned for failure.
*/ */
bool Sd2Card::readData(uint8_t *dst) { bool Sd2Card::readData(uint8_t* dst) {
chipSelectLow(); chipSelectLow();
return readData(dst, 512); return readData(dst, 512);
} }
@@ -488,10 +485,9 @@ bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
uint16_t calcCrc = CRC_CCITT(dst, count); uint16_t calcCrc = CRC_CCITT(dst, count);
uint16_t recvCrc = spiRec() << 8; uint16_t recvCrc = spiRec() << 8;
recvCrc |= spiRec(); recvCrc |= spiRec();
if (calcCrc != recvCrc) if (calcCrc != recvCrc) {
{ error(SD_CARD_ERROR_CRC);
error(SD_CARD_ERROR_CRC); goto fail;
goto fail;
} }
} }
#else #else
@@ -501,8 +497,7 @@ bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
#endif #endif
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail:
fail:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@@ -515,8 +510,7 @@ bool Sd2Card::readRegister(uint8_t cmd, void* buf) {
goto fail; goto fail;
} }
return readData(dst, 16); return readData(dst, 16);
fail:
fail:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@@ -532,15 +526,14 @@ bool Sd2Card::readRegister(uint8_t cmd, void* buf) {
* the value zero, false, is returned for failure. * the value zero, false, is returned for failure.
*/ */
bool Sd2Card::readStart(uint32_t blockNumber) { bool Sd2Card::readStart(uint32_t blockNumber) {
if (type()!= SD_CARD_TYPE_SDHC) blockNumber <<= 9; if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
if (cardCommand(CMD18, blockNumber)) { if (cardCommand(CMD18, blockNumber)) {
error(SD_CARD_ERROR_CMD18); error(SD_CARD_ERROR_CMD18);
goto fail; goto fail;
} }
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail:
fail:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@@ -558,8 +551,7 @@ bool Sd2Card::readStop() {
} }
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail:
fail:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@@ -592,8 +584,7 @@ bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
if (((uint16_t)millis() - t0) >= timeoutMillis) goto fail; if (((uint16_t)millis() - t0) >= timeoutMillis) goto fail;
} }
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -626,8 +617,7 @@ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
} }
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail:
fail:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@@ -644,8 +634,7 @@ bool Sd2Card::writeData(const uint8_t* src) {
if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto fail; if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto fail;
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail:
fail:
error(SD_CARD_ERROR_WRITE_MULTIPLE); error(SD_CARD_ERROR_WRITE_MULTIPLE);
chipSelectHigh(); chipSelectHigh();
return false; return false;
@@ -664,8 +653,7 @@ bool Sd2Card::writeData(uint8_t token, const uint8_t* src) {
goto fail; goto fail;
} }
return true; return true;
fail:
fail:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@@ -695,8 +683,7 @@ bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
} }
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail:
fail:
chipSelectHigh(); chipSelectHigh();
return false; return false;
} }
@@ -713,8 +700,7 @@ bool Sd2Card::writeStop() {
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail; if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
chipSelectHigh(); chipSelectHigh();
return true; return true;
fail:
fail:
error(SD_CARD_ERROR_STOP_TRAN); error(SD_CARD_ERROR_STOP_TRAN);
chipSelectHigh(); chipSelectHigh();
return false; return false;

View File

@@ -118,35 +118,35 @@ uint8_t const SD_CARD_TYPE_SDHC = 3;
*/ */
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__)) #if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__))
#define SOFTWARE_SPI #define SOFTWARE_SPI
#elif USE_SOFTWARE_SPI #elif USE_SOFTWARE_SPI
#define SOFTWARE_SPI #define SOFTWARE_SPI
#endif // MEGA_SOFT_SPI #endif // MEGA_SOFT_SPI
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// SPI pin definitions - do not edit here - change in SdFatConfig.h // SPI pin definitions - do not edit here - change in SdFatConfig.h
// //
#if DISABLED(SOFTWARE_SPI) #if DISABLED(SOFTWARE_SPI)
// hardware pin defs // hardware pin defs
/** The default chip select pin for the SD card is SS. */ /** The default chip select pin for the SD card is SS. */
uint8_t const SD_CHIP_SELECT_PIN = SS_PIN; uint8_t const SD_CHIP_SELECT_PIN = SS_PIN;
// The following three pins must not be redefined for hardware SPI. // The following three pins must not be redefined for hardware SPI.
/** SPI Master Out Slave In pin */ /** SPI Master Out Slave In pin */
uint8_t const SPI_MOSI_PIN = MOSI_PIN; uint8_t const SPI_MOSI_PIN = MOSI_PIN;
/** SPI Master In Slave Out pin */ /** SPI Master In Slave Out pin */
uint8_t const SPI_MISO_PIN = MISO_PIN; uint8_t const SPI_MISO_PIN = MISO_PIN;
/** SPI Clock pin */ /** SPI Clock pin */
uint8_t const SPI_SCK_PIN = SCK_PIN; uint8_t const SPI_SCK_PIN = SCK_PIN;
#else // SOFTWARE_SPI #else // SOFTWARE_SPI
/** SPI chip select pin */ /** SPI chip select pin */
uint8_t const SD_CHIP_SELECT_PIN = SOFT_SPI_CS_PIN; uint8_t const SD_CHIP_SELECT_PIN = SOFT_SPI_CS_PIN;
/** SPI Master Out Slave In pin */ /** SPI Master Out Slave In pin */
uint8_t const SPI_MOSI_PIN = SOFT_SPI_MOSI_PIN; uint8_t const SPI_MOSI_PIN = SOFT_SPI_MOSI_PIN;
/** SPI Master In Slave Out pin */ /** SPI Master In Slave Out pin */
uint8_t const SPI_MISO_PIN = SOFT_SPI_MISO_PIN; uint8_t const SPI_MISO_PIN = SOFT_SPI_MISO_PIN;
/** SPI Clock pin */ /** SPI Clock pin */
uint8_t const SPI_SCK_PIN = SOFT_SPI_SCK_PIN; uint8_t const SPI_SCK_PIN = SOFT_SPI_SCK_PIN;
#endif // SOFTWARE_SPI #endif // SOFTWARE_SPI
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
@@ -178,7 +178,7 @@ class Sd2Card {
* \return true for success or false for failure. * \return true for success or false for failure.
*/ */
bool init(uint8_t sckRateID = SPI_FULL_SPEED, bool init(uint8_t sckRateID = SPI_FULL_SPEED,
uint8_t chipSelectPin = SD_CHIP_SELECT_PIN); uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
bool readBlock(uint32_t block, uint8_t* dst); bool readBlock(uint32_t block, uint8_t* dst);
/** /**
* Read a card's CID register. The CID contains card identification * Read a card's CID register. The CID contains card identification
@@ -203,7 +203,7 @@ class Sd2Card {
bool readCSD(csd_t* csd) { bool readCSD(csd_t* csd) {
return readRegister(CMD9, csd); return readRegister(CMD9, csd);
} }
bool readData(uint8_t *dst); bool readData(uint8_t* dst);
bool readStart(uint32_t blockNumber); bool readStart(uint32_t blockNumber);
bool readStop(); bool readStop();
bool setSckRate(uint8_t sckRateID); bool setSckRate(uint8_t sckRateID);

View File

@@ -331,57 +331,57 @@ uint8_t const MISO_PIN = 12; // B3
uint8_t const SCK_PIN = 10; // B1 uint8_t const SCK_PIN = 10; // B1
static const pin_map_t digitalPinMap[] = { static const pin_map_t digitalPinMap[] = {
{&DDRE, &PINE, &PORTE, 0}, // E0 0 {&DDRE, &PINE, &PORTE, 0}, // E0 0
{&DDRE, &PINE, &PORTE, 1}, // E1 1 {&DDRE, &PINE, &PORTE, 1}, // E1 1
{&DDRE, &PINE, &PORTE, 3}, // E3 2 {&DDRE, &PINE, &PORTE, 3}, // E3 2
{&DDRE, &PINE, &PORTE, 4}, // E4 3 {&DDRE, &PINE, &PORTE, 4}, // E4 3
{&DDRC, &PINC, &PORTC, 4}, // C4 4 {&DDRC, &PINC, &PORTC, 4}, // C4 4
{&DDRC, &PINC, &PORTC, 5}, // C5 5 {&DDRC, &PINC, &PORTC, 5}, // C5 5
{&DDRC, &PINC, &PORTC, 6}, // C6 6 {&DDRC, &PINC, &PORTC, 6}, // C6 6
{&DDRC, &PINC, &PORTC, 7}, // C7 7 {&DDRC, &PINC, &PORTC, 7}, // C7 7
{&DDRA, &PINA, &PORTA, 2}, // A2 8 {&DDRA, &PINA, &PORTA, 2}, // A2 8
{&DDRA, &PINA, &PORTA, 3}, // A3 9 {&DDRA, &PINA, &PORTA, 3}, // A3 9
{&DDRA, &PINA, &PORTA, 4}, // A4 10 {&DDRA, &PINA, &PORTA, 4}, // A4 10
{&DDRD, &PIND, &PORTD, 5}, // D5 11 {&DDRD, &PIND, &PORTD, 5}, // D5 11
{&DDRD, &PIND, &PORTD, 6}, // D6 12 {&DDRD, &PIND, &PORTD, 6}, // D6 12
{&DDRC, &PINC, &PORTC, 1}, // C1 13 {&DDRC, &PINC, &PORTC, 1}, // C1 13
{&DDRF, &PINF, &PORTF, 1}, // F1 14 {&DDRF, &PINF, &PORTF, 1}, // F1 14
{&DDRF, &PINF, &PORTF, 2}, // F2 15 {&DDRF, &PINF, &PORTF, 2}, // F2 15
{&DDRF, &PINF, &PORTF, 3}, // F3 16 {&DDRF, &PINF, &PORTF, 3}, // F3 16
{&DDRF, &PINF, &PORTF, 4}, // F4 17 {&DDRF, &PINF, &PORTF, 4}, // F4 17
{&DDRF, &PINF, &PORTF, 5}, // F5 18 {&DDRF, &PINF, &PORTF, 5}, // F5 18
{&DDRF, &PINF, &PORTF, 6}, // F6 19 {&DDRF, &PINF, &PORTF, 6}, // F6 19
{&DDRF, &PINF, &PORTF, 7}, // F7 20 {&DDRF, &PINF, &PORTF, 7}, // F7 20
{&DDRF, &PINF, &PORTF, 0}, // F0 21 {&DDRF, &PINF, &PORTF, 0}, // F0 21
{&DDRA, &PINA, &PORTA, 1}, // A1 22 {&DDRA, &PINA, &PORTA, 1}, // A1 22
{&DDRD, &PIND, &PORTD, 7}, // D7 23 {&DDRD, &PIND, &PORTD, 7}, // D7 23
{&DDRE, &PINE, &PORTE, 5}, // E5 24 {&DDRE, &PINE, &PORTE, 5}, // E5 24
{&DDRA, &PINA, &PORTA, 6}, // A6 25 {&DDRA, &PINA, &PORTA, 6}, // A6 25
{&DDRE, &PINE, &PORTE, 2}, // E2 26 {&DDRE, &PINE, &PORTE, 2}, // E2 26
{&DDRA, &PINA, &PORTA, 5}, // A5 27 {&DDRA, &PINA, &PORTA, 5}, // A5 27
{&DDRC, &PINC, &PORTC, 0}, // C0 28 {&DDRC, &PINC, &PORTC, 0}, // C0 28
{&DDRB, &PINB, &PORTB, 0}, // B0 29 {&DDRB, &PINB, &PORTB, 0}, // B0 29
{&DDRB, &PINB, &PORTB, 1}, // B1 30 {&DDRB, &PINB, &PORTB, 1}, // B1 30
{&DDRB, &PINB, &PORTB, 2}, // B2 31 {&DDRB, &PINB, &PORTB, 2}, // B2 31
{&DDRB, &PINB, &PORTB, 3}, // B3 32 {&DDRB, &PINB, &PORTB, 3}, // B3 32
{&DDRB, &PINB, &PORTB, 4}, // B4 33 {&DDRB, &PINB, &PORTB, 4}, // B4 33
{&DDRB, &PINB, &PORTB, 5}, // B5 34 {&DDRB, &PINB, &PORTB, 5}, // B5 34
{&DDRA, &PINA, &PORTA, 0}, // A0 35 {&DDRA, &PINA, &PORTA, 0}, // A0 35
{&DDRB, &PINB, &PORTB, 6}, // B6 36 {&DDRB, &PINB, &PORTB, 6}, // B6 36
{&DDRB, &PINB, &PORTB, 7}, // B7 37 {&DDRB, &PINB, &PORTB, 7}, // B7 37
{&DDRE, &PINE, &PORTE, 6}, // E6 38 {&DDRE, &PINE, &PORTE, 6}, // E6 38
{&DDRE, &PINE, &PORTE, 7}, // E7 39 {&DDRE, &PINE, &PORTE, 7}, // E7 39
{&DDRD, &PIND, &PORTD, 0}, // D0 40 {&DDRD, &PIND, &PORTD, 0}, // D0 40
{&DDRD, &PIND, &PORTD, 1}, // D1 41 {&DDRD, &PIND, &PORTD, 1}, // D1 41
{&DDRC, &PINC, &PORTC, 3}, // C3 42 {&DDRC, &PINC, &PORTC, 3}, // C3 42
{&DDRD, &PIND, &PORTD, 2}, // D2 43 {&DDRD, &PIND, &PORTD, 2}, // D2 43
{&DDRD, &PIND, &PORTD, 3}, // D3 44 {&DDRD, &PIND, &PORTD, 3}, // D3 44
{&DDRA, &PINA, &PORTA, 7}, // A7 45 {&DDRA, &PINA, &PORTA, 7}, // A7 45
{&DDRC, &PINC, &PORTC, 2}, // C2 46 {&DDRC, &PINC, &PORTC, 2}, // C2 46
{&DDRD, &PIND, &PORTD, 4}, // D4 47 {&DDRD, &PIND, &PORTD, 4}, // D4 47
{&DDRG, &PING, &PORTG, 2}, // G2 48 {&DDRG, &PING, &PORTG, 2}, // G2 48
{&DDRG, &PING, &PORTG, 1}, // G1 49 {&DDRG, &PING, &PORTG, 1}, // G1 49
{&DDRG, &PING, &PORTG, 0}, // G0 50 {&DDRG, &PING, &PORTG, 0}, // G0 50
}; };
#else // defined(__AVR_ATmega1280__) #else // defined(__AVR_ATmega1280__)
#error unknown chip #error unknown chip

View File

@@ -48,7 +48,7 @@ bool SdBaseFile::addCluster() {
bool SdBaseFile::addDirCluster() { bool SdBaseFile::addDirCluster() {
uint32_t block; uint32_t block;
// max folder size // max folder size
if (fileSize_/sizeof(dir_t) >= 0XFFFF) goto fail; if (fileSize_ / sizeof(dir_t) >= 0XFFFF) goto fail;
if (!addCluster()) goto fail; if (!addCluster()) goto fail;
if (!vol_->cacheFlush()) goto fail; if (!vol_->cacheFlush()) goto fail;
@@ -68,8 +68,7 @@ bool SdBaseFile::addDirCluster() {
// Increase directory file size by cluster size // Increase directory file size by cluster size
fileSize_ += 512UL << vol_->clusterSizeShift_; fileSize_ += 512UL << vol_->clusterSizeShift_;
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -78,8 +77,7 @@ bool SdBaseFile::addDirCluster() {
dir_t* SdBaseFile::cacheDirEntry(uint8_t action) { dir_t* SdBaseFile::cacheDirEntry(uint8_t action) {
if (!vol_->cacheRawBlock(dirBlock_, action)) goto fail; if (!vol_->cacheRawBlock(dirBlock_, action)) goto fail;
return vol_->cache()->dir + dirIndex_; return vol_->cache()->dir + dirIndex_;
fail:
fail:
return 0; return 0;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -125,7 +123,7 @@ bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
} }
} }
fail: fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -147,7 +145,7 @@ bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
* *
*/ */
bool SdBaseFile::createContiguous(SdBaseFile* dirFile, bool SdBaseFile::createContiguous(SdBaseFile* dirFile,
const char* path, uint32_t size) { const char* path, uint32_t size) {
uint32_t count; uint32_t count;
// don't allow zero length file // don't allow zero length file
if (size == 0) goto fail; if (size == 0) goto fail;
@@ -167,8 +165,7 @@ bool SdBaseFile::createContiguous(SdBaseFile* dirFile,
flags_ |= F_FILE_DIR_DIRTY; flags_ |= F_FILE_DIR_DIRTY;
return sync(); return sync();
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -191,8 +188,7 @@ bool SdBaseFile::dirEntry(dir_t* dir) {
// copy to caller's struct // copy to caller's struct
memcpy(dir, p, sizeof(dir_t)); memcpy(dir, p, sizeof(dir_t));
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -258,7 +254,8 @@ int16_t SdBaseFile::fgets(char* str, int16_t num, char* delim) {
str[n++] = ch; str[n++] = ch;
if (!delim) { if (!delim) {
if (ch == '\n') break; if (ch == '\n') break;
} else { }
else {
if (strchr(delim, ch)) break; if (strchr(delim, ch)) break;
} }
} }
@@ -318,11 +315,11 @@ void SdBaseFile::getpos(fpos_t* pos) {
void SdBaseFile::ls(uint8_t flags, uint8_t indent) { void SdBaseFile::ls(uint8_t flags, uint8_t indent) {
rewind(); rewind();
int8_t status; int8_t status;
while ((status = lsPrintNext( flags, indent))) { while ((status = lsPrintNext(flags, indent))) {
if (status > 1 && (flags & LS_R)) { if (status > 1 && (flags & LS_R)) {
uint16_t index = curPosition()/32 - 1; uint16_t index = curPosition() / 32 - 1;
SdBaseFile s; SdBaseFile s;
if (s.open(this, index, O_READ)) s.ls( flags, indent + 2); if (s.open(this, index, O_READ)) s.ls(flags, indent + 2);
seekSet(32 * (index + 1)); seekSet(32 * (index + 1));
} }
} }
@@ -330,7 +327,7 @@ void SdBaseFile::ls(uint8_t flags, uint8_t indent) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// saves 32 bytes on stack for ls recursion // saves 32 bytes on stack for ls recursion
// return 0 - EOF, 1 - normal file, or 2 - directory // return 0 - EOF, 1 - normal file, or 2 - directory
int8_t SdBaseFile::lsPrintNext( uint8_t flags, uint8_t indent) { int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) {
dir_t dir; dir_t dir;
uint8_t w = 0; uint8_t w = 0;
@@ -340,7 +337,7 @@ int8_t SdBaseFile::lsPrintNext( uint8_t flags, uint8_t indent) {
// skip deleted entry and entries for . and .. // skip deleted entry and entries for . and ..
if (dir.name[0] != DIR_NAME_DELETED && dir.name[0] != '.' if (dir.name[0] != DIR_NAME_DELETED && dir.name[0] != '.'
&& DIR_IS_FILE_OR_SUBDIR(&dir)) break; && DIR_IS_FILE_OR_SUBDIR(&dir)) break;
} }
// indent for dir level // indent for dir level
for (uint8_t i = 0; i < indent; i++) MYSERIAL.write(' '); for (uint8_t i = 0; i < indent; i++) MYSERIAL.write(' ');
@@ -365,9 +362,9 @@ int8_t SdBaseFile::lsPrintNext( uint8_t flags, uint8_t indent) {
// print modify date/time if requested // print modify date/time if requested
if (flags & LS_DATE) { if (flags & LS_DATE) {
MYSERIAL.write(' '); MYSERIAL.write(' ');
printFatDate( dir.lastWriteDate); printFatDate(dir.lastWriteDate);
MYSERIAL.write(' '); MYSERIAL.write(' ');
printFatTime( dir.lastWriteTime); printFatTime(dir.lastWriteTime);
} }
// print size if requested // print size if requested
if (!DIR_IS_SUBDIR(&dir) && (flags & LS_SIZE)) { if (!DIR_IS_SUBDIR(&dir) && (flags & LS_SIZE)) {
@@ -392,7 +389,8 @@ bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) {
if (n == 10) goto fail; // only one dot allowed if (n == 10) goto fail; // only one dot allowed
n = 10; // max index for full 8.3 name n = 10; // max index for full 8.3 name
i = 8; // place for extension i = 8; // place for extension
} else { }
else {
// illegal FAT characters // illegal FAT characters
PGM_P p = PSTR("|<>^+=?/[];,*\"\\"); PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
uint8_t b; uint8_t b;
@@ -400,14 +398,13 @@ bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) {
// check size and only allow ASCII printable characters // check size and only allow ASCII printable characters
if (i > n || c < 0X21 || c > 0X7E)goto fail; if (i > n || c < 0X21 || c > 0X7E)goto fail;
// only upper case allowed in 8.3 names - convert lower to upper // only upper case allowed in 8.3 names - convert lower to upper
name[i++] = (c < 'a' || c > 'z') ? (c) : (c + ('A' - 'a')); name[i++] = (c < 'a' || c > 'z') ? (c) : (c + ('A' - 'a'));
} }
} }
*ptr = str; *ptr = str;
// must have a file name, extension is optional // must have a file name, extension is optional
return name[0] != ' '; return name[0] != ' ';
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -454,8 +451,7 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) {
sub = parent != &dir1 ? &dir1 : &dir2; sub = parent != &dir1 ? &dir1 : &dir2;
} }
return mkdir(parent, dname); return mkdir(parent, dname);
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -503,7 +499,8 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
if (parent->isRoot()) { if (parent->isRoot()) {
d.firstClusterLow = 0; d.firstClusterLow = 0;
d.firstClusterHigh = 0; d.firstClusterHigh = 0;
} else { }
else {
d.firstClusterLow = parent->firstCluster_ & 0XFFFF; d.firstClusterLow = parent->firstCluster_ & 0XFFFF;
d.firstClusterHigh = parent->firstCluster_ >> 16; d.firstClusterHigh = parent->firstCluster_ >> 16;
} }
@@ -512,24 +509,23 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
// write first block // write first block
return vol_->cacheFlush(); return vol_->cacheFlush();
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Open a file in the current working directory. /** Open a file in the current working directory.
* *
* \param[in] path A path with a valid 8.3 DOS name for a file to be opened. * \param[in] path A path with a valid 8.3 DOS name for a file to be opened.
* *
* \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
* OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t). * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t).
* *
* \return The value one, true, is returned for success and * \return The value one, true, is returned for success and
* the value zero, false, is returned for failure. * the value zero, false, is returned for failure.
*/ */
bool SdBaseFile::open(const char* path, uint8_t oflag) { bool SdBaseFile::open(const char* path, uint8_t oflag) {
return open(cwd_, path, oflag); return open(cwd_, path, oflag);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Open a file or directory by name. /** Open a file or directory by name.
* *
@@ -584,8 +580,8 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag) { bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag) {
uint8_t dname[11]; uint8_t dname[11];
SdBaseFile dir1, dir2; SdBaseFile dir1, dir2;
SdBaseFile *parent = dirFile; SdBaseFile* parent = dirFile;
SdBaseFile *sub = &dir1; SdBaseFile* sub = &dir1;
if (!dirFile) goto fail; if (!dirFile) goto fail;
@@ -609,14 +605,13 @@ bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag) {
sub = parent != &dir1 ? &dir1 : &dir2; sub = parent != &dir1 ? &dir1 : &dir2;
} }
return open(parent, dname, oflag); return open(parent, dname, oflag);
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// open with filename in dname // open with filename in dname
bool SdBaseFile::open(SdBaseFile* dirFile, bool SdBaseFile::open(SdBaseFile* dirFile,
const uint8_t dname[11], uint8_t oflag) { const uint8_t dname[11], uint8_t oflag) {
bool emptyFound = false; bool emptyFound = false;
bool fileFound = false; bool fileFound = false;
uint8_t index; uint8_t index;
@@ -641,7 +636,8 @@ bool SdBaseFile::open(SdBaseFile* dirFile,
} }
// done if no entries follow // done if no entries follow
if (p->name[0] == DIR_NAME_FREE) break; if (p->name[0] == DIR_NAME_FREE) break;
} else if (!memcmp(dname, p->name, 11)) { }
else if (!memcmp(dname, p->name, 11)) {
fileFound = true; fileFound = true;
break; break;
} }
@@ -649,14 +645,16 @@ bool SdBaseFile::open(SdBaseFile* dirFile,
if (fileFound) { if (fileFound) {
// don't open existing file if O_EXCL // don't open existing file if O_EXCL
if (oflag & O_EXCL) goto fail; if (oflag & O_EXCL) goto fail;
} else { }
else {
// don't create unless O_CREAT and O_WRITE // don't create unless O_CREAT and O_WRITE
if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) goto fail; if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) goto fail;
if (emptyFound) { if (emptyFound) {
index = dirIndex_; index = dirIndex_;
p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
if (!p) goto fail; if (!p) goto fail;
} else { }
else {
if (dirFile->type_ == FAT_FILE_TYPE_ROOT_FIXED) goto fail; if (dirFile->type_ == FAT_FILE_TYPE_ROOT_FIXED) goto fail;
// add and zero cluster for dirFile - first cluster is in cache for write // add and zero cluster for dirFile - first cluster is in cache for write
@@ -674,7 +672,8 @@ bool SdBaseFile::open(SdBaseFile* dirFile,
if (dateTime_) { if (dateTime_) {
// call user date/time function // call user date/time function
dateTime_(&p->creationDate, &p->creationTime); dateTime_(&p->creationDate, &p->creationTime);
} else { }
else {
// use default date/time // use default date/time
p->creationDate = FAT_DEFAULT_DATE; p->creationDate = FAT_DEFAULT_DATE;
p->creationTime = FAT_DEFAULT_TIME; p->creationTime = FAT_DEFAULT_TIME;
@@ -688,8 +687,7 @@ bool SdBaseFile::open(SdBaseFile* dirFile,
} }
// open entry in cache // open entry in cache
return openCachedEntry(index, oflag); return openCachedEntry(index, oflag);
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -731,8 +729,7 @@ bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) {
} }
// open cached entry // open cached entry
return openCachedEntry(index & 0XF, oflag); return openCachedEntry(index & 0XF, oflag);
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -757,10 +754,12 @@ bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
if (DIR_IS_FILE(p)) { if (DIR_IS_FILE(p)) {
fileSize_ = p->fileSize; fileSize_ = p->fileSize;
type_ = FAT_FILE_TYPE_NORMAL; type_ = FAT_FILE_TYPE_NORMAL;
} else if (DIR_IS_SUBDIR(p)) { }
else if (DIR_IS_SUBDIR(p)) {
if (!vol_->chainSize(firstCluster_, &fileSize_)) goto fail; if (!vol_->chainSize(firstCluster_, &fileSize_)) goto fail;
type_ = FAT_FILE_TYPE_SUBDIR; type_ = FAT_FILE_TYPE_SUBDIR;
} else { }
else {
goto fail; goto fail;
} }
// save open flags for read/write // save open flags for read/write
@@ -771,8 +770,7 @@ bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
curPosition_ = 0; curPosition_ = 0;
if ((oflag & O_TRUNC) && !truncate(0)) return false; if ((oflag & O_TRUNC) && !truncate(0)) return false;
return oflag & O_AT_END ? seekEnd(0) : true; return oflag & O_AT_END ? seekEnd(0) : true;
fail:
fail:
type_ = FAT_FILE_TYPE_CLOSED; type_ = FAT_FILE_TYPE_CLOSED;
return false; return false;
} }
@@ -818,8 +816,7 @@ bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) {
return openCachedEntry(index, oflag); return openCachedEntry(index, oflag);
} }
} }
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -862,8 +859,9 @@ bool SdBaseFile::openParent(SdBaseFile* dir) {
// '..' is pointer to first cluster of parent. open '../..' to find parent // '..' is pointer to first cluster of parent. open '../..' to find parent
if (p->firstClusterHigh == 0 && p->firstClusterLow == 0) { if (p->firstClusterHigh == 0 && p->firstClusterLow == 0) {
if (!file.openRoot(dir->volume())) goto fail; if (!file.openRoot(dir->volume())) goto fail;
} else { }
if (!file.openCachedEntry(1, O_READ)) goto fail; else if (!file.openCachedEntry(1, O_READ)) {
goto fail;
} }
// search for parent in '../..' // search for parent in '../..'
do { do {
@@ -872,9 +870,8 @@ bool SdBaseFile::openParent(SdBaseFile* dir) {
c |= (uint32_t)entry.firstClusterHigh << 16; c |= (uint32_t)entry.firstClusterHigh << 16;
} while (c != cluster); } while (c != cluster);
// open parent // open parent
return open(&file, file.curPosition()/32 - 1, O_READ); return open(&file, file.curPosition() / 32 - 1, O_READ);
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -895,11 +892,13 @@ bool SdBaseFile::openRoot(SdVolume* vol) {
type_ = FAT_FILE_TYPE_ROOT_FIXED; type_ = FAT_FILE_TYPE_ROOT_FIXED;
firstCluster_ = 0; firstCluster_ = 0;
fileSize_ = 32 * vol->rootDirEntryCount(); fileSize_ = 32 * vol->rootDirEntryCount();
} else if (vol->fatType() == 32) { }
else if (vol->fatType() == 32) {
type_ = FAT_FILE_TYPE_ROOT32; type_ = FAT_FILE_TYPE_ROOT32;
firstCluster_ = vol->rootDirStart(); firstCluster_ = vol->rootDirStart();
if (!vol->chainSize(firstCluster_, &fileSize_)) goto fail; if (!vol->chainSize(firstCluster_, &fileSize_)) goto fail;
} else { }
else {
// volume is not initialized, invalid, or FAT12 without support // volume is not initialized, invalid, or FAT12 without support
return false; return false;
} }
@@ -915,8 +914,7 @@ bool SdBaseFile::openRoot(SdVolume* vol) {
dirBlock_ = 0; dirBlock_ = 0;
dirIndex_ = 0; dirIndex_ = 0;
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -940,7 +938,7 @@ int SdBaseFile::peek() {
* \param[in] printSlash Print '/' after directory names if true. * \param[in] printSlash Print '/' after directory names if true.
*/ */
void SdBaseFile::printDirName(const dir_t& dir, void SdBaseFile::printDirName(const dir_t& dir,
uint8_t width, bool printSlash) { uint8_t width, bool printSlash) {
uint8_t w = 0; uint8_t w = 0;
for (uint8_t i = 0; i < 11; i++) { for (uint8_t i = 0; i < 11; i++) {
if (dir.name[i] == ' ')continue; if (dir.name[i] == ' ')continue;
@@ -962,7 +960,7 @@ void SdBaseFile::printDirName(const dir_t& dir,
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// print uint8_t with width 2 // print uint8_t with width 2
static void print2u( uint8_t v) { static void print2u(uint8_t v) {
if (v < 10) MYSERIAL.write('0'); if (v < 10) MYSERIAL.write('0');
MYSERIAL.print(v, DEC); MYSERIAL.print(v, DEC);
} }
@@ -985,9 +983,9 @@ static void print2u( uint8_t v) {
void SdBaseFile::printFatDate(uint16_t fatDate) { void SdBaseFile::printFatDate(uint16_t fatDate) {
MYSERIAL.print(FAT_YEAR(fatDate)); MYSERIAL.print(FAT_YEAR(fatDate));
MYSERIAL.write('-'); MYSERIAL.write('-');
print2u( FAT_MONTH(fatDate)); print2u(FAT_MONTH(fatDate));
MYSERIAL.write('-'); MYSERIAL.write('-');
print2u( FAT_DAY(fatDate)); print2u(FAT_DAY(fatDate));
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -998,12 +996,12 @@ void SdBaseFile::printFatDate(uint16_t fatDate) {
* \param[in] pr Print stream for output. * \param[in] pr Print stream for output.
* \param[in] fatTime The time field from a directory entry. * \param[in] fatTime The time field from a directory entry.
*/ */
void SdBaseFile::printFatTime( uint16_t fatTime) { void SdBaseFile::printFatTime(uint16_t fatTime) {
print2u( FAT_HOUR(fatTime)); print2u(FAT_HOUR(fatTime));
MYSERIAL.write(':'); MYSERIAL.write(':');
print2u( FAT_MINUTE(fatTime)); print2u(FAT_MINUTE(fatTime));
MYSERIAL.write(':'); MYSERIAL.write(':');
print2u( FAT_SECOND(fatTime)); print2u(FAT_SECOND(fatTime));
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Print a file's name to Serial /** Print a file's name to Serial
@@ -1060,14 +1058,16 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) {
offset = curPosition_ & 0X1FF; // offset in block offset = curPosition_ & 0X1FF; // offset in block
if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { if (type_ == FAT_FILE_TYPE_ROOT_FIXED) {
block = vol_->rootDirStart() + (curPosition_ >> 9); block = vol_->rootDirStart() + (curPosition_ >> 9);
} else { }
else {
uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_);
if (offset == 0 && blockOfCluster == 0) { if (offset == 0 && blockOfCluster == 0) {
// start of new cluster // start of new cluster
if (curPosition_ == 0) { if (curPosition_ == 0) {
// use first cluster in file // use first cluster in file
curCluster_ = firstCluster_; curCluster_ = firstCluster_;
} else { }
else {
// get next cluster from FAT // get next cluster from FAT
if (!vol_->fatGet(curCluster_, &curCluster_)) goto fail; if (!vol_->fatGet(curCluster_, &curCluster_)) goto fail;
} }
@@ -1082,7 +1082,8 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) {
// no buffering needed if n == 512 // no buffering needed if n == 512
if (n == 512 && block != vol_->cacheBlockNumber()) { if (n == 512 && block != vol_->cacheBlockNumber()) {
if (!vol_->readBlock(block, dst)) goto fail; if (!vol_->readBlock(block, dst)) goto fail;
} else { }
else {
// read block to cache and copy data to caller // read block to cache and copy data to caller
if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto fail; if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) goto fail;
uint8_t* src = vol_->cache()->data + offset; uint8_t* src = vol_->cache()->data + offset;
@@ -1093,8 +1094,7 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) {
toRead -= n; toRead -= n;
} }
return nbyte; return nbyte;
fail:
fail:
return -1; return -1;
} }
@@ -1131,15 +1131,15 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) {
// Fill the long filename if we have a long filename entry. // Fill the long filename if we have a long filename entry.
// Long filename entries are stored before the short filename. // Long filename entries are stored before the short filename.
if (longFilename != NULL && DIR_IS_LONG_NAME(dir)) { if (longFilename != NULL && DIR_IS_LONG_NAME(dir)) {
vfat_t *VFAT = (vfat_t*)dir; vfat_t* VFAT = (vfat_t*)dir;
// Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0 // Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0
if (VFAT->firstClusterLow == 0 && (VFAT->sequenceNumber & 0x1F) > 0 && (VFAT->sequenceNumber & 0x1F) <= MAX_VFAT_ENTRIES) { if (VFAT->firstClusterLow == 0 && (VFAT->sequenceNumber & 0x1F) > 0 && (VFAT->sequenceNumber & 0x1F) <= MAX_VFAT_ENTRIES) {
// TODO: Store the filename checksum to verify if a none-long filename aware system modified the file table. // TODO: Store the filename checksum to verify if a none-long filename aware system modified the file table.
n = ((VFAT->sequenceNumber & 0x1F) - 1) * FILENAME_LENGTH; n = ((VFAT->sequenceNumber & 0x1F) - 1) * FILENAME_LENGTH;
for (uint8_t i=0; i<FILENAME_LENGTH; i++) for (uint8_t i = 0; i < FILENAME_LENGTH; i++)
longFilename[n+i] = (i < 5) ? VFAT->name1[i] : (i < 11) ? VFAT->name2[i-5] : VFAT->name3[i-11]; longFilename[n + i] = (i < 5) ? VFAT->name1[i] : (i < 11) ? VFAT->name2[i - 5] : VFAT->name3[i - 11];
// If this VFAT entry is the last one, add a NUL terminator at the end of the string // If this VFAT entry is the last one, add a NUL terminator at the end of the string
if (VFAT->sequenceNumber & 0x40) longFilename[n+FILENAME_LENGTH] = '\0'; if (VFAT->sequenceNumber & 0x40) longFilename[n + FILENAME_LENGTH] = '\0';
} }
} }
// Return if normal file or subdirectory // Return if normal file or subdirectory
@@ -1166,8 +1166,7 @@ dir_t* SdBaseFile::readDirCache() {
// return pointer to entry // return pointer to entry
return vol_->cache()->dir + i; return vol_->cache()->dir + i;
fail:
fail:
return 0; return 0;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -1202,8 +1201,7 @@ bool SdBaseFile::remove() {
// write entry to SD // write entry to SD
return vol_->cacheFlush(); return vol_->cacheFlush();
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -1228,8 +1226,7 @@ bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) {
SdBaseFile file; SdBaseFile file;
if (!file.open(dirFile, path, O_WRITE)) goto fail; if (!file.open(dirFile, path, O_WRITE)) goto fail;
return file.remove(); return file.remove();
fail:
fail:
// can't set iostate - static function // can't set iostate - static function
return false; return false;
} }
@@ -1272,7 +1269,8 @@ bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) {
if (!file.open(dirFile, newPath, O_CREAT | O_EXCL | O_WRITE)) { if (!file.open(dirFile, newPath, O_CREAT | O_EXCL | O_WRITE)) {
goto restore; goto restore;
} }
} else { }
else {
// don't create missing path prefix components // don't create missing path prefix components
if (!file.mkdir(dirFile, newPath, false)) { if (!file.mkdir(dirFile, newPath, false)) {
goto restore; goto restore;
@@ -1311,14 +1309,14 @@ bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) {
} }
return vol_->cacheFlush(); return vol_->cacheFlush();
restore: restore:
d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE); d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
if (!d) goto fail; if (!d) goto fail;
// restore entry // restore entry
d->name[0] = entry.name[0]; d->name[0] = entry.name[0];
vol_->cacheFlush(); vol_->cacheFlush();
fail: fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -1358,8 +1356,7 @@ bool SdBaseFile::rmdir() {
type_ = FAT_FILE_TYPE_NORMAL; type_ = FAT_FILE_TYPE_NORMAL;
flags_ |= O_WRITE; flags_ |= O_WRITE;
return remove(); return remove();
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -1384,7 +1381,7 @@ bool SdBaseFile::rmRfStar() {
rewind(); rewind();
while (curPosition_ < fileSize_) { while (curPosition_ < fileSize_) {
// remember position // remember position
index = curPosition_/32; index = curPosition_ / 32;
dir_t* p = readDirCache(); dir_t* p = readDirCache();
if (!p) goto fail; if (!p) goto fail;
@@ -1402,14 +1399,15 @@ bool SdBaseFile::rmRfStar() {
if (f.isSubDir()) { if (f.isSubDir()) {
// recursively delete // recursively delete
if (!f.rmRfStar()) goto fail; if (!f.rmRfStar()) goto fail;
} else { }
else {
// ignore read-only // ignore read-only
f.flags_ |= O_WRITE; f.flags_ |= O_WRITE;
if (!f.remove()) goto fail; if (!f.remove()) goto fail;
} }
// position to next entry if required // position to next entry if required
if (curPosition_ != (32*(index + 1))) { if (curPosition_ != (32 * (index + 1))) {
if (!seekSet(32*(index + 1))) goto fail; if (!seekSet(32 * (index + 1))) goto fail;
} }
} }
// don't try to delete root // don't try to delete root
@@ -1417,8 +1415,7 @@ bool SdBaseFile::rmRfStar() {
if (!rmdir()) goto fail; if (!rmdir()) goto fail;
} }
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -1465,7 +1462,8 @@ bool SdBaseFile::seekSet(uint32_t pos) {
if (nNew < nCur || curPosition_ == 0) { if (nNew < nCur || curPosition_ == 0) {
// must follow chain from first cluster // must follow chain from first cluster
curCluster_ = firstCluster_; curCluster_ = firstCluster_;
} else { }
else {
// advance from curPosition // advance from curPosition
nNew -= nCur; nNew -= nCur;
} }
@@ -1474,10 +1472,10 @@ bool SdBaseFile::seekSet(uint32_t pos) {
} }
curPosition_ = pos; curPosition_ = pos;
done: done:
return true; return true;
fail: fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -1520,7 +1518,7 @@ bool SdBaseFile::sync() {
} }
return vol_->cacheFlush(); return vol_->cacheFlush();
fail: fail:
writeError = true; writeError = true;
return false; return false;
} }
@@ -1560,7 +1558,7 @@ bool SdBaseFile::timestamp(SdBaseFile* file) {
// write back entry // write back entry
return vol_->cacheFlush(); return vol_->cacheFlush();
fail: fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -1598,22 +1596,22 @@ bool SdBaseFile::timestamp(SdBaseFile* file) {
* the value zero, false, is returned for failure. * the value zero, false, is returned for failure.
*/ */
bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month, bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
uint16_t dirDate; uint16_t dirDate;
uint16_t dirTime; uint16_t dirTime;
dir_t* d; dir_t* d;
if (!isOpen() if (!isOpen()
|| year < 1980 || year < 1980
|| year > 2107 || year > 2107
|| month < 1 || month < 1
|| month > 12 || month > 12
|| day < 1 || day < 1
|| day > 31 || day > 31
|| hour > 23 || hour > 23
|| minute > 59 || minute > 59
|| second > 59) { || second > 59) {
goto fail; goto fail;
} }
// update directory entry // update directory entry
if (!sync()) goto fail; if (!sync()) goto fail;
@@ -1637,8 +1635,7 @@ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
d->lastWriteTime = dirTime; d->lastWriteTime = dirTime;
} }
return vol_->cacheFlush(); return vol_->cacheFlush();
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -1674,7 +1671,8 @@ bool SdBaseFile::truncate(uint32_t length) {
// free all clusters // free all clusters
if (!vol_->freeChain(firstCluster_)) goto fail; if (!vol_->freeChain(firstCluster_)) goto fail;
firstCluster_ = 0; firstCluster_ = 0;
} else { }
else {
uint32_t toFree; uint32_t toFree;
if (!vol_->fatGet(curCluster_, &toFree)) goto fail; if (!vol_->fatGet(curCluster_, &toFree)) goto fail;
@@ -1696,7 +1694,7 @@ bool SdBaseFile::truncate(uint32_t length) {
// set file to correct position // set file to correct position
return seekSet(newPos); return seekSet(newPos);
fail: fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -1739,16 +1737,19 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
if (firstCluster_ == 0) { if (firstCluster_ == 0) {
// allocate first cluster of file // allocate first cluster of file
if (!addCluster()) goto fail; if (!addCluster()) goto fail;
} else { }
else {
curCluster_ = firstCluster_; curCluster_ = firstCluster_;
} }
} else { }
else {
uint32_t next; uint32_t next;
if (!vol_->fatGet(curCluster_, &next)) goto fail; if (!vol_->fatGet(curCluster_, &next)) goto fail;
if (vol_->isEOC(next)) { if (vol_->isEOC(next)) {
// add cluster if at end of chain // add cluster if at end of chain
if (!addCluster()) goto fail; if (!addCluster()) goto fail;
} else { }
else {
curCluster_ = next; curCluster_ = next;
} }
} }
@@ -1768,13 +1769,15 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
vol_->cacheSetBlockNumber(0XFFFFFFFF, false); vol_->cacheSetBlockNumber(0XFFFFFFFF, false);
} }
if (!vol_->writeBlock(block, src)) goto fail; if (!vol_->writeBlock(block, src)) goto fail;
} else { }
else {
if (blockOffset == 0 && curPosition_ >= fileSize_) { if (blockOffset == 0 && curPosition_ >= fileSize_) {
// start of new block don't need to read into cache // start of new block don't need to read into cache
if (!vol_->cacheFlush()) goto fail; if (!vol_->cacheFlush()) goto fail;
// set cache dirty and SD address of block // set cache dirty and SD address of block
vol_->cacheSetBlockNumber(block, true); vol_->cacheSetBlockNumber(block, true);
} else { }
else {
// rewrite part of block // rewrite part of block
if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto fail; if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto fail;
} }
@@ -1789,7 +1792,8 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
// update fileSize and insure sync will update dir entry // update fileSize and insure sync will update dir entry
fileSize_ = curPosition_; fileSize_ = curPosition_;
flags_ |= F_FILE_DIR_DIRTY; flags_ |= F_FILE_DIR_DIRTY;
} else if (dateTime_ && nbyte) { }
else if (dateTime_ && nbyte) {
// insure sync will update modified date and time // insure sync will update modified date and time
flags_ |= F_FILE_DIR_DIRTY; flags_ |= F_FILE_DIR_DIRTY;
} }
@@ -1799,7 +1803,7 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
} }
return nbyte; return nbyte;
fail: fail:
// return for write error // return for write error
writeError = true; writeError = true;
return -1; return -1;
@@ -1807,7 +1811,7 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// suppress cpplint warnings with NOLINT comment // suppress cpplint warnings with NOLINT comment
#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) #if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN)
void (*SdBaseFile::oldDateTime_)(uint16_t& date, uint16_t& time) = 0; // NOLINT void (*SdBaseFile::oldDateTime_)(uint16_t& date, uint16_t& time) = 0; // NOLINT
#endif // ALLOW_DEPRECATED_FUNCTIONS #endif // ALLOW_DEPRECATED_FUNCTIONS

View File

@@ -158,7 +158,7 @@ static inline uint8_t FAT_HOUR(uint16_t fatTime) {
* \return Extracted minute [0,59] * \return Extracted minute [0,59]
*/ */
static inline uint8_t FAT_MINUTE(uint16_t fatTime) { static inline uint8_t FAT_MINUTE(uint16_t fatTime) {
return(fatTime >> 5) & 0X3F; return (fatTime >> 5) & 0X3F;
} }
/** second part of FAT directory time field /** second part of FAT directory time field
* Note second/2 is stored in packed time. * Note second/2 is stored in packed time.
@@ -168,7 +168,7 @@ static inline uint8_t FAT_MINUTE(uint16_t fatTime) {
* \return Extracted second [0,58] * \return Extracted second [0,58]
*/ */
static inline uint8_t FAT_SECOND(uint16_t fatTime) { static inline uint8_t FAT_SECOND(uint16_t fatTime) {
return 2*(fatTime & 0X1F); return 2 * (fatTime & 0X1F);
} }
/** Default date for file timestamps is 1 Jan 2000 */ /** Default date for file timestamps is 1 Jan 2000 */
uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1;
@@ -184,7 +184,7 @@ class SdBaseFile {
/** Create an instance. */ /** Create an instance. */
SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {} SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {}
SdBaseFile(const char* path, uint8_t oflag); SdBaseFile(const char* path, uint8_t oflag);
~SdBaseFile() {if(isOpen()) close();} ~SdBaseFile() {if (isOpen()) close();}
/** /**
* writeError is set to true if an error occurs during a write(). * writeError is set to true if an error occurs during a write().
* Set writeError to false before calling print() and/or write() and check * Set writeError to false before calling print() and/or write() and check
@@ -205,7 +205,7 @@ class SdBaseFile {
bool close(); bool close();
bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
bool createContiguous(SdBaseFile* dirFile, bool createContiguous(SdBaseFile* dirFile,
const char* path, uint32_t size); const char* path, uint32_t size);
/** \return The current cluster number for a file or directory. */ /** \return The current cluster number for a file or directory. */
uint32_t curCluster() const {return curCluster_;} uint32_t curCluster() const {return curCluster_;}
/** \return The current position for a file or directory. */ /** \return The current position for a file or directory. */
@@ -266,7 +266,7 @@ class SdBaseFile {
bool isRoot() const { bool isRoot() const {
return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32; return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32;
} }
void ls( uint8_t flags = 0, uint8_t indent = 0); void ls(uint8_t flags = 0, uint8_t indent = 0);
bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true); bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true);
// alias for backward compactability // alias for backward compactability
bool makeDir(SdBaseFile* dir, const char* path) { bool makeDir(SdBaseFile* dir, const char* path) {
@@ -279,7 +279,7 @@ class SdBaseFile {
bool openRoot(SdVolume* vol); bool openRoot(SdVolume* vol);
int peek(); int peek();
static void printFatDate(uint16_t fatDate); static void printFatDate(uint16_t fatDate);
static void printFatTime( uint16_t fatTime); static void printFatTime(uint16_t fatTime);
bool printName(); bool printName();
int16_t read(); int16_t read();
int16_t read(void* buf, uint16_t nbyte); int16_t read(void* buf, uint16_t nbyte);
@@ -309,7 +309,7 @@ class SdBaseFile {
bool sync(); bool sync();
bool timestamp(SdBaseFile* file); bool timestamp(SdBaseFile* file);
bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day, bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day,
uint8_t hour, uint8_t minute, uint8_t second); uint8_t hour, uint8_t minute, uint8_t second);
/** Type of file. You should use isFile() or isDir() instead of type() /** Type of file. You should use isFile() or isDir() instead of type()
* if possible. * if possible.
* *
@@ -320,7 +320,7 @@ class SdBaseFile {
/** \return SdVolume that contains this file. */ /** \return SdVolume that contains this file. */
SdVolume* volume() const {return vol_;} SdVolume* volume() const {return vol_;}
int16_t write(const void* buf, uint16_t nbyte); int16_t write(const void* buf, uint16_t nbyte);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
// allow SdFat to set cwd_ // allow SdFat to set cwd_
friend class SdFat; friend class SdFat;
@@ -352,18 +352,18 @@ class SdBaseFile {
bool addCluster(); bool addCluster();
bool addDirCluster(); bool addDirCluster();
dir_t* cacheDirEntry(uint8_t action); dir_t* cacheDirEntry(uint8_t action);
int8_t lsPrintNext( uint8_t flags, uint8_t indent); int8_t lsPrintNext(uint8_t flags, uint8_t indent);
static bool make83Name(const char* str, uint8_t* name, const char** ptr); static bool make83Name(const char* str, uint8_t* name, const char** ptr);
bool mkdir(SdBaseFile* parent, const uint8_t dname[11]); bool mkdir(SdBaseFile* parent, const uint8_t dname[11]);
bool open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag); bool open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag);
bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags); bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags);
dir_t* readDirCache(); dir_t* readDirCache();
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// to be deleted // to be deleted
static void printDirName( const dir_t& dir, static void printDirName(const dir_t& dir,
uint8_t width, bool printSlash); uint8_t width, bool printSlash);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Deprecated functions - suppress cpplint warnings with NOLINT comment // Deprecated functions - suppress cpplint warnings with NOLINT comment
#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) #if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN)
public: public:
/** \deprecated Use: /** \deprecated Use:
@@ -375,16 +375,16 @@ class SdBaseFile {
bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT
return contiguousRange(&bgnBlock, &endBlock); return contiguousRange(&bgnBlock, &endBlock);
} }
/** \deprecated Use: /** \deprecated Use:
* bool createContiguous(SdBaseFile* dirFile, * bool createContiguous(SdBaseFile* dirFile,
* const char* path, uint32_t size) * const char* path, uint32_t size)
* \param[in] dirFile The directory where the file will be created. * \param[in] dirFile The directory where the file will be created.
* \param[in] path A path with a valid DOS 8.3 file name. * \param[in] path A path with a valid DOS 8.3 file name.
* \param[in] size The desired file size. * \param[in] size The desired file size.
* \return true for success or false for failure. * \return true for success or false for failure.
*/ */
bool createContiguous(SdBaseFile& dirFile, // NOLINT bool createContiguous(SdBaseFile& dirFile, // NOLINT
const char* path, uint32_t size) { const char* path, uint32_t size) {
return createContiguous(&dirFile, path, size); return createContiguous(&dirFile, path, size);
} }
/** \deprecated Use: /** \deprecated Use:
@@ -422,7 +422,7 @@ class SdBaseFile {
* \return true for success or false for failure. * \return true for success or false for failure.
*/ */
bool open(SdBaseFile& dirFile, // NOLINT bool open(SdBaseFile& dirFile, // NOLINT
const char* path, uint8_t oflag) { const char* path, uint8_t oflag) {
return open(&dirFile, path, oflag); return open(&dirFile, path, oflag);
} }
/** \deprecated Do not use in new apps /** \deprecated Do not use in new apps
@@ -465,8 +465,8 @@ class SdBaseFile {
static bool remove(SdBaseFile& dirFile, const char* path) { // NOLINT static bool remove(SdBaseFile& dirFile, const char* path) { // NOLINT
return remove(&dirFile, path); return remove(&dirFile, path);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// rest are private // rest are private
private: private:
static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT
static void oldToNew(uint16_t* date, uint16_t* time) { static void oldToNew(uint16_t* date, uint16_t* time) {

View File

@@ -25,100 +25,100 @@
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
#ifndef SdFatConfig_h #ifndef SdFatConfig_h
#define SdFatConfig_h #define SdFatConfig_h
#include <stdint.h> #include <stdint.h>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
* To use multiple SD cards set USE_MULTIPLE_CARDS nonzero. * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero.
* *
* Using multiple cards costs 400 - 500 bytes of flash. * Using multiple cards costs 400 - 500 bytes of flash.
* *
* Each card requires about 550 bytes of SRAM so use of a Mega is recommended. * Each card requires about 550 bytes of SRAM so use of a Mega is recommended.
*/ */
#define USE_MULTIPLE_CARDS 0 #define USE_MULTIPLE_CARDS 0
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
* Call flush for endl if ENDL_CALLS_FLUSH is nonzero * Call flush for endl if ENDL_CALLS_FLUSH is nonzero
* *
* The standard for iostreams is to call flush. This is very costly for * The standard for iostreams is to call flush. This is very costly for
* SdFat. Each call to flush causes 2048 bytes of I/O to the SD. * SdFat. Each call to flush causes 2048 bytes of I/O to the SD.
* *
* SdFat has a single 512 byte buffer for SD I/O so it must write the current * SdFat has a single 512 byte buffer for SD I/O so it must write the current
* data block to the SD, read the directory block from the SD, update the * data block to the SD, read the directory block from the SD, update the
* directory entry, write the directory block to the SD and read the data * directory entry, write the directory block to the SD and read the data
* block back into the buffer. * block back into the buffer.
* *
* The SD flash memory controller is not designed for this many rewrites * The SD flash memory controller is not designed for this many rewrites
* so performance may be reduced by more than a factor of 100. * so performance may be reduced by more than a factor of 100.
* *
* If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force
* all data to be written to the SD. * all data to be written to the SD.
*/ */
#define ENDL_CALLS_FLUSH 0 #define ENDL_CALLS_FLUSH 0
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
* Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero * Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero
*/ */
#define ALLOW_DEPRECATED_FUNCTIONS 1 #define ALLOW_DEPRECATED_FUNCTIONS 1
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
* Allow FAT12 volumes if FAT12_SUPPORT is nonzero. * Allow FAT12 volumes if FAT12_SUPPORT is nonzero.
* FAT12 has not been well tested. * FAT12 has not been well tested.
*/ */
#define FAT12_SUPPORT 0 #define FAT12_SUPPORT 0
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
* SPI init rate for SD initialization commands. Must be 5 (F_CPU/64) * SPI init rate for SD initialization commands. Must be 5 (F_CPU/64)
* or 6 (F_CPU/128). * or 6 (F_CPU/128).
*/ */
#define SPI_SD_INIT_RATE 5 #define SPI_SD_INIT_RATE 5
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
* Set the SS pin high for hardware SPI. If SS is chip select for another SPI * Set the SS pin high for hardware SPI. If SS is chip select for another SPI
* device this will disable that device during the SD init phase. * device this will disable that device during the SD init phase.
*/ */
#define SET_SPI_SS_HIGH 1 #define SET_SPI_SS_HIGH 1
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
* Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos. * Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos.
* Pins used are SS 10, MOSI 11, MISO 12, and SCK 13. * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13.
* *
* MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used
* on Mega Arduinos. Software SPI works well with GPS Shield V1.1 * on Mega Arduinos. Software SPI works well with GPS Shield V1.1
* but many SD cards will fail with GPS Shield V1.0. * but many SD cards will fail with GPS Shield V1.0.
*/ */
#define MEGA_SOFT_SPI 0 #define MEGA_SOFT_SPI 0
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
* Set USE_SOFTWARE_SPI nonzero to always use software SPI. * Set USE_SOFTWARE_SPI nonzero to always use software SPI.
*/ */
#define USE_SOFTWARE_SPI 0 #define USE_SOFTWARE_SPI 0
// define software SPI pins so Mega can use unmodified 168/328 shields // define software SPI pins so Mega can use unmodified 168/328 shields
/** Software SPI chip select pin for the SD */ /** Software SPI chip select pin for the SD */
uint8_t const SOFT_SPI_CS_PIN = 10; uint8_t const SOFT_SPI_CS_PIN = 10;
/** Software SPI Master Out Slave In pin */ /** Software SPI Master Out Slave In pin */
uint8_t const SOFT_SPI_MOSI_PIN = 11; uint8_t const SOFT_SPI_MOSI_PIN = 11;
/** Software SPI Master In Slave Out pin */ /** Software SPI Master In Slave Out pin */
uint8_t const SOFT_SPI_MISO_PIN = 12; uint8_t const SOFT_SPI_MISO_PIN = 12;
/** Software SPI Clock pin */ /** Software SPI Clock pin */
uint8_t const SOFT_SPI_SCK_PIN = 13; uint8_t const SOFT_SPI_SCK_PIN = 13;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
* The __cxa_pure_virtual function is an error handler that is invoked when * The __cxa_pure_virtual function is an error handler that is invoked when
* a pure virtual function is called. * a pure virtual function is called.
*/ */
#define USE_CXA_PURE_VIRTUAL 1 #define USE_CXA_PURE_VIRTUAL 1
/** Number of UTF-16 characters per entry */ /** Number of UTF-16 characters per entry */
#define FILENAME_LENGTH 13 #define FILENAME_LENGTH 13
/** /**
* Defines for long (vfat) filenames * Defines for long (vfat) filenames
*/ */
/** Number of VFAT entries used. Every entry has 13 UTF-16 characters */ /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */
#define MAX_VFAT_ENTRIES (2) #define MAX_VFAT_ENTRIES (2)
/** Total size of the buffer used to store the long filenames */ /** Total size of the buffer used to store the long filenames */
#define LONG_FILENAME_LENGTH (FILENAME_LENGTH*MAX_VFAT_ENTRIES+1) #define LONG_FILENAME_LENGTH (FILENAME_LENGTH*MAX_VFAT_ENTRIES+1)
#endif // SdFatConfig_h #endif // SdFatConfig_h

View File

@@ -55,9 +55,9 @@ struct partitionTable {
*/ */
uint8_t boot; uint8_t boot;
/** /**
* Head part of Cylinder-head-sector address of the first block in * Head part of Cylinder-head-sector address of the first block in
* the partition. Legal values are 0-255. Only used in old PC BIOS. * the partition. Legal values are 0-255. Only used in old PC BIOS.
*/ */
uint8_t beginHead; uint8_t beginHead;
/** /**
* Sector part of Cylinder-head-sector address of the first block in * Sector part of Cylinder-head-sector address of the first block in
@@ -337,10 +337,10 @@ struct fat32_boot {
* Bits 0-3 -- Zero-based number of active FAT. * Bits 0-3 -- Zero-based number of active FAT.
* Only valid if mirroring is disabled. * Only valid if mirroring is disabled.
* Bits 4-6 -- Reserved. * Bits 4-6 -- Reserved.
* Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. * Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs.
* -- 1 means only one FAT is active; it is the one referenced * -- 1 means only one FAT is active; it is the one referenced
* in bits 0-3. * in bits 0-3.
* Bits 8-15 -- Reserved. * Bits 8-15 -- Reserved.
*/ */
uint16_t fat32Flags; uint16_t fat32Flags;
/** /**

View File

@@ -33,7 +33,7 @@ int SdFatUtil::FreeRam() {
return &top - reinterpret_cast<char*>(sbrk(0)); return &top - reinterpret_cast<char*>(sbrk(0));
} }
#else // __arm__ #else // __arm__
extern char *__brkval; extern char* __brkval;
extern char __bss_end; extern char __bss_end;
/** Amount of free RAM /** Amount of free RAM
* \return The number of free bytes. * \return The number of free bytes.
@@ -50,7 +50,7 @@ int SdFatUtil::FreeRam() {
* \param[in] pr Print object for output. * \param[in] pr Print object for output.
* \param[in] str Pointer to string stored in flash memory. * \param[in] str Pointer to string stored in flash memory.
*/ */
void SdFatUtil::print_P( PGM_P str) { void SdFatUtil::print_P(PGM_P str) {
for (uint8_t c; (c = pgm_read_byte(str)); str++) MYSERIAL.write(c); for (uint8_t c; (c = pgm_read_byte(str)); str++) MYSERIAL.write(c);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -59,8 +59,8 @@ void SdFatUtil::print_P( PGM_P str) {
* \param[in] pr Print object for output. * \param[in] pr Print object for output.
* \param[in] str Pointer to string stored in flash memory. * \param[in] str Pointer to string stored in flash memory.
*/ */
void SdFatUtil::println_P( PGM_P str) { void SdFatUtil::println_P(PGM_P str) {
print_P( str); print_P(str);
MYSERIAL.println(); MYSERIAL.println();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -77,6 +77,6 @@ void SdFatUtil::SerialPrint_P(PGM_P str) {
* \param[in] str Pointer to string stored in flash memory. * \param[in] str Pointer to string stored in flash memory.
*/ */
void SdFatUtil::SerialPrintln_P(PGM_P str) { void SdFatUtil::SerialPrintln_P(PGM_P str) {
println_P( str); println_P(str);
} }
#endif #endif

View File

@@ -35,8 +35,8 @@
namespace SdFatUtil { namespace SdFatUtil {
int FreeRam(); int FreeRam();
void print_P( PGM_P str); void print_P(PGM_P str);
void println_P( PGM_P str); void println_P(PGM_P str);
void SerialPrint_P(PGM_P str); void SerialPrint_P(PGM_P str);
void SerialPrintln_P(PGM_P str); void SerialPrintln_P(PGM_P str);
} }

View File

@@ -55,15 +55,13 @@ int16_t SdFile::write(const void* buf, uint16_t nbyte) {
* Use writeError to check for errors. * Use writeError to check for errors.
*/ */
#if ARDUINO >= 100 #if ARDUINO >= 100
size_t SdFile::write(uint8_t b) size_t SdFile::write(uint8_t b) {
{
return SdBaseFile::write(&b, 1); return SdBaseFile::write(&b, 1);
} }
#else #else
void SdFile::write(uint8_t b) void SdFile::write(uint8_t b) {
{
SdBaseFile::write(&b, 1); SdBaseFile::write(&b, 1);
} }
#endif #endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Write a string to a file. Used by the Arduino Print class. /** Write a string to a file. Used by the Arduino Print class.

View File

@@ -38,7 +38,7 @@ class SdFile : public SdBaseFile, public Print {
SdFile() {} SdFile() {}
SdFile(const char* name, uint8_t oflag); SdFile(const char* name, uint8_t oflag);
#if ARDUINO >= 100 #if ARDUINO >= 100
size_t write(uint8_t b); size_t write(uint8_t b);
#else #else
void write(uint8_t b); void write(uint8_t b);
#endif #endif

View File

@@ -118,13 +118,13 @@ typedef struct CID {
/** Manufacturing date month */ /** Manufacturing date month */
unsigned char mdt_month : 4; unsigned char mdt_month : 4;
/** Manufacturing date year low digit */ /** Manufacturing date year low digit */
unsigned char mdt_year_low :4; unsigned char mdt_year_low : 4;
// byte 15 // byte 15
/** not used always 1 */ /** not used always 1 */
unsigned char always1 : 1; unsigned char always1 : 1;
/** CRC7 checksum */ /** CRC7 checksum */
unsigned char crc : 7; unsigned char crc : 7;
}cid_t; } cid_t;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** CSD for version 1.00 cards */ /** CSD for version 1.00 cards */
typedef struct CSDV1 { typedef struct CSDV1 {
@@ -146,7 +146,7 @@ typedef struct CSDV1 {
unsigned char c_size_high : 2; unsigned char c_size_high : 2;
unsigned char reserved2 : 2; unsigned char reserved2 : 2;
unsigned char dsr_imp : 1; unsigned char dsr_imp : 1;
unsigned char read_blk_misalign :1; unsigned char read_blk_misalign : 1;
unsigned char write_blk_misalign : 1; unsigned char write_blk_misalign : 1;
unsigned char read_bl_partial : 1; unsigned char read_bl_partial : 1;
// byte 7 // byte 7
@@ -154,7 +154,7 @@ typedef struct CSDV1 {
// byte 8 // byte 8
unsigned char vdd_r_curr_max : 3; unsigned char vdd_r_curr_max : 3;
unsigned char vdd_r_curr_min : 3; unsigned char vdd_r_curr_min : 3;
unsigned char c_size_low :2; unsigned char c_size_low : 2;
// byte 9 // byte 9
unsigned char c_size_mult_high : 2; unsigned char c_size_mult_high : 2;
unsigned char vdd_w_cur_max : 3; unsigned char vdd_w_cur_max : 3;
@@ -186,7 +186,7 @@ typedef struct CSDV1 {
// byte 15 // byte 15
unsigned char always1 : 1; unsigned char always1 : 1;
unsigned char crc : 7; unsigned char crc : 7;
}csd1_t; } csd1_t;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** CSD for version 2.00 cards */ /** CSD for version 2.00 cards */
typedef struct CSDV2 { typedef struct CSDV2 {
@@ -212,7 +212,7 @@ typedef struct CSDV2 {
unsigned char reserved2 : 4; unsigned char reserved2 : 4;
unsigned char dsr_imp : 1; unsigned char dsr_imp : 1;
/** fixed to 0 */ /** fixed to 0 */
unsigned char read_blk_misalign :1; unsigned char read_blk_misalign : 1;
/** fixed to 0 */ /** fixed to 0 */
unsigned char write_blk_misalign : 1; unsigned char write_blk_misalign : 1;
/** fixed to 0 - no partial read */ /** fixed to 0 - no partial read */
@@ -268,7 +268,7 @@ typedef struct CSDV2 {
unsigned char always1 : 1; unsigned char always1 : 1;
/** checksum */ /** checksum */
unsigned char crc : 7; unsigned char crc : 7;
}csd2_t; } csd2_t;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** union of old and new style CSD register */ /** union of old and new style CSD register */
union csd_t { union csd_t {

View File

@@ -23,12 +23,12 @@
#include "SdVolume.h" #include "SdVolume.h"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if !USE_MULTIPLE_CARDS #if !USE_MULTIPLE_CARDS
// raw block cache // raw block cache
uint32_t SdVolume::cacheBlockNumber_; // current block number uint32_t SdVolume::cacheBlockNumber_; // current block number
cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card
Sd2Card* SdVolume::sdCard_; // pointer to SD card object Sd2Card* SdVolume::sdCard_; // pointer to SD card object
bool SdVolume::cacheDirty_; // cacheFlush() will write block if true bool SdVolume::cacheDirty_; // cacheFlush() will write block if true
uint32_t SdVolume::cacheMirrorBlock_; // mirror block for second FAT uint32_t SdVolume::cacheMirrorBlock_; // mirror block for second FAT
#endif // USE_MULTIPLE_CARDS #endif // USE_MULTIPLE_CARDS
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// find a contiguous group of clusters // find a contiguous group of clusters
@@ -50,7 +50,8 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
// don't save new start location // don't save new start location
setStart = false; setStart = false;
} else { }
else {
// start at likely place for free cluster // start at likely place for free cluster
bgnCluster = allocSearchStart_; bgnCluster = allocSearchStart_;
@@ -75,7 +76,8 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
if (f != 0) { if (f != 0) {
// cluster in use try next cluster as bgnCluster // cluster in use try next cluster as bgnCluster
bgnCluster = endCluster + 1; bgnCluster = endCluster + 1;
} else if ((endCluster - bgnCluster + 1) == count) { }
else if ((endCluster - bgnCluster + 1) == count) {
// done - found space // done - found space
break; break;
} }
@@ -99,8 +101,7 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
if (setStart) allocSearchStart_ = bgnCluster + 1; if (setStart) allocSearchStart_ = bgnCluster + 1;
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -119,8 +120,7 @@ bool SdVolume::cacheFlush() {
cacheDirty_ = 0; cacheDirty_ = 0;
} }
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -132,8 +132,7 @@ bool SdVolume::cacheRawBlock(uint32_t blockNumber, bool dirty) {
} }
if (dirty) cacheDirty_ = true; if (dirty) cacheDirty_ = true;
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -146,8 +145,7 @@ bool SdVolume::chainSize(uint32_t cluster, uint32_t* size) {
} while (!isEOC(cluster)); } while (!isEOC(cluster));
*size = s; *size = s;
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -173,9 +171,11 @@ bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) {
} }
if (fatType_ == 16) { if (fatType_ == 16) {
lba = fatStartBlock_ + (cluster >> 8); lba = fatStartBlock_ + (cluster >> 8);
} else if (fatType_ == 32) { }
else if (fatType_ == 32) {
lba = fatStartBlock_ + (cluster >> 7); lba = fatStartBlock_ + (cluster >> 7);
} else { }
else {
goto fail; goto fail;
} }
if (lba != cacheBlockNumber_) { if (lba != cacheBlockNumber_) {
@@ -183,12 +183,12 @@ bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) {
} }
if (fatType_ == 16) { if (fatType_ == 16) {
*value = cacheBuffer_.fat16[cluster & 0XFF]; *value = cacheBuffer_.fat16[cluster & 0XFF];
} else { }
else {
*value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK; *value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK;
} }
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -231,23 +231,25 @@ bool SdVolume::fatPut(uint32_t cluster, uint32_t value) {
} }
if (fatType_ == 16) { if (fatType_ == 16) {
lba = fatStartBlock_ + (cluster >> 8); lba = fatStartBlock_ + (cluster >> 8);
} else if (fatType_ == 32) { }
else if (fatType_ == 32) {
lba = fatStartBlock_ + (cluster >> 7); lba = fatStartBlock_ + (cluster >> 7);
} else { }
else {
goto fail; goto fail;
} }
if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail; if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail;
// store entry // store entry
if (fatType_ == 16) { if (fatType_ == 16) {
cacheBuffer_.fat16[cluster & 0XFF] = value; cacheBuffer_.fat16[cluster & 0XFF] = value;
} else { }
else {
cacheBuffer_.fat32[cluster & 0X7F] = value; cacheBuffer_.fat32[cluster & 0X7F] = value;
} }
// mirror second FAT // mirror second FAT
if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_; if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -268,8 +270,7 @@ bool SdVolume::freeChain(uint32_t cluster) {
} while (!isEOC(cluster)); } while (!isEOC(cluster));
return true; return true;
fail:
fail:
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -284,9 +285,11 @@ int32_t SdVolume::freeClusterCount() {
if (fatType_ == 16) { if (fatType_ == 16) {
n = 256; n = 256;
} else if (fatType_ == 32) { }
else if (fatType_ == 32) {
n = 128; n = 128;
} else { }
else {
// put FAT12 here // put FAT12 here
return -1; return -1;
} }
@@ -298,7 +301,8 @@ int32_t SdVolume::freeClusterCount() {
for (uint16_t i = 0; i < n; i++) { for (uint16_t i = 0; i < n; i++) {
if (cacheBuffer_.fat16[i] == 0) free++; if (cacheBuffer_.fat16[i] == 0) free++;
} }
} else { }
else {
for (uint16_t i = 0; i < n; i++) { for (uint16_t i = 0; i < n; i++) {
if (cacheBuffer_.fat32[i] == 0) free++; if (cacheBuffer_.fat32[i] == 0) free++;
} }
@@ -338,10 +342,10 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
if (part) { if (part) {
if (part > 4)goto fail; if (part > 4)goto fail;
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail; if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail;
part_t* p = &cacheBuffer_.mbr.part[part-1]; part_t* p = &cacheBuffer_.mbr.part[part - 1];
if ((p->boot & 0X7F) !=0 || if ((p->boot & 0X7F) != 0 ||
p->totalSectors < 100 || p->totalSectors < 100 ||
p->firstSector == 0) { p->firstSector == 0) {
// not a valid partition // not a valid partition
goto fail; goto fail;
} }
@@ -350,11 +354,11 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail; if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail;
fbs = &cacheBuffer_.fbs32; fbs = &cacheBuffer_.fbs32;
if (fbs->bytesPerSector != 512 || if (fbs->bytesPerSector != 512 ||
fbs->fatCount == 0 || fbs->fatCount == 0 ||
fbs->reservedSectorCount == 0 || fbs->reservedSectorCount == 0 ||
fbs->sectorsPerCluster == 0) { fbs->sectorsPerCluster == 0) {
// not valid FAT volume // not valid FAT volume
goto fail; goto fail;
} }
fatCount_ = fbs->fatCount; fatCount_ = fbs->fatCount;
blocksPerCluster_ = fbs->sectorsPerCluster; blocksPerCluster_ = fbs->sectorsPerCluster;
@@ -365,7 +369,7 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
if (clusterSizeShift_++ > 7) goto fail; if (clusterSizeShift_++ > 7) goto fail;
} }
blocksPerFat_ = fbs->sectorsPerFat16 ? blocksPerFat_ = fbs->sectorsPerFat16 ?
fbs->sectorsPerFat16 : fbs->sectorsPerFat32; fbs->sectorsPerFat16 : fbs->sectorsPerFat32;
fatStartBlock_ = volumeStartBlock + fbs->reservedSectorCount; fatStartBlock_ = volumeStartBlock + fbs->reservedSectorCount;
@@ -376,11 +380,12 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
rootDirStart_ = fatStartBlock_ + fbs->fatCount * blocksPerFat_; rootDirStart_ = fatStartBlock_ + fbs->fatCount * blocksPerFat_;
// data start for FAT16 and FAT32 // data start for FAT16 and FAT32
dataStartBlock_ = rootDirStart_ + ((32 * fbs->rootDirEntryCount + 511)/512); dataStartBlock_ = rootDirStart_ + ((32 * fbs->rootDirEntryCount + 511) / 512);
// total blocks for FAT16 or FAT32 // total blocks for FAT16 or FAT32
totalBlocks = fbs->totalSectors16 ? totalBlocks = fbs->totalSectors16 ?
fbs->totalSectors16 : fbs->totalSectors32; fbs->totalSectors16 : fbs->totalSectors32;
// total data blocks // total data blocks
clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock); clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock);
@@ -391,15 +396,16 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
if (clusterCount_ < 4085) { if (clusterCount_ < 4085) {
fatType_ = 12; fatType_ = 12;
if (!FAT12_SUPPORT) goto fail; if (!FAT12_SUPPORT) goto fail;
} else if (clusterCount_ < 65525) { }
else if (clusterCount_ < 65525) {
fatType_ = 16; fatType_ = 16;
} else { }
else {
rootDirStart_ = fbs->fat32RootCluster; rootDirStart_ = fbs->fat32RootCluster;
fatType_ = 32; fatType_ = 32;
} }
return true; return true;
fail:
fail:
return false; return false;
} }
#endif #endif

View File

@@ -117,7 +117,7 @@ class SdVolume {
* \return true for success or false for failure * \return true for success or false for failure
*/ */
bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);} bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
// Allow SdBaseFile access to SdVolume private data. // Allow SdBaseFile access to SdVolume private data.
friend class SdBaseFile; friend class SdBaseFile;
@@ -154,12 +154,15 @@ class SdVolume {
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool allocContiguous(uint32_t count, uint32_t* curCluster); bool allocContiguous(uint32_t count, uint32_t* curCluster);
uint8_t blockOfCluster(uint32_t position) const { uint8_t blockOfCluster(uint32_t position) const {
return (position >> 9) & (blocksPerCluster_ - 1);} return (position >> 9) & (blocksPerCluster_ - 1);
}
uint32_t clusterStartBlock(uint32_t cluster) const { uint32_t clusterStartBlock(uint32_t cluster) const {
return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);} return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);
}
uint32_t blockNumber(uint32_t cluster, uint32_t position) const { uint32_t blockNumber(uint32_t cluster, uint32_t position) const {
return clusterStartBlock(cluster) + blockOfCluster(position);} return clusterStartBlock(cluster) + blockOfCluster(position);
cache_t *cache() {return &cacheBuffer_;} }
cache_t* cache() {return &cacheBuffer_;}
uint32_t cacheBlockNumber() {return cacheBlockNumber_;} uint32_t cacheBlockNumber() {return cacheBlockNumber_;}
#if USE_MULTIPLE_CARDS #if USE_MULTIPLE_CARDS
bool cacheFlush(); bool cacheFlush();
@@ -187,11 +190,12 @@ class SdVolume {
return cluster >= FAT32EOC_MIN; return cluster >= FAT32EOC_MIN;
} }
bool readBlock(uint32_t block, uint8_t* dst) { bool readBlock(uint32_t block, uint8_t* dst) {
return sdCard_->readBlock(block, dst);} return sdCard_->readBlock(block, dst);
}
bool writeBlock(uint32_t block, const uint8_t* dst) { bool writeBlock(uint32_t block, const uint8_t* dst) {
return sdCard_->writeBlock(block, dst); return sdCard_->writeBlock(block, dst);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Deprecated functions - suppress cpplint warnings with NOLINT comment // Deprecated functions - suppress cpplint warnings with NOLINT comment
#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN) #if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN)
public: public: