|
| 1 | +from micropython import const # NOQA |
| 2 | +import pointer_framework |
| 3 | +import time |
| 4 | +import machine # NOQA |
| 5 | + |
| 6 | + |
| 7 | +I2C_ADDR = 0x1A |
| 8 | +BITS = 8 |
| 9 | + |
| 10 | +# 4 byte read |
| 11 | +# PROJECT_ID = byte2 << 8 | byte3 |
| 12 | +# CHIP_TYPE = byte0 << 8 | byte1 |
| 13 | +_ID_REG = const(0xD204) |
| 14 | + |
| 15 | +# BYTE 3:FW_MAJOR |
| 16 | +# BYTE 2:FW_MINOR |
| 17 | +# BYTE 1 ~ BYTE 0:FW_BUILD |
| 18 | +# 4 byte read |
| 19 | +# MAJOR = byte0 |
| 20 | +# MINOR = byte1 |
| 21 | +# MICRO = byte2 << 8 | byte3 |
| 22 | +_FW_VERSION_REG = const(0xD208) |
| 23 | + |
| 24 | + |
| 25 | +_MODE_NORMAL_REG = const(0xD109) |
| 26 | + |
| 27 | + |
| 28 | +# touch information register |
| 29 | +# MODE_NORMAL |
| 30 | +# BYTE0: |
| 31 | +# BITS 0 - 3: Touch state (0x06) == touched |
| 32 | +# BITS 4 - 7: N/A |
| 33 | + |
| 34 | +# BYTE1, BYTE2, BYTE3 |
| 35 | +# BYTE1: BIT 7 ~ BIT 0: X high 8 bits |
| 36 | +# BYTE2: BIT 7 ~ BIT 0: Y high 8 bits |
| 37 | +# BYTE3: BITS 0 - 3: Y low 4 bits, BITS 4 - 7 X low 4 bits |
| 38 | +# x = BYTE1 << 4 | BYTE3 >> 4 |
| 39 | +# y = BYTE2 << 4 | BYTE3 & 0x0F |
| 40 | + |
| 41 | +# BYTE4: |
| 42 | +# BITS 0 - 7: Touch pressure |
| 43 | + |
| 44 | +# BYTE5: |
| 45 | +# BITS 0 - 3: Finger count |
| 46 | +# BITS 4 - 7: N/A |
| 47 | +_TOUCH_DATA_REG = const(0xD000) |
| 48 | +_TOUCH_STATE_MASK = const(0x0F) |
| 49 | +_TOUCH_STATE_PRESSED = const(0x06) |
| 50 | +_TOUCH_COUNT_MASK = const(0x0F) |
| 51 | + |
| 52 | + |
| 53 | +class CST328(pointer_framework.PointerDriver): |
| 54 | + |
| 55 | + def _read_reg(self, reg, num_bytes): |
| 56 | + self._tx_buf[0] = reg >> 8 |
| 57 | + self._tx_buf[1] = reg & 0xFF |
| 58 | + |
| 59 | + self._rx_buf[:num_bytes] = bytearray([0x00] * num_bytes) |
| 60 | + |
| 61 | + self._device.write_readinto(self._tx_mv[:2], self._rx_mv[:num_bytes]) |
| 62 | + |
| 63 | + def _write_reg(self, reg, value=None): |
| 64 | + self._tx_buf[0] = reg >> 8 |
| 65 | + self._tx_buf[1] = reg & 0xFF |
| 66 | + |
| 67 | + if value is None: |
| 68 | + self._device.write(self._tx_mv[:2]) |
| 69 | + else: |
| 70 | + self._tx_buf[2] = value |
| 71 | + self._device.write(self._tx_mv[:3]) |
| 72 | + |
| 73 | + def __init__( |
| 74 | + self, |
| 75 | + device, |
| 76 | + reset_pin=None, |
| 77 | + touch_cal=None, |
| 78 | + startup_rotation=pointer_framework.lv.DISPLAY_ROTATION._0, |
| 79 | + debug=False |
| 80 | + ): |
| 81 | + self._tx_buf = bytearray(2) |
| 82 | + self._tx_mv = memoryview(self._tx_buf) |
| 83 | + self._rx_buf = bytearray(6) |
| 84 | + self._rx_mv = memoryview(self._rx_buf) |
| 85 | + |
| 86 | + self._device = device |
| 87 | + |
| 88 | + if not isinstance(reset_pin, int): |
| 89 | + self._reset_pin = reset_pin |
| 90 | + else: |
| 91 | + self._reset_pin = machine.Pin(reset_pin, machine.Pin.OUT) |
| 92 | + |
| 93 | + if self._reset_pin: |
| 94 | + self._reset_pin.value(1) |
| 95 | + |
| 96 | + self.hw_reset() |
| 97 | + |
| 98 | + self._read_reg(_ID_REG, 4) |
| 99 | + chip_id = (self._rx_buf[0] << 8) | self._rx_buf[1] |
| 100 | + project_id = (self._rx_buf[2] << 8) | self._rx_buf[3] |
| 101 | + |
| 102 | + print(f'Chip ID: 0x{hex(chip_id)[2:].upper()}') |
| 103 | + print(f'Proj ID: 0x{hex(project_id)[2:].upper()}') |
| 104 | + |
| 105 | + self._read_reg(_FW_VERSION_REG, 4) |
| 106 | + version = f'{self._rx_buf[0]}.{self._rx_buf[1]}.{(self._rx_buf[2] << 8) | self._rx_buf[3]}' |
| 107 | + print('FW Version:', version) |
| 108 | + |
| 109 | + self._write_reg(_MODE_NORMAL_REG) |
| 110 | + |
| 111 | + self._touch_thresh = 10 |
| 112 | + |
| 113 | + super().__init__( |
| 114 | + touch_cal=touch_cal, startup_rotation=startup_rotation, debug=debug |
| 115 | + ) |
| 116 | + |
| 117 | + @property |
| 118 | + def touch_threshold(self): |
| 119 | + return self._touch_thresh |
| 120 | + |
| 121 | + @touch_threshold.setter |
| 122 | + def touch_threshold(self, value): |
| 123 | + if value < 1: |
| 124 | + value = 1 |
| 125 | + elif value > 255: |
| 126 | + value = 255 |
| 127 | + self._touch_thresh = value |
| 128 | + |
| 129 | + def hw_reset(self): |
| 130 | + if self._reset_pin is None: |
| 131 | + return |
| 132 | + |
| 133 | + self._reset_pin(0) |
| 134 | + time.sleep_ms(1) # NOQA |
| 135 | + self._reset_pin(1) |
| 136 | + time.sleep_ms(50) # NOQA |
| 137 | + |
| 138 | + def _get_coords(self): |
| 139 | + self._read_reg(_TOUCH_DATA_REG, 6) |
| 140 | + |
| 141 | + touch_count = self._rx_buf[5] & _TOUCH_COUNT_MASK |
| 142 | + if touch_count: |
| 143 | + if self._rx_buf[0] & _TOUCH_STATE_MASK == _TOUCH_STATE_PRESSED: |
| 144 | + state = self.PRESSED |
| 145 | + |
| 146 | + if self._rx_buf[4] < self._touch_thresh: |
| 147 | + return None |
| 148 | + else: |
| 149 | + state = self.RELEASED |
| 150 | + |
| 151 | + x = (self._rx_buf[1] << 4) | (self._rx_buf[3] >> 4) |
| 152 | + y = (self._rx_buf[2] << 4) | (self._rx_buf[3] & 0x0F) |
| 153 | + |
| 154 | + return state, x, y |
0 commit comments