Skip to content

Commit 1cf1c8e

Browse files
authored
Fix several SD card issues (#4876)
- File might not eval to false if opened with write/append and SD is gone - Allow card to be formatted if FAT partition was not found - Mark card as gone in certain situations - Fix several logic errors in low level SD API
1 parent 3fe7c2e commit 1cf1c8e

File tree

7 files changed

+90
-40
lines changed

7 files changed

+90
-40
lines changed

Diff for: libraries/FS/src/FS.cpp

+16-16
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ using namespace fs;
2525

2626
size_t File::write(uint8_t c)
2727
{
28-
if (!_p) {
28+
if (!*this) {
2929
return 0;
3030
}
3131

@@ -34,7 +34,7 @@ size_t File::write(uint8_t c)
3434

3535
time_t File::getLastWrite()
3636
{
37-
if (!_p) {
37+
if (!*this) {
3838
return 0;
3939
}
4040

@@ -43,7 +43,7 @@ time_t File::getLastWrite()
4343

4444
size_t File::write(const uint8_t *buf, size_t size)
4545
{
46-
if (!_p) {
46+
if (!*this) {
4747
return 0;
4848
}
4949

@@ -52,7 +52,7 @@ size_t File::write(const uint8_t *buf, size_t size)
5252

5353
int File::available()
5454
{
55-
if (!_p) {
55+
if (!*this) {
5656
return false;
5757
}
5858

@@ -61,7 +61,7 @@ int File::available()
6161

6262
int File::read()
6363
{
64-
if (!_p) {
64+
if (!*this) {
6565
return -1;
6666
}
6767

@@ -75,7 +75,7 @@ int File::read()
7575

7676
size_t File::read(uint8_t* buf, size_t size)
7777
{
78-
if (!_p) {
78+
if (!*this) {
7979
return -1;
8080
}
8181

@@ -84,7 +84,7 @@ size_t File::read(uint8_t* buf, size_t size)
8484

8585
int File::peek()
8686
{
87-
if (!_p) {
87+
if (!*this) {
8888
return -1;
8989
}
9090

@@ -96,7 +96,7 @@ int File::peek()
9696

9797
void File::flush()
9898
{
99-
if (!_p) {
99+
if (!*this) {
100100
return;
101101
}
102102

@@ -105,7 +105,7 @@ void File::flush()
105105

106106
bool File::seek(uint32_t pos, SeekMode mode)
107107
{
108-
if (!_p) {
108+
if (!*this) {
109109
return false;
110110
}
111111

@@ -114,7 +114,7 @@ bool File::seek(uint32_t pos, SeekMode mode)
114114

115115
size_t File::position() const
116116
{
117-
if (!_p) {
117+
if (!*this) {
118118
return 0;
119119
}
120120

@@ -123,7 +123,7 @@ size_t File::position() const
123123

124124
size_t File::size() const
125125
{
126-
if (!_p) {
126+
if (!*this) {
127127
return 0;
128128
}
129129

@@ -140,12 +140,12 @@ void File::close()
140140

141141
File::operator bool() const
142142
{
143-
return !!_p;
143+
return _p != nullptr && *_p != false;
144144
}
145145

146146
const char* File::name() const
147147
{
148-
if (!_p) {
148+
if (!*this) {
149149
return nullptr;
150150
}
151151

@@ -155,23 +155,23 @@ const char* File::name() const
155155
//to implement
156156
boolean File::isDirectory(void)
157157
{
158-
if (!_p) {
158+
if (!*this) {
159159
return false;
160160
}
161161
return _p->isDirectory();
162162
}
163163

164164
File File::openNextFile(const char* mode)
165165
{
166-
if (!_p) {
166+
if (!*this) {
167167
return File();
168168
}
169169
return _p->openNextFile(mode);
170170
}
171171

172172
void File::rewindDirectory(void)
173173
{
174-
if (!_p) {
174+
if (!*this) {
175175
return;
176176
}
177177
_p->rewindDirectory();

Diff for: libraries/SD/src/SD.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ using namespace fs;
2222

2323
SDFS::SDFS(FSImplPtr impl): FS(impl), _pdrv(0xFF) {}
2424

25-
bool SDFS::begin(uint8_t ssPin, SPIClass &spi, uint32_t frequency, const char * mountpoint, uint8_t max_files)
25+
bool SDFS::begin(uint8_t ssPin, SPIClass &spi, uint32_t frequency, const char * mountpoint, uint8_t max_files, bool format_if_empty)
2626
{
2727
if(_pdrv != 0xFF) {
2828
return true;
@@ -35,7 +35,7 @@ bool SDFS::begin(uint8_t ssPin, SPIClass &spi, uint32_t frequency, const char *
3535
return false;
3636
}
3737

38-
if(!sdcard_mount(_pdrv, mountpoint, max_files)){
38+
if(!sdcard_mount(_pdrv, mountpoint, max_files, format_if_empty)){
3939
sdcard_unmount(_pdrv);
4040
sdcard_uninit(_pdrv);
4141
_pdrv = 0xFF;

Diff for: libraries/SD/src/SD.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class SDFS : public FS
2929

3030
public:
3131
SDFS(FSImplPtr impl);
32-
bool begin(uint8_t ssPin=SS, SPIClass &spi=SPI, uint32_t frequency=4000000, const char * mountpoint="/sd", uint8_t max_files=5);
32+
bool begin(uint8_t ssPin=SS, SPIClass &spi=SPI, uint32_t frequency=4000000, const char * mountpoint="/sd", uint8_t max_files=5, bool format_if_empty=false);
3333
void end();
3434
sdcard_type_t cardType();
3535
uint64_t cardSize();

Diff for: libraries/SD/src/sd_diskio.cpp

+67-17
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,31 @@ typedef struct {
6060

6161
static ardu_sdcard_t* s_cards[FF_VOLUMES] = { NULL };
6262

63+
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
64+
const char * fferr2str[] = {
65+
"(0) Succeeded",
66+
"(1) A hard error occurred in the low level disk I/O layer",
67+
"(2) Assertion failed",
68+
"(3) The physical drive cannot work",
69+
"(4) Could not find the file",
70+
"(5) Could not find the path",
71+
"(6) The path name format is invalid",
72+
"(7) Access denied due to prohibited access or directory full",
73+
"(8) Access denied due to prohibited access",
74+
"(9) The file/directory object is invalid",
75+
"(10) The physical drive is write protected",
76+
"(11) The logical drive number is invalid",
77+
"(12) The volume has no work area",
78+
"(13) There is no valid FAT volume",
79+
"(14) The f_mkfs() aborted due to any problem",
80+
"(15) Could not get a grant to access the volume within defined period",
81+
"(16) The operation is rejected according to the file sharing policy",
82+
"(17) LFN working buffer could not be allocated",
83+
"(18) Number of open files > FF_FS_LOCK",
84+
"(19) Given parameter is invalid"
85+
};
86+
#endif
87+
6388
/*
6489
* SD SPI
6590
* */
@@ -73,6 +98,9 @@ bool sdWait(uint8_t pdrv, int timeout)
7398
resp = s_cards[pdrv]->spi->transfer(0xFF);
7499
} while (resp == 0x00 && (millis() - start) < (unsigned int)timeout);
75100

101+
if (!resp) {
102+
log_w("Wait Failed");
103+
}
76104
return (resp > 0x00);
77105
}
78106

@@ -91,7 +119,10 @@ bool sdSelectCard(uint8_t pdrv)
91119
{
92120
ardu_sdcard_t * card = s_cards[pdrv];
93121
digitalWrite(card->ssPin, LOW);
94-
sdWait(pdrv, 300);
122+
bool s = sdWait(pdrv, 300);
123+
if (!s) {
124+
log_e("Select Failed");
125+
}
95126
return true;
96127
}
97128

@@ -105,10 +136,11 @@ char sdCommand(uint8_t pdrv, char cmd, unsigned int arg, unsigned int* resp)
105136
token = sdCommand(pdrv, APP_CMD, 0, NULL);
106137
sdDeselectCard(pdrv);
107138
if (token > 1) {
108-
return token;
139+
break;
109140
}
110141
if(!sdSelectCard(pdrv)) {
111-
return 0xFF;
142+
token = 0xFF;
143+
break;
112144
}
113145
}
114146

@@ -159,7 +191,10 @@ char sdCommand(uint8_t pdrv, char cmd, unsigned int arg, unsigned int* resp)
159191

160192
break;
161193
}
162-
194+
if (token == 0xFF) {
195+
log_e("Card Failed! cmd: 0x%02x", cmd);
196+
card->status = STA_NOINIT;
197+
}
163198
return token;
164199
}
165200

@@ -215,7 +250,7 @@ bool sdReadSector(uint8_t pdrv, char* buffer, unsigned long long sector)
215250
{
216251
for (int f = 0; f < 3; f++) {
217252
if(!sdSelectCard(pdrv)) {
218-
break;
253+
return false;
219254
}
220255
if (!sdCommand(pdrv, READ_BLOCK_SINGLE, (s_cards[pdrv]->type == CARD_SDHC) ? sector : sector << 9, NULL)) {
221256
bool success = sdReadBytes(pdrv, buffer, 512);
@@ -235,7 +270,7 @@ bool sdReadSectors(uint8_t pdrv, char* buffer, unsigned long long sector, int co
235270
{
236271
for (int f = 0; f < 3;) {
237272
if(!sdSelectCard(pdrv)) {
238-
break;
273+
return false;
239274
}
240275

241276
if (!sdCommand(pdrv, READ_BLOCK_MULTIPLE, (s_cards[pdrv]->type == CARD_SDHC) ? sector : sector << 9, NULL)) {
@@ -271,7 +306,7 @@ bool sdWriteSector(uint8_t pdrv, const char* buffer, unsigned long long sector)
271306
{
272307
for (int f = 0; f < 3; f++) {
273308
if(!sdSelectCard(pdrv)) {
274-
break;
309+
return false;
275310
}
276311
if (!sdCommand(pdrv, WRITE_BLOCK_SINGLE, (s_cards[pdrv]->type == CARD_SDHC) ? sector : sector << 9, NULL)) {
277312
char token = sdWriteBytes(pdrv, buffer, 0xFE);
@@ -307,12 +342,12 @@ bool sdWriteSectors(uint8_t pdrv, const char* buffer, unsigned long long sector,
307342
for (int f = 0; f < 3;) {
308343
if (card->type != CARD_MMC) {
309344
if (sdTransaction(pdrv, SET_WR_BLK_ERASE_COUNT, currentCount, NULL)) {
310-
break;
345+
return false;
311346
}
312347
}
313348

314349
if(!sdSelectCard(pdrv)) {
315-
break;
350+
return false;
316351
}
317352

318353
if (!sdCommand(pdrv, WRITE_BLOCK_MULTIPLE, (card->type == CARD_SDHC) ? currentSector : currentSector << 9, NULL)) {
@@ -344,9 +379,8 @@ bool sdWriteSectors(uint8_t pdrv, const char* buffer, unsigned long long sector,
344379
break;
345380
}
346381

347-
sdDeselectCard(pdrv);
348-
349382
if (token == 0x0A) {
383+
sdDeselectCard(pdrv);
350384
unsigned int writtenBlocks = 0;
351385
if (card->type != CARD_MMC && sdSelectCard(pdrv)) {
352386
if (!sdCommand(pdrv, SEND_NUM_WR_BLOCKS, 0, NULL)) {
@@ -365,7 +399,7 @@ bool sdWriteSectors(uint8_t pdrv, const char* buffer, unsigned long long sector,
365399
currentCount = count - writtenBlocks;
366400
continue;
367401
} else {
368-
return false;
402+
break;
369403
}
370404
}
371405
} else {
@@ -380,7 +414,7 @@ unsigned long sdGetSectorsCount(uint8_t pdrv)
380414
{
381415
for (int f = 0; f < 3; f++) {
382416
if(!sdSelectCard(pdrv)) {
383-
break;
417+
return false;
384418
}
385419

386420
if (!sdCommand(pdrv, SEND_CSD, 0, NULL)) {
@@ -714,7 +748,7 @@ uint8_t sdcard_unmount(uint8_t pdrv)
714748
return 0;
715749
}
716750

717-
bool sdcard_mount(uint8_t pdrv, const char* path, uint8_t max_files)
751+
bool sdcard_mount(uint8_t pdrv, const char* path, uint8_t max_files, bool format_if_empty)
718752
{
719753
ardu_sdcard_t * card = s_cards[pdrv];
720754
if(pdrv >= FF_VOLUMES || card == NULL){
@@ -739,9 +773,25 @@ bool sdcard_mount(uint8_t pdrv, const char* path, uint8_t max_files)
739773

740774
FRESULT res = f_mount(fs, drv, 1);
741775
if (res != FR_OK) {
742-
log_e("f_mount failed 0x(%x)", res);
743-
esp_vfs_fat_unregister_path(path);
744-
return false;
776+
log_e("f_mount failed: %s", fferr2str[res]);
777+
if(res == 13 && format_if_empty){
778+
BYTE work[FF_MAX_SS];
779+
res = f_mkfs(drv, FM_ANY, 0, work, sizeof(work));
780+
if (res != FR_OK) {
781+
log_e("f_mkfs failed: %s", fferr2str[res]);
782+
esp_vfs_fat_unregister_path(path);
783+
return false;
784+
}
785+
res = f_mount(fs, drv, 1);
786+
if (res != FR_OK) {
787+
log_e("f_mount failed: %s", fferr2str[res]);
788+
esp_vfs_fat_unregister_path(path);
789+
return false;
790+
}
791+
} else {
792+
esp_vfs_fat_unregister_path(path);
793+
return false;
794+
}
745795
}
746796
AcquireSPI lock(card);
747797
card->sectors = sdGetSectorsCount(pdrv);

Diff for: libraries/SD/src/sd_diskio.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
uint8_t sdcard_init(uint8_t cs, SPIClass * spi, int hz);
2323
uint8_t sdcard_uninit(uint8_t pdrv);
2424

25-
bool sdcard_mount(uint8_t pdrv, const char* path, uint8_t max_files);
25+
bool sdcard_mount(uint8_t pdrv, const char* path, uint8_t max_files, bool format_if_empty);
2626
uint8_t sdcard_unmount(uint8_t pdrv);
2727

2828
sdcard_type_t sdcard_type(uint8_t pdrv);

Diff for: libraries/SD_MMC/src/SD_MMC.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ SDMMCFS::SDMMCFS(FSImplPtr impl)
3535
: FS(impl), _card(NULL)
3636
{}
3737

38-
bool SDMMCFS::begin(const char * mountpoint, bool mode1bit)
38+
bool SDMMCFS::begin(const char * mountpoint, bool mode1bit, bool format_if_mount_failed)
3939
{
4040
if(_card) {
4141
return true;
@@ -68,7 +68,7 @@ bool SDMMCFS::begin(const char * mountpoint, bool mode1bit)
6868
}
6969

7070
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
71-
.format_if_mount_failed = false,
71+
.format_if_mount_failed = format_if_mount_failed,
7272
.max_files = 5,
7373
.allocation_unit_size = 0
7474
};

Diff for: libraries/SD_MMC/src/SD_MMC.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class SDMMCFS : public FS
2929

3030
public:
3131
SDMMCFS(FSImplPtr impl);
32-
bool begin(const char * mountpoint="/sdcard", bool mode1bit=false);
32+
bool begin(const char * mountpoint="/sdcard", bool mode1bit=false, bool format_if_mount_failed=false);
3333
void end();
3434
sdcard_type_t cardType();
3535
uint64_t cardSize();

0 commit comments

Comments
 (0)