Added Move constructor and bug fixes.
This commit is contained in:
parent
57900b21d2
commit
aadedbf206
38 changed files with 500 additions and 175 deletions
13
README.md
13
README.md
|
|
@ -1,13 +1,8 @@
|
|||
### Warning: Major Reformat of Source in 2.2.2
|
||||
File copy constructors and file assignment operators have been made private by
|
||||
default in 2.2.3 to prevent call by value and multiple copies of file instances.
|
||||
|
||||
There are a huge number of changes in 2.2.2 since I decided to use clang-format
|
||||
to force Google style formatting.
|
||||
|
||||
I did this to avoid warnings from the static analysis programs Cppcheck and
|
||||
cpplint.
|
||||
|
||||
clang-format is aggressive so it may actually cause code to fail. For example
|
||||
clang-format rearranges the order of includes according to the selected style.
|
||||
SdFatConfig.h has options to make file constructors and assignment operators
|
||||
public.
|
||||
|
||||
UTF-8 encoded filenames are supported in v2.1.0 or later.
|
||||
|
||||
|
|
|
|||
BIN
doc/html.zip
BIN
doc/html.zip
Binary file not shown.
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||
#define SD_FAT_TYPE 0
|
||||
#define SD_FAT_TYPE 3
|
||||
/*
|
||||
Change the value of SD_CS_PIN if you are using SPI and
|
||||
your hardware does not use the default value, SS.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||
#define SD_FAT_TYPE 0
|
||||
#define SD_FAT_TYPE 3
|
||||
/*
|
||||
Change the value of SD_CS_PIN if you are using SPI and
|
||||
your hardware does not use the default value, SS.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||
#define SD_FAT_TYPE 0
|
||||
#define SD_FAT_TYPE 3
|
||||
/*
|
||||
Change the value of SD_CS_PIN if you are using SPI and
|
||||
your hardware does not use the default value, SS.
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ void loop() {
|
|||
}
|
||||
cout << F("\nCard successfully initialized.\n");
|
||||
if (sd.vol()->fatType() == 0) {
|
||||
cout << F("Can't find a valid FAT16/FAT32 partition.\n");
|
||||
cout << F("Can't find a valid FAT16/FAT32/exFAT partition.\n");
|
||||
reformatMsg();
|
||||
return;
|
||||
}
|
||||
|
|
@ -163,7 +163,11 @@ void loop() {
|
|||
cout << F("Card size: ") << sizeMB;
|
||||
cout << F(" MB (MB = 1,000,000 bytes)\n");
|
||||
cout << endl;
|
||||
cout << F("Volume is FAT") << int(sd.vol()->fatType());
|
||||
if (sd.fatType() <= 32) {
|
||||
cout << F("\nVolume is FAT") << int(sd.fatType());
|
||||
} else {
|
||||
cout << F("\nVolume is exFAT");
|
||||
}
|
||||
cout << F(", Cluster size (bytes): ") << sd.vol()->bytesPerCluster();
|
||||
cout << endl << endl;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||
#define SD_FAT_TYPE 0
|
||||
#define SD_FAT_TYPE 3
|
||||
/*
|
||||
Change the value of SD_CS_PIN if you are using SPI and
|
||||
your hardware does not use the default value, SS.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||
#define SD_FAT_TYPE 0
|
||||
#define SD_FAT_TYPE 3
|
||||
/*
|
||||
Change the value of SD_CS_PIN if you are using SPI and
|
||||
your hardware does not use the default value, SS.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
/*
|
||||
* This program attempts to initialize an SD card and analyze its structure.
|
||||
* The CID and CSD registers are also printed in HEX for use in online
|
||||
* decoders like these.
|
||||
*
|
||||
* https://gurumeditation.org/1342/sd-memory-card-register-decoder/
|
||||
* https://archive.goughlui.com/static/multicid.htm
|
||||
*/
|
||||
#include "SdFat.h"
|
||||
#include "sdios.h"
|
||||
|
|
@ -55,7 +60,8 @@ void cidDmp() {
|
|||
cout << F("Serial number: ") << hex << cid.psn() << dec << endl;
|
||||
cout << F("Manufacturing date: ");
|
||||
cout << cid.mdtMonth() << '/' << cid.mdtYear() << endl;
|
||||
cout << endl;
|
||||
cout << F("CID HEX: ");
|
||||
hexDmp(&cid, sizeof(cid));
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void clearSerialInput() {
|
||||
|
|
@ -69,7 +75,7 @@ void clearSerialInput() {
|
|||
//------------------------------------------------------------------------------
|
||||
void csdDmp() {
|
||||
eraseSize = csd.eraseSize();
|
||||
cout << F("cardSize: ") << 0.000512 * csd.capacity();
|
||||
cout << F("\ncardSize: ") << 0.000512 * csd.capacity();
|
||||
cout << F(" MB (MB = 1,000,000 bytes)\n");
|
||||
|
||||
cout << F("flashEraseSize: ") << int(eraseSize) << F(" blocks\n");
|
||||
|
|
@ -85,6 +91,8 @@ void csdDmp() {
|
|||
} else {
|
||||
cout << F("zeros\n");
|
||||
}
|
||||
cout << F("CSD HEX: ");
|
||||
hexDmp(&csd, sizeof(csd));
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void errorPrint() {
|
||||
|
|
@ -96,10 +104,19 @@ void errorPrint() {
|
|||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void hexDmp(void* reg, uint8_t size) {
|
||||
uint8_t* u8 = reinterpret_cast<uint8_t*>(reg);
|
||||
cout << hex << noshowbase;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
cout << setw(2) << setfill('0') << int(u8[i]);
|
||||
}
|
||||
cout << dec << endl;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool mbrDmp() {
|
||||
MbrSector_t mbr;
|
||||
bool valid = true;
|
||||
if (!sd.card()->readSector(0, (uint8_t *)&mbr)) {
|
||||
if (!sd.card()->readSector(0, (uint8_t*)&mbr)) {
|
||||
cout << F("\nread MBR failed.\n");
|
||||
errorPrint();
|
||||
return false;
|
||||
|
|
@ -107,7 +124,7 @@ bool mbrDmp() {
|
|||
cout << F("\nSD Partition Table\n");
|
||||
cout << F("part,boot,bgnCHS[3],type,endCHS[3],start,length\n");
|
||||
for (uint8_t ip = 1; ip < 5; ip++) {
|
||||
MbrPart_t *pt = &mbr.part[ip - 1];
|
||||
MbrPart_t* pt = &mbr.part[ip - 1];
|
||||
if ((pt->boot != 0 && pt->boot != 0X80) ||
|
||||
getLe32(pt->relativeSectors) > csd.capacity()) {
|
||||
valid = false;
|
||||
|
|
@ -242,7 +259,7 @@ void loop() {
|
|||
printCardType();
|
||||
cout << F("sdSpecVer: ") << 0.01 * scr.sdSpecVer() << endl;
|
||||
cout << F("HighSpeedMode: ");
|
||||
if (scr.sdSpecVer() && sd.card()->cardCMD6(0X00FFFFFF, cmd6Data) &&
|
||||
if (scr.sdSpecVer() > 101 && sd.card()->cardCMD6(0X00FFFFFF, cmd6Data) &&
|
||||
(2 & cmd6Data[13])) {
|
||||
cout << F("true\n");
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||
#define SD_FAT_TYPE 0
|
||||
#define SD_FAT_TYPE 3
|
||||
//
|
||||
// Chip select may be constant or RAM variable.
|
||||
const uint8_t SD_CS_PIN = 10;
|
||||
|
|
|
|||
66
examples/SpiLoopBackTest/SpiLoopBackTest.ino
Normal file
66
examples/SpiLoopBackTest/SpiLoopBackTest.ino
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
// This is a simple SPI loop-back test.
|
||||
//
|
||||
// Connect SD_MISO to SD_MOSI
|
||||
//
|
||||
// Modify these defines for your configuration.
|
||||
#define SD_SPI SPI
|
||||
#define SD_MISO MISO
|
||||
#define SD_MOSI MOSI
|
||||
|
||||
#include "SPI.h"
|
||||
void setup() {
|
||||
uint8_t rx, tx;
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
yield();
|
||||
}
|
||||
Serial.println(F("\nType any character to start"));
|
||||
while (!Serial.available()) {
|
||||
yield();
|
||||
}
|
||||
Serial.print("Begin, SD_MISO: ");
|
||||
Serial.print(SD_MISO), Serial.print(", SD_MOSI: ");
|
||||
Serial.println(SD_MOSI);
|
||||
pinMode(SD_MISO, INPUT_PULLUP);
|
||||
pinMode(SD_MOSI, OUTPUT);
|
||||
digitalWrite(SD_MOSI, HIGH);
|
||||
if (!digitalRead(SD_MISO)) {
|
||||
Serial.println("Error: SD_MISO not HIGH");
|
||||
goto fail;
|
||||
}
|
||||
digitalWrite(SD_MOSI, LOW);
|
||||
if (digitalRead(SD_MISO)) {
|
||||
Serial.println("Error: SD_MISO not LOW");
|
||||
goto fail;
|
||||
}
|
||||
pinMode(SD_MISO, INPUT);
|
||||
pinMode(SD_MOSI, INPUT);
|
||||
|
||||
// Modify if SD_SPI.begin has arguments and use this style SdFat begin call:
|
||||
// sd.begin(SdSpiConfig(CS_PIN, USER_SPI_BEGIN | <other options>, &SD_SPI));
|
||||
SD_SPI.begin();
|
||||
|
||||
// Start with a 400 kHz clock. Try full speed if success for 400 kHz.
|
||||
SD_SPI.beginTransaction(SPISettings(400000, MSBFIRST, SPI_MODE0));
|
||||
tx = 0;
|
||||
do {
|
||||
rx = SD_SPI.transfer(tx);
|
||||
if (tx != rx) {
|
||||
Serial.print("Error rx: 0x");
|
||||
Serial.print(rx, HEX);
|
||||
Serial.print(" != tx: 0x");
|
||||
Serial.println(tx, HEX);
|
||||
SD_SPI.endTransaction();
|
||||
goto fail;
|
||||
}
|
||||
} while (tx++ < 255);
|
||||
SD_SPI.endTransaction();
|
||||
Serial.println("Success!");
|
||||
return;
|
||||
|
||||
fail:
|
||||
SD_SPI.endTransaction();
|
||||
Serial.println("Is SD_MISO connected to SD_MOSI?");
|
||||
Serial.println("Are SD_MISO and SD_MOSI correct?");
|
||||
}
|
||||
void loop() {}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
/*
|
||||
* This program is a simple binary write/read benchmark.
|
||||
*/
|
||||
#include "FreeStack.h"
|
||||
#include "SdFat.h"
|
||||
#include "FreeStack.h"
|
||||
#include "sdios.h"
|
||||
|
||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||
#define SD_FAT_TYPE 0
|
||||
#define SD_FAT_TYPE 3
|
||||
/*
|
||||
Change the value of SD_CS_PIN if you are using SPI and
|
||||
your hardware does not use the default value, SS.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||
#define SD_FAT_TYPE 0
|
||||
#define SD_FAT_TYPE 3
|
||||
|
||||
/*
|
||||
Change the value of SD_CS_PIN if you are using SPI and
|
||||
|
|
|
|||
11
extras/fmt_src.bat
Normal file
11
extras/fmt_src.bat
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
clang-format --style=Google -i *.cpp *.h
|
||||
rem clang-format --style=Google -i DigitalIO/*.h
|
||||
rem clang-format --style=Google -i DigitalIO/boards/*.h
|
||||
clang-format --style=Google -i common/*.cpp common/*.h
|
||||
clang-format --style=Google -i ExFatLib/*.cpp ExFatLib/*.h
|
||||
clang-format --style=Google -i FatLib/*.cpp FatLib/*.h
|
||||
clang-format --style=Google -i FsLib/*.cpp FsLib/*.h
|
||||
clang-format --style=Google -i iostream/*.cpp iostream/*.h
|
||||
clang-format --style=Google -i SdCard/*.cpp SdCard/*.h
|
||||
clang-format --style=Google -i SpiDriver/*.cpp SpiDriver/*.h
|
||||
pause
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
name=SdFat
|
||||
version=2.2.2
|
||||
version=2.2.3
|
||||
license=MIT
|
||||
author=Bill Greiman <fat16lib@sbcglobal.net>
|
||||
maintainer=Bill Greiman <fat16lib@sbcglobal.net>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -223,7 +223,8 @@ bool ExFatFile::open(ExFatFile* dirFile, const char* path, oflag_t oflag) {
|
|||
DBG_WARN_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
tmpDir = *this;
|
||||
// tmpDir = *this;
|
||||
tmpDir.copy(this);
|
||||
dirFile = &tmpDir;
|
||||
close();
|
||||
}
|
||||
|
|
@ -254,7 +255,8 @@ bool ExFatFile::openCwd() {
|
|||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
*this = *ExFatVolume::cwv()->vwd();
|
||||
// *this = *ExFatVolume::cwv()->vwd();
|
||||
this->copy(ExFatVolume::cwv()->vwd());
|
||||
rewind();
|
||||
return true;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -71,12 +71,78 @@ class ExFatFile {
|
|||
*/
|
||||
ExFatFile(const char* path, oflag_t oflag) { open(path, oflag); }
|
||||
|
||||
/** Copy from to this.
|
||||
* \param[in] from Source file.
|
||||
*/
|
||||
void copy(const ExFatFile* from) {
|
||||
if (from != this) {
|
||||
#if FILE_COPY_CONSTRUCTOR_SELECT
|
||||
*this = *from;
|
||||
#else // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
memcpy(this, from, sizeof(ExFatFile));
|
||||
#endif // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
}
|
||||
}
|
||||
/** move from to this.
|
||||
* \param[in] from Source file.
|
||||
*/
|
||||
void move(ExFatFile* from) {
|
||||
if (from != this) {
|
||||
copy(from);
|
||||
from->m_attributes = FILE_ATTR_CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
#if FILE_COPY_CONSTRUCTOR_SELECT == FILE_COPY_CONSTRUCTOR_PUBLIC
|
||||
/** Copy constructor.
|
||||
* \param[in] from Move from file.
|
||||
*
|
||||
*/
|
||||
ExFatFile(const ExFatFile& from) = default;
|
||||
/** Copy assignment operator.
|
||||
* \param[in] from Move from file.
|
||||
* \return Copied file.
|
||||
*/
|
||||
ExFatFile& operator=(const ExFatFile& from) = default;
|
||||
#elif FILE_COPY_CONSTRUCTOR_SELECT == FILE_COPY_CONSTRUCTOR_PRIVATE
|
||||
|
||||
private:
|
||||
ExFatFile(const ExFatFile& from) = default;
|
||||
ExFatFile& operator=(const ExFatFile& from) = default;
|
||||
|
||||
public:
|
||||
#else // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
ExFatFile(const ExFatFile& from) = delete;
|
||||
ExFatFile& operator=(const ExFatFile& from) = delete;
|
||||
#endif // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
|
||||
#if FILE_MOVE_CONSTRUCTOR_SELECT
|
||||
/** Move constructor.
|
||||
* \param[in] from Move from file.
|
||||
*/
|
||||
ExFatFile(ExFatFile&& from) { move(&from); }
|
||||
/** Move assignment operator.
|
||||
* \param[in] from Move from file.
|
||||
* \return Moved file.
|
||||
*/
|
||||
ExFatFile& operator=(ExFatFile&& from) {
|
||||
move(&from);
|
||||
return *this;
|
||||
}
|
||||
#else // FILE_MOVE_CONSTRUCTOR_SELECT
|
||||
ExFatFile(ExFatFile&& from) = delete;
|
||||
ExFatFile& operator=(ExFatFile&& from) = delete;
|
||||
#endif
|
||||
|
||||
/** Destructor */
|
||||
#if DESTRUCTOR_CLOSES_FILE
|
||||
~ExFatFile() {
|
||||
if (isOpen()) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
#else // DESTRUCTOR_CLOSES_FILE
|
||||
~ExFatFile() = default;
|
||||
#endif // DESTRUCTOR_CLOSES_FILE
|
||||
|
||||
/** The parenthesis operator.
|
||||
|
|
@ -223,7 +289,7 @@ class ExFatFile {
|
|||
*
|
||||
* \param[out] name An array of characters for the file's name.
|
||||
* \param[in] size The size of the array in characters.
|
||||
* \return the name length.
|
||||
* \return length for success or zero for failure.
|
||||
*/
|
||||
size_t getName(char* name, size_t size) {
|
||||
#if USE_UTF8_LONG_NAMES
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -179,7 +179,8 @@ bool ExFatFile::mkdir(ExFatFile* parent, const char* path, bool pFlag) {
|
|||
goto fail;
|
||||
}
|
||||
}
|
||||
tmpDir = *this;
|
||||
// tmpDir = *this;
|
||||
tmpDir.copy(this);
|
||||
parent = &tmpDir;
|
||||
close();
|
||||
}
|
||||
|
|
@ -312,7 +313,8 @@ bool ExFatFile::rename(ExFatFile* dirFile, const char* newPath) {
|
|||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
oldFile = *this;
|
||||
// oldFile = *this;
|
||||
oldFile.copy(this);
|
||||
m_dirPos = file.m_dirPos;
|
||||
m_setCount = file.m_setCount;
|
||||
m_flags |= FILE_FLAG_DIR_DIRTY;
|
||||
|
|
@ -463,8 +465,9 @@ bool ExFatFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|
|||
uint16_t time;
|
||||
uint8_t ms10;
|
||||
|
||||
if (!isFile() || year < 1980 || year > 2107 || month < 1 || month > 12 ||
|
||||
day < 1 || day > 31 || hour > 23 || minute > 59 || second > 59) {
|
||||
if (!isFileOrSubDir() || year < 1980 || year > 2107 || month < 1 ||
|
||||
month > 12 || day < 1 || day > 31 || hour > 23 || minute > 59 ||
|
||||
second > 59) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -37,7 +37,8 @@ bool ExFatVolume::chdir(const char* path) {
|
|||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
m_vwd = dir;
|
||||
// m_vwd = dir;
|
||||
m_vwd.copy(&dir);
|
||||
return true;
|
||||
|
||||
fail:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -354,7 +354,8 @@ bool FatFile::mkdir(FatFile* parent, const char* path, bool pFlag) {
|
|||
goto fail;
|
||||
}
|
||||
}
|
||||
tmpDir = *this;
|
||||
// tmpDir = *this;
|
||||
tmpDir.copy(this);
|
||||
parent = &tmpDir;
|
||||
close();
|
||||
}
|
||||
|
|
@ -477,7 +478,8 @@ bool FatFile::open(FatFile* dirFile, const char* path, oflag_t oflag) {
|
|||
DBG_WARN_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
tmpDir = *this;
|
||||
// tmpDir = *this;
|
||||
tmpDir.copy(this);
|
||||
dirFile = &tmpDir;
|
||||
close();
|
||||
}
|
||||
|
|
@ -632,7 +634,8 @@ bool FatFile::openCwd() {
|
|||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
*this = *FatVolume::cwv()->vwd();
|
||||
// *this = *FatVolume::cwv()->vwd();
|
||||
this->copy(FatVolume::cwv()->vwd());
|
||||
rewind();
|
||||
return true;
|
||||
|
||||
|
|
@ -965,7 +968,8 @@ bool FatFile::rename(FatFile* dirFile, const char* newPath) {
|
|||
}
|
||||
// sync() and cache directory entry
|
||||
sync();
|
||||
oldFile = *this;
|
||||
// oldFile = *this;
|
||||
oldFile.copy(this);
|
||||
dir = cacheDirEntry(FsCache::CACHE_FOR_READ);
|
||||
if (!dir) {
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -1281,8 +1285,9 @@ bool FatFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|
|||
uint16_t dirTime;
|
||||
DirFat_t* dir;
|
||||
|
||||
if (!isFile() || year < 1980 || year > 2107 || month < 1 || month > 12 ||
|
||||
day < 1 || day > 31 || hour > 23 || minute > 59 || second > 59) {
|
||||
if (!isFileOrSubDir() || year < 1980 || year > 2107 || month < 1 ||
|
||||
month > 12 || day < 1 || day > 31 || hour > 23 || minute > 59 ||
|
||||
second > 59) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -117,14 +117,80 @@ class FatFile {
|
|||
* OR of open flags. see FatFile::open(FatFile*, const char*, uint8_t).
|
||||
*/
|
||||
FatFile(const char* path, oflag_t oflag) { open(path, oflag); }
|
||||
#if DESTRUCTOR_CLOSES_FILE
|
||||
|
||||
/** Copy from to this.
|
||||
* \param[in] from Source file.
|
||||
*/
|
||||
void copy(const FatFile* from) {
|
||||
if (from != this) {
|
||||
#if FILE_COPY_CONSTRUCTOR_SELECT
|
||||
*this = *from;
|
||||
#else // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
memcpy(this, from, sizeof(FatFile));
|
||||
#endif // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
}
|
||||
}
|
||||
/** move from to this.
|
||||
* \param[in] from Source file.
|
||||
*/
|
||||
void move(FatFile* from) {
|
||||
if (from != this) {
|
||||
copy(from);
|
||||
from->m_attributes = FILE_ATTR_CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
#if FILE_COPY_CONSTRUCTOR_SELECT == FILE_COPY_CONSTRUCTOR_PUBLIC
|
||||
/** Copy constructor.
|
||||
* \param[in] from Move from file.
|
||||
*
|
||||
*/
|
||||
FatFile(const FatFile& from) = default;
|
||||
/** Copy assignment operator.
|
||||
* \param[in] from Move from file.
|
||||
* \return Copied file.
|
||||
*/
|
||||
FatFile& operator=(const FatFile& from) = default;
|
||||
#elif FILE_COPY_CONSTRUCTOR_SELECT == FILE_COPY_CONSTRUCTOR_PRIVATE
|
||||
|
||||
private:
|
||||
FatFile(const FatFile& from) = default;
|
||||
FatFile& operator=(const FatFile& from) = default;
|
||||
|
||||
public:
|
||||
#else // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
FatFile(const FatFile& from) = delete;
|
||||
FatFile& operator=(const FatFile& from) = delete;
|
||||
#endif // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
|
||||
#if FILE_MOVE_CONSTRUCTOR_SELECT
|
||||
/** Move constructor.
|
||||
* \param[in] from Move from file.
|
||||
*/
|
||||
FatFile(FatFile&& from) { move(&from); }
|
||||
/** Move assignment operator.
|
||||
* \param[in] from Move from file.
|
||||
* \return Moved file.
|
||||
*/
|
||||
FatFile& operator=(FatFile&& from) {
|
||||
move(&from);
|
||||
return *this;
|
||||
}
|
||||
#else // FILE_MOVE_CONSTRUCTOR_SELECT
|
||||
FatFile(FatFile&& from) = delete;
|
||||
FatFile& operator=(FatFile&& from) = delete;
|
||||
#endif
|
||||
/** Destructor */
|
||||
#if DESTRUCTOR_CLOSES_FILE
|
||||
~FatFile() {
|
||||
if (isOpen()) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
#else // DESTRUCTOR_CLOSES_FILE
|
||||
~FatFile() = default;
|
||||
#endif // DESTRUCTOR_CLOSES_FILE
|
||||
|
||||
/** The parenthesis operator.
|
||||
*
|
||||
* \return true if a file is open.
|
||||
|
|
@ -323,8 +389,7 @@ class FatFile {
|
|||
*
|
||||
* \param[out] name An array of characters for the file's name.
|
||||
* \param[in] size The size of the array in bytes. The array
|
||||
* must be at least 13 bytes long. The file's name will be
|
||||
* truncated if the file's name is too long.
|
||||
* must be at least 13 bytes long.
|
||||
* \return length for success or zero for failure.
|
||||
*/
|
||||
size_t getName(char* name, size_t size);
|
||||
|
|
@ -333,7 +398,7 @@ class FatFile {
|
|||
*
|
||||
* \param[out] name An array of characters for the file's name.
|
||||
* \param[in] size The size of the array in characters.
|
||||
* \return the name length.
|
||||
* \return length for success or zero for failure.
|
||||
*/
|
||||
size_t getName7(char* name, size_t size);
|
||||
/**
|
||||
|
|
@ -341,7 +406,7 @@ class FatFile {
|
|||
*
|
||||
* \param[out] name An array of characters for the file's name.
|
||||
* \param[in] size The size of the array in characters.
|
||||
* \return the name length.
|
||||
* \return length for success or zero for failure.
|
||||
*/
|
||||
size_t getName8(char* name, size_t size);
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
|
@ -784,7 +849,7 @@ class FatFile {
|
|||
*/
|
||||
bool rename(FatFile* dirFile, const char* newPath);
|
||||
/** Set the file's current position to zero. */
|
||||
void rewind() { seekSet(0); }
|
||||
void rewind() { seekSet(0UL); }
|
||||
/** Remove a directory file.
|
||||
*
|
||||
* The directory file will be removed only if it is empty and is not the
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -54,7 +54,9 @@ static void putLfnChar(DirLfn_t* ldir, uint8_t i, uint16_t c) {
|
|||
}
|
||||
//==============================================================================
|
||||
bool FatFile::cmpName(uint16_t index, FatLfn_t* fname, uint8_t lfnOrd) {
|
||||
FatFile dir = *this;
|
||||
// FatFile dir = *this;
|
||||
FatFile dir;
|
||||
dir.copy(this);
|
||||
DirLfn_t* ldir;
|
||||
fname->reset();
|
||||
for (uint8_t order = 1; order <= lfnOrd; order++) {
|
||||
|
|
@ -92,7 +94,9 @@ fail:
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatFile::createLFN(uint16_t index, FatLfn_t* fname, uint8_t lfnOrd) {
|
||||
FatFile dir = *this;
|
||||
// FatFile dir = *this;
|
||||
FatFile dir;
|
||||
dir.copy(this);
|
||||
DirLfn_t* ldir;
|
||||
uint8_t checksum = lfnChecksum(fname->sfn);
|
||||
uint8_t fc = 0;
|
||||
|
|
@ -376,7 +380,6 @@ create:
|
|||
if (freeFound == 0) {
|
||||
freeIndex = curIndex;
|
||||
}
|
||||
|
||||
while (freeFound < freeNeed) {
|
||||
dir = dirFile->readDirCache();
|
||||
if (!dir) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -156,7 +156,8 @@ bool FatFile::openExistingSFN(const char* path) {
|
|||
if (*path == 0) {
|
||||
return openRoot(vol);
|
||||
}
|
||||
*this = *vol->vwd();
|
||||
// *this = *vol->vwd();
|
||||
this->copy(vol->vwd());
|
||||
do {
|
||||
if (!parsePathName(path, &fname, &path)) {
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -183,7 +184,7 @@ bool FatFile::openSFN(FatSfn_t* fname) {
|
|||
goto fail;
|
||||
}
|
||||
while (true) {
|
||||
if (read(&dir, 32) != 32) {
|
||||
if (read(&dir, sizeof(dir)) != sizeof(dir)) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -192,7 +193,7 @@ bool FatFile::openSFN(FatSfn_t* fname) {
|
|||
goto fail;
|
||||
}
|
||||
if (isFatFileOrSubdir(&dir) && memcmp(fname->sfn, dir.name, 11) == 0) {
|
||||
uint16_t saveDirIndex = (m_curPosition - 32) >> 5;
|
||||
uint16_t saveDirIndex = (m_curPosition - sizeof(dir)) >> 5;
|
||||
uint32_t saveDirCluster = m_firstCluster;
|
||||
memset(this, 0, sizeof(FatFile));
|
||||
m_attributes = dir.attributes & FS_ATTRIB_COPY;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -37,7 +37,8 @@ bool FatVolume::chdir(const char* path) {
|
|||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
m_vwd = dir;
|
||||
// m_vwd = dir;
|
||||
m_vwd.copy(&dir);
|
||||
return true;
|
||||
|
||||
fail:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -23,32 +23,36 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "FsLib.h"
|
||||
#if FILE_COPY_CONSTRUCTOR_SELECT
|
||||
//------------------------------------------------------------------------------
|
||||
FsBaseFile::FsBaseFile(const FsBaseFile& from) {
|
||||
m_fFile = nullptr;
|
||||
m_xFile = nullptr;
|
||||
if (from.m_fFile) {
|
||||
m_fFile = new (m_fileMem) FatFile;
|
||||
*m_fFile = *from.m_fFile;
|
||||
} else if (from.m_xFile) {
|
||||
m_xFile = new (m_fileMem) ExFatFile;
|
||||
*m_xFile = *from.m_xFile;
|
||||
FsBaseFile::FsBaseFile(const FsBaseFile& from) { copy(&from); }
|
||||
//------------------------------------------------------------------------------
|
||||
FsBaseFile& FsBaseFile::operator=(const FsBaseFile& from) {
|
||||
copy(&from);
|
||||
return *this;
|
||||
}
|
||||
#endif // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
//------------------------------------------------------------------------------
|
||||
void FsBaseFile::copy(const FsBaseFile* from) {
|
||||
if (from != this) {
|
||||
m_fFile = nullptr;
|
||||
m_xFile = nullptr;
|
||||
if (from->m_fFile) {
|
||||
m_fFile = new (m_fileMem) FatFile;
|
||||
m_fFile->copy(from->m_fFile);
|
||||
} else if (from->m_xFile) {
|
||||
m_xFile = new (m_fileMem) ExFatFile;
|
||||
m_xFile->copy(from->m_xFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
FsBaseFile& FsBaseFile::operator=(const FsBaseFile& from) {
|
||||
if (this == &from) {
|
||||
return *this;
|
||||
void FsBaseFile::move(FsBaseFile* from) {
|
||||
if (from != this) {
|
||||
copy(from);
|
||||
from->m_fFile = nullptr;
|
||||
from->m_xFile = nullptr;
|
||||
}
|
||||
close();
|
||||
if (from.m_fFile) {
|
||||
m_fFile = new (m_fileMem) FatFile;
|
||||
*m_fFile = *from.m_fFile;
|
||||
} else if (from.m_xFile) {
|
||||
m_xFile = new (m_fileMem) ExFatFile;
|
||||
*m_xFile = *from.m_xFile;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool FsBaseFile::close() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -49,9 +49,18 @@ class FsBaseFile {
|
|||
*/
|
||||
FsBaseFile(const char* path, oflag_t oflag) { open(path, oflag); }
|
||||
|
||||
~FsBaseFile() { close(); }
|
||||
/** Copy from to this.
|
||||
* \param[in] from Source file.
|
||||
*/
|
||||
void copy(const FsBaseFile* from);
|
||||
|
||||
/** move from to this.
|
||||
* \param[in] from Source file.
|
||||
*/
|
||||
void move(FsBaseFile* from);
|
||||
|
||||
#if FILE_COPY_CONSTRUCTOR_SELECT == FILE_COPY_CONSTRUCTOR_PUBLIC
|
||||
/** Copy constructor.
|
||||
*
|
||||
* \param[in] from Object used to initialize this instance.
|
||||
*/
|
||||
FsBaseFile(const FsBaseFile& from);
|
||||
|
|
@ -60,6 +69,46 @@ class FsBaseFile {
|
|||
* \return assigned object.
|
||||
*/
|
||||
FsBaseFile& operator=(const FsBaseFile& from);
|
||||
#elif FILE_COPY_CONSTRUCTOR_SELECT == FILE_COPY_CONSTRUCTOR_PRIVATE
|
||||
|
||||
private:
|
||||
FsBaseFile(const FsBaseFile& from);
|
||||
FsBaseFile& operator=(const FsBaseFile& from);
|
||||
|
||||
public:
|
||||
#else // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
FsBaseFile(const FsBaseFile& from) = delete;
|
||||
FsBaseFile& operator=(const FsBaseFile& from) = delete;
|
||||
#endif // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
|
||||
#if FILE_MOVE_CONSTRUCTOR_SELECT
|
||||
/** Move constructor.
|
||||
* \param[in] from File to move.
|
||||
*/
|
||||
FsBaseFile(FsBaseFile&& from) { move(&from); }
|
||||
/** Move assignment operator.
|
||||
* \param[in] from File to move.
|
||||
* \return Assigned file.
|
||||
*/
|
||||
FsBaseFile& operator=(FsBaseFile&& from) {
|
||||
move(&from);
|
||||
return *this;
|
||||
}
|
||||
#else // FILE_MOVE_CONSTRUCTOR_SELECT
|
||||
FsBaseFile(FsBaseFile&& from) = delete;
|
||||
FsBaseFile& operator=(FsBaseFile&& from) = delete;
|
||||
#endif // FILE_MOVE_CONSTRUCTOR_SELECT
|
||||
|
||||
#if DESTRUCTOR_CLOSES_FILE
|
||||
~FsBaseFile() {
|
||||
if (isOpen()) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
#else // DESTRUCTOR_CLOSES_FILE
|
||||
~FsBaseFile() = default;
|
||||
#endif // DESTRUCTOR_CLOSES_FILE
|
||||
|
||||
/** The parenthesis operator.
|
||||
*
|
||||
* \return true if a file is open.
|
||||
|
|
@ -752,7 +801,7 @@ class FsBaseFile {
|
|||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool seekSet(uint64_t pos) {
|
||||
return m_fFile ? pos < (1ULL << 32) && m_fFile->seekSet(pos)
|
||||
return m_fFile ? pos < (1ULL << 32) && m_fFile->seekSet((uint32_t)pos)
|
||||
: m_xFile ? m_xFile->seekSet(pos)
|
||||
: false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -64,11 +64,10 @@ class SdCardFactory {
|
|||
/** Initialize SPI card.
|
||||
*
|
||||
* \param[in] config SPI configuration.
|
||||
* \return generic card pointer.
|
||||
* \return generic card pointer or nullptr if failure.
|
||||
*/
|
||||
SdCard* newCard(SdSpiConfig config) {
|
||||
m_spiCard.begin(config);
|
||||
return &m_spiCard;
|
||||
return m_spiCard.begin(config) ? &m_spiCard : nullptr;
|
||||
}
|
||||
/** Initialize SDIO card.
|
||||
*
|
||||
|
|
@ -77,8 +76,7 @@ class SdCardFactory {
|
|||
*/
|
||||
SdCard* newCard(SdioConfig config) {
|
||||
#if HAS_SDIO_CLASS
|
||||
m_sdioCard.begin(config);
|
||||
return &m_sdioCard;
|
||||
return m_sdioCard.begin(config) ? &m_sdioCard : nullptr;
|
||||
#else // HAS_SDIO_CLASS
|
||||
(void)config;
|
||||
return nullptr;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
SD_CARD_ERROR(CMD8, "Send and check interface settings") \
|
||||
SD_CARD_ERROR(CMD9, "Read CSD data") \
|
||||
SD_CARD_ERROR(CMD10, "Read CID data") \
|
||||
SD_CARD_ERROR(CMD12, "Stop multiple block read") \
|
||||
SD_CARD_ERROR(CMD12, "Stop multiple block transmission") \
|
||||
SD_CARD_ERROR(CMD13, "Read card status") \
|
||||
SD_CARD_ERROR(CMD17, "Read single block") \
|
||||
SD_CARD_ERROR(CMD18, "Read multiple blocks") \
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -59,6 +59,8 @@ class SdCardInterface : public FsBlockDeviceInterface {
|
|||
virtual bool hasDedicatedSpi() { return false; }
|
||||
/** \return false by default */
|
||||
bool virtual isDedicatedSpi() { return false; }
|
||||
/** \return false by default */
|
||||
bool virtual isSpi() { return false; }
|
||||
/** Set SPI sharing state
|
||||
* \param[in] value desired state.
|
||||
* \return false by default.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -123,6 +123,8 @@ static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
|
|||
// SharedSpiCard member functions
|
||||
//------------------------------------------------------------------------------
|
||||
bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
|
||||
uint8_t cardType;
|
||||
uint32_t arg;
|
||||
Timeout timeout;
|
||||
// Restore state to creator.
|
||||
initSharedSpiCard();
|
||||
|
|
@ -140,7 +142,7 @@ bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
|
|||
spiSetSckSpeed(1000UL * SD_MAX_INIT_RATE_KHZ);
|
||||
spiBegin(spiConfig);
|
||||
m_beginCalled = true;
|
||||
uint32_t arg;
|
||||
|
||||
spiStart();
|
||||
|
||||
// must supply min of 74 clock cycles with CS high.
|
||||
|
|
@ -169,7 +171,7 @@ bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
|
|||
// check SD version
|
||||
while (true) {
|
||||
if (cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND) {
|
||||
type(SD_CARD_TYPE_SD1);
|
||||
cardType = SD_CARD_TYPE_SD1;
|
||||
break;
|
||||
}
|
||||
// Skip first three bytes.
|
||||
|
|
@ -177,7 +179,7 @@ bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
|
|||
m_status = spiReceive();
|
||||
}
|
||||
if (m_status == 0XAA) {
|
||||
type(SD_CARD_TYPE_SD2);
|
||||
cardType = SD_CARD_TYPE_SD2;
|
||||
break;
|
||||
}
|
||||
if (timeout.timedOut()) {
|
||||
|
|
@ -186,7 +188,7 @@ bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
|
|||
}
|
||||
}
|
||||
// initialize card and send host supports SDHC if SD2
|
||||
arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;
|
||||
arg = cardType == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;
|
||||
while (cardAcmd(ACMD41, arg) != R1_READY_STATE) {
|
||||
// check for timeout
|
||||
if (timeout.timedOut()) {
|
||||
|
|
@ -195,13 +197,13 @@ bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
|
|||
}
|
||||
}
|
||||
// if SD2 read OCR register to check for SDHC card
|
||||
if (type() == SD_CARD_TYPE_SD2) {
|
||||
if (cardType == SD_CARD_TYPE_SD2) {
|
||||
if (cardCommand(CMD58, 0)) {
|
||||
error(SD_CARD_ERROR_CMD58);
|
||||
goto fail;
|
||||
}
|
||||
if ((spiReceive() & 0XC0) == 0XC0) {
|
||||
type(SD_CARD_TYPE_SDHC);
|
||||
cardType = SD_CARD_TYPE_SDHC;
|
||||
}
|
||||
// Discard rest of ocr - contains allowed voltage range.
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
|
|
@ -210,6 +212,7 @@ bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
|
|||
}
|
||||
spiStop();
|
||||
spiSetSckSpeed(spiConfig.maxSck);
|
||||
m_type = cardType;
|
||||
return true;
|
||||
|
||||
fail:
|
||||
|
|
@ -307,7 +310,7 @@ bool SharedSpiCard::erase(uint32_t firstSector, uint32_t lastSector) {
|
|||
goto fail;
|
||||
}
|
||||
}
|
||||
if (m_type != SD_CARD_TYPE_SDHC) {
|
||||
if (type() != SD_CARD_TYPE_SDHC) {
|
||||
firstSector <<= 9;
|
||||
lastSector <<= 9;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,8 @@ class SharedSpiCard {
|
|||
bool isBusy();
|
||||
/** \return false, can't be in dedicated state. */
|
||||
bool isDedicatedSpi() { return false; }
|
||||
/** \return true if card is on SPI bus. */
|
||||
bool isSpi() { return true; }
|
||||
/**
|
||||
* Read a card's CID register. The CID contains card identification
|
||||
* information such as Manufacturer ID, Product name, Product serial
|
||||
|
|
@ -301,7 +303,6 @@ class SharedSpiCard {
|
|||
void spiStart();
|
||||
void spiStop();
|
||||
void spiUnselect() { sdCsWrite(m_csPin, true); }
|
||||
void type(uint8_t value) { m_type = value; }
|
||||
bool waitReady(uint16_t ms);
|
||||
bool writeData(uint8_t token, const uint8_t* src);
|
||||
#if SPI_DRIVER_SELECT < 2
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -176,21 +176,11 @@ class SdioCard : public SdCardInterface {
|
|||
* \param[in] sector Address of first sector in sequence.
|
||||
*
|
||||
* \note This function is used with readData() and readStop() for optimized
|
||||
* multiple sector reads. SPI chipSelect must be low for the entire sequence.
|
||||
* multiple sector reads.
|
||||
*
|
||||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool readStart(uint32_t sector);
|
||||
/** Start a read multiple sectors sequence.
|
||||
*
|
||||
* \param[in] sector Address of first sector in sequence.
|
||||
* \param[in] count Maximum sector count.
|
||||
* \note This function is used with readData() and readStop() for optimized
|
||||
* multiple sector reads. SPI chipSelect must be low for the entire sequence.
|
||||
*
|
||||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool readStart(uint32_t sector, uint32_t count);
|
||||
/** End a read multiple sectors sequence.
|
||||
*
|
||||
* \return true for success or false for failure.
|
||||
|
|
@ -251,16 +241,6 @@ class SdioCard : public SdCardInterface {
|
|||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool writeStart(uint32_t sector);
|
||||
/** Start a write multiple sectors sequence.
|
||||
*
|
||||
* \param[in] sector Address of first sector in sequence.
|
||||
* \param[in] count Maximum sector count.
|
||||
* \note This function is used with writeData() and writeStop()
|
||||
* for optimized multiple sector writes.
|
||||
*
|
||||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool writeStart(uint32_t sector, uint32_t count);
|
||||
|
||||
/** End a write multiple sectors sequence.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -764,11 +764,23 @@ bool SdioCard::begin(SdioConfig sdioConfig) {
|
|||
// Determine if High Speed mode is supported and set frequency.
|
||||
// Check status[16] for error 0XF or status[16] for new mode 0X1.
|
||||
uint8_t status[64];
|
||||
if (m_scr.sdSpec() > 0 && cardCMD6(0X00FFFFFF, status) && (2 & status[13]) &&
|
||||
cardCMD6(0X80FFFFF1, status) && (status[16] & 0XF) == 1) {
|
||||
kHzSdClk = 50000;
|
||||
} else {
|
||||
kHzSdClk = 25000;
|
||||
kHzSdClk = 25000;
|
||||
if (m_scr.sdSpec() > 0) {
|
||||
// card is 1.10 or greater - must support CMD6
|
||||
if (!cardCMD6(0X00FFFFFF, status)) {
|
||||
return false;
|
||||
}
|
||||
if (2 & status[13]) {
|
||||
// Card supports High Speed mode - switch mode.
|
||||
if (!cardCMD6(0X80FFFFF1, status)) {
|
||||
return false;
|
||||
}
|
||||
if ((status[16] & 0XF) == 1) {
|
||||
kHzSdClk = 50000;
|
||||
} else {
|
||||
return sdError(SD_CARD_ERROR_CMD6);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Disable GPIO.
|
||||
enableGPIO(false);
|
||||
|
|
@ -1036,8 +1048,10 @@ bool SdioCard::syncDevice() {
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t SdioCard::type() const {
|
||||
return m_version2 ? m_highCapacity ? SD_CARD_TYPE_SDHC : SD_CARD_TYPE_SD2
|
||||
: SD_CARD_TYPE_SD1;
|
||||
return !m_initDone ? 0
|
||||
: !m_version2 ? SD_CARD_TYPE_SD1
|
||||
: !m_highCapacity ? SD_CARD_TYPE_SD2
|
||||
: SD_CARD_TYPE_SDHC;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool SdioCard::writeData(const uint8_t* src) {
|
||||
|
|
|
|||
17
src/SdFat.h
17
src/SdFat.h
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -38,9 +38,9 @@
|
|||
#endif // INCLUDE_SDIOS
|
||||
//------------------------------------------------------------------------------
|
||||
/** SdFat version for cpp use. */
|
||||
#define SD_FAT_VERSION 20202
|
||||
#define SD_FAT_VERSION 20203
|
||||
/** SdFat version as string. */
|
||||
#define SD_FAT_VERSION_STR "2.2.2"
|
||||
#define SD_FAT_VERSION_STR "2.2.3"
|
||||
//==============================================================================
|
||||
/**
|
||||
* \class SdBase
|
||||
|
|
@ -80,7 +80,7 @@ class SdBase : public Vol {
|
|||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool begin(SdSpiConfig spiConfig) {
|
||||
return cardBegin(spiConfig) && Vol::begin(m_card);
|
||||
return cardBegin(spiConfig) && volumeBegin();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
/** Initialize SD card and file system for SDIO mode.
|
||||
|
|
@ -89,7 +89,7 @@ class SdBase : public Vol {
|
|||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool begin(SdioConfig sdioConfig) {
|
||||
return cardBegin(sdioConfig) && Vol::begin(m_card);
|
||||
return cardBegin(sdioConfig) && volumeBegin();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
/** \return Pointer to SD card object. */
|
||||
|
|
@ -347,7 +347,9 @@ class SdBase : public Vol {
|
|||
*
|
||||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool volumeBegin() { return Vol::begin(m_card); }
|
||||
bool volumeBegin() {
|
||||
return Vol::begin(m_card) || Vol::begin(m_card, true, 0);
|
||||
}
|
||||
#if ENABLE_ARDUINO_SERIAL
|
||||
/** Print error details after begin() fails. */
|
||||
void initErrorPrint() { initErrorPrint(&Serial); }
|
||||
|
|
@ -445,7 +447,6 @@ typedef FsBaseFile SdBaseFile;
|
|||
#if defined __has_include
|
||||
#if __has_include(<FS.h>)
|
||||
#define HAS_INCLUDE_FS_H
|
||||
#warning File not defined because __has_include(FS.h)
|
||||
#endif // __has_include(<FS.h>)
|
||||
#endif // defined __has_include
|
||||
#ifndef HAS_INCLUDE_FS_H
|
||||
|
|
@ -457,6 +458,8 @@ typedef ExFile File;
|
|||
#elif SDFAT_FILE_TYPE == 3
|
||||
typedef FsFile File;
|
||||
#endif // SDFAT_FILE_TYPE
|
||||
#elif !defined(DISABLE_FS_H_WARNING)
|
||||
#warning File not defined because __has_include(FS.h)
|
||||
#endif // HAS_INCLUDE_FS_H
|
||||
/**
|
||||
* \class SdFile
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2022 Bill Greiman
|
||||
* Copyright (c) 2011-2024 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
#endif // __AVR__
|
||||
//
|
||||
// To try UTF-8 encoded filenames.
|
||||
// #define USE_UTF8_LONG_NAMES 1
|
||||
// #define USE_UTF8_LONG_NAMES 1
|
||||
//
|
||||
// For minimum flash size use these settings:
|
||||
// #define USE_FAT_FILE_FLAG_CONTIGUOUS 0
|
||||
|
|
@ -46,6 +46,48 @@
|
|||
// Options can be set in a makefile or an IDE like platformIO
|
||||
// if they are in a #ifndef/#endif block below.
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Options for file class constructors, assignment operators and destructors.
|
||||
*
|
||||
* By default file copy constructors and copy assignment operators are
|
||||
* private to prevent multiple copies of a instance for a file.
|
||||
*
|
||||
* File move constructors and move assignment operators are public to permit
|
||||
* return of a file instance for compilers that aren't able to use copy elision.
|
||||
*
|
||||
*/
|
||||
/** File copy constructors and copy assignment operators are deleted */
|
||||
#define FILE_COPY_CONSTRUCTOR_DELETED 0
|
||||
/** File copy constructors and copy assignment operators are private */
|
||||
#define FILE_COPY_CONSTRUCTOR_PRIVATE 1
|
||||
/** File copy constructors and copy assignment operators are public */
|
||||
#define FILE_COPY_CONSTRUCTOR_PUBLIC 2
|
||||
|
||||
#ifndef FILE_COPY_CONSTRUCTOR_SELECT
|
||||
/** Specify kind of file copy constructors and copy assignment operators */
|
||||
#define FILE_COPY_CONSTRUCTOR_SELECT FILE_COPY_CONSTRUCTOR_PRIVATE
|
||||
#endif // FILE_COPY_CONSTRUCTOR_SELECT
|
||||
/** File move constructors and move assignment operators are deleted. */
|
||||
#define FILE_MOVE_CONSTRUCTOR_DELETED 0
|
||||
/** File move constructors and move assignment operators are public. */
|
||||
#define FILE_MOVE_CONSTRUCTOR_PUBLIC 1
|
||||
|
||||
#ifndef FILE_MOVE_CONSTRUCTOR_SELECT
|
||||
/** Specify kind of file move constructors and move assignment operators */
|
||||
#define FILE_MOVE_CONSTRUCTOR_SELECT FILE_MOVE_CONSTRUCTOR_PUBLIC
|
||||
#endif // FILE_MOVE_CONSTRUCTOR_SELECT
|
||||
|
||||
#if FILE_MOVE_CONSTRUCTOR_SELECT != FILE_MOVE_CONSTRUCTOR_PUBLIC && \
|
||||
FILE_COPY_CONSTRUCTOR_SELECT != FILE_COPY_CONSTRUCTOR_PUBLIC
|
||||
#error "No public move or copy assign operators"
|
||||
#endif // FILE_MOVE_CONSTRUCTOR_SELECT && FILE_MOVE_CONSTRUCTOR_SELECT
|
||||
/**
|
||||
* Set DESTRUCTOR_CLOSES_FILE nonzero to close a file in its destructor. */
|
||||
#ifndef DESTRUCTOR_CLOSES_FILE
|
||||
#define DESTRUCTOR_CLOSES_FILE 0
|
||||
#endif // DESTRUCTOR_CLOSES_FILE
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** For Debug - must be one */
|
||||
#define ENABLE_ARDUINO_FEATURES 1
|
||||
/** For Debug - must be one */
|
||||
|
|
@ -327,15 +369,6 @@ typedef uint8_t SdCsPin_t;
|
|||
#define FAT12_SUPPORT 0
|
||||
#endif // FAT12_SUPPORT
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* Set DESTRUCTOR_CLOSES_FILE nonzero to close a file in its destructor.
|
||||
*
|
||||
* Causes use of lots of heap in ARM.
|
||||
*/
|
||||
#ifndef DESTRUCTOR_CLOSES_FILE
|
||||
#define DESTRUCTOR_CLOSES_FILE 0
|
||||
#endif // DESTRUCTOR_CLOSES_FILE
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* Call flush for endl if ENDL_CALLS_FLUSH is nonzero
|
||||
*
|
||||
|
|
|
|||
|
|
@ -33,30 +33,25 @@ constexpr uint16_t compileYear() {
|
|||
return 1000 * (__DATE__[7] - '0') + 100 * (__DATE__[8] - '0') +
|
||||
10 * (__DATE__[9] - '0') + (__DATE__[10] - '0');
|
||||
}
|
||||
/** \return true if str equals the month field of the __DATE__ macro. */
|
||||
constexpr bool compileMonthIs(const char* str) {
|
||||
return __DATE__[0] == str[0] && __DATE__[1] == str[1] &&
|
||||
__DATE__[2] == str[2];
|
||||
}
|
||||
/** \return month field of the __DATE__ macro. */
|
||||
constexpr uint8_t compileMonth() {
|
||||
return compileMonthIs("Jan") ? 1
|
||||
: compileMonthIs("Feb") ? 2
|
||||
: compileMonthIs("Mar") ? 3
|
||||
: compileMonthIs("Apr") ? 4
|
||||
: compileMonthIs("May") ? 5
|
||||
: compileMonthIs("Jun") ? 6
|
||||
: compileMonthIs("Jul") ? 7
|
||||
: compileMonthIs("Aug") ? 8
|
||||
: compileMonthIs("Sep") ? 9
|
||||
: compileMonthIs("Oct") ? 10
|
||||
: compileMonthIs("Nov") ? 11
|
||||
: compileMonthIs("Dec") ? 12
|
||||
: 0;
|
||||
return __DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n' ? 1
|
||||
: __DATE__[0] == 'F' && __DATE__[1] == 'e' && __DATE__[2] == 'b' ? 2
|
||||
: __DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r' ? 3
|
||||
: __DATE__[0] == 'A' && __DATE__[1] == 'p' && __DATE__[2] == 'r' ? 4
|
||||
: __DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y' ? 5
|
||||
: __DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n' ? 6
|
||||
: __DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l' ? 7
|
||||
: __DATE__[0] == 'A' && __DATE__[1] == 'u' && __DATE__[2] == 'g' ? 8
|
||||
: __DATE__[0] == 'S' && __DATE__[1] == 'e' && __DATE__[2] == 'p' ? 9
|
||||
: __DATE__[0] == 'O' && __DATE__[1] == 'c' && __DATE__[2] == 't' ? 10
|
||||
: __DATE__[0] == 'N' && __DATE__[1] == 'o' && __DATE__[2] == 'v' ? 11
|
||||
: __DATE__[0] == 'D' && __DATE__[1] == 'e' && __DATE__[2] == 'c' ? 12
|
||||
: 0;
|
||||
}
|
||||
/** \return day field of the __DATE__ macro. */
|
||||
constexpr uint8_t compileDay() {
|
||||
return 10 * (__DATE__[4] == ' ' ? 0 : __DATE__[4] - '0') +
|
||||
return 10 * ((__DATE__[4] == ' ' ? '0' : __DATE__[4]) - '0') +
|
||||
(__DATE__[5] - '0');
|
||||
}
|
||||
/** \return hour field of the __TIME__ macro. */
|
||||
|
|
|
|||
|
|
@ -201,7 +201,10 @@ int StdioStream::fseek(int32_t offset, int origin) {
|
|||
break;
|
||||
|
||||
case SEEK_SET:
|
||||
if (!StreamBaseFile::seekSet(offset)) {
|
||||
if (offset < 0) {
|
||||
goto fail;
|
||||
}
|
||||
if (!StreamBaseFile::seekSet((uint32_t)offset)) {
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
|
|
@ -349,7 +352,7 @@ bool StdioStream::rewind() {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
StreamBaseFile::seekSet(0);
|
||||
StreamBaseFile::seekSet(0UL);
|
||||
m_r = 0;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue