LVGL and SD Card won't share SPI bus

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
PM-TPI
Posts: 75
Joined: Fri Jun 28, 2019 3:09 pm

LVGL and SD Card won't share SPI bus

Post by PM-TPI » Fri May 15, 2020 3:34 pm

I posted in LittlevGl fourm also...
https://forum.littlevgl.com/t/lvgl-and- ... i-bus/2268

In post see...
This problem was fixed in espressif/esp-idf@067f3d2, but that commit is not included yet in Micropython (at least not on the last release v1.12, which lv_micropython is aligned to)
Is there a micropython fix planned??
Or a workaround??

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: LVGL and SD Card won't share SPI bus

Post by pythoncoder » Fri May 15, 2020 5:37 pm

See this PR.

I hit this problem with a board where an SD card shares the bus with a chip. For reasons which nobody has yet explained successfully, it is necessary to send 0xff with the SD card CS False prior to accessing the card. You might like to try this version of sdcard.py.

Please post the outcome.
Peter Hinch
Index to my micropython libraries.

PM-TPI
Posts: 75
Joined: Fri Jun 28, 2019 3:09 pm

Re: LVGL and SD Card won't share SPI bus

Post by PM-TPI » Fri May 15, 2020 6:30 pm

This is my past initialization that would mount...
uos.mount(SDCard(slot=2, sck=18, miso=19, mosi=23, cs=4), '/sd')

tried...

Code: Select all

try:
    # uos.mount(SDCard(slot=2, sck=18, miso=19, mosi=23, cs=4), '/sd')
    sd = sdcard.SDCard(machine.SPI(1), machine.Pin(4))
    uos.mount(sd, '/sd')
    print(uos.listdir('/sd/data'))

except:
    print('\nSD Card Error\n')
get> SD Card Error

PM-TPI
Posts: 75
Joined: Fri Jun 28, 2019 3:09 pm

Re: LVGL and SD Card won't share SPI bus

Post by PM-TPI » Fri May 15, 2020 6:59 pm

got to mount...

Code: Select all

spi = SPI(2, sck=Pin(18), mosi=Pin(23), miso=Pin(19) )

try:
    # uos.mount(SDCard(slot=2, sck=18, miso=19, mosi=23, cs=4), '/sd')
    sd = sdcard.SDCard(spi, Pin(4))
    uos.mount(sd, '/sd')
    print(uos.listdir('/sd/data'))

except:
    print('\nSD Card Error\n')
but when lvgl initialized... not able to write to sd card

PM-TPI
Posts: 75
Joined: Fri Jun 28, 2019 3:09 pm

Re: LVGL and SD Card won't share SPI bus

Post by PM-TPI » Fri May 15, 2020 8:43 pm

If I initialized LVGL first...
and then mount sd card...

Code: Select all

try:
    sd = sdcard.SDCard(machine.SPI(1, sck=machine.Pin(18), mosi=machine.Pin(23), miso=machine.Pin(19)), machine.Pin(4))
    uos.mount(sd, '/sd')
    print(uos.listdir('/sd/data'))

except:
    print('\nSD Card Error\n')
>>>
ILI9341 initialization completed
Enable backlight
Double buffer
E (4840) spi: SPI2 already claimed by spi master.
E (4840) spi_master: spi_bus_initialize(231): host already in use

SD Card Error

I am at a loss

User avatar
Mike Teachman
Posts: 155
Joined: Mon Jun 13, 2016 3:19 pm
Location: Victoria, BC, Canada

Re: LVGL and SD Card won't share SPI bus

Post by Mike Teachman » Sat May 16, 2020 12:20 am

Are you using the Python or C based ILI9341 display driver? If you use the C driver I found a work around ...

I faced the same problem and found a workaround by modifying the C based ILI9341 display driver, as follows:
- change the SPI bus config to full duplex
here are the code changes
custom lvgl branch: https://github.com/miketeachman/lv_bind ... treetsense
commit: https://github.com/miketeachman/lv_bind ... fbbf169885
specific file change: https://github.com/miketeachman/lv_bind ... 3712caR171

This problem is discussed a bit in this project log:
https://hackaday.io/project/162059-stre ... -littlevgl

The downside to this work around are slower display updates compared to half duplex operation.

Another useful display customization involved adding an option to the C based ILI9341 MicroPython interface where the display driver does not initialize the SPI bus - initialization is handled earlier in the program when the SD Card is initialized.
commit: https://github.com/miketeachman/lv_bind ... 84bf3ef9cd

A working example is shown in the StreetSense project:
https://github.com/miketeachman/micropy ... etsense.py

SD card init: https://github.com/miketeachman/micropy ... e.py#L1091
ILI9341 init: https://github.com/miketeachman/micropy ... se.py#L429

Hopefully this might help ! At least you know it can work.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: LVGL and SD Card won't share SPI bus

Post by pythoncoder » Sat May 16, 2020 8:44 am

@PM-TPI Do I take it that this version of sdcard.py https://github.com/peterhinch/micropyth ... /sdcard.py didn't fix the problem?
Peter Hinch
Index to my micropython libraries.

PM-TPI
Posts: 75
Joined: Fri Jun 28, 2019 3:09 pm

Re: LVGL and SD Card won't share SPI bus

Post by PM-TPI » Sat May 16, 2020 11:57 am

Peter... yes using sdcard.py, your theory of the issues are exactly what I'm feeling is going on here.

Mike... I'm using the micropython version.
What is the philosophy of the changes in your C code that I can possibly apply to the uPy code?
Was your approach similar to Peters?

In trying to fix this issue I was Googling mostly "micropython ... yada yada" and got few results.
but when I Googled... "SD card shared SPI" then I got an avalanche of issues, but few with concise answers.
It is reported that using different SD cards have various successes.
Some mention using 100 Ohms termination resistors even on short lead runs <5".

I believe most failures are due to SD Cards that do not release the SPI bus back to the cpu.
When I saw your explanation Peter I thought your method was going to work.
it's possible I could still be implementing it incorrectly.

fstengel
Posts: 55
Joined: Tue Apr 17, 2018 4:37 pm

Re: LVGL and SD Card won't share SPI bus

Post by fstengel » Sat May 16, 2020 11:59 am

I just tried @pythoncoder's SDCard class. What happens is that:
  • claiming the bus using SPI(1) fails because the HSPI bus is already in use (by the screen). I expected that
  • claiming the bus using SPI(2) or SPI(2, sck=Pin(18), mosi=Pin(23), miso=Pin(19)) freezes the screen. furthermore one gets a "OSError: couldn't determine SD card version" exception...
I have used @Mike Teachman's solution (and the derived code I found in that repo https://github.com/sci-bots/lv_binding_ ... fed5fac8a2). It works. What bugs me is that I often got hard resets when I wanted a soft reset. I did not try too hard to find if the cause was the C driver or double buffering. For the time being I can wait some time until I have real need for an SD card.

PM-TPI
Posts: 75
Joined: Fri Jun 28, 2019 3:09 pm

Re: LVGL and SD Card won't share SPI bus

Post by PM-TPI » Sat May 16, 2020 7:41 pm

fstengel wrote:
Sat May 16, 2020 11:59 am
I have used @Mike Teachman's solution (and the derived code I found in that repo https://github.com/sci-bots/lv_binding_ ... fed5fac8a2). It works.
What did I get wrong....

got test(ili9341.py-shared-SPI)... changed ili9341.py settings for LOLIN D2 Pro

Code: Select all

def __init__(self,
        miso=19, mosi=23, clk=18, cs=14, dc=27, rst=33, power=-1, backlight=32, backlight_on=1, power_on=1,
        spihost=esp.HSPI_HOST, mhz=40, factor=4, hybrid=True, width=320, height=240, 
        colormode=COLOR_MODE_BGR, rot=LANDSCAPE, invert=False, double_buffer=True
    ):
mount SD Card

Code: Select all

uos.mount(SDCard(slot=2, cs=4), '/sd')
it mounts and saves a file... good

then initialized LVGL and got...

Code: Select all

>>> import tft
E (61690) spi_master: spi_bus_add_device(373): host not initialized
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "tft.py", line 16, in <module>
  File "ili9341.py", line 121, in __init__
  File "ili9341.py", line 338, in init
  File "ili9341.py", line 218, in disp_spi_init
RuntimeError: Failed adding SPI device
>>>

Post Reply