116 lines
3.1 KiB
Python
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()
|