peterhinch / micropython-touch

A GUI for touch panel displays.
MIT License
24 stars 5 forks source link

Data disrupted when utilizing MicroPython Touch and SD Card Reader #15

Closed bianc104 closed 1 day ago

bianc104 commented 6 days ago

I've been writing an application for a Raspberry Pi Pico and connected Pico-ResTouch-LCD-2.8 which involves the use of a touchscreen GUI (using this library) and the SD card reader attached to the Pico-ResTouch-LCD-2.8 to manage files in an attached SD card. I encountered issues however where display actions would lead to the disruption of SD Card data, which I discovered was because by default the data is transferred through SPI connection, which can conflict with the pathways used by the touchscreen portion. While it is possible to switch the SD Card connection to an SDIO mode, this is a process that I'd rather avoid, if at all possible.

Is there a good/preferrable way to suspend graphics transmissions while I am running file I/O operations?

peterhinch commented 5 days ago

I think you can do this. Please read this section for background. To read data from the SD card you need something like:

async def read_data():
    async with Screen.rfsh_lock:
        # set up the SPI bus baudrate for the SD card
        # read the data
    await asyncio.sleep_ms(0)  # Allow refresh and touch to proceed
    # Do anything else you need

The code within the context manager should be synchronous. That way both refresh and touch controller access will be locked out for the duration.

Given that your Display will be initiated with SPI baudrates for ST7789 and XPT2046:

display = Display(ssd, tpad, (spi, 33_000_000, 2_500_000))

the GUI will use the correct rates when the context manager exits and refresh re-commences.

Please report back on whether this works. If it does, I'll document it (and credit you with the verification).

bianc104 commented 1 day ago

This appears to have worked, thank you very much!

A little more detail: I made my import and export functions async, and put the actual file operations inside the async with Screen.rfrsh_lock: blocks as suggested. Within those blocks I re-initialized the SD card that I had defined earlier in the program (when I was getting a list of available files on the SD Card) using sd.init_card(30_000_000) and mounted it. I was then able to do standard file operations (reading or writing) before ultimately closing the file and un-mounting the SD card again (something I also did in the beginning when getting my file list).

When it came to calling said functions, I took a page out of the micro-gui audio demo as suggested in the section you linked, calling them with self.reg_task(asyncio.create_task(myfunction))

Thanks again!

peterhinch commented 1 day ago

Thanks for confirming.

I encountered another issue with that display. I wrote a simple boot.py which mounts the SD card: this enables the SD card to be managed with mpremote. Initially I got erratic results with boot.py sometimes failing with e.g. ENODEV. Then I realised it is essential to set the XPT2046 and ST7789 chip selects high to avoid contention on the MISO line.

This doesn't happen if the SD card is instantiated after the XPT2046 and ST7789 because, by then the CS/ lines are under control.