2020-03-22 16:40:18 +01:00
|
|
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
# Copyright (C) 2020 Daniel Thompson
|
|
|
|
|
2020-05-14 22:36:09 +02:00
|
|
|
"""Hynitron CST816S touch contoller driver
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2020-03-08 11:18:08 +01:00
|
|
|
"""
|
|
|
|
|
|
|
|
import array
|
2020-06-09 12:18:27 +02:00
|
|
|
import time
|
|
|
|
from machine import Pin
|
2020-03-06 22:09:43 +01:00
|
|
|
|
|
|
|
class CST816S:
|
2020-05-14 22:36:09 +02:00
|
|
|
"""Hynitron CST816S I2C touch controller driver.
|
|
|
|
|
|
|
|
.. automethod:: __init__
|
|
|
|
"""
|
2020-06-09 12:18:27 +02:00
|
|
|
|
2020-07-01 00:04:01 +02:00
|
|
|
def __init__(self, bus, intr, rst, schedule=None):
|
2020-05-14 22:36:09 +02:00
|
|
|
"""Specify the bus used by the touch controller.
|
|
|
|
|
|
|
|
:param machine.I2C bus: I2C bus for the CST816S.
|
|
|
|
"""
|
2020-03-07 12:47:25 +01:00
|
|
|
self.i2c = bus
|
2020-06-09 12:18:27 +02:00
|
|
|
self.tp_int = intr
|
|
|
|
self.tp_rst = rst
|
2020-07-01 00:04:01 +02:00
|
|
|
self.schedule = schedule
|
2020-03-06 22:09:43 +01:00
|
|
|
self.dbuf = bytearray(6)
|
2020-03-08 11:18:08 +01:00
|
|
|
self.event = array.array('H', (0, 0, 0))
|
2020-03-06 22:09:43 +01:00
|
|
|
|
2020-06-09 12:18:27 +02:00
|
|
|
self._reset()
|
|
|
|
self.tp_int.irq(trigger=Pin.IRQ_FALLING, handler=self.get_touch_data)
|
|
|
|
|
|
|
|
def _reset(self):
|
|
|
|
self.tp_rst.off()
|
|
|
|
time.sleep_ms(5)
|
|
|
|
self.tp_rst.on()
|
|
|
|
time.sleep_ms(50)
|
|
|
|
|
|
|
|
def get_touch_data(self, pin_obj):
|
|
|
|
"""Receive a touch event by interrupt.
|
2020-03-06 22:09:43 +01:00
|
|
|
|
|
|
|
Check for a pending touch event and, if an event is pending,
|
|
|
|
prepare it ready to go in the event queue.
|
|
|
|
"""
|
|
|
|
dbuf = self.dbuf
|
2020-03-08 11:18:08 +01:00
|
|
|
event = self.event
|
|
|
|
|
2020-03-06 22:09:43 +01:00
|
|
|
try:
|
2020-03-07 12:47:25 +01:00
|
|
|
self.i2c.readfrom_mem_into(21, 1, dbuf)
|
2020-03-06 22:09:43 +01:00
|
|
|
except OSError:
|
2020-03-08 11:18:08 +01:00
|
|
|
return None
|
|
|
|
|
2020-06-09 12:18:27 +02:00
|
|
|
event[0] = dbuf[0] # event
|
|
|
|
event[1] = ((dbuf[2] & 0xf) << 8) + dbuf[3] # x coord
|
|
|
|
event[2] = ((dbuf[4] & 0xf) << 8) + dbuf[5] # y coord
|
2020-03-08 11:18:08 +01:00
|
|
|
|
2020-07-01 00:04:01 +02:00
|
|
|
if self.schedule:
|
|
|
|
self.schedule(self)
|
|
|
|
|
2020-06-09 12:18:27 +02:00
|
|
|
def get_event(self):
|
|
|
|
"""Receive a touch event.
|
2020-03-08 11:18:08 +01:00
|
|
|
|
2020-06-09 12:18:27 +02:00
|
|
|
Check for a pending touch event and, if an event is pending,
|
|
|
|
prepare it ready to go in the event queue.
|
2020-03-08 11:18:08 +01:00
|
|
|
|
2020-06-09 12:18:27 +02:00
|
|
|
:return: An event record if an event is received, None otherwise.
|
|
|
|
"""
|
|
|
|
if self.event[0] == 0:
|
2020-03-08 11:18:08 +01:00
|
|
|
return None
|
2020-03-06 22:09:43 +01:00
|
|
|
|
2020-06-09 12:18:27 +02:00
|
|
|
return self.event
|
|
|
|
|
|
|
|
def reset_touch_data(self):
|
|
|
|
"""Reset touch data.
|
|
|
|
|
|
|
|
Reset touch data, call this function after processing an event.
|
|
|
|
"""
|
|
|
|
self.event[0] = 0
|
|
|
|
|
|
|
|
def wake(self):
|
|
|
|
"""Wake up touch controller chip.
|
|
|
|
|
|
|
|
Just reset the chip in order to wake it up
|
|
|
|
"""
|
|
|
|
self._reset()
|
2020-09-21 21:12:38 +02:00
|
|
|
self.event[0] = 0
|
2020-06-09 12:18:27 +02:00
|
|
|
|
|
|
|
def sleep(self):
|
|
|
|
"""Put touch controller chip on sleep mode to save power.
|
|
|
|
"""
|
2020-08-15 21:40:26 +02:00
|
|
|
# Before we can send the sleep command we have to reset the
|
2020-06-09 12:18:27 +02:00
|
|
|
# panel to get the I2C hardware running again...
|
|
|
|
self._reset()
|
2020-08-15 21:40:26 +02:00
|
|
|
try:
|
|
|
|
self.i2c.writeto_mem(21, 0xa5, b'\x03')
|
|
|
|
except:
|
|
|
|
# If we can't power down then let's just put it in reset instead
|
|
|
|
self.tp_rst.off()
|
2020-06-09 12:18:27 +02:00
|
|
|
|
|
|
|
# Ensure get_event() cannot return anything
|
|
|
|
self.event[0] = 0
|