drivers: cst816s: optimize for power saving and responsiveness
Signed-off-by: Fuji Pebri <pebri86@gmail.com> [daniel@redfelineinja.org.uk: removed leading underscore from method arguments, removed redundant state tracking, adopt i2c.writeto_mem] Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk>
This commit is contained in:
parent
acf318c122
commit
df9d80f6f7
4 changed files with 61 additions and 35 deletions
|
@ -81,7 +81,7 @@ try:
|
||||||
Signal(Pin('USB_PWR', Pin.IN), invert=True))
|
Signal(Pin('USB_PWR', Pin.IN), invert=True))
|
||||||
i2c = I2C(1, scl='I2C_SCL', sda='I2C_SDA')
|
i2c = I2C(1, scl='I2C_SCL', sda='I2C_SDA')
|
||||||
accel = BMA421(i2c)
|
accel = BMA421(i2c)
|
||||||
touch = CST816S(i2c)
|
touch = CST816S(i2c, Pin('TP_INT', Pin.IN), Pin('TP_RST', Pin.OUT, value=0))
|
||||||
vibrator = Vibrator(Pin('MOTOR', Pin.OUT, value=0), active_low=True)
|
vibrator = Vibrator(Pin('MOTOR', Pin.OUT, value=0), active_low=True)
|
||||||
|
|
||||||
# Release flash from deep power-down
|
# Release flash from deep power-down
|
||||||
|
|
|
@ -13,6 +13,7 @@ def print_exception(exc, file=sys.stdout):
|
||||||
sys.print_exception = print_exception
|
sys.print_exception = print_exception
|
||||||
|
|
||||||
import draw565
|
import draw565
|
||||||
|
import array
|
||||||
|
|
||||||
from machine import I2C
|
from machine import I2C
|
||||||
from machine import Pin
|
from machine import Pin
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import array
|
import array
|
||||||
|
import time
|
||||||
|
from machine import Pin
|
||||||
|
|
||||||
class CST816S:
|
class CST816S:
|
||||||
"""Hynitron CST816S I2C touch controller driver.
|
"""Hynitron CST816S I2C touch controller driver.
|
||||||
|
@ -13,15 +15,44 @@ class CST816S:
|
||||||
.. automethod:: __init__
|
.. automethod:: __init__
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bus):
|
def __init__(self, bus, intr, rst):
|
||||||
"""Specify the bus used by the touch controller.
|
"""Specify the bus used by the touch controller.
|
||||||
|
|
||||||
:param machine.I2C bus: I2C bus for the CST816S.
|
:param machine.I2C bus: I2C bus for the CST816S.
|
||||||
"""
|
"""
|
||||||
self.i2c = bus
|
self.i2c = bus
|
||||||
|
self.tp_int = intr
|
||||||
|
self.tp_rst = rst
|
||||||
self.dbuf = bytearray(6)
|
self.dbuf = bytearray(6)
|
||||||
self.event = array.array('H', (0, 0, 0))
|
self.event = array.array('H', (0, 0, 0))
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Check for a pending touch event and, if an event is pending,
|
||||||
|
prepare it ready to go in the event queue.
|
||||||
|
"""
|
||||||
|
dbuf = self.dbuf
|
||||||
|
event = self.event
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.i2c.readfrom_mem_into(21, 1, dbuf)
|
||||||
|
except OSError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
def get_event(self):
|
def get_event(self):
|
||||||
"""Receive a touch event.
|
"""Receive a touch event.
|
||||||
|
|
||||||
|
@ -30,38 +61,32 @@ class CST816S:
|
||||||
|
|
||||||
:return: An event record if an event is received, None otherwise.
|
:return: An event record if an event is received, None otherwise.
|
||||||
"""
|
"""
|
||||||
dbuf = self.dbuf
|
if self.event[0] == 0:
|
||||||
event = self.event
|
|
||||||
|
|
||||||
# TODO: check the interrupt pin
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.i2c.readfrom_mem_into(21, 1, dbuf)
|
|
||||||
except OSError:
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Skip junk events
|
return self.event
|
||||||
if dbuf[0] == 0:
|
|
||||||
return None
|
|
||||||
|
|
||||||
x = ((dbuf[2] & 0xf) << 8) + dbuf[3]
|
def reset_touch_data(self):
|
||||||
y = ((dbuf[4] & 0xf) << 8) + dbuf[5]
|
"""Reset touch data.
|
||||||
swipe_start = dbuf[2] & 0x80
|
|
||||||
|
|
||||||
# Skip identical events... when the I2C interface comes alive
|
Reset touch data, call this function after processing an event.
|
||||||
# we can still get back stale events
|
"""
|
||||||
if dbuf[0] == event[0] and x == event[1] and y == event[2] \
|
self.event[0] = 0
|
||||||
and not swipe_start:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# This is a good event, lets save it
|
def wake(self):
|
||||||
event[0] = dbuf[0]
|
"""Wake up touch controller chip.
|
||||||
event[1] = x
|
|
||||||
event[2] = y
|
|
||||||
|
|
||||||
# Do not forward swipe start events
|
Just reset the chip in order to wake it up
|
||||||
if dbuf[2] & 0x80:
|
"""
|
||||||
event[0] = 0
|
self._reset()
|
||||||
return None
|
|
||||||
|
|
||||||
return event
|
def sleep(self):
|
||||||
|
"""Put touch controller chip on sleep mode to save power.
|
||||||
|
"""
|
||||||
|
# Before we can sent the sleep command we have to reset the
|
||||||
|
# panel to get the I2C hardware running again...
|
||||||
|
self._reset()
|
||||||
|
self.i2c.writeto_mem(21, 0xa5, b'\x03')
|
||||||
|
|
||||||
|
# Ensure get_event() cannot return anything
|
||||||
|
self.event[0] = 0
|
||||||
|
|
|
@ -232,6 +232,7 @@ class Manager():
|
||||||
self.switch(self.quick_ring[0])
|
self.switch(self.quick_ring[0])
|
||||||
self.app.sleep()
|
self.app.sleep()
|
||||||
watch.display.poweroff()
|
watch.display.poweroff()
|
||||||
|
watch.touch.sleep()
|
||||||
self._charging = watch.battery.charging()
|
self._charging = watch.battery.charging()
|
||||||
self.sleep_at = None
|
self.sleep_at = None
|
||||||
|
|
||||||
|
@ -241,9 +242,7 @@ class Manager():
|
||||||
watch.display.poweron()
|
watch.display.poweron()
|
||||||
self.app.wake()
|
self.app.wake()
|
||||||
watch.backlight.set(self._brightness)
|
watch.backlight.set(self._brightness)
|
||||||
|
watch.touch.wake()
|
||||||
# Discard any pending touch events
|
|
||||||
_ = watch.touch.get_event()
|
|
||||||
|
|
||||||
self.keep_awake()
|
self.keep_awake()
|
||||||
|
|
||||||
|
@ -277,6 +276,7 @@ class Manager():
|
||||||
self.navigate(event[0])
|
self.navigate(event[0])
|
||||||
elif event[0] == 5 and self.event_mask & EventMask.TOUCH:
|
elif event[0] == 5 and self.event_mask & EventMask.TOUCH:
|
||||||
self.app.touch(event)
|
self.app.touch(event)
|
||||||
|
watch.touch.reset_touch_data()
|
||||||
|
|
||||||
def _tick(self):
|
def _tick(self):
|
||||||
"""Handle the system tick.
|
"""Handle the system tick.
|
||||||
|
|
Loading…
Reference in a new issue