lv_binding_micropython: Can't mount SD card and display at the same time when sharing the same SPI bus
Summary
I’m trying to use LittlevGL with an m5stack development board (esp32-based with an ili9341 display). Both the display and SD card interface share the same SPI bus, and it’s not currently possible to initialize either device on an existing SPI bus.
Based on the work of @miketeachman, I was able to produce a workaround using the ILI9341 C module (details here). Basically, this involves removing the SPI initialization code in disp_spi_init()
and setting the display to communicate in full-duplex instead of half-duplex mode. I have tried to port these changes to the Pure/Hybrid ili9341 driver, but I can’t seem to get it work.
boot.py (v1)
The following boot.py
is a minimal example of loading a LittlevGL button on the m5stack:
import machine
import os
import ili9341
import lvgl as lv
lv.init()
disp = ili9341.ili9341(spihost=1, miso=19, mosi=23, clk=18, cs=14,
dc=27, rst=33, backlight=32, backlight_on=1,
hybrid=True, mhz=25, width=320, height=240,
colormode=ili9341.ili9341.COLOR_MODE_BGR,
rot=ili9341.ili9341.MADCTL_ML, invert=True)
scr = lv.obj()
btn = lv.btn(scr)
btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text("Button")
lv.scr_load(scr)
This produces a blue button on a white screen:
boot.py (v2): mount SD card before initializing display
This is the same boot.py
, but it tries to mount an SD card prior to initializing the display:
import machine
import os
import ili9341
import lvgl as lv
# Mount the SD card (note that this initializes the SPI bus)
os.mount(machine.SDCard(slot=3, sck=18, mosi=23, miso=19, cs=4), '/sd')
lv.init()
disp = ili9341.ili9341(spihost=1, miso=19, mosi=23, clk=18, cs=14,
dc=27, rst=33, backlight=32, backlight_on=1,
hybrid=True, mhz=25, width=320, height=240,
colormode=ili9341.ili9341.COLOR_MODE_BGR,
rot=ili9341.ili9341.MADCTL_ML, invert=True)
scr = lv.obj()
btn = lv.btn(scr)
btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text("Button")
lv.scr_load(scr)
As expected, this fails with the error:
E (420) spi: SPI2 already claimed by spi master.
E (420) spi_master: spi_bus_initialize(242): host already in use
Traceback (most recent call last):
File "boot.py", line 15, in <module>
File "ili9341.py", line 113, in __init__
File "ili9341.py", line 326, in init
File "ili9341.py", line 196, in disp_spi_init
RuntimeError: Failed initializing SPI bus
Attempted workaround
I tried modifying the pure/hybrid ili9341 driver by removing the SPI initialization code in disp_spi_init()
and setting the display to communicate in full-duplex mode instead of half-duplex (the things that seemed to resolve the issue for the ILI9341 C module). The changes can be seen here. When I tried testing this modified driver with the boot.py (v2)
from above, it resulted in the following error:
E (930) spi_master: check_trans_valid(1103): txdata transfer > host maximum
I’m not really sure what else to try. I’m happy to have a workaround using the C module, but it looks like the C module is being deprecated in favor of the pure/hybrid python driver, so if possible, I’d like to find a fix for that too. It would also be nice to be able to decide at run time whether you want to attach to a new or pre-initialized SPI bus.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 16 (6 by maintainers)
Hi amirgon, I think we have to rewrite the sdCard driver but added into illixxx.py with esp idf module functions to resolve this problem. I don’t Know if it’s possible. I’m searching.