Closed FrankBoesing closed 2 years ago
I can confirm there is an issue with SD and core 2.02: Core 2.01 reading text file from sd, to be sent to client took 15 ms Core 2.02 , same task, took 6000+ ms Needed to go back to 2.01
SD works very slow in 2.02
@AppsByDavideV: It is OK to just remove these lines: https://github.com/espressif/arduino-esp32/pull/5988/commits/f32c0da7e2e8336c05171cf312541369b45737f2
@AppsByDavideV: It is OK to just remove these lines: f32c0da
Yes, it works fine now with core 2.02, thanks
Likewise, if the lines in https://github.com/espressif/arduino-esp32/commit/f32c0da7e2e8336c05171cf312541369b45737f2 are removed, SD works in V2.0.2, tested with PlatformIO, thanks to @FrankBoesing
Hello @FrankBoesing, we will take a look on this issue. Thanks for reporting.
Related to #6078. These 2 issues can be validate and tested together, @P-R-O-C-H-Y.
Hello, the same here : SD read and write very slow since 2.0.2. Speed was around 400-500 ko/s before, now 4 ko/s after 2.0.2 upgrade. Thanks
getting random [sd_diskio.cpp:186] sdCommand(): token error [23] 0x4
and [sd_diskio.cpp:174] sdCommand(): no token received
under heavy load too.
During a screen capture test, 6 files out of 256 failed to write to SD with an average size of 40kb, this is after applying @FrankBoesing's fix.
Hello, can you try editing sd_diskio.cpp as PR #6103 and test it? It should fix the bug. Thanks
@P-R-O-C-H-Y confirmed unbroken SD after applying this PR
[edit] as pointed out by @Vigeant unbroken state isn't persistent, goes back to broken after a power cycle :-(
Hello,
Yes it is OK after romvind lines in d_diskio.cpp
Thanks
----- Mail original ----- De: "P-R-O-C-H-Y" @.> À: "espressif/arduino-esp32" @.> Cc: "edouardreg" @.>, "Comment" @.> Envoyé: Lundi 10 Janvier 2022 11:20:14 Objet: Re: [espressif/arduino-esp32] SD card status check bug (Issue #6081)
Hello, can you try editing sd_diskio.cpp as PR #6103 and test it? It should fix the bug. Thanks
— Reply to this email directly, view it on GitHub , or unsubscribe . Triage notifications on the go with GitHub Mobile for iOS or Android . You are receiving this because you commented. Message ID: <espressif/arduino-esp32/issues/6081/1008725333 @ github . com>
Well, after upgrading to 2.02 and applying the fix from PR #6103 as suggested by @P-R-O-C-H-Y my sketch worked for a while and I could read the card again. However, when I resumed work today, it would fail again in the sd_diskio.cpp in the sdWait()<-sdSelectCard() trace. I tried reloading and resetting many times and it would always fail to mount. I reverted my esp32 library back to 1.06 as I had to do before to fix my sd card mounting issues and my card mounted fine. Once the card mounted, I could re-update to 2.02 and apply the PR #6103 fix and my card would keep working. Not sure what happens in the card but it seems like something happens to the card that makes the sdWait() fail in 2.02 that is simply ignored or fixed in 1.06. When running a diff between the 1.06 and 2.02 sd_diskio.cpp you see that the sdSelectCard() is slightly different. In 1.06 it logs that sdWait() failed and keeps going and it still mounts successfully (and fixes the card somehow). In 2.02, if this sdWait fails, it deasserts the ss and errors out stopping the initialization of the card. All that to say that there seem to be more to it than just the PR #6103. There seem to be a fail condition that 1.06 handles better than 2.02 during initialization. Any help from a dev here would be appreciated.
Status check bug fix is merged now so this issue gets automatically closed.
Working on reported issues with mounting sd cards :) Thanks @Vigeant for report.
@Vigeant @tobozo Can you try removing(commenting) these 2 lines from sd_diskio.cpp
in function sdSelectCard
?
This can be the issue you are getting. I cannot reproduce the issue so I will be glad if you or someone can test that.
bool sdSelectCard(uint8_t pdrv)
{
ardu_sdcard_t * card = s_cards[pdrv];
digitalWrite(card->ssPin, LOW);
bool s = sdWait(pdrv, 300);
if (!s) {
log_e("Select Failed");
//digitalWrite(card->ssPin, HIGH); comment these 2
//return false;
}
return true;
}
These 2 lines are not in 1.0.6. Please let me know :) Thanks
@P-R-O-C-H-Y this seems to solve the SD mounting issue on ESP32-Wroom and ESP32-S2 and the fix persists across power cycles \o/
@P-R-O-C-H-Y this seems to solve the SD mounting issue on ESP32-Wroom and ESP32-S2 and the fix persists across power cycles \o/
Thanks @tobozo for testing. Will look why it was added and if its necessary to have these lines.
Hi @P-R-O-C-H-Y , This is what I am running with since my post and haven't had problems mounting. This seems to be the issue.
@tobozo @Vigeant When you commented out these 2 lines, the sdwait
still fails right? Can you try making sdWait with longer timeout(lets try double = 600 or 1000)? I would appreciate any help with that. I cannot reproduce the issue with my HW and SD cards. Thanks!
bool sdSelectCard(uint8_t pdrv)
{
ardu_sdcard_t * card = s_cards[pdrv];
digitalWrite(card->ssPin, LOW);
bool s = sdWait(pdrv, 600); <--- edit to 600 or 1000
if (!s) {
log_e("Select Failed");
digitalWrite(card->ssPin, HIGH);
return false;
}
return true;
}
@P-R-O-C-H-Y mounting fails both at 600 and 1000 on ESP32-S2, but I can't see the error as it happens before USBCDC is ready, and using setDebugOutput(true) seems to create other problems.
ESP32-Wroom (M5Stack Grey) doesn't seeem to care about this change, works fine in both situations.
@tobozo For me on ESP32-S2 even if I change the timeout to 10 it still works... Can you try that with different sd cards? Maybe its more related to HW. So hard to find the issue when its working totally fine for me :/
@P-R-O-C-H-Y I have three microsd cards (4GB kingston, 32GB sandisk, 16GB sandisk), the 4GB is a faulty one stuck in readonly mode I keep to test edgy cases, all three show similar symptoms.
The hardware isn't very special, the ESP32-S2 device is an USB dongle with hall sensor connected to gpio0 and a SD card.
In the sketch it's started using SD.begin(SD_CS, SPI, 40000000);
#define SD_MISO 37
#define SD_MOSI 35
#define SD_SCK 36
#define SD_CS 34
Maybe @AprilBrother can send you a sample of their ESP32-WUD? I got mine shipped to europe in less than 10 days.
@P-R-O-C-H-Y here are the requested tests.
bool sdSelectCard(uint8_t pdrv)
{
ardu_sdcard_t * card = s_cards[pdrv];
digitalWrite(card->ssPin, LOW);
bool s = sdWait(pdrv, 300);
if (!s) {
log_e("Select Failed");
digitalWrite(card->ssPin, HIGH);
return false;
}
return true;
}
and ran the sd example without power cycling the sparkfun esp32 thing. The card mounted.
The card failed to mount following a power cycle with following log trace:
[ 335][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 335][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[ 335][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 340][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 649][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 649][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Card Mount Failed
Card failed to mount same error as test2
Card failed to mount same error as test2
bool sdSelectCard(uint8_t pdrv)
{
ardu_sdcard_t * card = s_cards[pdrv];
digitalWrite(card->ssPin, LOW);
bool s = sdWait(pdrv, 100);
if (!s) {
log_e("Select Failed");
//digitalWrite(card->ssPin, HIGH);
//return false;
}
return true;
}
Card mounted and worked fine with smaller delay.
SD Card Type: SDHC
SD Card Size: 30436MB
Listing directory: /
DIR : System Volume Information
FILE: test.txt SIZE: 1048576
FILE: foo.txt SIZE: 13
...
Removing Dir: /mydir
Dir removed
Writing file: /hello.txt
File written
Appending to file: /hello.txt
Message appended
Reading file: /hello.txt
Read from file: Hello World!
Deleting file: /foo.txt
File deleted
Renaming file /hello.txt to /foo.txt
File renamed
Reading file: /foo.txt
Read from file: Hello World!
1048576 bytes read for 1420 ms
1048576 bytes written for 2756 ms
Total space: 30419MB
Used space: 25MB
Also, no log of the sdWait() failing
@tobozo So on the ESP32 it works and ESP32S2 it does not. Can you try to measure or just ignore the timeout in sdWait and how long it takes to success or if it ever success?
bool sdWait(uint8_t pdrv, int timeout)
{
char resp;
uint32_t start = millis();
do {
resp = s_cards[pdrv]->spi->transfer(0xFF);
} while (resp == 0x00); //removed timeout, just waiting for resp==0x00
if (!resp) {
log_w("Wait Failed");
}
return (resp > 0x00);
}
If that success, can you measure the time it needed to pass?
bool sdWait(uint8_t pdrv, int timeout)
{
char resp;
uint32_t start = millis();
do {
resp = s_cards[pdrv]->spi->transfer(0xFF);
} while (resp == 0x00);
log_w("Time to pass: %d",millis()-start); //enable core debug level to warning or edit the line :)
if (!resp) {
log_w("Wait Failed");
}
return (resp > 0x00);
}
@Vigeant Thanks for testing :) But I still don't get why the sdWait fails... Its just waiting for SPI transfer response. maybe its more related to used SPI by SD lib.
According to test 2: If you try multiple times SD.Begin() will that connect after some errors or will never work again? Like this:
while (!SD.begin(SDCARD_SPI_GPIO_CS, SPI)) delay(100);
@P-R-O-C-H-Y
No luck it never logs that it fails ; ( even though its ignored.
void setup() {
Serial.begin(115200);
while (!SD.begin(16, SPI, 25000000)){
Serial.println("Card Mount loop Failed");
delay(100);
}
/*
if (!SD.begin(16, SPI, 25000000)) {
Serial.println("Card Mount Failed");
return;
}
*/
...
}
trace is
Card Mount loop Failed
[ 21520][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 21520][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[ 21520][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 21525][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 21633][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 21633][E][sd_diskio.cpp:126] sdSelectCard():
[ 21844][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 21844][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[ 21844][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 21849][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 21957][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 21957][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Card Mount loop Failed
[ 22168][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 22168][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[ 22168][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 22173][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 22281][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 22281][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Card Mount loop Failed
[ 22492][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 22492][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[ 22492][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 22497][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 22605][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 22605][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Card Mount loop Failed
[ 22816][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 22816][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[ 22816][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 22821][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 22929][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 22929][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Card Mount loop Failed
[ 23140][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 23140][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[ 23140][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 23145][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 23253][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 23253][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Card Mount loop Failed
[ 23464][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 23464][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[ 23464][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 23469][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 23577][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 23577][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Card Mount loop Failed
[ 23788][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 23788][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[ 23788][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 23793][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 23901][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 23901][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Card Mount loop Failed
so fails forever...
@Vigeant can you specify SPI pins in setup? Can you try this exact setup? Without setting SD frequency?
//change pins you use
#define SDCARD_SPI_MISO 2
#define SDCARD_SPI_MOSI 15
#define SDCARD_SPI_SCK 14
#define SDCARD_SPI_CS 13
void setup() {
Serial.begin(115200);
delay(100);
SPI.begin(SDCARD_SPI_SCK,
SDCARD_SPI_MISO,
SDCARD_SPI_MOSI,
SDCARD_SPI_CS); //SCK, MISO, MOSI, SS (CS)
while (!SD.begin(SDCARD_SPI_CS, SPI)) {
Serial.println("Card Mount loop Failed");
delay(100);
}
//...
}
Interesting!
//change pins you use (Sparkfun esp32 thing with gpio 16 for my card)
#define SDCARD_SPI_MISO 19
#define SDCARD_SPI_MOSI 23
#define SDCARD_SPI_SCK 18
#define SDCARD_SPI_CS 16
void setup() {
Serial.begin(115200);
delay(100);
SPI.begin(SDCARD_SPI_SCK,
SDCARD_SPI_MISO,
SDCARD_SPI_MOSI,
SDCARD_SPI_CS); //SCK, MISO, MOSI, SS (CS)
while (!SD.begin(SDCARD_SPI_CS, SPI)) {
Serial.println("Card Mount loop Failed");
delay(100);
}
...
}
and the trace !
[ 135][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 236][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 337][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 437][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
[ 437][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 438][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 448][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 553][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 654][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 754][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
Card Mount loop Failed
[ 861][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 962][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1063][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1163][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
[ 1163][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 1164][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 1173][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1279][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1380][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1480][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
Card Mount loop Failed
SD Card Type: SDHC
SD Card Size: 30436MB
Listing directory: /
DIR : System Volume Information
FILE: test.txt SIZE: 0
FILE: foo.txt SIZE: 13
...
0 bytes read for 0 ms
1048576 bytes written for 5164 ms
Total space: 30419MB
Used space: 29MB
Important to note that the size of test.txt should be 1048576 Bytes!!!. So it eventually mounted but clobbered the test.txt file??? Also, the card is running kind of slow... (half speed)
@Vigeant Hmm we are getting somewhere.. Now there is no problem with sdWait but its still failing in mount for some time.
Can you list dirs again after writing to the file?
@P-R-O-C-H-Y This time it worked flawlessly
SD Card Type: SDHC
SD Card Size: 30436MB
Listing directory: /
DIR : System Volume Information
FILE: test.txt SIZE: 1048576
FILE: foo.txt SIZE: 13
DIR : edit
DIR : recordings
DIR : www
FILE: index.htm SIZE: 5450
Creating Dir: /mydir
Dir created
Listing directory: /
DIR : System Volume Information
FILE: test.txt SIZE: 1048576
FILE: foo.txt SIZE: 13
DIR : mydir
DIR : edit
DIR : recordings
DIR : www
FILE: index.htm SIZE: 5450
Removing Dir: /mydir
Dir removed
Writing file: /hello.txt
File written
Appending to file: /hello.txt
Message appended
Reading file: /hello.txt
Read from file: Hello World!
Deleting file: /foo.txt
File deleted
Renaming file /hello.txt to /foo.txt
File renamed
Reading file: /foo.txt
Read from file: Hello World!
1048576 bytes read for 3306 ms
1048576 bytes written for 4570 ms
Listing directory: /
DIR : System Volume Information
FILE: test.txt SIZE: 1048576
FILE: foo.txt SIZE: 13
DIR : edit
DIR : recordings
DIR : www
FILE: index.htm SIZE: 5450
Total space: 30419MB
Used space: 29MB
Oh but fails forever following a power cycle...
Card Mount loop Failed
[ 47495][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 47495][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[ 47495][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 47500][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 47808][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 47808][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Card Mount loop Failed
[ 48219][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 48219][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[ 48219][W][sd_diskio.cpp:510] ff_sd_initialize(): GO_IDLE_STATE failed
[ 48224][E][sd_diskio.cpp:796] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[ 48532][W][sd_diskio.cpp:104] sdWait(): Wait Failed
[ 48532][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
Card Mount loop Failed
commenting the 2 lines in sdSelectCard
fixes it.
And than is again problem in sdWait().. so commenting out fixes that but that's not a fix :D
Speed is slower because when you don't specify frequency, it will be set to 4Mhz. Before you used 25Mhz.
exactly. The weird part is that it will work until a power cycle so it points to something with the SPI module initialization maybe?
is there a way to dump the spi module status/config registers? I would dump it and compare.
What if you call SPI.end() ? Sorry for dumb question.. Its working until a power cycle. So you are restarting the cpu right?
ya
Can you call SD.end() and SPI.end() before restart?
so call SPI.end() before begin()?
You can try that :) but I mean before you restart CPU end the SD and SPI and after that restart cpu
not sure what you mean with restart cpu. In software using arduino API?
How are you doing the power cycle?
I disconnect from usb and battery
When I was testing a was just using software to restart the CPU, will try with disconnecting to. So I mean after the routine of listing and writing to file call SD.end() and SPI.end(). After that disconnect and connect board again. If still doesn't work you can try to call SPI.end before calling begin. But I think it won't make any change
Ya soft reset does not make it fail. Only a full power cycle.
Adding SD.end() and SPI.end() did not help (Had to comment out the lines for this to happen and then uncomment en powercycle...)
I still have no problems.. Cannot reproduce the issues :/ even I disconnect the board.
Isn't that related to Pullups resistors now? For your case.
not sure. Here is the trace on the first reboot that fixes the card:
10:26:38.516 -> [ 434][W][sd_diskio.cpp:104] sdWait(): Wait Failed
10:26:38.516 -> [ 434][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
10:26:38.516 -> [ 434][W][sd_diskio.cpp:180] sdCommand(): crc error
10:26:38.610 -> [ 537][W][sd_diskio.cpp:180] sdCommand(): crc error
10:26:38.845 -> SD Card Type: SDHC
10:26:38.892 -> SD Card Size: 30436MB
Do you want me to try and configure my CS pin with a pullup before I start my spi bus and sd card? well the begin configures it as output itself. want me to change this to OUTPUT_OPEN_DRAIN
?
Try that on MOSI pin according to this: sdspi-espidf
hmm Guess I would need to set MOSI to OUTPUT_OPEN_DRAIN
and add a physical 10k pullup.
Mod needs to be on line 230 of espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-spi.c
.
Cannot try this ATM. Does your setup have an external 10k pullup? There is no such thing as OUTPUT_PULLUP...
Board
WT32-SC01
Device Description
ESP-Wrover-Kit
Hardware Configuration
SD Slot
Version
latest master
IDE Name
Platformio
Operating System
Windows 10
Flash frequency
80MHz
PSRAM enabled
no
Upload speed
115200
Description
Enabled log shows many many SD- CRC Failures, reading is not possible wit 2.0.2
After revert the mentioned change, SD starts working again.
Sketch
Debug Message
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide