SPI Sharing... machine.SDCard w/ili9341 & xpt2046 YES Again

This issue has gone on far to long.
Using the python drivers ili9XXX.py and xpt2046.py with either machine.SDCard or sdcard.py drivers
I could not find any combination where these three divices would work together.
I have also tryed using the lv_spi.py with no success.
Also sdcard.py has issues with 2GB cards and other problems, so I’d rather use machine.SDCard!
Let fix this once and for all !!!

I am using an ESP32 Wrover module with spiram
lv_micropython v9 using micropython v1.20
built with ESP-IDF v4.4.5

With the following code I am able to mount my SDCard.
List Directories… listdir(‘/sd’) and os.listdir(‘/sd/data’) ouput correctly.
Then initialize the display and touch drivers.
Load display elements…

Then TRY to List Directories AGAIN…
/sd shows… /sd: [‘test.txt’] should be… /sd: [‘System Volume Information’, ‘data’]
/sd/data gets…
:diamonds:Traceback (most recent call last):
File “”, line 45, in
OSError: [Errno 2] ENOENT

Display and Touch functions work fine but the SD driver… not sooo much.


import lvgl as lv
from ili9XXX import ili9341
from xpt2046 import xpt2046
from machine import SDCard
import os

print('Mount SD Card')
try:
	sd = SDCard(slot=2, cs=14, freq=20_000_000)
	os.mount(sd, '/sd')
	print("\nList Dir's")
	print(f"/sd: {os.listdir('/sd')}")
	print(f"/sd/data: {os.listdir('/sd/data')}")	
except Exception as e:
	print(f'SD Error\n{e}')

print('Load TFT Driver')
disp = ili9341(hybrid=True, spihost=2, miso=-1, mosi=-1, clk=-1, cs=15, mhz=20, dc=13, rst=-1, power=-1, factor=48, half_duplex=False, backlight=27, backlight_on=1)
print('Load Touch Driver')
touch = xpt2046(spihost=2, cs=5)		# half_duplex=False causes button to lock up !!!


def button_cb(e):
	if e.get_code() == lv.EVENT.CLICKED:
		print("Clicked")

scr = lv.scr_act()
u_name = lv.label(scr)
u_name.align(lv.ALIGN.TOP_MID, 0, 40)
u_name.set_style_text_font(lv.font_montserrat_20, 0)
u_name.set_text('SPI Issue')

btn = lv.btn(scr)
btn.align(lv.ALIGN.TOP_MID, 0, 250)
btn.add_event(button_cb, lv.EVENT.CLICKED, None)
btn_lbl = lv.label(btn)
btn_lbl.set_text("CLICK Me")

lv.scr_load(scr)

print("\nList Dir's AGAIN")
print(f"/sd: {os.listdir('/sd')}")
print(f"/sd/data: {os.listdir('/sd/data')}")

Output…


>>>
>>>
Mount SD Card

List Dir's
/sd: ['System Volume Information', 'data']
/sd/data: ['test.txt']
Load TFT Driver
Double buffer
ILI9341 initialization completed
Enable backlight
Load Touch Driver

List Dir's AGAIN
/sd: ['test.txt']
♦Traceback (most recent call last):
  File "<stdin>", line 45, in <module>
OSError: [Errno 2] ENOENT
♦>
MicroPython v1.20.0-700-g841ece132-dirty on 2023-09-15; ESP32 module (spiram) with ESP32
Type "help()" for more information.
>>>
>>>

I’m hoping the new maintainers of LV_Micropython could tackle this insidious problem
that this and the micropython forum are plagued with help wanted re. this issue.

So I reashed out to micropython.org

I seem to be closer.
see

As far as I know, there is only one way for esp32 to use lv_micropython while also using ili9xxx/st77xx, xpt2046, and sd cards: lv_spi.py
Unfortunately, I have never succeeded.
But other devices (such as Raspberry Pie Pico) are fine, and you can use the drivers in this directory:

https://github.com/lvgl/lv_binding_micropython/tree/master/driver/generic

to work with SD card drivers.
Just like this:

from st77xx import *
from xpt2046 import *

spi=machine.SPI(
    1,
    baudrate=30_000_000,
    polarity=0,
    phase=0,
    sck=machine.Pin(10,machine.Pin.OUT),
    mosi=machine.Pin(11,machine.Pin.OUT),
    miso=machine.Pin(12,machine.Pin.IN)
)

lcd=St7789(rot=1,res=(240,320),spi=spi,cs=9,dc=8,bl=13,rst=15,rp2_dma=None,factor=8)
touch=Xpt2046(spi=spi,cs=16,rot=1,spiPrereadCb=lcd.rp2_wait_dma)

from sdcard import SDCard
import os
sd = SDCard(spi, machine.Pin(22, machine.Pin.OUT), 30_000_000)
os.mount(sd, '/sd')

I have tried lv_spi with with no success.

So the below code will all attach all three devices to the SPI bus !!!
But Accessing SD card will give random intermittent errors that are I believe are caused by collisions with the display or touch drivers, possibly in the buffer area, but I am not experienced enough to troubleshoot this.
I hope the new maintainers for lv_micropython will make this a first priority as if you look up SPI related issues, there are numerous both here and at the micropython forum.

import lvgl as lv
from ili9XXX import ili9341
from xpt2046 import xpt2046
import os, time, sdcard
from machine import SPI, Pin

sd = sdcard.SDCard(SPI(2), Pin(14), baudrate=10_000_000)
os.mount(sd, '/sd')

lv.init()
disp = ili9341(spihost=2, miso=-1, mosi=-1, clk=-1, cs=15, mhz=10, dc=13, rst=-1, power=-1, factor=48, half_duplex=False, double_buffer=True, backlight=27, backlight_on=1)
touch = xpt2046(spihost=2, cs=5, mhz=10, half_duplex=False)

print(os.listdir('/sd'))
print(os.listdir('sd/data'))
OUTPUT......
>>>
>>>
Double buffer
ILI9341 initialization completed
Enable backlight
['System Volume Information', 'data']      All Good !!
['test.txt']                               All Good !!
Ready
♦♦>
MicroPython v1.20.0-702-g1ed8b7c0d-dirty on 2023-10-18; ESP32 module (spiram) with ESP32
Type "help()" for more information.
>>>
>>> print(os.listdir('sd/data'))           No Good !!!!!!!!!!!!!!! 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sdcard.py", line 256, in readblocks
OSError: [Errno 5] EIO
>>>

links to Disp and Touch drivers

I think this thread might shed some light on the issue.

So digging even deeper I found out that if I comment out the TOUCH driver that listing the directories work.
So this is narrowed down now to the touch driver as being the culprit !!