Files
mcp_screen/circuitpython/code.py
T
2026-06-21 21:14:18 -04:00

116 lines
3.1 KiB
Python

"""CircuitPython entrypoint for Waveshare ESP32-S3-RLCD-4.2 migration.
Copy this file to CIRCUITPY/code.py after flashing CircuitPython.
"""
import gc
import os
import time
import board
import busio
import digitalio
from audio_cp import BoardAudio
from gif_player import GIFPlayer
from rlcd_cp import RLCD
# Keep pin choices in one place because CircuitPython board builds differ in
# how they expose ESP32-S3 pins. If board.IO## is missing, run `dir(board)` on
# the serial console and update these names.
PINS = {
"display_sck": board.IO11,
"display_mosi": board.IO12,
"display_cs": board.IO40,
"display_dc": board.IO5,
"display_rst": board.IO41,
"i2c_sda": board.IO13,
"i2c_scl": board.IO14,
"i2s_bclk": board.IO9,
"i2s_lrck": board.IO45,
"i2s_dout": board.IO8,
"audio_mclk": board.IO16,
"audio_amp": board.IO46,
}
def exists(path):
try:
os.stat(path)
return True
except OSError:
return False
def init_display():
spi = busio.SPI(clock=PINS["display_sck"], MOSI=PINS["display_mosi"])
# Match the working MicroPython code's 20 MHz SPI if the build supports it.
while not spi.try_lock():
pass
try:
spi.configure(baudrate=20000000, phase=0, polarity=0)
finally:
spi.unlock()
display = RLCD(
spi,
cs=digitalio.DigitalInOut(PINS["display_cs"]),
dc=digitalio.DigitalInOut(PINS["display_dc"]),
rst=digitalio.DigitalInOut(PINS["display_rst"]),
)
return display
def init_audio():
i2c = busio.I2C(scl=PINS["i2c_scl"], sda=PINS["i2c_sda"])
return BoardAudio(
i2c,
bit_clock=PINS["i2s_bclk"],
word_select=PINS["i2s_lrck"],
data=PINS["i2s_dout"],
mclk=PINS["audio_mclk"],
amp=PINS["audio_amp"],
)
def draw_boot_screen(display, message="CircuitPython RLCD"):
display.clear(0)
display.text("ESP32-S3-RLCD", 10, 10, 1)
display.line(10, 22, 390, 22, 1)
display.text_large("CIRCUITPY", 18, 45, scale=3, color=1)
display.text(message, 18, 86, 1)
display.text("MP3: /demo.mp3", 18, 116, 1)
display.text("GIF: /demo.gif", 18, 132, 1)
display.text("If visible, ST7305 init works", 18, 170, 1)
display.show()
def main():
display = init_display()
draw_boot_screen(display, "Display initialized")
time.sleep(1)
# Try GIF first because it verifies display animation support.
if exists("/demo.gif"):
draw_boot_screen(display, "Playing GIF...")
GIFPlayer(display).play("/demo.gif", loops=1)
draw_boot_screen(display, "GIF done")
gc.collect()
# Try MP3 if present. If this fails silently, verify MCLK on IO16 and codec
# register sequence against a known-good WAV/tone first.
if exists("/demo.mp3"):
draw_boot_screen(display, "Playing MP3...")
try:
audio = init_audio()
ok = audio.play_mp3("/demo.mp3", volume=65)
draw_boot_screen(display, "MP3 ok" if ok else "MP3 failed")
except Exception as exc:
draw_boot_screen(display, "MP3 error: " + str(exc)[:28])
while True:
time.sleep(5)
main()