You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
308 lines
8.0 KiB
Python
308 lines
8.0 KiB
Python
# Copyright (c) 2024 - 2025 Kevin G. Schlosser
|
|
|
|
from micropython import const # NOQA
|
|
import pointer_framework
|
|
import time
|
|
import machine # NOQA
|
|
|
|
|
|
I2C_ADDR = 0x15
|
|
BITS = 8
|
|
|
|
# 0x00: No gesture
|
|
# 0x01: Swipe up
|
|
# 0x02: Swipe down
|
|
# 0x03: Swipe left
|
|
# 0x04: Swipe right
|
|
# 0x05: Single click
|
|
# 0x0B: Double click
|
|
# 0x0C: Long press
|
|
_GestureID = const(0x01)
|
|
|
|
# 0: No finger
|
|
# 1: 1 finger
|
|
_FingerNum = const(0x02)
|
|
|
|
# & 0xF << 8
|
|
_XposH = const(0x03)
|
|
_XposL = const(0x04)
|
|
|
|
# & 0xF << 8
|
|
_YposH = const(0x05)
|
|
_YposL = const(0x06)
|
|
|
|
_RegisterVersion = const(0x15)
|
|
|
|
_BPC0H = const(0xB0)
|
|
_BPC0L = const(0xB1)
|
|
|
|
_BPC1H = const(0xB2)
|
|
_BPC1L = const(0xB3)
|
|
|
|
_ChipID = const(0xA7)
|
|
_ChipIDValue = const(0xB5)
|
|
_ChipIDValue2 = const(0xB6)
|
|
|
|
_ProjID = const(0xA8)
|
|
_FwVersion = const(0xA9)
|
|
|
|
|
|
# ===============================
|
|
_MotionMask = const(0xEC)
|
|
|
|
# Enables continuous left and right sliding
|
|
_EnConLR = const(0x04)
|
|
# Enables continuous up and down sliding
|
|
_EnConUD = const(0x02)
|
|
# Enable double-click action
|
|
_EnDClick = const(0x01)
|
|
# ===============================
|
|
|
|
# Interrupt low pulse output width.
|
|
# Unit 0.1ms, optional value: 1~200. The default value is 10.
|
|
_IrqPluseWidth = const(0xED)
|
|
|
|
# Normal fast detection cycle.
|
|
# This value affects LpAutoWakeTime and AutoSleepTime.
|
|
# Unit 10ms, optional value: 1~30. The default value is 1.
|
|
_NorScanPer = const(0xEE)
|
|
|
|
# Gesture detection sliding partition angle control. Angle=tan(c)*10
|
|
# c is the angle based on the positive direction of the x-axis.
|
|
_MotionSlAngle = const(0xEF)
|
|
|
|
_LpScanRaw1H = const(0xF0)
|
|
_LpScanRaw1L = const(0xF1)
|
|
_LpScanRaw2H = const(0xF2)
|
|
_LpScanRaw2L = const(0xF3)
|
|
|
|
# Automatic recalibration period in low power consumption.
|
|
# Unit: 1 minute, optional value: 1 to 5. The default value is 5.
|
|
_LpAutoWakeTime = const(0xF4)
|
|
|
|
|
|
# Low power scan wake-up threshold. The smaller the value,
|
|
# the more sensitive it is.
|
|
# Optional values: 1 to 255. The default value is 48.
|
|
_LpScanTH = const(0xF5)
|
|
|
|
# Low power scan range. The larger the value, the more sensitive it is,
|
|
# and the higher the power consumption is.
|
|
# Optional values: 0, 1, 2, 3. The default value is 3.
|
|
_LpScanWin = const(0xF6)
|
|
|
|
# Low power scan frequency. The smaller the value, the more sensitive it is.
|
|
# Optional values: 1 to 255. The default value is 7.
|
|
_LpScanFreq = const(0xF7)
|
|
|
|
# Low power scan current. The smaller the value, the more sensitive it is.
|
|
# Optional values: 1 to 255.
|
|
_LpScanIdac = const(0xF8)
|
|
|
|
|
|
# Automatically enters low power mode when there is no touch within x seconds.
|
|
# Unit: 1S, default value: 2S.
|
|
_AutoSleepTime = const(0xF9)
|
|
|
|
# ===============================
|
|
_IrqCtl = const(0xFA)
|
|
# Interrupt pin test, automatically sends low pulses periodically after enabling
|
|
_EnTest = const(0x80)
|
|
# Sends low pulses periodically when touch is detected.
|
|
_EnTouch = const(0x40)
|
|
# Sends low pulses when touch state changes are detected.
|
|
_EnChange = const(0x20)
|
|
# Sends low pulses when gestures are detected.
|
|
_EnMotion = const(0x10)
|
|
# Long press gesture only sends one low pulse signal.
|
|
_OnceWLP = const(0x01)
|
|
# ===============================
|
|
|
|
|
|
# Automatically reset when there is touch but no valid gesture within x seconds.
|
|
# Unit: 1S. This function is not enabled when it is 0. The default value is 5.
|
|
_AutoReset = const(0xFB)
|
|
|
|
# Automatically reset after long pressing for x seconds.
|
|
# Unit: 1S. This function is not enabled when it is 0. The default value is 10.
|
|
_LongPressTime = const(0xFC)
|
|
|
|
# ===============================
|
|
_IOCtl = const(0xFD)
|
|
|
|
# The master controller realizes the soft reset function
|
|
# of the touch screen by pulling down the IRQ pin.
|
|
# 0: Disable soft reset.
|
|
# 1: Enable soft reset.
|
|
_SOFT_RST = const(0x04)
|
|
|
|
# IIC pin drive mode, the default is resistor pull-up.
|
|
# 0: Resistor pull-up
|
|
# 1: OD
|
|
_IIC_OD = const(0x02)
|
|
|
|
# IIC and IRQ pin level selection, the default is VDD level.
|
|
# 0: VDD
|
|
# 1: 1.8V
|
|
_En1v8 = const(0x01)
|
|
# ===============================
|
|
|
|
# The default value is 0, enabling automatic entry into low power mode.
|
|
# When the value is non-zero, automatic entry into low power mode is disabled.
|
|
# 0: enabled
|
|
# 1: disabled
|
|
_DisAutoSleep = const(0xFE)
|
|
|
|
|
|
class CST816S(pointer_framework.PointerDriver):
|
|
|
|
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])
|
|
|
|
def __init__(
|
|
self,
|
|
device,
|
|
reset_pin=None,
|
|
touch_cal=None,
|
|
startup_rotation=pointer_framework.lv.DISPLAY_ROTATION._0, # NOQA
|
|
debug=False
|
|
):
|
|
self._tx_buf = bytearray(2)
|
|
self._tx_mv = memoryview(self._tx_buf)
|
|
self._rx_buf = bytearray(1)
|
|
self._rx_mv = memoryview(self._rx_buf)
|
|
|
|
self._device = device
|
|
|
|
if not isinstance(reset_pin, int):
|
|
self._reset_pin = reset_pin
|
|
else:
|
|
self._reset_pin = machine.Pin(reset_pin, machine.Pin.OUT)
|
|
|
|
if self._reset_pin:
|
|
self._reset_pin.value(1)
|
|
|
|
self.hw_reset()
|
|
self.auto_sleep = False
|
|
|
|
self._read_reg(_ChipID)
|
|
print('Chip ID:', hex(self._rx_buf[0]))
|
|
chip_id = self._rx_buf[0]
|
|
|
|
self._read_reg(_RegisterVersion)
|
|
print('Touch version:', self._rx_buf[0])
|
|
|
|
self._read_reg(_ProjID)
|
|
print('Proj ID:', hex(self._rx_buf[0]))
|
|
|
|
self._read_reg(_FwVersion)
|
|
print('FW Version:', hex(self._rx_buf[0]))
|
|
|
|
if chip_id not in (_ChipIDValue, _ChipIDValue2):
|
|
raise RuntimeError(f'Incorrect chip id ({hex(chip_id)})')
|
|
|
|
self._write_reg(_IrqCtl, _EnTouch | _EnChange)
|
|
|
|
super().__init__(
|
|
touch_cal=touch_cal, startup_rotation=startup_rotation, debug=debug
|
|
)
|
|
|
|
@property
|
|
def wake_up_threshold(self):
|
|
self._read_reg(_LpScanTH)
|
|
return 256 - self._rx_buf[0]
|
|
|
|
@wake_up_threshold.setter
|
|
def wake_up_threshold(self, value):
|
|
if value < 1:
|
|
value = 1
|
|
elif value > 255:
|
|
value = 255
|
|
|
|
self._write_reg(_LpScanTH, 256 - value)
|
|
|
|
@property
|
|
def wake_up_scan_frequency(self):
|
|
self._read_reg(_LpScanFreq)
|
|
return 256 - self._rx_buf[0]
|
|
|
|
@wake_up_scan_frequency.setter
|
|
def wake_up_scan_frequency(self, value):
|
|
if value < 1:
|
|
value = 1
|
|
elif value > 255:
|
|
value = 255
|
|
|
|
self._write_reg(_LpScanFreq, 256 - value)
|
|
|
|
@property
|
|
def auto_sleep_timeout(self):
|
|
self._read_reg(_AutoSleepTime)
|
|
return self._rx_buf[0]
|
|
|
|
@auto_sleep_timeout.setter
|
|
def auto_sleep_timeout(self, value):
|
|
if value < 1:
|
|
value = 1
|
|
elif value > 255:
|
|
value = 255
|
|
|
|
self._write_reg(_AutoSleepTime, value)
|
|
|
|
def wake_up(self):
|
|
auto_sleep = self.auto_sleep
|
|
|
|
self._write_reg(_DisAutoSleep, 0x00)
|
|
time.sleep_ms(10) # NOQA
|
|
self._write_reg(_DisAutoSleep, 0xFE)
|
|
time.sleep_ms(50) # NOQA
|
|
self._write_reg(_DisAutoSleep, 0xFE)
|
|
time.sleep_ms(50) # NOQA
|
|
self._write_reg(_DisAutoSleep, int(not auto_sleep))
|
|
|
|
@property
|
|
def auto_sleep(self):
|
|
self._read_reg(_DisAutoSleep)
|
|
return self._rx_buf[0] == 0x00
|
|
|
|
@auto_sleep.setter
|
|
def auto_sleep(self, en):
|
|
if en:
|
|
self._write_reg(_DisAutoSleep, 0x00)
|
|
else:
|
|
self._write_reg(_DisAutoSleep, 0xFE)
|
|
|
|
def hw_reset(self):
|
|
if self._reset_pin is None:
|
|
return
|
|
|
|
self._reset_pin(0)
|
|
time.sleep_ms(1) # NOQA
|
|
self._reset_pin(1)
|
|
time.sleep_ms(50) # NOQA
|
|
|
|
def _get_coords(self):
|
|
self._read_reg(_FingerNum)
|
|
if self._rx_buf[0] == 0:
|
|
return None
|
|
|
|
self._read_reg(_XposH)
|
|
x = (self._rx_buf[0] & 0x0F) << 8
|
|
self._read_reg(_XposL)
|
|
x |= self._rx_buf[0]
|
|
|
|
self._read_reg(_YposH)
|
|
y = (self._rx_buf[0] & 0x0F) << 8
|
|
self._read_reg(_YposL)
|
|
y |= self._rx_buf[0]
|
|
|
|
return self.PRESSED, x, y
|