continued to break out keys and pins

This commit is contained in:
2022-01-06 22:18:08 +01:00
parent cb59e3145e
commit 2e41f548b9
2 changed files with 98 additions and 99 deletions

View File

@@ -1,100 +1,37 @@
import digitalio import digitalio
from enum import Enum
from micropython import const from micropython import const
from pin import Pin, PinEvent
class PinState: class KeyState(Enum):
PRESSED: int = const(0)
RELEASED: int = const(1)
class PinEvent:
NONE: int = const(0)
PRESSED: int = const(1)
RELEASED: int = const(2)
class KeyState:
"""Interpretations of hardware pin state""" """Interpretations of hardware pin state"""
PRESSED = const(0) __pressed = 0
"""Key is pressed""" """Key is pressed"""
UNPRESSED = const(1) __unpressed = const(1)
"""Key is not pressed""" """Key is not pressed"""
PRESSED_TOGGLED_ON = const(2) __pressed_toggled_on = const(2)
"""Key is pressed and is emulating a toggle key in ON state that is not released until the physical key is released, then pressed again""" """Key is pressed and is emulating a toggle key in ON state that is not released until the physical key is released, then pressed again"""
UNPRESSED_TOGGLED_ON = const(3) __unpressed_toggled_on = const(3)
"""Key is unpressed and is emulating a toggle key in ON state that is not released unit the physical key is pressed again""" """Key is unpressed and is emulating a toggle key in ON state that is not released unit the physical key is pressed again"""
PRESSED_TOGGLED_OFF = const(4) __pressed_toggled_off = const(4)
"""Key is pressed and is emulating a toggle key in OFF state""" """Key is pressed and is emulating a toggle key in OFF state"""
DEBOUNCE = const(5) __debounce = const(5)
"""Further state changes of any kind are ignored until key has been physically released released""" """Further state changes of any kind are ignored until key has been physically released released"""
class KeyEvent: class KeyEvent(Enum):
"""Interpretations of KeyStates as single events""" """Interpretations of KeyStates as single events"""
NONE: int = const(0) __no_event: int = const(0)
"""No new event has occurred""" """No new event has occurred"""
PRESSED = "" __pressed = const(1)
"""The key was pressed""" """The key was pressed"""
RELEASED: int = const(2) __released: int = const(2)
"""The key was released""" """The key was released"""
SOFT_RELEASE: int = const(3) __soft_released: int = const(3)
"""The key was released programatically, and not by an actual physical release of a button.""" """The key was released programatically, and not by an actual physical release of a button."""
class PinStates:
current: int
previous: int
def __init__(self, current: int, previous: int):
self.current = current
self.previous = previous
class Pin:
index: int
hw_pin: digitalio.DigitalInOut
previous_state: int
def __init__(self, index, hw_pin: digitalio.DigitalInOut):
self.index = index
self.hw_pin = hw_pin
self.previous_state = PinState.RELEASED
def _consume_next_state(self) -> PinStates:
states = PinStates(int(self.hw_pin.value), int(self.previous_state))
self.previous_state = states.current
return states
def read_event(self) -> int:
current, previous = self._consume_next_state()
if previous == PinState.RELEASED:
if current == PinState.RELEASED:
return PinEvent.NONE
if current == PinState.PRESSED:
return PinEvent.PRESSED
if previous == PinState.PRESSED:
if current == PinState.PRESSED:
return PinEvent.NONE
if current == PinState.RELEASED:
return PinEvent.RELEASED
raise NotImplementedError()
class Key:
index: int
previous_state: KeyState
def __init__(self):
pass
def set_index(self, index) -> None:
assert 0 <= index
self.index = index
def handle(self, keyboard):
assert self.index is not None
class KeyStates: class KeyStates:
current: int current: int
previous: int previous: int
@@ -104,6 +41,16 @@ class KeyStates:
self.previous = previous self.previous = previous
class Key:
previous_state: int
def __init__(self):
self.previous_state = KeyState.__unpressed
def handle(self, keyboard):
pass
class Keycode(Key): class Keycode(Key):
keycode: int keycode: int
@@ -114,44 +61,43 @@ class Keycode(Key):
def _consume_next_state(self, pin: Pin) -> KeyStates: def _consume_next_state(self, pin: Pin) -> KeyStates:
"""Interprets the changes to hardware pins as current and previous KeyState""" """Interprets the changes to hardware pins as current and previous KeyState"""
event = pin.read_event() event = pin.read_event()
if event == PinEvent.NONE: if event == PinEvent.no_event:
return KeyStates(self.previous_state, self.previous_state) return KeyStates(self.previous_state, self.previous_state)
if event == PinEvent.PRESSED: if event == PinEvent.pressed:
states = KeyStates(KeyState.PRESSED, int(self.previous_state)) states = KeyStates(KeyState.__pressed, int(self.previous_state))
self.previous_state = states.current self.previous_state = states.current
return states return states
if event == PinEvent.RELEASED: if event == PinEvent.released:
states = KeyStates(KeyState.UNPRESSED, int(self.previous_state)) states = KeyStates(KeyState.__unpressed, int(self.previous_state))
self.previous_state = states.current self.previous_state = states.current
return states return states
raise NotImplementedError() raise NotImplementedError()
def _read_event(self, pin) -> KeyEvent: def _read_event(self, pin) -> int:
"""Interprets the current and previous KeyState as a KeyEvent""" """Interprets the current and previous KeyState as a KeyEvent"""
states = self._consume_next_state(pin) states = self._consume_next_state(pin)
current, previous = states if states.previous == KeyState.__unpressed:
if previous == KeyState.UNPRESSED: if states.current == KeyState.__unpressed:
if current == KeyState.UNPRESSED: return KeyEvent.__no_event
return KeyEvent.NONE if states.current == KeyState.__pressed:
if current == KeyState.PRESSED: return KeyEvent.__pressed
return KeyEvent.PRESSED if states.previous == KeyState.__pressed:
if previous == KeyState.PRESSED: if states.current == KeyState.__pressed:
if current == KeyState.PRESSED: return KeyEvent.__no_event
return KeyEvent.NONE if states.current == KeyState.__unpressed:
if current == KeyState.UNPRESSED: return KeyEvent.__released
return KeyEvent.RELEASED
raise NotImplementedError() raise NotImplementedError()
def _react_to_event(self, event: KeyEvent, keyboard) -> None: def _react_to_event(self, event: int, keyboard) -> None:
if event == KeyEvent.NONE: if event == KeyEvent.__no_event:
return return
if event == KeyEvent.PRESSED: if event == KeyEvent.__pressed:
keyboard.add_keycode_to_report(self.keycode) keyboard.add_keycode_to_report(self.keycode)
if event == KeyEvent.RELEASED: if event == KeyEvent.__released:
keyboard.remove_keycode_from_report(self.keycode) keyboard.remove_keycode_from_report(self.keycode)
def handle(self, keyboard, pin): def handle(self, keyboard, pin):
super().handle() super().handle(keyboard)
event = self._read_event(pin) event = self._read_event(pin)
self._react_to_event(event, keyboard) self._react_to_event(event, keyboard)

53
pin.py Normal file
View File

@@ -0,0 +1,53 @@
import digitalio
from micropython import const
from adafruit_blinka import Enum
class PinState(Enum):
PRESSED: int = 0
RELEASED: int = 1
class PinEvent(Enum):
NO_EVENT: int = 0
PRESSED: int = 1
RELEASED: int = 2
class PinStates:
current: int
previous: int
def __init__(self, current: int, previous: int):
self.current = current
self.previous = previous
class Pin:
index: int
hw_pin: digitalio.DigitalInOut
previous_state: int
def __init__(self, index, hw_pin: digitalio.DigitalInOut):
self.index = index
self.hw_pin = hw_pin
self.previous_state = PinState.RELEASED
def _consume_next_state(self) -> PinStates:
states = PinStates(int(self.hw_pin.value), int(self.previous_state))
self.previous_state = states.current
return states
def read_event(self) -> int:
states = self._consume_next_state()
if states.previous == PinState.RELEASED:
if states.current == PinState.RELEASED:
return PinEvent.NO_EVENT
if states.current == PinState.PRESSED:
return PinEvent.PRESSED
if states.previous == PinState.PRESSED:
if states.current == PinState.PRESSED:
return PinEvent.NO_EVENT
if states.current == PinState.RELEASED:
return PinEvent.RELEASED
raise NotImplementedError()