diff --git a/kmk/handlers/stock.py b/kmk/handlers/stock.py index f98e4e4..ba301eb 100644 --- a/kmk/handlers/stock.py +++ b/kmk/handlers/stock.py @@ -1,4 +1,4 @@ -from kmk.kmktime import sleep_ms +from time import sleep def passthrough(key, keyboard, *args, **kwargs): @@ -95,7 +95,7 @@ def bkdl_released(key, keyboard, KC, *args, **kwargs): def sleep_pressed(key, keyboard, KC, *args, **kwargs): - sleep_ms(key.meta.ms) + sleep(key.meta.ms / 1000) return keyboard diff --git a/kmk/kmk_keyboard.py b/kmk/kmk_keyboard.py index 672dee1..7f806df 100644 --- a/kmk/kmk_keyboard.py +++ b/kmk/kmk_keyboard.py @@ -1,7 +1,8 @@ +from supervisor import ticks_ms + from kmk.consts import KMK_RELEASE, UnicodeMode from kmk.hid import BLEHID, USBHID, AbstractHID, HIDModes from kmk.keys import KC -from kmk.kmktime import ticks_ms from kmk.matrix import MatrixScanner, intify_coordinate from kmk.types import TapDanceKeyMeta diff --git a/kmk/kmktime.py b/kmk/kmktime.py index 18b62a8..82ed7cd 100644 --- a/kmk/kmktime.py +++ b/kmk/kmktime.py @@ -1,23 +1,15 @@ -import time +from micropython import const + +_TICKS_PERIOD = const(1 << 29) +_TICKS_MAX = const(_TICKS_PERIOD - 1) +_TICKS_HALFPERIOD = const(_TICKS_PERIOD // 2) -def sleep_ms(ms): - return time.sleep(ms / 1000) +def ticks_diff(new, start): + diff = (new - start) & _TICKS_MAX + diff = ((diff + _TICKS_HALFPERIOD) & _TICKS_MAX) - _TICKS_HALFPERIOD + return diff -def ticks_ms(): - '''Has .25s granularity, but is cheap''' - return time.monotonic() * 1000 - - -def ticks_diff(new, old): - return new - old - - -def accurate_ticks(): - '''Is more expensive, but good for time critical things''' - return time.monotonic_ns() - - -def accurate_ticks_diff(new, old, ms): - return bool(new - old < ms * 1000000) +def check_deadline(new, start, ms): + return ticks_diff(new, start) < ms diff --git a/kmk/modules/encoder.py b/kmk/modules/encoder.py index 86c841f..a7aca5c 100644 --- a/kmk/modules/encoder.py +++ b/kmk/modules/encoder.py @@ -1,6 +1,6 @@ import digitalio +from supervisor import ticks_ms -from kmk.kmktime import ticks_ms from kmk.modules import Module diff --git a/kmk/modules/layers.py b/kmk/modules/layers.py index 416bc27..1d7a281 100644 --- a/kmk/modules/layers.py +++ b/kmk/modules/layers.py @@ -1,9 +1,10 @@ '''One layer isn't enough. Adds keys to get to more of them''' from micropython import const +from supervisor import ticks_ms from kmk.key_validators import layer_key_validator from kmk.keys import make_argumented_key -from kmk.kmktime import accurate_ticks, accurate_ticks_diff +from kmk.kmktime import check_deadline from kmk.modules import Module @@ -131,15 +132,13 @@ class Layers(Module): def _lt_pressed(self, key, keyboard, *args, **kwargs): # Sets the timer start and acts like MO otherwise - self.start_time[LayerType.LT] = accurate_ticks() + self.start_time[LayerType.LT] = ticks_ms() self._mo_pressed(key, keyboard, *args, **kwargs) def _lt_released(self, key, keyboard, *args, **kwargs): # On keyup, check timer, and press key if needed. if self.start_time[LayerType.LT] and ( - accurate_ticks_diff( - accurate_ticks(), self.start_time[LayerType.LT], keyboard.tap_time - ) + check_deadline(ticks_ms(), self.start_time[LayerType.LT], keyboard.tap_time) ): keyboard.hid_pending = True keyboard.tap_key(key.meta.kc) @@ -171,10 +170,10 @@ class Layers(Module): ''' if self.start_time[LayerType.TT] is None: # Sets the timer start and acts like MO otherwise - self.start_time[LayerType.TT] = accurate_ticks() + self.start_time[LayerType.TT] = ticks_ms() self._mo_pressed(key, keyboard, *args, **kwargs) - elif accurate_ticks_diff( - accurate_ticks(), self.start_time[LayerType.TT], keyboard.tap_time + elif check_deadline( + ticks_ms(), self.start_time[LayerType.TT], keyboard.tap_time ): self.start_time[LayerType.TT] = None self._tg_pressed(key, keyboard, *args, **kwargs) @@ -182,8 +181,8 @@ class Layers(Module): return def _tt_released(self, key, keyboard, *args, **kwargs): - if self.start_time[LayerType.TT] is None or not accurate_ticks_diff( - accurate_ticks(), self.start_time[LayerType.TT], keyboard.tap_time + if self.start_time[LayerType.TT] is None or not check_deadline( + ticks_ms(), self.start_time[LayerType.TT], keyboard.tap_time ): # On first press, works like MO. On second press, does nothing unless let up within # time window, then acts like TG. diff --git a/kmk/modules/modtap.py b/kmk/modules/modtap.py index 5402899..76e9755 100644 --- a/kmk/modules/modtap.py +++ b/kmk/modules/modtap.py @@ -1,6 +1,8 @@ +from supervisor import ticks_ms + from kmk.key_validators import mod_tap_validator from kmk.keys import make_argumented_key -from kmk.kmktime import accurate_ticks, accurate_ticks_diff +from kmk.kmktime import check_deadline from kmk.modules import Module @@ -39,16 +41,14 @@ class ModTap(Module): '''Sets the timer start and acts like a modifier otherwise''' keyboard.keys_pressed.add(key.meta.mods) - self._mod_tap_timer = accurate_ticks() + self._mod_tap_timer = ticks_ms() return keyboard def mt_released(self, key, keyboard, *args, **kwargs): '''On keyup, check timer, and press key if needed.''' keyboard.keys_pressed.discard(key.meta.mods) if self._mod_tap_timer and ( - accurate_ticks_diff( - accurate_ticks(), self._mod_tap_timer, keyboard.tap_time - ) + check_deadline(ticks_ms(), self._mod_tap_timer, keyboard.tap_time) ): keyboard.hid_pending = True keyboard.tap_key(key.meta.kc) diff --git a/kmk/modules/power.py b/kmk/modules/power.py index b0a09d6..aa72eb1 100644 --- a/kmk/modules/power.py +++ b/kmk/modules/power.py @@ -1,9 +1,12 @@ import board import digitalio +from supervisor import ticks_ms + +from time import sleep from kmk.handlers.stock import passthrough as handler_passthrough from kmk.keys import make_key -from kmk.kmktime import sleep_ms, ticks_diff, ticks_ms +from kmk.kmktime import check_deadline from kmk.modules import Module @@ -100,10 +103,10 @@ class Power(Module): ''' Sleeps longer and longer to save power the more time in between updates. ''' - if ticks_diff(ticks_ms(), self._powersave_start) <= 60000: - sleep_ms(8) - elif ticks_diff(ticks_ms(), self._powersave_start) >= 240000: - sleep_ms(180) + if check_deadline(ticks_ms(), self._powersave_start) <= 60000: + sleep(8 / 1000) + elif check_deadline(ticks_ms(), self._powersave_start) >= 240000: + sleep(180 / 1000) return def psave_time_reset(self): @@ -120,7 +123,7 @@ class Power(Module): return def usb_rescan_timer(self): - return bool(ticks_diff(ticks_ms(), self._usb_last_scan) > 5000) + return bool(check_deadline(ticks_ms(), self._usb_last_scan) > 5000) def usb_time_reset(self): self._usb_last_scan = ticks_ms() diff --git a/kmk/modules/split.py b/kmk/modules/split.py index 0de7e17..c5dfd1c 100644 --- a/kmk/modules/split.py +++ b/kmk/modules/split.py @@ -1,10 +1,11 @@ '''Enables splitting keyboards wirelessly or wired''' import busio from micropython import const +from supervisor import ticks_ms from storage import getmount -from kmk.kmktime import ticks_diff, ticks_ms +from kmk.kmktime import check_deadline from kmk.matrix import intify_coordinate from kmk.modules import Module @@ -241,7 +242,7 @@ class Split(Module): def ble_rescan_timer(self): '''If true, the rescan timer is up''' - return bool(ticks_diff(ticks_ms(), self._ble_last_scan) > 5000) + return bool(check_deadline(ticks_ms(), self._ble_last_scan) > 5000) def ble_time_reset(self): '''Resets the rescan timer'''