ducalex/retro-go

Question about reading sd card

Alocih opened this issue · 14 comments

Alocih commented

Recently I compiled this project for esplay-micro but cannot read the sd card file.
Reading sd card file by 1bitmode(clk 14, cmd 15, d0 2)
The Serial show the following error:

sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd return 0x109
diskio_sdmmc: sdmmc_read_blocks failed (265)

Then I found a solution. By removing the jumper between IO0 and IO2, I can read the SD card normally.

But when I use esplay-micro firmware, I can read SD card files normally without removing the jumper.
WHY? Is there a way to read normally without removing the jumper?

Sounds like a conflict between GPIO_0 and GPIO_2 but I don't think retro-go uses GPIO_0 for anything. It could be initialized by mistake, though. Or maybe the esplay-micro firmware configures GPIO_0 it in a specific way and we don't do the same.

Do you know why the esplay-micro has a jumper to link GPIO_0 and GPIO_2 to begin with? That might help me understand what's going on here.

Also maybe @Cralex knows more, he made the port to the micro.

Alocih commented

Sounds like a conflict between GPIO_0 and GPIO_2 but I don't think retro-go uses GPIO_0 for anything. It could be initialized by mistake, though. Or maybe the esplay-micro firmware configures GPIO_0 it in a specific way and we don't do the same.

Do you know why the esplay-micro has a jumper to link GPIO_0 and GPIO_2 to begin with? That might help me understand what's going on here.

I think IO0 and IO2 connections are used to flash. When this jumper is connected, the computer can directly flash firmware to esp32, but not when it is disconnected.

IO0 is connected to the AUTO RESET circuit
autoreset

Alocih commented

I used the esp-idf sdmmc example to test sd card reading without removing the jumper. It worked.
And i find a issue about this.
https://github.com/espressif/esp-idf/issues/2478
Then, I set host_config.max_freq_khz = 5000; Not working.

Cralex commented

I did a fresh clone of the project and tried compiling it, and everything seems to be working fine on my end. (I was worried that I'd pushed something broken since my initial port was done on a time crunch.) Are you saying that it works normally with the stock firmware but not Retro-Go, or that it seems to work on Retro-Go but that it doesn't work with some command-line utilities? Regrettably, I don't know much at all when it comes to low-level esp32 stuff or the actual device schematics, so my only frame of reference when porting Retro-Go has been if the end-user experience works or not. It's quite possible that something else isn't set up right.

Finally, you're working with this hardware, right? There's more than one esplay micro revision but I only have the v2 to test against.

Can you share the entire serial log from the time you power it until the error appears?

I'm curious if the card gets mounted successfully but errors out later.

Alocih commented

I did a fresh clone of the project and tried compiling it, and everything seems to be working fine on my end. (I was worried that I'd pushed something broken since my initial port was done on a time crunch.) Are you saying that it works normally with the stock firmware but not Retro-Go, or that it seems to work on Retro-Go but that it doesn't work with some command-line utilities? Regrettably, I don't know much at all when it comes to low-level esp32 stuff or the actual device schematics, so my only frame of reference when porting Retro-Go has been if the end-user experience works or not. It's quite possible that something else isn't set up right.

Finally, you're working with this hardware, right? There's more than one esplay micro revision but I only have the v2 to test against.

It works normally with pebri86‘s firmware. Retro-go also can works normally, but need remove jumper. I just wanna solve this problem.
I'm using this hardware with few changes.

Alocih commented

Can you share the entire serial log from the time you power it until the error appears?

I'm curious if the card gets mounted successfully but errors out later.

Yes.

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x3b (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:2
load:0x3fff0030,len:5960
load:0x40078000,len:15544
load:0x40080400,len:4452
entry 0x400806a0
I (27) boot: ESP-IDF v4.4.5-dirty 2nd stage bootloader
I (27) boot: compile time 18:10:15
I (27) boot: chip revision: v1.0
I (31) qio_mode: Enabling QIO for flash chip GD
I (36) boot.esp32: SPI Speed      : 40MHz
I (40) boot.esp32: SPI Mode       : QIO
I (45) boot.esp32: SPI Flash Size : 4MB
I (49) boot: Enabling RNG early entropy source...
I (55) boot: Partition Table:
I (58) boot: ## Label            Usage          Type ST Offset   Length
I (66) boot:  0 nvs              WiFi data        01 02 00009000 00004000
I (73) boot:  1 otadata          OTA data         01 00 0000d000 00002000
I (81) boot:  2 phy_init         RF data          01 01 0000f000 00001000
I (88) boot:  3 launcher         OTA app          00 10 00010000 000e0000
I (96) boot:  4 retro-core       OTA app          00 11 000f0000 000a0000
I (103) boot: End of partition table
I (107) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=2b1cch (176588) map
I (143) esp_image: segment 1: paddr=0003b1f4 vaddr=3ffb0000 size=03054h ( 12372) load
I (145) esp_image: segment 2: paddr=0003e250 vaddr=40080000 size=01dc8h (  7624) load
I (150) esp_image: segment 3: paddr=00040020 vaddr=400d0020 size=98828h (624680) map
I (253) esp_image: segment 4: paddr=000d8850 vaddr=40081dc8 size=14660h ( 83552) load
I (280) boot: Loaded app from partition at offset 0x10000
I (280) boot: Disabling RNG early entropy source...

========================================================
launcher 1 (Sep 26 2023 18:08:07)
 built for: ESPLAY-MICRO. aud=0 disp=0 pad=0 sd=0 cfg=0
========================================================

[info] rg_system_init: Chip info: model 1 rev1 (2 cores), reset reason: 1
[info] rg_system_init: Internal memory: free=283903, total=338195
[info] rg_system_init: External memory: free=4179783, total=4179783
[info] rg_storage_init: Storage mounted at /sd. driver=2
[info] rg_i2c_init: I2C driver ready (SDA:21 SCL:22).
[info] rg_input_init: Input ready. driver='C', state=00000000 00000000
[info] open_config_file: Opening /sd/retro-go/config/global.json for rb
[info] open_config_file: Opening /sd/retro-go/config/boot.json for rb
[info] rg_display_init: Initialization...
[info] open_config_file: Opening /sd/retro-go/config/launcher.json for rb
[info] rg_alloc: SIZE=2560, CAPS=DMA|8BIT, PTR=0x3ffc3810
[info] rg_alloc: SIZE=2560, CAPS=DMA|8BIT, PTR=0x3ffc4214
[info] rg_alloc: SIZE=2560, CAPS=DMA|8BIT, PTR=0x3ffc4c18
[info] rg_alloc: SIZE=2560, CAPS=DMA|8BIT, PTR=0x3ffc561c
[info] rg_alloc: SIZE=2560, CAPS=DMA|8BIT, PTR=0x3ffc6020
[info] lcd_set_backlight: backlight set to 60%
[info] rg_display_init: Display ready.
[info] rg_alloc: SIZE=12800, CAPS=SPIRAM|8BIT, PTR=0x3f805474
[info] rg_gui_set_font_type: Font set to: points=15, scaling=1.00
[info] rg_gui_set_theme: Using built-in theme!
[info] rg_audio_init: Audio ready. sink='Ext DAC', samplerate=32000, volume=30
E (1345) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1345) diskio_sdmmc: sdmmc_read_blocks failed (265)
[info] rg_system_load_time: Time is now: Wed Jul 23 23:09:20 2025

[info] rg_system_init: Retro-Go ready.

E (1365) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1365) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1375) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1375) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1395) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1395) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1405) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1405) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1415) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1415) diskio_sdmmc: sdmmc_read_blocks failed (265)
�[0;31mE (1435) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1435) diskio_sdmmc: sdmmc_read_blocks failed (265)
[info] rg_alloc: SIZE=153600, CAPS=SPIRAM|8BIT, PTR=0x3f808678
[info] gui_add_tab: Tab 'nes' added at index 0
[info] application: Application 'Super Nintendo' (snes9x-go) not present, skipping
[info] gui_add_tab: Tab 'gb' added at index 1
[info] gui_add_tab: Tab 'gbc' added at index 2
[info] gui_add_tab: Tab 'gw' added at index 3
[info] application: Application 'Sega Master System' (smsplusgx-go) not present, skipping
[info] application: Application 'Sega Game Gear' (smsplusgx-go) not present, skipping
[info] application: Application 'Sega Mega Drive' (gwenesis) not present, skipping
[info] application: Application 'Coleco ColecoVision' (smsplusgx-go) not present, skipping
[info] gui_add_tab: Tab 'pce' added at index 4
[info] gui_add_tab: Tab 'lnx' added at index 5
[info] application: Application 'DOOM' (prboom-go) not present, skipping
[info] application: Application 'Bootstrap' (bootstrap) not present, skipping
E (1555) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1555) diskio_sdmmc: sdmmc_read_blocks failed (265)
[info] gui_add_tab: Tab 'favorite' added at index 6
E (1575) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1575) diskio_sdmmc: sdmmc_read_blocks failed (265)
[info] gui_add_tab: Tab 'recent' added at index 7
E (1585) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1585) diskio_sdmmc: sdmmc_read_blocks failed (265)
[info] open_config_file: Opening /sd/retro-go/config/wifi.json for rb
E (1615) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1615) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1625) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1635) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1645) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1645) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1655) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1655) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1665) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1665) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1685) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1685) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1695) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1695) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1705) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1705) diskio_sdmmc: sdmmc_read_blocks failed (265)
[info] rg_network_wifi_load_config: Looking for 'ssid0' (slot 0)
[info] rg_network_wifi_load_config: Looking for 'ssid' (slot -1)
[warn] rg_network_wifi_start: Can't start wifi: No SSID has been configured.
[info] webui_start: Web server started
STACK:5228, HEAP:168+3494 (108+3264), BUSY:0%, FPS:33 (SKIP:33, PART:0, FULL:0), BATT:100
STACK:5228, HEAP:168+3494 (108+3264), BUSY:0%, FPS:54 (SKIP:54, PART:0, FULL:0), BATT:100
STACK:5228, HEAP:167+3494 (108+3264), BUSY:0%, FPS:54 (SKIP:54, PART:0, FULL:0), BATT:100
STACK:5228, HEAP:168+3494 (108+3264), BUSY:0%, FPS:55 (SKIP:55, PART:0, FULL:0), BATT:100
STACK:5228, HEAP:168+3494 (108+3264), BUSY:0%, FPS:55 (SKIP:55, PART:0, FULL:0), BATT:100
STACK:5228, HEAP:168+3494 (108+3264), BUSY:0%, FPS:55 (SKIP:55, PART:0, FULL:0), BATT:100
STACK:5228, HEAP:168+3494 (108+3264), BUSY:0%, FPS:56 (SKIP:56, PART:0, FULL:0), BATT:100

So the card mounts successfully and trying to read the settings files causes no error. But later there are errors when it tries to read the clock file.

Quite a bit happens between the two but mainly display init and audio init. I guess it must be one of those causing all the issues?

The easiest one to test would be audio. In rg_system.c find rg_audio_init(sampleRate); and move it all the way down just before RG_LOGI("Retro-Go ready.\n\n");.

If the following error is gone after the change, then I guess we're doing something stupid during audio init.

[info] rg_audio_init: Audio ready. sink='Ext DAC', samplerate=32000, volume=30
E (1345) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1345) diskio_sdmmc: sdmmc_read_blocks failed (265)
[info] rg_system_load_time: Time is now: Wed Jul 23 23:09:20 2025
Alocih commented

You are right.
I did it, the error is gone as you expected.

[info] rg_system_init: Chip info: model 1 rev1 (2 cores), reset reason: 3
[info] rg_system_init: Internal memory: free=283903, total=338195
[info] rg_system_init: External memory: free=4179783, total=4179783
[info] rg_storage_init: Storage mounted at /sd. driver=2
[info] rg_i2c_init: I2C driver ready (SDA:21 SCL:22).
[info] rg_input_init: Input ready. driver='C', state=00000000 00000000
[info] open_config_file: Opening /sd/retro-go/config/global.json for rb
[info] open_config_file: Opening /sd/retro-go/config/boot.json for rb
[info] rg_display_init: Initialization...
[info] open_config_file: Opening /sd/retro-go/config/launcher.json for rb
[info] rg_alloc: SIZE=2560, CAPS=DMA|8BIT, PTR=0x3ffc3810
[info] rg_alloc: SIZE=2560, CAPS=DMA|8BIT, PTR=0x3ffc4214
[info] rg_alloc: SIZE=2560, CAPS=DMA|8BIT, PTR=0x3ffc4c18
[info] rg_alloc: SIZE=2560, CAPS=DMA|8BIT, PTR=0x3ffc561c
[info] rg_alloc: SIZE=2560, CAPS=DMA|8BIT, PTR=0x3ffc6020
[info] lcd_set_backlight: backlight set to 60%
[info] rg_display_init: Display ready.
[info] rg_alloc: SIZE=12800, CAPS=SPIRAM|8BIT, PTR=0x3f805474
[info] rg_gui_set_font_type: Font set to: points=15, scaling=1.00
[info] rg_gui_set_theme: Using built-in theme!
[info] rg_system_load_time: Time loaded from storage
[info] rg_system_load_time: Time is now: Tue Aug  8 12:40:17 2023

[info] rg_audio_init: Audio ready. sink='Ext DAC', samplerate=32000, volume=30
[info] rg_system_init: Retro-Go ready.

E (1134) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1134) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1144) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1144) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1154) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1154) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1174) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1174) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1184) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1184) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1194) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1194) diskio_sdmmc: sdmmc_read_blocks failed (265)
[info] rg_alloc: SIZE=153600, CAPS=SPIRAM|8BIT, PTR=0x3f808678
[info] gui_add_tab: Tab 'nes' added at index 0
[info] application: Application 'Super Nintendo' (snes9x-go) not present, skipping

Then i just remove rg_audio_init(sampleRate); to test it, the SD can be read normally.
I think i need look into what happend in rg_audio_init(sampleRate); next.

Thanks a lot!

You can try disabling rg_audio_set_mute() in rg_audio.c since it does gpio stuff. Just comment its body and see if it helps (I doubt it will, esplay does pretty much the same thing, but it's an easy test).

Other than that, the only difference I see between esplay firmware and retro-go would be that they do .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 instead of .intr_alloc_flags = 0.

I don't see how it relates to GPIOs but I guess it's worth a try? replacing 0 by ESP_INTR_FLAG_LEVEL1 (it's the one at line 129)

Alocih commented

I've tried both methods, no lucky, it doesn't work. I also tried modifying other configuration values, still not work.
I'm confused!

Is there a way to detect where the code is running and there is an error in sd reading?

Is there a way to detect where the code is running and there is an error in sd reading?

I don't think it matters what code causes the error to show up, the issue is at a lower level.

But if I follow the code path taken by this particular log:

[info] rg_system_init: Retro-Go ready.

E (1134) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1134) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1144) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1144) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1154) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1154) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1174) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1174) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1184) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1184) diskio_sdmmc: sdmmc_read_blocks failed (265)
E (1194) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x109
E (1194) diskio_sdmmc: sdmmc_read_blocks failed (265)
[info] rg_alloc: SIZE=153600, CAPS=SPIRAM|8BIT, PTR=0x3f808678
[info] gui_add_tab: Tab 'nes' added at index 0

Then those errors are probably triggered by:

  1. rg_storage_mkdir (calls mkdir) called in app_main in launcher/main/main.c
  2. rg_storage_mkdir (calls mkdir) called in app_main in launcher/main/main.c
  3. rg_settings_commit (possibly calls fopen, fputs, mkdir, unlink, opendir, etc) called in try_migrate in launcher/main/main.c
Alocih commented

Thanks. I'll look into it.