1
0
Fork 0

wasp: Switch to scheduling from interrupt

This has two useful properties. Firstly it means the watch will be
maintained in the background, allowing the REPL to be used for
notifications and other updates. Secondly it will save a little bit
of power by reducing the work needed to handle spurious wake ups.

Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk>
pull/45/head
Daniel Thompson 2020-06-30 23:04:01 +01:00
parent 11be7ca328
commit ae5743529f
6 changed files with 57 additions and 8 deletions

@ -1 +1 @@
Subproject commit d11200432c211fc9e413c74eace1308c1c5e9ff1
Subproject commit df61f43d562ec33388bdb27b07fb6f0bbdbe8b8b

View File

@ -44,7 +44,8 @@ def unsync(c):
process too early then the sendline will not have completed.
"""
c.sendline('wasp.system.run()')
c.expect('Watch is running, use Ctrl-C to stop')
c.expect(['Watch is running, use Ctrl-C to stop',
'Watch already running in the background'])
c.send('\x18')
def paste(c, f, verbose=False, chunk=None):

View File

@ -1,10 +1,16 @@
# SPDX-License-Identifier: LGPL-3.0-or-later
# Copyright (C) 2020 Daniel Thompson
def nop():
pass
schedule = nop
def _callback(obj):
schedule()
# Start measuring time (and feeding the watchdog) before *anything* else
from machine import RTCounter
from drivers.nrf_rtc import RTC
rtc = RTC(RTCounter(1, mode=RTCounter.PERIODIC))
rtc = RTC(RTCounter(1, mode=RTCounter.PERIODIC, period=1, callback=_callback))
rtc.counter.start()
import os
@ -83,7 +89,9 @@ try:
i2c = I2C(1, scl='I2C_SCL', sda='I2C_SDA')
accel = BMA421(i2c)
hrs = HRS3300(i2c)
touch = CST816S(i2c, Pin('TP_INT', Pin.IN), Pin('TP_RST', Pin.OUT, value=0))
touch = CST816S(i2c,
Pin('TP_INT', Pin.IN), Pin('TP_RST', Pin.OUT, value=0),
_callback)
vibrator = Vibrator(Pin('MOTOR', Pin.OUT, value=0), active_low=True)
# Release flash from deep power-down

View File

@ -15,7 +15,7 @@ class CST816S:
.. automethod:: __init__
"""
def __init__(self, bus, intr, rst):
def __init__(self, bus, intr, rst, schedule=None):
"""Specify the bus used by the touch controller.
:param machine.I2C bus: I2C bus for the CST816S.
@ -23,6 +23,7 @@ class CST816S:
self.i2c = bus
self.tp_int = intr
self.tp_rst = rst
self.schedule = schedule
self.dbuf = bytearray(6)
self.event = array.array('H', (0, 0, 0))
@ -53,6 +54,9 @@ class CST816S:
event[1] = ((dbuf[2] & 0xf) << 8) + dbuf[3] # x coord
event[2] = ((dbuf[4] & 0xf) << 8) + dbuf[5] # y coord
if self.schedule:
self.schedule(self)
def get_event(self):
"""Receive a touch event.

View File

@ -2,4 +2,4 @@
# Copyright (C) 2020 Daniel Thompson
import wasp
wasp.system.run()
wasp.system.schedule()

View File

@ -17,6 +17,7 @@
import gc
import machine
import micropython
import watch
import widgets
@ -106,6 +107,8 @@ class Manager():
self._brightness = 2
self._button = PinHandler(watch.button)
self._charging = True
self._scheduled = False
self._scheduling = False
# TODO: Eventually these should move to main.py
self.register(ClockApp(), True)
@ -242,7 +245,8 @@ class Manager():
"""Return to a running state.
"""
watch.display.poweron()
self.app.wake()
if 'wake' in dir(self.app):
self.app.wake()
watch.backlight.set(self._brightness)
watch.touch.wake()
@ -326,6 +330,10 @@ class Manager():
normal execution context meaning any exceptions and other problems
can be observed interactively via the console.
"""
if self._scheduling:
print('Watch already running in the background')
return
if not self.app:
self.switch(self.quick_ring[0])
@ -353,8 +361,36 @@ class Manager():
# Currently there is no code to control how fast the system
# ticks. In other words this code will break if we improve the
# power management... we are currently relying on no being able
# power management... we are currently relying on not being able
# to stay in the low-power state for very long.
machine.deepsleep()
def _work(self):
self._scheduled = False
try:
self._tick()
except Exception as e:
# Only print the exception if the watch provides a way to do so!
if 'print_exception' in dir(watch):
watch.print_exception(e)
self.switch(CrashApp(e))
def _schedule(self):
"""Asynchronously schedule a system management cycle."""
if not self._scheduled:
self._scheduled = True
micropython.schedule(Manager._work, self)
def schedule(self, enable=True):
"""Run the system manager synchronously."""
if not self.app:
self.switch(self.quick_ring[0])
if enable:
watch.schedule = self._schedule
else:
watch.schedule = watch.nop
self._scheduling = enable
system = Manager()