You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
Improve lilygo_t_display_s3 board detection
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import sys
|
||||
import time
|
||||
|
||||
import machine
|
||||
|
||||
|
||||
def _adc_read(adc):
|
||||
if hasattr(adc, "read_u16"):
|
||||
return adc.read_u16()
|
||||
return adc.read()
|
||||
|
||||
|
||||
def _pin_snapshot(pin_id):
|
||||
pin = machine.Pin(pin_id)
|
||||
snapshot = {"pin": pin, "mode": None, "pull": None, "value": None}
|
||||
for attr in ("mode", "pull"):
|
||||
getter = getattr(pin, attr, None)
|
||||
if callable(getter):
|
||||
try:
|
||||
snapshot[attr] = getter()
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
snapshot["value"] = pin.value()
|
||||
except Exception:
|
||||
pass
|
||||
return snapshot
|
||||
|
||||
|
||||
def _try_pin_snapshot(pin_id):
|
||||
try:
|
||||
return _pin_snapshot(pin_id), None
|
||||
except Exception as exc:
|
||||
return None, exc
|
||||
|
||||
|
||||
def _restore_pin(snapshot):
|
||||
pin = snapshot["pin"]
|
||||
mode = snapshot.get("mode")
|
||||
pull = snapshot.get("pull")
|
||||
value = snapshot.get("value")
|
||||
|
||||
try:
|
||||
if hasattr(pin, "init"):
|
||||
kwargs = {}
|
||||
if mode is not None:
|
||||
kwargs["mode"] = mode
|
||||
if pull is not None:
|
||||
kwargs["pull"] = pull
|
||||
if value is not None and mode in (machine.Pin.OUT, getattr(machine.Pin, "OPEN_DRAIN", None)):
|
||||
kwargs["value"] = value
|
||||
if kwargs:
|
||||
pin.init(**kwargs)
|
||||
return
|
||||
if value is not None and mode in (machine.Pin.OUT, getattr(machine.Pin, "OPEN_DRAIN", None)):
|
||||
pin.value(value)
|
||||
except Exception as exc:
|
||||
print("pinstates: WARNING: failed to restore GPIO%02d: %r" % (pin.id(), exc))
|
||||
|
||||
|
||||
def _detect_board():
|
||||
impl = [repr(sys.implementation)]
|
||||
impl.append(getattr(sys.implementation, "_machine", ""))
|
||||
impl.append(getattr(sys.implementation, "machine", ""))
|
||||
haystack = " ".join(impl).upper()
|
||||
if "ESP32S3" in haystack:
|
||||
return "esp32s3"
|
||||
return "esp32"
|
||||
|
||||
|
||||
def _candidate_pins(board, skiplist=None):
|
||||
extra_skip = set(skiplist or [])
|
||||
if board in ("esp32", "esp32-wroom", "esp32-wrover"):
|
||||
skip = {6, 7, 8, 9, 10, 11, 20, 24, 28, 29, 30, 31}
|
||||
return [p for p in range(0, 40) if p not in skip and p not in extra_skip]
|
||||
if board in ("esp32s3", "esp32-s3"):
|
||||
skip = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 45, 46}
|
||||
return [p for p in range(0, 49) if p not in skip and p not in extra_skip]
|
||||
raise ValueError("Unsupported board type: %r" % board)
|
||||
|
||||
|
||||
def read_all_pins(skiplist=None):
|
||||
board = _detect_board()
|
||||
pins = _candidate_pins(board, skiplist=skiplist)
|
||||
results = {"digital": {}, "analog": {}, "errors": {"digital": {}, "analog": {}}}
|
||||
|
||||
for p in pins:
|
||||
pin_snapshot, snapshot_error = _try_pin_snapshot(p)
|
||||
if snapshot_error is not None:
|
||||
results["errors"]["digital"][p] = repr(snapshot_error)
|
||||
continue
|
||||
try:
|
||||
print("Reading digital GPIO%02d..." % p)
|
||||
pin = machine.Pin(p, machine.Pin.IN)
|
||||
results["digital"][p] = pin.value()
|
||||
#time.sleep(1)
|
||||
except Exception as exc:
|
||||
results["errors"]["digital"][p] = repr(exc)
|
||||
finally:
|
||||
try:
|
||||
_restore_pin(pin_snapshot)
|
||||
except Exception as exc:
|
||||
results["errors"]["digital"][p] = repr(exc)
|
||||
|
||||
for p in pins:
|
||||
pin_snapshot, snapshot_error = _try_pin_snapshot(p)
|
||||
if snapshot_error is not None:
|
||||
results["errors"]["analog"][p] = repr(snapshot_error)
|
||||
continue
|
||||
try:
|
||||
print("Reading analog GPIO%02d..." % p)
|
||||
adc = machine.ADC(machine.Pin(p))
|
||||
results["analog"][p] = _adc_read(adc)
|
||||
#time.sleep(1)
|
||||
except Exception as exc:
|
||||
results["errors"]["analog"][p] = repr(exc)
|
||||
finally:
|
||||
try:
|
||||
_restore_pin(pin_snapshot)
|
||||
except Exception as exc:
|
||||
results["errors"]["analog"][p] = repr(exc)
|
||||
|
||||
print("=== Pin State Readout ===")
|
||||
print("Board:", board)
|
||||
print("=== Digital Reads ===")
|
||||
for p in pins:
|
||||
if p in results["digital"]:
|
||||
print("GPIO%02d:" % p, results["digital"][p])
|
||||
else:
|
||||
print("GPIO%02d:" % p, "ERR", results["errors"]["digital"].get(p))
|
||||
|
||||
print("=== Analog Reads ===")
|
||||
for p in pins:
|
||||
if p in results["analog"]:
|
||||
print("GPIO%02d:" % p, results["analog"][p])
|
||||
else:
|
||||
print("GPIO%02d:" % p, "ERR", results["errors"]["analog"].get(p))
|
||||
|
||||
return results
|
||||
@@ -1,6 +1,8 @@
|
||||
import _thread
|
||||
import lvgl as lv
|
||||
|
||||
from machine import Pin
|
||||
|
||||
import mpos.ui
|
||||
import mpos.ui.topmenu
|
||||
|
||||
@@ -55,32 +57,21 @@ def single_address_i2c_scan(i2c_bus, address):
|
||||
|
||||
|
||||
def fail_save_i2c(sda, scl):
|
||||
from machine import I2C, Pin
|
||||
from machine import I2C
|
||||
|
||||
print(f"Try to I2C initialized on {sda=} {scl=}")
|
||||
try:
|
||||
i2c0 = I2C(0, sda=Pin(sda), scl=Pin(scl))
|
||||
except Exception as e:
|
||||
print(f"Failed: {e}")
|
||||
print(f"fail_save_i2c failed: {e}")
|
||||
return None
|
||||
else:
|
||||
print("OK")
|
||||
print("fail_save_i2c ok")
|
||||
return i2c0
|
||||
|
||||
|
||||
def check_pins(*pins):
|
||||
from machine import Pin
|
||||
|
||||
print(f"Test {pins=}...")
|
||||
for pin in pins:
|
||||
try:
|
||||
Pin(pin)
|
||||
except Exception as e:
|
||||
print(f"Failed to initialize {pin=}: {e}")
|
||||
return True
|
||||
print("All pins initialized successfully")
|
||||
return True
|
||||
|
||||
def restore_i2c(sda, scl):
|
||||
Pin(sda, Pin.IN, pull=None)
|
||||
Pin(scl, Pin.IN, pull=None)
|
||||
|
||||
def detect_board():
|
||||
import sys
|
||||
@@ -88,6 +79,18 @@ def detect_board():
|
||||
return "linux"
|
||||
elif sys.platform == "esp32":
|
||||
|
||||
'''
|
||||
# Reading and storing all pinstates can be useful for board detection
|
||||
# But reading some pins can break peripherals
|
||||
# So it's disabled by default - it's more for development
|
||||
try:
|
||||
import mpos
|
||||
from mpos.board import pinstates
|
||||
mpos.pinstates = pinstates.read_all_pins(skiplist = [7,8])
|
||||
except Exception as e:
|
||||
print("pinstates: WARNING: failed to read pins:", e)
|
||||
'''
|
||||
|
||||
# First do unique_id-based board detections because they're fast and don't mess with actual hardware configurations
|
||||
import machine
|
||||
unique_id_prefixes = machine.unique_id()[0:3]
|
||||
@@ -96,10 +99,6 @@ def detect_board():
|
||||
if unique_id_prefixes == b'\x30\x30\xf9':
|
||||
return "unphone"
|
||||
|
||||
print("(emulated) lilygo_t_display_s3 ?")
|
||||
if unique_id_prefixes == b'\x10\x01\x00' or unique_id_prefixes == b'\xc0\x4e\x30':
|
||||
return "lilygo_t_display_s3" # display gets confused by the i2c stuff below
|
||||
|
||||
print("odroid_go ?")
|
||||
if unique_id_prefixes == b'\x30\xae\xa4':
|
||||
return "odroid_go"
|
||||
@@ -109,37 +108,53 @@ def detect_board():
|
||||
# or: if single_address_i2c_scan(i2c0, 0x6A): # IMU currently not installed on prototype board
|
||||
return "fri3d_2026"
|
||||
|
||||
# Do I2C-based board detection
|
||||
|
||||
print("lilygo_t_watch_s3_plus ?")
|
||||
if i2c0 := fail_save_i2c(sda=10, scl=11):
|
||||
if single_address_i2c_scan(i2c0, 0x19): # IMU on 0x19, vibrator on 0x5A and scan also shows: [52, 81]
|
||||
return "lilygo_t_watch_s3_plus" # example MAC address: D0:CF:13:33:36:306
|
||||
restore_i2c(sda=10, scl=11)
|
||||
|
||||
# Then do I2C-based board detection
|
||||
print("matouch_esp32_s3_spi_ips_2_8_with_camera_ov3660 ?")
|
||||
if i2c0 := fail_save_i2c(sda=39, scl=38):
|
||||
if single_address_i2c_scan(i2c0, 0x14) or single_address_i2c_scan(i2c0, 0x5D): # "ghost" or real GT911 touch screen
|
||||
return "matouch_esp32_s3_spi_ips_2_8_with_camera_ov3660"
|
||||
restore_i2c(sda=39, scl=38) # fix pin 39 (data0) breaking lilygo_t_display_s3's display
|
||||
|
||||
print("waveshare_esp32_s3_touch_lcd_2 ?")
|
||||
if i2c0 := fail_save_i2c(sda=48, scl=47):
|
||||
# IO48 is floating on matouch_esp32_s3_spi_ips_2_8_with_camera_ov3660 and therefore, using that for I2C will find many devices, so do this after matouch_esp32_s3_spi_ips_2_8_with_camera_ov3660
|
||||
if single_address_i2c_scan(i2c0, 0x15) and single_address_i2c_scan(i2c0, 0x6B): # CST816S touch screen and IMU
|
||||
return "waveshare_esp32_s3_touch_lcd_2"
|
||||
restore_i2c(sda=48, scl=47) # fix pin 47 (data6) and 48 (data7) breaking lilygo_t_display_s3's display
|
||||
|
||||
print("m5stack_fire ?")
|
||||
if i2c0 := fail_save_i2c(sda=21, scl=22):
|
||||
if single_address_i2c_scan(i2c0, 0x68): # IMU (MPU6886)
|
||||
return "m5stack_fire"
|
||||
restore_i2c(sda=21, scl=22)
|
||||
|
||||
print("fri3d_2024 ?")
|
||||
if i2c0 := fail_save_i2c(sda=9, scl=18):
|
||||
if single_address_i2c_scan(i2c0, 0x6B): # IMU (plus possibly the Communicator's LANA TNY at 0x38)
|
||||
return "fri3d_2024"
|
||||
restore_i2c(sda=9, scl=18)
|
||||
|
||||
# On devices without I2C, we use known GPIO states
|
||||
|
||||
print("(emulated) lilygo_t_display_s3 ?")
|
||||
try:
|
||||
# 2 buttons have PCB pull-ups so they'll be high unless pressed
|
||||
pin0 = Pin(0, Pin.IN)
|
||||
pin14 = Pin(14, Pin.IN)
|
||||
if pin0.value() == 1 and pin14.value() == 1:
|
||||
return "lilygo_t_display_s3" # display gets confused by the i2c stuff below
|
||||
except Exception as e:
|
||||
print(f"lilygo_t_display_s3 detection got exception: {e}")
|
||||
|
||||
print("Unknown board: couldn't detect known I2C devices or unique_id prefix")
|
||||
|
||||
|
||||
# EXECUTION STARTS HERE
|
||||
|
||||
print(f"MicroPythonOS {BuildInfo.version.release} running lib/mpos/main.py")
|
||||
|
||||
Reference in New Issue
Block a user