diff --git a/wasp/boards/pinetime/manifest.py b/wasp/boards/pinetime/manifest.py index 9243d77..cb2d788 100644 --- a/wasp/boards/pinetime/manifest.py +++ b/wasp/boards/pinetime/manifest.py @@ -22,6 +22,7 @@ freeze('../..', manifest_240x240.manifest + 'gadgetbridge.py', 'ppg.py', 'shell.py', + 'motion.py', 'wasp.py', ), opt=3 diff --git a/wasp/boards/pinetime/watch.py.in b/wasp/boards/pinetime/watch.py.in index 91c59c3..8bd4a85 100644 --- a/wasp/boards/pinetime/watch.py.in +++ b/wasp/boards/pinetime/watch.py.in @@ -90,7 +90,7 @@ try: Signal(Pin('CHARGING', Pin.IN), invert=True), Signal(Pin('USB_PWR', Pin.IN), invert=True)) i2c = I2C(1, scl='I2C_SCL', sda='I2C_SDA') - accel = BMA421(i2c) + accel = BMA421(i2c, Pin('ACCEL_INT', Pin.IN)) hrs = HRS3300(i2c) touch = CST816S(i2c, Pin('TP_INT', Pin.IN), Pin('TP_RST', Pin.OUT, value=0), diff --git a/wasp/drivers/bma421.py b/wasp/drivers/bma421.py index 4657bc8..fa40fcc 100644 --- a/wasp/drivers/bma421.py +++ b/wasp/drivers/bma421.py @@ -7,6 +7,8 @@ import bma42x import time +import motion +from machine import Pin # Sensor orientation definition. # The 6 most significant bits define the indexes of the x, y, and z values @@ -28,13 +30,18 @@ class BMA421: .. automethod:: __init__ """ - def __init__(self, i2c, orientation=_DEFAULT_ORIENTATION): + def __init__(self, i2c, intr=None, orientation=_DEFAULT_ORIENTATION): """Configure the driver. :param machine.I2C i2c: I2C bus used to access the sensor. """ self._dev = bma42x.BMA42X(i2c) self._orientation = orientation + self._gesture_int = intr + self._gesture_event = motion.AccelGestureEvent.NONE + + if self._gesture_int != None: + self._gesture_int.irq(trigger=Pin.IRQ_FALLING, handler=self.handle_interrupt) def reset(self): """Reset and reinitialize the sensor.""" @@ -60,6 +67,29 @@ class BMA421: # Software readout is remapped manually in accel_xyz(). dev.set_remap_axes(self._orientation) + # Enable gesture interrupts + dev.set_int_pin_config(int_line=bma42x.INTR1_MAP, + edge_ctrl=bma42x.LEVEL_TRIGGER, + lvl=bma42x.ACTIVE_LOW, + od=bma42x.PUSH_PULL, + output_en=True, input_en=False) + dev.feature_enable(bma42x.WRIST_WEAR, True) + #dev.feature_enable(bma42x.DOUBLE_TAP, True) + dev.map_interrupt(bma42x.INTR1_MAP, bma42x.WRIST_WEAR_INT, True) + + def handle_interrupt(self, pin_obj): + """Interrupt handler for gesture events originating from the sensor""" + self._dev.read_int_status() # TODO: Actually read status from the register + self._gesture_event = motion.AccelGestureEvent.WRIST_TILT + + def get_gesture_event(self): + """Receive the latest gesture event if any""" + return self._gesture_event + + def reset_gesture_event(self): + """Call after processing the gesture event""" + self._gesture_event = motion.AccelGestureEvent.NONE + @property def steps(self): """Report the number of steps counted.""" diff --git a/wasp/modules/bma42x-upy b/wasp/modules/bma42x-upy index 85622fc..905652f 160000 --- a/wasp/modules/bma42x-upy +++ b/wasp/modules/bma42x-upy @@ -1 +1 @@ -Subproject commit 85622fc37610ebb3821f0b315c37c69a4bffa72d +Subproject commit 905652f9fd6541283591cf6e085c31f9aa63bf40 diff --git a/wasp/motion.py b/wasp/motion.py new file mode 100644 index 0000000..f8cb0ee --- /dev/null +++ b/wasp/motion.py @@ -0,0 +1,7 @@ +from micropython import const + +class AccelGestureEvent(): + """Enumerated ids for accelerometer-based gesture events + """ + NONE = const(0) + WRIST_TILT = const(1) diff --git a/wasp/wasp.py b/wasp/wasp.py index b81ad22..2ebf1e6 100644 --- a/wasp/wasp.py +++ b/wasp/wasp.py @@ -20,6 +20,7 @@ import micropython import sys import watch import widgets +import motion from apps.launcher import LauncherApp from apps.pager import PagerApp, CrashApp, NotificationApp @@ -498,11 +499,14 @@ class Manager(): self.wake() if self.raise_wake: - now = rtc.get_uptime_ms() - if now >= self.accel_poll_expiry: - self.accel_poll_expiry = (now + self.accel_poll_ms) - if self._do_raise_wake(): - self.wake() + if watch.accel.get_gesture_event() == motion.AccelGestureEvent.WRIST_TILT: + watch.accel.reset_gesture_event() + self.wake() + #now = rtc.get_uptime_ms() + #if now >= self.accel_poll_expiry: + # self.accel_poll_expiry = (now + self.accel_poll_ms) + # if self._do_raise_wake(): + # self.wake() def _do_raise_wake(self):