Open specternecter opened 11 months ago
@specternecter The machine.SDCard bindings for the ESP32 port are written in such a way that they expect the device to support both MMC and SD. The C3 doesn't support MMC (see https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-reference/storage/sdmmc.html#_CPPv415sdmmc_card_initPK12sdmmc_host_tP12sdmmc_card_t).
It would be relatively straightforward to conditionally remove the MMC bits from esp32/machine_sdcard.c when compiling for C3. But because it's never been enabled, esp32/machine_sdcard.c
also hasn't had other tweaks put in place for C3 support like which SPI peripheral to use, pins, etc (i.e. it's only been set up for ESP32/ESP32S2/ESP32S3). That also shouldn't be too difficult.
In the meantime I suggest using the pure-python sdcard driver which you can install from micropython-lib which works on all ports (even with SoftSPI). https://github.com/micropython/micropython-lib/tree/master/micropython/drivers/storage/sdcard
Thank you, this is very helpful
hey @specternecter, have you figured out another way to use SD-Card with ESP32-C3?
Like many things with the C3, sd card operations are a little finicky. This is a modified version of sdcard.py that is probably the best it's gonna get. Upload it to your board and then you can see how my custom boot file handles sd operations.
Sorry, I didn't realize you can't upload python files unless they're zipped. I zipped them on android so if you're using windows you'll probably have to use 7zip to unzip it properly.
Oh and you may have to use "import sdcard". That's probably not in the boot file because these files are from my own compiled version of micropython with sdcard.py frozen into it.
Will test it, just now! Thanks a lot! :)
I got ImportError: no module named 'ledColor'
, but I can import it like this. :)
No problem. Let me know how it goes
Oh yeah that's for a neopixel and you can just comment those out. The sd card portions of that boot file are how you can do those operations. That boot file is checking for an sd card to see whether to run the file system from flash or sd card. If an sd card is detected it's actually writing default files. I can take a look and see if I can explain it better
I just discovered, that I don't have an SPI on my devboard. It's directly wired using CMD
, CLK
, D0
, D1
, ...
You can flash my custom version if you want to make it easier but you must use the native usb port. This board doesn't use the UART port. But that will use the sd card for all files if it's present. DDC3_microPython-8bin_0603_074724.zip
Mounting the sd card goes like this: `try: os.mount(sd, '/sd') except:
time.sleep(0.25)
try:
os.mount(sd, '/sd')
except:
useInternal = True
imReason = 'Failed to Mount SD Card'`
Oh yeah you may not be able to use my version I provided.
But this is how sd is set up:
spi = SPI(1, baudrate=10000000, polarity=0, phase=0, sck=Pin(4), mosi=Pin(6), miso=Pin(5)) sd = None
You should be able to just change the pins
I flashed and getting the following endlessly spamming into the console:
...
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffESP-ROM:esp32c3-api1-20210207
Build:Feb 7 2021
rst:0x7 (TG0WDT_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40053f88
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
...
Erase the flash, then reflash to 0x0
But if your sd card pins don't match what I listed above, the version I provided won't work
esptool --chip esp32c3 --port COM4 --baud 460800 write_flash -z 0x0 DDC3_microPython-8.bin
flashed, but I'm getting AttributeError: 'NoneType' object has no attribute 'readblocks'
when trying your os.mount(sd, '/sd')
code.
Maybe Arduino-based is easier to implement 😅
That looks like the pins don't match what the boot file is defining as the sd card pins
Yes my pinout is different: CMD=GPIO4
, CLK=GPIO5
, D0=GPIO6
, D3=GPIO7
..
Since you can't change them, that boot file should work in the standard version of micropython. Just change the pin numbers accordingly and comment out anything you see that says ledColor.
I could compile a version to match your pins but it would be later tonight before I could get to it
As for the boot file, you probably don't want to actually run that unless you're actually using my version. It's more for an example to see how I'm mounting and writing to the sd card
Yeah will revert to ESP32_GENERIC_C3-20240222-v1.22.2.bin
. But since I'm not utilizing SPI on my devboard how is it supposed to be compatible with your sdcard.py
?
As for whether arduino is easier to implement... yeah it actually is, especially if you're not that familiar with micropython. Micropython is far easier to develop with though because there's no waiting for compilation just to find there's an error 30 times until you figure it out
Where you see spi toward the beginning of the boot file, change those pins
I'm pretty sure all spi in micropython is software spi if that's what you mean. So it should run on any pins you set (except a few that would conflict with other hardware). Spi is a requirement for sd card though. If your dev board put the sd card on those pins, spi can work on them.
Yes I wanted to use MicroPython for ease of use, rather than developing my own solution in order to use it in MicroPython :D Will try directly with ESP-IDF example: https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card/sdspi
machine.SPI is usually hardware SPI, machine.SoftSPI is (guess what) Software SPI. The assignment of Pins to hardware SPI signals is port-specific. The ESP32 allows to assign almost every Pin to any hardware SPI signal. So I see not reason why the SDCARD driver should not run with the generic firmware. You have to create a SPI object with the proper pins and choose a Pin for CS. That's all.
Yeah implementing new things in micropython can be difficult and confusing. The reason I compiled my own version of micropython was specifically because sd card wasn't supported by default and I wanted people to easily be able to flip between arduino and micropython. I also made my own arduino core because the standard core for the c3 is absolutely riddled with bugs and the people that are in charge of that would much rather steer you around the bugs rather than fixing them or even accepting a fix. That's why I used the true spi pins when i designed that board. That's what arduino wants if you want things to work smoothly with minimal effort. If you have too much trouble and really want to use micropython, come back and I'll compile a version that matches the pins of your board. It would literally only take me a couple minutes but I won't have access to the computer that can run that until later tonight
So I grabbed a simple generic ESP32_C3 board (2$ from Ali), a passive SD-Card plug, wired it up to that board at pins 5 to 8 and copied sdcard.py to the board. Code, typed at the REPL prompt
>>> from machine import SPI, Pin
>>> import os
>>> import sdcard
>>> spi=SPI(1, miso=5, mosi=6, sck=7)
>>> sd=sdcard.SDCard(spi, Pin(8))
>>> os.mount(sd, "/sd")
>>> os.listdir("/sd")
['NB1-41019.dup', 'updater.elf', 'upgdiff_33080-to-41019.dup', 'upgdiff_39529-to-41019.dup', 'upgdiff_40343-to-41019.dup', 'upgdiff_41065-to-41019.dup', 'main.py', 'noboot.py', 'LOST.DIR', '.android_secure', 'Android', 'messages.db', 'NB1-46262.dup', 'vfstest.py', 'sdcard_stress_test.py', 'test_file.txt', 'boot.py', 'mount.py', 'looptest.py', 'rats.txt', '.Trash-1000', 'rats1.txt', 'test01.txt', 'test', 't_read.py', 'btest']
>>>
The pins I used are not special. Note that when creating the sd object a SD card has to be present.
Problem does not seem to be reproducible. Proposing to close issue.
I have a custom ESP32C3 board that has an SD Card on it. I can easily run SD Card functions in Arduino with it but when I put micropython on it using the latest release, SDCard isn't even found when you try to call it. It's not my first time compiling my own board though so went into ports/esp32/boards/ESP32_GENERIC_C3/mpconfigboard.h (Using v5.1 of esp-idf and a current copy of this repository), changed
#define MICROPY_HW_ENABLE_SDCARD (0)
to#define MICROPY_HW_ENABLE_SDCARD (1)
and then changed ports/esp32/machine_sdcard.c to the proper pins of sck=4 miso=5 and mosi=6 (also cs=1 in my case). I get the following errors.../home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c:124:20: error: 'SPI3_HOST' undeclared here (not in a function); did you mean 'SPI2_HOST'? 124 | .host_id = SPI3_HOST, | ^
~~~~ | SPI2_HOST /home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c: In function 'machine_sdcard_make_new': /home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c:238:35: error: implicit declaration of function 'SDMMC_HOST_DEFAULT'; did you mean 'SDSPI_HOST_DEFAULT'? [-Werror=implicit-function-declaration] 238 | sdmmc_host_t _temp_host = SDMMC_HOST_DEFAULT(); | ^~~~~~ | SDSPI_HOST_DEFAULT /home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c:238:35: error: invalid initializer /home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c:295:9: error: unknown type name 'sdmmc_slot_config_t' 295 | sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); | ^~~~~~~ /home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c:295:43: error: implicit declaration of function 'SDMMC_SLOT_CONFIG_DEFAULT'; did you mean 'SDSPI_DEVICE_CONFIG_DEFAULT'? [-Werror=implicit-function-declaration] 295 | sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); | ^~~~~~~~~ | SDSPI_DEVICE_CONFIG_DEFAULT /home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c:136:11: error: request for member 'gpio_cd' in something not a structure or union 136 | config.pin_var = machine_pin_get_id(arg_vals[arg_id].u_obj) | ^ /home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c:301:9: note: in expansion of macro 'SET_CONFIG_PIN' 301 | SET_CONFIG_PIN(slot_config, gpio_cd, ARG_cd); | ^~~~~~ /home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c:136:11: error: request for member 'gpio_wp' in something not a structure or union 136 | config.pin_var = machine_pin_get_id(arg_vals[arg_id].u_obj) | ^ /home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c:302:9: note: in expansion of macro 'SET_CONFIG_PIN' 302 | SET_CONFIG_PIN(slot_config, gpio_wp, ARG_wp); | ^~~~~~ /home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c:306:24: error: request for member 'width' in something not a structure or union 306 | slot_config.width = width; | ^ /home/brad/esp-idf/micropython/ports/esp32/machine_sdcard.c:312:23: error: implicit declaration of function 'sdmmc_host_init_slot' [-Werror=implicit-function-declaration] 312 | check_esp_err(sdmmc_host_init_slot(self->host.slot, &slot_config)); | ^~~~~~~~ cc1: some warnings being treated as errors ninja: build stopped: subcommand failed. ninja failed with exit code 1, output of the command is in the /home/brad/esp-idf/micropython/ports/esp32/build-ESP32_GENERIC_C3/log/idf_py_stderr_output_1718238 and /home/brad/esp-idf/micropython/ports/esp32/build-ESP32_GENERIC_C3/log/idf_py_stdout_output_1718238 -e See https://github.com/micropython/micropython/wiki/Build-Troubleshooting make: *** [Makefile:62: all] Error 1Like I said, SD works perfectly fine in Arduino so I know there's no hardware issue or anything like that because I know I'm calling the proper pins. When I change things back to
#define MICROPY_HW_ENABLE_SDCARD (0)
everything compiles fine, but obviously there's no way to use an sd card without it set to 1. It's also obvious there are no definitions in machine_sdcard.c to support the ESP32C3, but I don't know how to fix it aside from changing to the necessary SPI pins.