README: Add appendix on SPI bus sharing.

pull/55/head
Peter Hinch 2024-10-08 16:41:38 +01:00
rodzic 67e1e8ea5b
commit 59365fc641
3 zmienionych plików z 82 dodań i 1 usunięć

Wyświetl plik

@ -163,6 +163,7 @@ under development so check for updates.
[Appendix 2 Freezing bytecode](./README.md#appendix-2-freezing-bytecode) Optional way to save RAM.
[Appendix 3 Cross compiling](./README.md#appendix-3-cross-compiling) Another way to save RAM.
[Appendix 4 GUI Design notes](./README.md#appendix-4-gui-design-notes) The reason for continuous refresh.
[Appendix 5 Bus sharing](./README.md#appendix-5-bus-sharing) Using the SD card on Waveshare boards.
# 1. Basic concepts
@ -3578,3 +3579,45 @@ def test():
test()
```
###### [Contents](./README.md#0-contents)
## Appendix 5 Bus sharing
Boards from Waveshare use the same SPI bus to access the display controller, the
touch controller, and an optional SD card. If an SD card is fitted, it is
possible to mount this in `boot.py`: doing this enables the filesystem on the
SD card to be managed at the Bash prompt using `mpremote`. There is a "gotcha"
here. For this to work reliably, the `CS\` pins of the display controller and
the touch controller must be set high, otherwise bus contention on the `miso`
line can occur. Note that this still applies even if the touch controller is
unused: it should still be prevented from asserting `miso`. The following is an
example of a `boot.py` for the 2.8" Pico Res touch.
```py
from machine import SPI, Pin
from sdcard import SDCard
import os
BAUDRATE = 3_000_000 # Much higher rates seem OK, but may depend on card.
# Initialise all CS\ pins
cst = Pin(16, Pin.OUT, value=1) # Touch XPT2046
csd = Pin(9, Pin.OUT, value=1) # Display ST7789
css = Pin(22, Pin.OUT, value=1) # SD card
spi = SPI(1, BAUDRATE, sck=Pin(10), mosi=Pin(11), miso=Pin(12))
sd = SDCard(spi, css, BAUDRATE)
vfs = os.VfsFat(sd)
os.mount(vfs, "/sd")
```
An application which is to access the SD card must ensure that the GUI is
prevented from accessing the SPI bus for the duration of SD card access. This
may be done with an asynchronous context manager. When the context manager
terminates, refresh will re-start.
```py
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
```
See section 8 for further background. Tested by @bianc104 in micropython-touch
[iss 15](https://github.com/peterhinch/micropython-touch/issues/15#issuecomment-2397988225)
###### [Contents](./README.md#0-contents)

Wyświetl plik

@ -22,13 +22,14 @@ pyb.Pin("EN_3V3").on() # provide 3.3V on 3V3 output pin
# ======= I2S CONFIGURATION =======
I2S_ID = 1
# allocate sample array once
wav_samples = bytearray(WAVSIZE)
# The proper way is to parse the WAV file as per
# https://github.com/miketeachman/micropython-i2s-examples/blob/master/examples/wavplayer.py
# Here for simplicity we assume stereo files ripped from CD's.
# Pyboard D
I2S_ID = 1
config = {
"sck": Pin("W29"),
"ws": Pin("W16"),
@ -40,6 +41,19 @@ config = {
"ibuf": BUFSIZE, # Buffer size
}
# RP2 from https://docs.micropython.org/en/latest/rp2/quickref.html#i2s-bus
# I2S_ID = 0
# config = {
# "sck": Pin(16),
# "ws": Pin(17),
# "sd": Pin(18),
# "mode": I2S.TX,
# "bits": 16, # Sample size in bits/channel
# "format": I2S.STEREO,
# "rate": 44100, # Sample rate in Hz
# "ibuf": BUFSIZE, # Buffer size
# }
audio_out = I2S(I2S_ID, **config)
# ======= GUI =======

Wyświetl plik

@ -0,0 +1,24 @@
# pico_epaper_42_v2.py
# hardware_setup file for a Pico ePaper 4.2" V2 with a Pico plugged in.
# The two user buttons on the display provide the interface
from machine import Pin, SPI, freq
import gc
from drivers.epaper.pico_epaper_42_v2 import EPD as SSD
freq(250_000_000) # RP2 overclock
gc.collect() # Precaution before instantiating framebuf
# Using the onboard socket connection default args apply
ssd = SSD()
gc.collect()
from gui.core.ugui import Display, quiet
# quiet()
# Create and export a Display instance
# Define control buttons: these are the buttons on the display unit.
nxt = Pin(17, Pin.IN, Pin.PULL_UP) # Move to next control
sel = Pin(15, Pin.IN, Pin.PULL_UP) # Operate current control
# display = Display(ssd, nxt, sel, prev) # 3-button mode
display = Display(ssd, nxt, sel) # 2-button mode
ssd.wait_until_ready() # Blocking wait