Improve lilygo_t_watch_s3_plus

This commit is contained in:
Thomas Farstrike
2026-03-01 22:45:30 +01:00
parent ffd2a68636
commit f492278b99
6 changed files with 185 additions and 18 deletions
@@ -0,0 +1,10 @@
"""Input device drivers package helpers."""
try:
import sys
from . import focaltech_touch as _focaltech_touch
if "focaltech_touch" not in sys.modules:
sys.modules["focaltech_touch"] = _focaltech_touch
except Exception:
pass
@@ -0,0 +1,124 @@
# Copyright (c) 2024 - 2025 Kevin G. Schlosser
from micropython import const # NOQA
import pointer_framework
import machine # NOQA
# Register of the current mode
_DEV_MODE_REG = const(0x00)
# ** Possible modes as of FT6X36_DEV_MODE_REG **
_DEV_MODE_WORKING = const(0x00)
_CTRL = const(0x86)
# Status register: stores number of active touch points (0, 1, 2)
_TD_STAT_REG = const(0x02)
_P1_XH = const(0x03)
_P1_XL = const(0x04)
_P1_YH = const(0x05)
_P1_YL = const(0x06)
_MSB_MASK = const(0x0F)
_LSB_MASK = const(0xFF)
# Report rate in Active mode
_PERIOD_ACTIVE_REG = const(0x88)
_VENDID = const(0x11)
_CHIPID_REG = const(0xA3)
_FIRMWARE_ID_REG = const(0xA6)
_RELEASECODE_REG = const(0xAF)
_PANEL_ID_REG = const(0xA8)
_G_MODE = const(0xA4)
class FocalTechTouch(pointer_framework.PointerDriver):
def __init__(
self,
device,
touch_cal,
startup_rotation, # NOQA
debug,
factors,
*chip_ids
): # NOQA
self._tx_buf = bytearray(5)
self._tx_mv = memoryview(self._tx_buf)
self._rx_buf = bytearray(5)
self._rx_mv = memoryview(self._rx_buf)
self._device = device
self._factors = factors
self._read_reg(_PANEL_ID_REG)
print("Touch Device ID: 0x%02x" % self._rx_buf[0])
ven_id = self._rx_buf[0] # NOQA
self._read_reg(_CHIPID_REG)
print("Touch Chip ID: 0x%02x" % self._rx_buf[0])
chip_id = self._rx_buf[0]
self._read_reg(_DEV_MODE_REG)
print("Touch Device mode: 0x%02x" % self._rx_buf[0])
self._read_reg(_FIRMWARE_ID_REG)
print("Touch Firmware ID: 0x%02x" % self._rx_buf[0])
self._read_reg(_RELEASECODE_REG)
print("Touch Release code: 0x%02x" % self._rx_buf[0])
if chip_id not in chip_ids:
raise RuntimeError(
f'IC is not compatable with the {self.__class__.__name__} driver' # NOQA
)
self._write_reg(_DEV_MODE_REG, _DEV_MODE_WORKING)
self._write_reg(_PERIOD_ACTIVE_REG, 0x0E)
self._write_reg(_G_MODE, 0x00)
# This is needed so the TS doesn't go to sleep
self._write_reg(_CTRL, 0x00)
super().__init__(
touch_cal=touch_cal, startup_rotation=startup_rotation, debug=debug
)
def _get_coords(self):
self._tx_buf[0] = _TD_STAT_REG
try:
self._device.write_readinto(self._tx_mv, self._rx_mv)
except OSError:
return None
buf = self._rx_buf
touch_pnt_cnt = buf[0]
if touch_pnt_cnt != 1:
return None
x = ((buf[1] & _MSB_MASK) << 8) | buf[2]
y = ((buf[3] & _MSB_MASK) << 8) | buf[4]
if self._factors is not None:
x = round(x / self._factors[0])
y = round(y / self._factors[1])
return self.PRESSED, x, y
def _read_reg(self, reg):
self._tx_buf[0] = reg
self._rx_buf[0] = 0x00
self._device.write_readinto(self._tx_mv[:1], self._rx_mv[:1])
def _write_reg(self, reg, value):
self._tx_buf[0] = reg
self._tx_buf[1] = value
self._device.write(self._tx_mv[:2])
@@ -0,0 +1,37 @@
# Copyright (c) 2024 - 2025 Kevin G. Schlosser
# FT6236/FT6336/FT6436/FT6436L
from micropython import const # NOQA
import focaltech_touch
import pointer_framework
I2C_ADDR = const(0x38)
BITS = 8
_FT6x36_CHIPID_1 = const(0x36)
_FT6x36_CHIPID_2 = const(0x64)
_FT6x36_CHIPID_3 = const(0xCD)
class FT6x36(focaltech_touch.FocalTechTouch):
def __init__(
self,
device,
touch_cal=None,
startup_rotation=pointer_framework.lv.DISPLAY_ROTATION._0, # NOQA
debug=False
): # NOQA
super().__init__(
device,
touch_cal,
startup_rotation,
debug,
None,
_FT6x36_CHIPID_1,
_FT6x36_CHIPID_2,
_FT6x36_CHIPID_3
)
@@ -2,13 +2,10 @@ print("lilygo_t_watch_s3_plus.py initialization")
# Manufacturer's website at https://lilygo.cc/products/t-watch-s3-plus
import lcd_bus
import machine
import i2c
import lvgl as lv
import task_handler
import drivers.display.st7789 as st7789
import mpos.ui
spi_bus = machine.SPI.Bus(
@@ -27,6 +24,7 @@ _BUFFER_SIZE = const(28800)
fb1 = display_bus.allocate_framebuffer(_BUFFER_SIZE, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_DMA)
fb2 = display_bus.allocate_framebuffer(_BUFFER_SIZE, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_DMA)
import drivers.display.st7789 as st7789
mpos.ui.main_display = st7789.ST7789(
data_bus=display_bus,
frame_buffer1=fb1,
@@ -38,19 +36,17 @@ mpos.ui.main_display = st7789.ST7789(
rgb565_byte_swap=True,
backlight_pin=45,
backlight_on_state=st7789.STATE_PWM,
)
) # triggers lv.init()
mpos.ui.main_display.init()
mpos.ui.main_display.set_power(True)
mpos.ui.main_display.set_backlight(100)
# TODO:
# Touch handling:
#import drivers.indev.cst816s as cst816s
#i2c_bus = i2c.I2C.Bus(host=0, scl=40, sda=39, freq=400000, use_locks=False)
#touch_dev = i2c.I2C.Device(bus=i2c_bus, dev_id=0x15, reg_bits=8)
#indev=cst816s.CST816S(touch_dev)
lv.init()
import i2c
import drivers.indev.ft6x36 as ft6x36
i2c_bus = i2c.I2C.Bus(host=0, sda=39, scl=40, freq=400000, use_locks=False)
touch_dev = i2c.I2C.Device(bus=i2c_bus, dev_id=ft6x36.I2C_ADDR, reg_bits=ft6x36.BITS)
import pointer_framework
indev=ft6x36.FT6x36(touch_dev, startup_rotation=pointer_framework.lv.DISPLAY_ROTATION._180)
# TODO:
# - battery
@@ -72,7 +72,7 @@ mpos.ui.main_display = st7789.ST7789(
rgb565_byte_swap=True,
backlight_pin=LCD_BL,
backlight_on_state=st7789.STATE_PWM,
)
) # triggers lv.init()
mpos.ui.main_display.init()
mpos.ui.main_display.set_power(True)
mpos.ui.main_display.set_backlight(100)
@@ -82,7 +82,6 @@ i2c_bus = i2c.I2C.Bus(host=I2C_BUS, scl=TP_SCL, sda=TP_SDA, freq=I2C_FREQ, use_l
touch_dev = i2c.I2C.Device(bus=i2c_bus, dev_id=TP_ADDR, reg_bits=TP_REGBITS)
indev=cst816s.CST816S(touch_dev,startup_rotation=lv.DISPLAY_ROTATION._180) # button in top left, good
lv.init()
mpos.ui.main_display.set_rotation(lv.DISPLAY_ROTATION._90) # must be done after initializing display and creating the touch drivers, to ensure proper handling
# Battery voltage ADC measuring
+5 -4
View File
@@ -105,6 +105,11 @@ def detect_board():
# or: if single_address_i2c_scan(i2c0, 0x6A): # IMU currently not installed on prototype board
return "fri3d_2026"
print("lilygo_t_watch_s3_plus ?")
if i2c0 := fail_save_i2c(sda=10, scl=11):
if single_address_i2c_scan(i2c0, 0x19): # IMU on 32? but scan shows: [25, 52, 81, 90]
return "lilygo_t_watch_s3_plus" # example MAC address: D0:CF:13:33:36:306
# 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):
@@ -127,10 +132,6 @@ def detect_board():
if single_address_i2c_scan(i2c0, 0x6B): # IMU (plus possibly the Communicator's LANA TNY at 0x38)
return "fri3d_2024"
print("lilygo_t_watch_s3_plus ?")
if i2c0 := fail_save_i2c(sda=10, scl=11):
if single_address_i2c_scan(i2c0, 0x20): # IMU
return "lilygo_t_watch_s3_plus" # example MAC address: D0:CF:13:33:36:306
print("Unknown board: couldn't detect known I2C devices or unique_id prefix")