# Summary
I'm trying to use LittlevGL with an [m5stack](https://m5stack.com/cā¦ollections/m5-core) 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](https://github.com/sci-bots/m5-lvgl/issues/1)). 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](https://github.com/littlevgl/lv_binding_micropython/blob/master/driver/esp32/ili9341.py), 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:
```python
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:
```python
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:
```python
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](https://github.com/sci-bots/m5-lvgl/issues/1)). The changes can be [seen here](https://github.com/sci-bots/lv_binding_micropython/commit/686e42b9ba20307163a4b89208d70efed5fac8a2). When I tried testing this modified driver with the `boot.py (v2)` from above, it resulted in the following error:
```python
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.