You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
2f4adfcace
https://unphone.net/ What worked: - hx8357d Display and XPT2046 touch screen works - Turn display backlight on/off via TCA9555 chip - Buttons TODOs: - Use LEDs - LoRa - IR `.../lib/drivers/display/hx8357d/` is a not modified copy from https://github.com/lvgl-micropython/lvgl_micropython/tree/main/api_drivers/common_api_drivers/display/hx8357d `.../lib/drivers/indev/xpt2046.py` based on https://github.com/lvgl-micropython/lvgl_micropython/blob/main/api_drivers/common_api_drivers/indev/xpt2046.py but is modified: Because of the shared SPI bus for SPI for hx8357d display and xpt2046 touch controller. For this i add the management of `CS` pins for reading the touch controller. Let's discuss how to add this to upstream in https://github.com/lvgl-micropython/lvgl_micropython/issues/536
128 lines
3.8 KiB
Python
128 lines
3.8 KiB
Python
# Copyright (c) 2024 - 2025 Kevin G. Schlosser
|
|
|
|
import lvgl as lv # NOQA
|
|
from micropython import const # NOQA
|
|
import micropython # NOQA
|
|
import machine # NOQA
|
|
import pointer_framework
|
|
import time
|
|
|
|
|
|
_CMD_X_READ = const(0xD0) # 12 bit resolution
|
|
_CMD_Y_READ = const(0x90) # 12 bit resolution
|
|
_CMD_Z1_READ = const(0xB0)
|
|
_CMD_Z2_READ = const(0xC0)
|
|
_MIN_RAW_COORD = const(10)
|
|
_MAX_RAW_COORD = const(4090)
|
|
|
|
|
|
class XPT2046(pointer_framework.PointerDriver):
|
|
touch_threshold = 400
|
|
confidence = 5
|
|
margin = 50
|
|
|
|
def __init__(
|
|
self,
|
|
device: machine.SPI.Bus,
|
|
display_width: int,
|
|
display_height: int,
|
|
lcd_cs: int,
|
|
touch_cs: int,
|
|
touch_cal=None,
|
|
startup_rotation=lv.DISPLAY_ROTATION._0,
|
|
debug=False,
|
|
):
|
|
self._device = device # machine.SPI.Bus() instance, shared with display
|
|
self._debug = debug
|
|
|
|
self.lcd_cs = machine.Pin(lcd_cs, machine.Pin.OUT, value=0)
|
|
self.touch_cs = machine.Pin(touch_cs, machine.Pin.OUT, value=1)
|
|
|
|
self._width = display_width
|
|
self._height = display_height
|
|
|
|
self._tx_buf = bytearray(3)
|
|
self._tx_mv = memoryview(self._tx_buf)
|
|
|
|
self._rx_buf = bytearray(3)
|
|
self._rx_mv = memoryview(self._rx_buf)
|
|
|
|
self.__confidence = max(min(self.confidence, 25), 3)
|
|
self.__points = [[0, 0] for _ in range(self.__confidence)]
|
|
|
|
margin = max(min(self.margin, 100), 1)
|
|
self.__margin = margin * margin
|
|
|
|
super().__init__(
|
|
touch_cal=touch_cal, startup_rotation=startup_rotation, debug=debug
|
|
)
|
|
|
|
def _read_reg(self, reg, num_bytes):
|
|
self._tx_buf[0] = reg
|
|
self._device.write_readinto(self._tx_mv[:num_bytes], self._rx_mv[:num_bytes])
|
|
return ((self._rx_buf[1] << 8) | self._rx_buf[2]) >> 3
|
|
|
|
def _get_coords(self):
|
|
try:
|
|
self.lcd_cs.value(1) # deselect LCD to avoid conflicts
|
|
self.touch_cs.value(0) # select touch chip
|
|
|
|
z1 = self._read_reg(_CMD_Z1_READ, 3)
|
|
z2 = self._read_reg(_CMD_Z2_READ, 3)
|
|
z = z1 + ((_MAX_RAW_COORD + 6) - z2)
|
|
if z < self.touch_threshold:
|
|
return None # Not touched
|
|
|
|
points = self.__points
|
|
count = 0
|
|
end_time = time.ticks_us() + 5000
|
|
while time.ticks_us() < end_time:
|
|
if count == self.__confidence:
|
|
break
|
|
|
|
raw_x = self._read_reg(_CMD_X_READ, 3)
|
|
if raw_x < _MIN_RAW_COORD:
|
|
continue
|
|
|
|
raw_y = self._read_reg(_CMD_Y_READ, 3)
|
|
if raw_y > _MAX_RAW_COORD:
|
|
continue
|
|
|
|
# put in buff
|
|
points[count][0] = raw_x
|
|
points[count][1] = raw_y
|
|
count += 1
|
|
|
|
finally:
|
|
self.touch_cs.value(1) # deselect touch chip
|
|
self.lcd_cs.value(0) # select LCD
|
|
|
|
if not count:
|
|
return None # Not touched
|
|
|
|
meanx = sum([points[i][0] for i in range(count)]) // count
|
|
meany = sum([points[i][1] for i in range(count)]) // count
|
|
dev = (
|
|
sum(
|
|
[
|
|
(points[i][0] - meanx) ** 2 + (points[i][1] - meany) ** 2
|
|
for i in range(count)
|
|
]
|
|
)
|
|
/ count
|
|
)
|
|
if dev >= self.__margin:
|
|
return None # Not touched
|
|
|
|
x = pointer_framework.remap(
|
|
meanx, _MIN_RAW_COORD, _MAX_RAW_COORD, 0, self._orig_width
|
|
)
|
|
y = pointer_framework.remap(
|
|
meany, _MIN_RAW_COORD, _MAX_RAW_COORD, 0, self._orig_height
|
|
)
|
|
if self._debug:
|
|
print(
|
|
f"{self.__class__.__name__}_TP_DATA({count=} {meanx=} {meany=} {z1=} {z2=} {z=})"
|
|
) # NOQA
|
|
return self.PRESSED, x, y
|