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

[SDMMC] ESP32-S3-N8R8 fails to start a microSD card in SDMMC_FREQ_HIGHSPEED mode (IDFGH-6901) #8521

Closed
1 task done
ThanosSiopoudis opened this issue Mar 7, 2022 · 11 comments
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally

Comments

@ThanosSiopoudis
Copy link

ThanosSiopoudis commented Mar 7, 2022

Environment

  • Module or chip used: [ESP32-S3-WROOM-1-N8R8]
  • IDF version (run git describe --tags to find it): v5.0-dev-1867-g5faf116d26
  • Build System: [idf.py]
  • Compiler version (run xtensa-esp32-elf-gcc --version to find it): xtensa-esp32-elf-gcc (crosstool-NG esp-2021r2-patch3) 8.4.0
  • Operating System: [macOS]
  • Using an IDE?: [Yes (please give details)]: VSCode
  • Power Supply: [external 3.3V]

Problem Description

ESP32-S3-WROOM-1-N8R8 module has trouble with microSD cards at 40MHz / 4-line mode. I have tried both an ESP32-S3-DEVKITC-1-N8R8 and an ESP32-S3-WROOM-1-N8R8 module on a printed circuit board.

The PCB is populated with 10KOhm pull-ups on CMD and D0-D3 lines (and I also tried adding an extra pull-up on the CLK line).
The Devkit was tested with just the internal weak pull-ups enabled.

In both cases, and after trying numerous brands, sizes and speed-rated microSD cards, I have found that they can rarely start at 40MHz (SDMMC_FREQ_HIGHSPEED) mode, and when they do, there are block read errors observed.

Expected Behavior

Expected the microSD card to start in HIGHSPEED mode.

Actual Behavior

Most of the times, the card fails to start in 40MHz mode with the following errors:

E (1037) sdmmc_common: sdmmc_init_ocr: send_op_cond (1) returned 0x107
E (1037) vfs_fat_sdmmc: sdmmc_card_init failed (0x107).

After resetting, it can sometimes start at 40MHz, but when proceeding to read data, block read errors eventually occur:

E (3340) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (3340) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (3342) sdmmc_req: handle_idle_state_events unhandled: 00000008 00000000

Starting the cards at 20MHz mode works fine with no errors.

Steps to reproduce

  1. Setup an ESP32S3-N8R8 module or devkit with the following pin assignments:
const gpio_num_t kSDSCK_Pin = GPIO_NUM_8;
const gpio_num_t kSDCMD_Pin = GPIO_NUM_9;
const gpio_num_t kSDD0_Pin = GPIO_NUM_18;
const gpio_num_t kSDD1_Pin = GPIO_NUM_7;
const gpio_num_t kSDD2_Pin = GPIO_NUM_17;
const gpio_num_t kSDD3_Pin = GPIO_NUM_16;
  1. Attach 10k pull-up resistors to all lines above except for SCK (CLK)
  2. Compile and run the example code below
  3. SD card fails to start at 40MHz, or when it starts, read errors occur

Code to reproduce this issue

      sdmmc_host_t host = SDMMC_HOST_DEFAULT();
      host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;

      sdmmc_slot_config_t slot_config = {
        .clk    = kSDSCK_Pin,
        .cmd    = kSDCMD_Pin,
        .d0     = kSDD0_Pin,
        .d1     = kSDD1_Pin,
        .d2     = kSDD2_Pin,
        .d3     = kSDD3_Pin,
        .d4     = GPIO_NUM_NC,
        .d5     = GPIO_NUM_NC,
        .d6     = GPIO_NUM_NC,
        .d7     = GPIO_NUM_NC,
        .cd     = SDMMC_SLOT_NO_CD,
        .wp     = SDMMC_SLOT_NO_WP,
        .width  = 4,
        .flags  = SDMMC_SLOT_FLAG_INTERNAL_PULLUP
      };

      esp_vfs_fat_sdmmc_mount_config_t mount_config = {
        .format_if_mount_failed = false,
        .max_files = 5,
        .allocation_unit_size = 16 * 1024
      };

      sdmmc_card_t* card;
      esp_err_t mountRes = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
      sdmmc_card_print_info(stdout, card);

Debug Logs

I (957) gpio: GPIO[8]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (963) gpio: GPIO[9]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (973) gpio: GPIO[18]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (983) gpio: GPIO[7]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (991) gpio: GPIO[17]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (1001) gpio: GPIO[16]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
E (1037) sdmmc_common: sdmmc_init_ocr: send_op_cond (1) returned 0x107
E (1037) vfs_fat_sdmmc: sdmmc_card_init failed (0x107).

Other items if possible

  • sdkconfig file (attach the sdkconfig file from your project folder)
    sdkconfig.zip
@espressif-bot espressif-bot added the Status: Opened Issue is new label Mar 7, 2022
@github-actions github-actions bot changed the title [SDMMC] ESP32-S3-N8R8 fails to start a microSD card in SDMMC_FREQ_HIGHSPEED mode [SDMMC] ESP32-S3-N8R8 fails to start a microSD card in SDMMC_FREQ_HIGHSPEED mode (IDFGH-6901) Mar 7, 2022
@ntwallace
Copy link

I'm seeing the same issue with an N8R8 devkit and also on a custom PCB with an WROOM-N8R2 or WROOM-N8R8. The PCB has an SPI bus running at 80MHz without issue, so it's not a problem with the trace lengths.

@igrr
Copy link
Member

igrr commented Mar 11, 2022

@ThanosSiopoudis @ntwallace Thank you for reporting the issue! Could you please try to apply the attached patch and see if it improves the situation?
0001-Draft-sdmmc-fix-unreasonable-i-o-clock-phase-setting.patch.txt

@ThanosSiopoudis
Copy link
Author

ThanosSiopoudis commented Mar 12, 2022

Thanks @igrr, I've applied the patch and I can confirm that it now consistently starts at 40MHz and no read errors are observed (I did not test extensively however).

Name: SC16G
Type: SDHC/SDXC
Speed: 40 MHz
Size: 15193MB
CSD: ver=2, sector_size=512, capacity=31116288 read_bl_len=9
SSR: bus_width=4

@mishaturnbull
Copy link

Hey all, I think I might have a similar issue. I'm using an ESP32-S3 as well (specifically the ESP32-S3-DevKitC-1) and can't get it to talk to a microSD card. Card's connected over the following pins:

  • MOSI: GPIO11
  • MISO: GPIO13
  • SCLK: GPIO12
  • CS: GPIO10
    The SD card breakout board includes 10kohm pullup resistors on each of those lines, which seems to be necessary for this particular devkit.

I'm getting the same error message that ThanosSlopoudis is in the initial issue, however, applying Igor's patch did not fix the issue for me. The only difference I've noticed is that I haven't yet tried SDMMC_FREQ_HIGHSPEED, only SDMMC_FREQ_PROBING and the default, but I'll give that a try as well.

esp-idf version: 5963de1 plus Igor's patch from above

Full code:

 39 esp_err_t autoconfigure_usd_card(void) {                                        
 40     esp_err_t err;                                                              
 41 #if USDLOG_USE_ADV_MOUNT // false                                                       
 42     err = configure_usd_card();                                                 
 43 #else                                                                           
 44     ESP_LOGW(SDTAG, "proceeding without SD card error checking!");              
 45     setup_spi();                                                                
 46     esp_vfs_fat_sdmmc_mount_config_t mount_config = {                           
 47 #if USDLOG_FORMAT_IF_MOUNT_FAIL                                                 
 48         .format_if_mount_failed = true,                                         
 49 #else                                                                           
 50         .format_if_mount_failed = false,                                        
 51 #endif                                                                          
 52         .max_files = MAX_OPEN_FILES,                                            
 53         .allocation_unit_size = ALLOC_UNIT_SIZE                                 
 54     };                                                                          
 55     // do not init -- output pointer argument                                   
 56     sdmmc_card_t *card;                                                         
 57     const char mountpoint[] = MOUNTPOINT;                                       
 58     sdspi_device_config_t slot_config = {                                       
 59         .host_id = SPI2_HOST,                                         
 60         .gpio_cs = USDLOG_PIN_CS,                                               
 61         .gpio_cd = SDSPI_SLOT_NO_CD,                                            
 62         .gpio_wp = SDSPI_SLOT_NO_WP,                                            
 63         .gpio_int = SDSPI_SLOT_NO_INT                                           
 64     };                                                                          
 65     sdmmc_host_t host = SDSPI_HOST_DEFAULT();                                   
 66     slot_config.host_id = host.slot;                                            
 67                                                                                 
 68     err = esp_vfs_fat_sdspi_mount(                                              
 69             mountpoint,                                                         
 70             &host,                                                              
 71             &slot_config,                                                       
 72             &mount_config,                                                      
 73             &card);                                                             
 74 #endif                                                                          
 75     if (err == ESP_OK) {                                                        
 76         sdmmc_card_print_info(stdout, card);                                    
 77     }                                                                           
 78     return err;                                                                 
 79 }

(the whole #if USDLOG_USE_ADV_MOUNT thing is to allow development to continue while using the all-in-one example function while also working on the production-safe reimplementation of it, as suggested in the API reference. I'm getting the exact same behavior in both methods right now.)

sdkconfig.txt

Apologies if my code makes no sense -- it's seen better days :)

@igrr
Copy link
Member

igrr commented Mar 16, 2022

@mishaturnbull I'm sorry, this issue isn't related to the problem you are seeing. Your code uses sdspi driver while this issue is about sdmmc. My patch won't help because it modifies the sdmmc driver.

Please try to run examples/storage/sd_card/sdspi from the master branch, adjusting the pins in menuconfig for your hardware. If that doesn't work, please open new issue and post the details, including console output at debug log level. Thanks!

@Paryavi
Copy link

Paryavi commented Aug 3, 2022

Hi @igrr

In my Arduino code following the SDMMC test example; https://github.com/espressif/arduino-esp32/blob/master/libraries/SD_MMC/examples/SDMMC_Test/SDMMC_Test.ino

for our custom designed ESP32S3Wroom1u with 16 MB of flash and OPI PSRAM

I have added the following to set pins

if(!SD_MMC.setPins(47, 48, 39, 40, 0, 38)){ // added setting pins and testing if SDMMCFS class bool setPins() returns False when setting pins
Serial.println("Setting Pins Failed");
return;
}

#define SOC_SDMMC_USE_GPIO_MATRIX;
#define BOARD_MAX_SDMMC_FREQ SDMMC_FREQ_DEFAULT

But for
if(!SD_MMC.begin()){
Serial.println("Card Mount Failed");
return;
}

I get the following error:

E (212) sdmmc_common: sdmmc_init_ocr: send_op_cond (1) returned 0x107
E (212) vfs_fat_sdmmc: sdmmc_card_init failed (0x107).
[ 349][E][SD_MMC.cpp:138] begin(): Failed to initialize the card (0x107). Make sure SD card lines have pull-up resistors in place.
SD Card Mount Failed
Although we have added external pull-up resistors.

Any comments on how to fix this issue?
Thanks

@igrr
Copy link
Member

igrr commented Aug 3, 2022

@Paryavi It seems that the card init fails at a very early stage. I think it's unrelated to the issue of high-speed mode being discussed here.
Please check the connections carefully, and use an oscilloscope or a logic analyzer to check if the card responds on the D0 line. You can open the issue in https://github.com/espressif/arduino-esp32 for further support.

@crohlfs
Copy link

crohlfs commented Aug 4, 2022

I ran into this issue as well with my PCB with a N32R8V module. The patch posted above fixed it and it now seems to mount every time.

@espressif-bot espressif-bot added Status: Reviewing Issue is being reviewed and removed Status: In Progress Work is in progress labels Aug 8, 2022
@NARRob
Copy link

NARRob commented Aug 24, 2022

@ThanosSiopoudis @ntwallace Thank you for reporting the issue! Could you please try to apply the attached patch and see if it improves the situation?
0001-Draft-sdmmc-fix-unreasonable-i-o-clock-phase-setting.patch.txt

@igrr Can this patch be applied to Stable 4.4.2? Facing the same issue with ESP32-S3-N8. Compiling with latest master is ok, compiling with 4.4.2 can only mount if 20 MHz and always fails on 40 MHz. Using SDMMC/4-bit. We must use the 4.4.2 as the ESP-ADF is not yet fully supported with v5.1 latest (any time frame for v5 to support ADF? or patches?)

Thanks

@remyhx
Copy link

remyhx commented Oct 21, 2022

@ThanosSiopoudis @ntwallace Thank you for reporting the issue! Could you please try to apply the attached patch and see if it improves the situation? 0001-Draft-sdmmc-fix-unreasonable-i-o-clock-phase-setting.patch.txt

Hi, I was just testing my custom PCB (ESP32-S3 Mini) with an eMMC (eMMC_Samsung-KLMAG1JETD-B041) and also run into the 0x109 error. My ESP-IDF version: ESP-IDF v5.1-dev-1384-g7052a14d61-dirty.

Applying the patch (git apply 0001-Draft-sdmmc-fix-unreasonable-i-o-clock-phase-setting.patch.txt in the ESP-IDF directory) worked! For 4-bit / 40MHz only with host.flags &= ~SDMMC_HOST_FLAG_DDR; enabled. (Or should I say disabled haha) and auto format if mount failed enabled.

For the 1-bit / 40MHz, I can omit the host.flags &= ~SDMMC_HOST_FLAG_DDR; code.

Is there maybe a more permanent fix to be expected?

@Blaster1920
Copy link

E (212) sdmmc_common: sdmmc_init_ocr: send_op_cond (1) returned 0x107

Hi @Paryavi ,
I'm having the same problem on a ESP32-S3-WROOM-1U-N16R8. Did you manage to fix it?
Set custom pins according to schematic and function contructor:

bool set_pins = SD_MMC.setPins(SDMMC_CLK, SDMMC_CMD,\ SDMMC_DAT_0, SDMMC_DAT_1,\ SDMMC_DAT_2, SDMMC_DAT_3);

Schematic is as follows:
image

Applying the patch didn't work. Microsd formatted as fat32 and exfat, same negative result. Microsd_det works correctly. Speed is 10kHz.

Thanks in advance.

@espressif-bot espressif-bot added Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Resolution: Done Issue is done internally and removed Status: Reviewing Issue is being reviewed Resolution: NA Issue resolution is unavailable labels Apr 17, 2023
espressif-bot pushed a commit that referenced this issue Apr 22, 2023
1. Fix incorrect meaning of SDMMC.clock bits, synchronize the names
   with the TRM.
2. Choose input and output phases to satisfy typical timing
   requirements.
3. Move use_hold_reg setting into the host driver, since it is related
   to timing.

Closes #8521
Related to #8257
espressif-bot pushed a commit that referenced this issue May 5, 2023
1. Fix incorrect meaning of SDMMC.clock bits, synchronize the names
   with the TRM.
2. Choose input and output phases to satisfy typical timing
   requirements.
3. Move use_hold_reg setting into the host driver, since it is related
   to timing.

Closes #8521
Related to #8257
espressif-bot pushed a commit that referenced this issue May 14, 2023
1. Fix incorrect meaning of SDMMC.clock bits, synchronize the names
   with the TRM.
2. Choose input and output phases to satisfy typical timing
   requirements.
3. Move use_hold_reg setting into the host driver, since it is related
   to timing.

Closes #8521
Related to #8257
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

10 participants