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
from enum import Enum
from micropython import const
from pin import Pin, PinEvent
class PinState:
PRESSED: int = const(0)
RELEASED: int = const(1)
class PinEvent:
NONE: int = const(0)
PRESSED: int = const(1)
RELEASED: int = const(2)
class KeyState:
class KeyState(Enum):
"""Interpretations of hardware pin state"""
PRESSED = const(0)
__pressed = 0
"""Key is pressed"""
UNPRESSED = const(1)
__unpressed = const(1)
"""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"""
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"""
PRESSED_TOGGLED_OFF = const(4)
__pressed_toggled_off = const(4)
"""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"""
class KeyEvent:
class KeyEvent(Enum):
"""Interpretations of KeyStates as single events"""
NONE: int = const(0)
__no_event: int = const(0)
"""No new event has occurred"""
PRESSED = ""
__pressed = const(1)
"""The key was pressed"""
RELEASED: int = const(2)
__released: int = const(2)
"""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."""
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:
current: int
previous: int
@@ -104,6 +41,16 @@ class KeyStates:
self.previous = previous
class Key:
previous_state: int
def __init__(self):
self.previous_state = KeyState.__unpressed
def handle(self, keyboard):
pass
class Keycode(Key):
keycode: int
@@ -114,44 +61,43 @@ class Keycode(Key):
def _consume_next_state(self, pin: Pin) -> KeyStates:
"""Interprets the changes to hardware pins as current and previous KeyState"""
event = pin.read_event()
if event == PinEvent.NONE:
if event == PinEvent.no_event:
return KeyStates(self.previous_state, self.previous_state)
if event == PinEvent.PRESSED:
states = KeyStates(KeyState.PRESSED, int(self.previous_state))
if event == PinEvent.pressed:
states = KeyStates(KeyState.__pressed, int(self.previous_state))
self.previous_state = states.current
return states
if event == PinEvent.RELEASED:
states = KeyStates(KeyState.UNPRESSED, int(self.previous_state))
if event == PinEvent.released:
states = KeyStates(KeyState.__unpressed, int(self.previous_state))
self.previous_state = states.current
return states
raise NotImplementedError()
def _read_event(self, pin) -> KeyEvent:
def _read_event(self, pin) -> int:
"""Interprets the current and previous KeyState as a KeyEvent"""
states = self._consume_next_state(pin)
current, previous = states
if previous == KeyState.UNPRESSED:
if current == KeyState.UNPRESSED:
return KeyEvent.NONE
if current == KeyState.PRESSED:
return KeyEvent.PRESSED
if previous == KeyState.PRESSED:
if current == KeyState.PRESSED:
return KeyEvent.NONE
if current == KeyState.UNPRESSED:
return KeyEvent.RELEASED
if states.previous == KeyState.__unpressed:
if states.current == KeyState.__unpressed:
return KeyEvent.__no_event
if states.current == KeyState.__pressed:
return KeyEvent.__pressed
if states.previous == KeyState.__pressed:
if states.current == KeyState.__pressed:
return KeyEvent.__no_event
if states.current == KeyState.__unpressed:
return KeyEvent.__released
raise NotImplementedError()
def _react_to_event(self, event: KeyEvent, keyboard) -> None:
if event == KeyEvent.NONE:
def _react_to_event(self, event: int, keyboard) -> None:
if event == KeyEvent.__no_event:
return
if event == KeyEvent.PRESSED:
if event == KeyEvent.__pressed:
keyboard.add_keycode_to_report(self.keycode)
if event == KeyEvent.RELEASED:
if event == KeyEvent.__released:
keyboard.remove_keycode_from_report(self.keycode)
def handle(self, keyboard, pin):
super().handle()
super().handle(keyboard)
event = self._read_event(pin)
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()