Page 1 of 4

LVGL and SD Card won't share SPI bus

Posted: Fri May 15, 2020 3:34 pm
by PM-TPI
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??

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

Posted: Fri May 15, 2020 5:37 pm
by pythoncoder
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.

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

Posted: Fri May 15, 2020 6:30 pm
by PM-TPI
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

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

Posted: Fri May 15, 2020 6:59 pm
by PM-TPI
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

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

Posted: Fri May 15, 2020 8:43 pm
by PM-TPI
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

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

Posted: Sat May 16, 2020 12:20 am
by Mike Teachman
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.

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

Posted: Sat May 16, 2020 8:44 am
by pythoncoder
@PM-TPI Do I take it that this version of sdcard.py https://github.com/peterhinch/micropyth ... /sdcard.py didn't fix the problem?

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

Posted: Sat May 16, 2020 11:57 am
by PM-TPI
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.

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

Posted: Sat May 16, 2020 11:59 am
by fstengel
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.

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

Posted: Sat May 16, 2020 7:41 pm
by PM-TPI
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
>>>