Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SD card status check bug #6081

Closed
1 task done
FrankBoesing opened this issue Dec 28, 2021 · 71 comments · Fixed by #6103
Closed
1 task done

SD card status check bug #6081

FrankBoesing opened this issue Dec 28, 2021 · 71 comments · Fixed by #6103
Assignees
Labels
Milestone

Comments

@FrankBoesing
Copy link
Contributor

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

-----
Any that uses SD.h

Debug Message

-----

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@FrankBoesing FrankBoesing added the Status: Awaiting triage Issue is waiting for triage label Dec 28, 2021
@AppsByDavideV
Copy link

AppsByDavideV commented Dec 29, 2021

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

@FrankBoesing
Copy link
Contributor Author

@AppsByDavideV: It is OK to just remove these lines: f32c0da

@AppsByDavideV
Copy link

@AppsByDavideV: It is OK to just remove these lines: f32c0da

Yes, it works fine now with core 2.02, thanks

@schreibfaul1
Copy link

Likewise, if the lines in f32c0da are removed, SD works in V2.0.2, tested with PlatformIO, thanks to @FrankBoesing

@VojtechBartoska
Copy link
Collaborator

Hello @FrankBoesing, we will take a look on this issue. Thanks for reporting.

@VojtechBartoska VojtechBartoska changed the title With https://github.com/espressif/arduino-esp32/pull/5988 SD is not usable SD card status check bug Jan 4, 2022
@VojtechBartoska
Copy link
Collaborator

VojtechBartoska commented Jan 4, 2022

Related to #6078. These 2 issues can be validate and tested together, @P-R-O-C-H-Y.

@edouardreg
Copy link

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

@tobozo
Copy link
Contributor

tobozo commented Jan 6, 2022

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.

@P-R-O-C-H-Y P-R-O-C-H-Y linked a pull request Jan 6, 2022 that will close this issue
@P-R-O-C-H-Y
Copy link
Member

Hello, can you try editing sd_diskio.cpp as PR #6103 and test it?
It should fix the bug.
Thanks

@tobozo
Copy link
Contributor

tobozo commented Jan 10, 2022

@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 :-(

@edouardreg
Copy link

edouardreg commented Jan 10, 2022 via email

@Vigeant
Copy link
Contributor

Vigeant commented Jan 14, 2022

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.

@P-R-O-C-H-Y
Copy link
Member

P-R-O-C-H-Y commented Jan 17, 2022

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.

@P-R-O-C-H-Y
Copy link
Member

P-R-O-C-H-Y commented Jan 18, 2022

@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

@tobozo
Copy link
Contributor

tobozo commented Jan 18, 2022

@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
Copy link
Member

@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.

@Vigeant
Copy link
Contributor

Vigeant commented Jan 18, 2022

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.

@Vigeant
Copy link
Contributor

Vigeant commented Jan 20, 2022

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

@Vigeant
Copy link
Contributor

Vigeant commented Jan 20, 2022

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?

@P-R-O-C-H-Y
Copy link
Member

Try that on MOSI pin according to this: sdspi-espidf

@Vigeant
Copy link
Contributor

Vigeant commented Jan 20, 2022

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...

@P-R-O-C-H-Y
Copy link
Member

P-R-O-C-H-Y commented Jan 20, 2022

I have this SD SPI module image
It seems that the module have 10k resistors on pins. (there are 4 10K resistors)

@Vigeant
Copy link
Contributor

Vigeant commented Jan 20, 2022

@Vigeant
Copy link
Contributor

Vigeant commented Jan 20, 2022

Added 10k pullup on my SD card and no luck. It still wont survive a power cycle.

SD setupt

@P-R-O-C-H-Y
Copy link
Member

P-R-O-C-H-Y commented Jan 21, 2022

Do you have 5V power to the microSD board? Seems that 10k pull-up resistor does not help..
I'm actually getting out of any ideas why its not working for you. It has to be HW related when I don't have any issue on any ESP boards..

@tobozo
Copy link
Contributor

tobozo commented Jan 21, 2022

@P-R-O-C-H-Y removing the timeout in sdWait created an endless loop, it waits forever.

Tried SD.end / SD.begin in a loop with various delays with no effect.

It feels like something (SPI driver?) is setting up the pins in a way that persists across reboots.

I'm out of ideas.

@P-R-O-C-H-Y
Copy link
Member

Yeah it seems the problem is with SPI driver, but more weird is that I can't reproduce any issue on official ESPs Devkits boards (tried on ESP32 and ESP32S2).
It has to be HW related. Even more weird is that ignoring the sdWait() failure makes the SD card to fully work right?

@AppsByDavideV
Copy link

Even CS pin should have a 10K pull-up tied to 3.3V

@P-R-O-C-H-Y
Copy link
Member

One more thing to try @tobozo, @Vigeant.
Can you try same test with 2 different SPI speeds? Read somewhere that some cards don't like this freq for init.
Change in file SPI.cpp SPICLASS _freq

SPIClass::SPIClass(uint8_t spi_bus)
    :_spi_num(spi_bus)
    ,_spi(NULL)
    ,_use_hw_ss(false)
    ,_sck(-1)
    ,_miso(-1)
    ,_mosi(-1)
    ,_ss(-1)
    ,_div(0)
    ,_freq(1000000) <----- can you try higher speed 16000000 (16Mhz) and lower speed 300000 (300kHz)
    ,_inTransaction(false)
{}

@tobozo
Copy link
Contributor

tobozo commented Jan 21, 2022

I can't reproduce any issue on official ESPs Devkits boards

@P-R-O-C-H-Y maybe enable USBCDC at boot and don't use the hardware serial?

[edit] my board settings

image

However I got some freezes when using USBSerial.setDebugOutput(true), maybe it's unrelated, maybe it's part of the problem, but I recommend to not enable it and use occasional USBSerial.printf statements instead.

@tobozo
Copy link
Contributor

tobozo commented Jan 21, 2022

@P-R-O-C-H-Y commenting out does not help it just fails on the next transaction.

@P-R-O-C-H-Y
Copy link
Member

@P-R-O-C-H-Y commenting out does not help it just fails on the next transaction.

Yes failed for me too.
Can you try changing the SPI speed?

@tobozo
Copy link
Contributor

tobozo commented Jan 21, 2022

tried a few speeds from 16, 27, 40MHz, even 400KHz, using FSPI, HSPI, constructor, pointer, all fail with sdWait, all succeed when I comment out the return false in sdSelectCard.

So if the problem on ESP32-S2 is SPI related, it's probably wrapped between some #if CONFIG_IDF_TARGET_ESP32S2 macros (maybe even with an extra || CONFIG_IDF_TARGET_ESP32) right?

@P-R-O-C-H-Y
Copy link
Member

P-R-O-C-H-Y commented Jan 21, 2022

Thanks for testing that out.
My esp32s2 is working :) I think its not a driver think. More will be a SD card stuff.
Gonna look if there is something "missing or wrong" with macros in SPI.

Another test for you :)

Can you do this change in DSTATUS ff_sd_initialize(uint8_t pdrv) in sd_diskio.cpp.
Changed that it will try 10 times to switch card to idle state before it will fail.

    uint8_t go_idle_count = 0;

    while (sdTransaction(pdrv, GO_IDLE_STATE, 0, NULL) != 1) {
        log_w("GO_IDLE_STATE failed");
        go_idle_count++;
        if(go_idle_count == 10)
        {
            goto unknown_card;
        }
    }

@tobozo
Copy link
Contributor

tobozo commented Jan 21, 2022

this fails too, I'm already hammering the SD card in a 10x loop so there was 100 failed attempts instead of 10 :-)

Returning true on the first error only confirms the sdWait only fails once:

bool sdSelectCard(uint8_t pdrv)
{
    ardu_sdcard_t * card = s_cards[pdrv];
    digitalWrite(card->ssPin, LOW);
    bool s = sdWait(pdrv, 300);
    static int failures = 0;
    if (!s) {
        if( failures++ == 0 ) {
            log_w("SD Card initial selection failed, mocking success");
            return true;
        }
        log_e("Select Failed");
        digitalWrite(card->ssPin, HIGH);
        return false;
    }
    return true;
}

@P-R-O-C-H-Y
Copy link
Member

P-R-O-C-H-Y commented Jan 21, 2022

OK so the SDwaits fails only once, when the Go idle state is called. Did I get that right?
After that the SDwait is working fine ?
Can you print the response in the SDWait() from the SPItransfer?

@tobozo
Copy link
Contributor

tobozo commented Jan 21, 2022

Can you print the response in the SDWait() from the SPItransfer?

it only prints resp=0x00 on failure, which is to be expected (sdWait returns (resp > 0x00))

@Vigeant
Copy link
Contributor

Vigeant commented Jan 21, 2022

I confirm sdWait() only fails once. I put in @tobozo's snipet in mine:

bool sdSelectCard(uint8_t pdrv)
{
    ardu_sdcard_t * card = s_cards[pdrv];
    digitalWrite(card->ssPin, LOW);
    bool s = sdWait(pdrv, 300);
    static unsigned int failcount = 0;
    if (!s) {
		if (failcount == 0){
			log_e("Select Failed on first attempt!!!");
			//digitalWrite(card->ssPin, HIGH);
			//return false;
		} else {
			log_e("Select Failed");
			digitalWrite(card->ssPin, HIGH);
			return false;
		}
		failcount ++;
    }
    return true;
}

@P-R-O-C-H-Y P-R-O-C-H-Y mentioned this issue Jan 24, 2022
1 task
@P-R-O-C-H-Y
Copy link
Member

P-R-O-C-H-Y commented Jan 24, 2022

Hi @tobozo, @Vigeant
According the facts we found out, sdWait fails only one before the GO_IDLE_STATE command.
Made new commit to the PR - #6162 where I added to ignore the sdWait in the init phase before that cmd.

For me, it works same as before :D so if you can't test the changes, I will be thankful :)

@tobozo
Copy link
Contributor

tobozo commented Feb 3, 2022

@P-R-O-C-H-Y this implementation works for me but ignores the sdWait every time although we know it's only blocking on first access.

Ignoring this error every time could make the underlying problem more difficult to solve.

One of the effects of this is that if a write timeout occurs after mounting the drive, it'll be silently ignored and eventually result in a corrupted file without even producing a warning.

@ifrew
Copy link

ifrew commented Jun 5, 2022

I have this same issue after upgrading to the latest esp32 ardunio core 2.0.3 and using the latest @tobozo m5stack-sd-menu code. I am running visual studio with vmicro on a m5stack gray module with no PSRAM. I have a thread going with @tobozo on this issue, see tobozo/M5Stack-SD-Updater#171 . I applied #6103 and commented out the two lines as suggested above by @P-R-O-C-H-Y but no luck. What I did find though which may help folks find the issue and be able to repro is that I have 3 SPI devices attached in my design. 1 is the M5stack display, 1 is the M5Stack TFcard and the other is a LORA communication module. All are on the same bus with different CS pins. If I remove the m5stack module from the lora board everything works perfectly. If I reattach it I get the errors below. after loading @tobozo M5Stack-sd-menu code from my main app. So I though I'd try stopping all 3 SPI busses before the software reset. This made no difference which surprised me. I'm not a SPI expert, but it would seem to be an SPI issue and some control Pin not being reset to the correct state. With this info, does this trigger any thoughts from folks on these errors?

rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13732
ho 0 tail 12 room 4
load:0x40080400,len:3608
entry 0x400805f0
[ 1][D][Button.cpp:42] Button(): Button on pin 39, invert=1, debounce=10ms
[ 1][D][Button.cpp:42] Button(): Button on pin 38, invert=1, debounce=10ms
[ 4][D][Button.cpp:42] Button(): Button on ��� 37, invert=1, debounce=10ms
[ 12][D][esp32-hal-cpu.c:214] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
ESP32-Chimera-Core initializing [Board=M5Stack_Core_ESP32] [Variant=m5stack_core_esp32]
[ 87][D][ESP32-Chimera-Core.cpp:93] begin(): Enabling LCD
[ 101][W][LGFX_AutoDetect_ESP32.hpp:415] _read_panel_id(): [LovyanGFX] [Autodetect] read cmd:04 = 000000e3
[ 102][W][LGFX_AutoDetect_ESP32.hpp:1237] autodetect(): [LovyanGFX] [Autodetect] M5Stack
[ 258][D][ESP32-Chimera-Core.cpp:246] sd_begin(): SD will use VSPI
[ 259][D][ESP32-Chimera-Core.cpp:258] sd_begin(): TFCARD_SPI_HOST=2, SPI_HOST=0, HSPI_HOST=1, VSPI_HOST=2 from core #1
[ 264][E][esp32-hal-cpu.c:110] addApbChangeCallback(): duplicate func=0x400f2810 arg=0x3ffbdda8
[ 283][D][ESP32-Chimera-Core.cpp:273] sd_begin(): SD Card Mount Success on pins scl/miso/mosi/cs 18/19/23/4 from core #1
ESP32-Chimera-Core started
ESP-IDF version is: v4.4.1-1-gb8050b365e
[ 304][V][M5StackUpdaterUI.h:512] SetupSDMenuConfig(): Attached buttonpressA
[ 304][V][M5StackUpdaterUI.h:513] SetupSDMenuConfig(): Attached buttonpressB
[ 310][V][M5StackUpdaterUI.h:514] SetupSDMenuConfig(): Attached buttonpressC
[ 317][V][M5StackUpdaterUI.h:515] SetupSDMenuConfig(): Attached buttons poller
[ 324][V][M5StackUpdaterUI.h:516] SetupSDMenuConfig(): Attached onProgress
[ 331][V][M5StackUpdaterUI.h:517] SetupSDMenuConfig(): Attached onMessage
[ 338][V][M5StackUpdaterUI.h:518] SetupSDMenuConfig(): Attached onError
[ 344][V][M5StackUpdaterUI.h:519] SetupSDMenuConfig(): Attached onBefore
[ 351][V][M5StackUpdaterUI.h:520] SetupSDMenuConfig(): Attached onAfter
[ 357][V][M5StackUpdaterUI.h:521] SetupSDMenuConfig(): Attached onSplashPage
[ 364][V][M5StackUpdaterUI.h:522] SetupSDMenuConfig(): Attached onButtonDraw
[ 371][V][M5StackUpdaterUI.h:526] SetupSDMenuConfig(): Attached onWaitForAction (button)
[ 379][D][M5StackUpdater.h:211] _fsBegin(): Checking for SD Support (pin #4)
[ 386][D][M5StackUpdater.h:217] _fsBegin(): SD Successfully mounted (pin #4)
[ 393][I][esp32-hal-i2c-slave.c:234] i2cSlaveInit(): Initialising I2C Slave: sda=22 scl=22 freq=100000, addr=0x15
[ 403][D][esp32-hal-i2c-slave.c:498] i2c_slave_set_frequency(): Fifo thresholds: rx_fifo_full = 28, tx_fifo_empty = 4
[ 414][E][Wire.cpp:260] getClock(): Bus is in Slave Mode
[ 419][E][Wire.cpp:308] beginTransmission(): Bus is in Slave Mode
[ 425][E][Wire.cpp:331] endTransmission(): Bus is in Slave Mode
[ 431][V][I2CUtil.cpp:73] writeCommand(): send to 0x08 [0x00] result:NG
[ 437][E][Wire.cpp:260] getClock(): Bus is in Slave Mode
Welcome to the M5Stack SD Menu Loader!
M5Stack SD Updater initializing...
M5StackSam loaded with 8 labels per page, max 96 items
Has PSRam: false
[ 463][I][menu.h:148] heapState():
RAM SIZE: 333.77 KB
FREE RAM: 263.60 KB
MAX ALLOC: 107.99 KB
[ 501][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 601][W][sd_diskio.cpp:180] sdCommand(): crc error
[ 701][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 801][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x11
[ 802][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 901][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1001][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1101][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x0d
[ 1101][E][sd_diskio.cpp:621] ff_sd_status(): Check status failed
[ 1103][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1208][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1308][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1407][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
[ 1407][W][sd_diskio.cpp:516] ff_sd_initialize(): GO_IDLE_STATE failed
[ 1408][E][vfs_api.cpp:104] open(): /sd/menu.bin does not exist, no permits for creation
[ 1416][W][menu.h:658] checkMenuTimeStamp(): Menu.bin has an obsolete time set (2022-06-05 00:27:10), will use this sketch build date to set the clock

[Hobo style] Clock set to an obsolete source (this sketch build): June 05 2022 00:27:10 (Sunday)
[ 1444][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1544][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1644][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1743][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
[ 1743][W][sd_diskio.cpp:516] ff_sd_initialize(): GO_IDLE_STATE failed
[ 1745][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1851][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 1951][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 2050][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
[ 2050][W][sd_diskio.cpp:516] ff_sd_initialize(): GO_IDLE_STATE failed
[ 2052][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 2158][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 2258][W][sd_diskio.cpp:174] sdCommand(): no token received
[ 2357][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
[ 2357][W][sd_diskio.cpp:516] ff_sd_initialize(): GO_IDLE_STATE failed

@ifrew
Copy link

ifrew commented Jun 7, 2022

Looks like my issue was due to the LGFX graphics library doing auto detect of boards on the SPI bus and some of the boards they were looking for used the same CS pins as my SPI device that started giving issues. Details on this thread for those interested.... tobozo/M5Stack-SD-Updater#171

@zhekch zhekch mentioned this issue Sep 22, 2023
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Development

Successfully merging a pull request may close this issue.

9 participants