SDCard() Instantiation Error on Soft Reboot: SPI bus already initialized; ESP_ERR_INVALID_STATE

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
quiltyja
Posts: 7
Joined: Sun Jul 10, 2022 12:10 pm

SDCard() Instantiation Error on Soft Reboot: SPI bus already initialized; ESP_ERR_INVALID_STATE

Post by quiltyja » Sat Jul 16, 2022 5:09 am

Hello everyone in the MicroPython community!

We're having trouble with microSD card access with MicroPython versions 1.16 through 1.19 on two different revisions of a single-board PCB based on the ESP32-WROVER-B (SPI RAM) with direct connections from the ESP32 pins to the pins of a MEM2075 microSD card connector (PDF). On first power-up, or after a hard reset, the card can be mounted on the REPL with the commands

Code: Select all

from machine import SDCard

# Revision A board pin configuration use:
sd = SDCard(slot=2, sck=13, miso=15, mosi=23, cs=12)

# Revision B board pin configuration use:
sd = SDCard(slot=2, sck=13, miso=34, mosi=23, cs=12)
and the cards can be accessed normally. Once a soft reboot is executed, trying to instantiate the SDCard() class results in an error. An example from a pristine MicroPython 1.19.1 on a Revision A board:

Code: Select all

MicroPython v1.19.1 on 2022-06-18; ESP32 module (spiram) with ESP32
Type "help()" for more information.
>>> from machine import SDCard
>>> sd = SDCard(slot=2, sck=13, miso=15, mosi=23, cs=12)
>>>
MPY: soft reboot
MicroPython v1.19.1 on 2022-06-18; ESP32 module (spiram) with ESP32
Type "help()" for more information.
>>> from machine import SDCard
>>> sd = SDCard(slot=2, sck=13, miso=15, mosi=23, cs=12)
E (xxxxx) spi: spi_bus_initialize(462): SPI bus already initialized.
E (xxxxx) sdspi_host: spi_bus_initialize failed with rc=0x103
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: (-259, 'ESP_ERR_INVALID_STATE')
where we are not using sd.deinit() because the MicroPython documentation says sd.deinit() is only implemented on the cc3200 port.

This problem does not appear to affect re-instantiating SDCard() after wake from deep sleep, only soft reboot. That said, access to the microSD card is an integral part of remote operation of our device and we feel this problem blocks us from migrating to MicroPython 1.19.1, keeping us on version 1.14. This is, needless to say, a pretty serious problem for us.

We're aware that we're not using the slot 2 pins recommended in class SDCard - ESP32 but we're uncertain whether changing the pin connections on the PCB will resolve the problem. We're using every pin on the ESP32, so changing the microSD card connections will be a non-trivial task. We'll do it if we know it will resolve the "SPI bus already initialized" error.

We were using MicroPython 1.14 when the boards were developed and did not, and do not, see this error with microSD card access that we see with later versions. The issue causing the errors above appears to have been introduced in version 1.16 of the firmware. Hopefully this provides a clue to the change(s) causing the problem and the potential resolution? Previous forum posts and GitHub Issues of similar errors on instantiating SDCard() after soft reboot coincide in time with the release of version 1.16:
Is anyone in the community able to shed any light on this problem and how to resolve it, please?

For example:
  • Will reconfiguration of the pins connecting the ESP32 to the MEM2075 to the ESP32 Slot 2 recommended pins certainly resolve the error?
  • Should we be doing something specific in our code to manually deinitialise the SPI port as a workaround?
  • Is this, perhaps, a problem with the firmware introduced in 1.16 and thus should be raised as an Issue at https://github.com/micropython/micropython/


User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: SDCard() Instantiation Error on Soft Reboot: SPI bus already initialized; ESP_ERR_INVALID_STATE

Post by Roberthh » Sat Jul 23, 2022 5:57 am

Should we be doing something specific in our code to manually deinitialise the SPI port as a workaround?
Looking into the code, the SPI devices are not free'd on soft reset. So you have to deinitialize it in your code. I do not know why it worked in v1.14. But the esp-idf version changed as well between v1.14 and v1.19.

quiltyja
Posts: 7
Joined: Sun Jul 10, 2022 12:10 pm

Re: SDCard() Instantiation Error on Soft Reboot: SPI bus already initialized; ESP_ERR_INVALID_STATE

Post by quiltyja » Sun Jul 24, 2022 1:53 am

Thanks, Roberthh, that helps. I believe I tried sd.deinit() while troubleshooting before posting but - as indicated in the documentation - it appeared to do nothing on the ESP32. I'll look into how/whether there are alternate methods for deinitialising the SPI device from MicroPython code.

I'm glad I raised Issue #8949 on the GitHub project: that the SPI device is not deinitialised and the SDCard() class can not be re-instantiated after soft reboot looks very much like a bug.

Roberthh, would you be able to post GitHub repo links to the source code to which you referred?

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: SDCard() Instantiation Error on Soft Reboot: SPI bus already initialized; ESP_ERR_INVALID_STATE

Post by Roberthh » Sun Jul 24, 2022 6:34 am

Sorry. I looked for SPI not SDCard. Bit there is also not sdcard deinit on soft reset. The code for that is in main.c.
Looking into machine_sdcard.c at the code for the deinit method, there is just the call to the espressif RTOS library, which changed from idf 4.2 on. The flags are set, so the RTOS function should be called.

Post Reply