"""Dummy pyb.Pin class"""
from typing import Optional, Callable, Dict
import time
from ._pin_names import PIN_ALIASES
[docs]class Pin:
"""Hardware pin class"""
IN = 0
OUT = 1
OUT_OD = 17
OUT_PP = 1
ALT = 2
AF_PP = 2
ANALOG = 3
OPEN_DRAIN = 17
ALT_OPEN_DRAIN = 18
PULL_NONE = 0
PULL_UP = 1
PULL_DOWN = 2
IRQ_FALLING = 1
IRQ_RISING = 2
# Track pin values, independent of object instances
_values: Dict[str, int] = {}
def __init__(self, pin_id: str, mode: int = IN,
pull: int = PULL_NONE,
af: int = -1):
"""Constructor"""
# Undo alias if it exists
self.pin_id = PIN_ALIASES.get(pin_id, pin_id)
if self.pin_id not in self._values:
self._values[self.pin_id] = 0
self._mode = self._pull = self._af = None
self._callback: Optional[Callable] = None
self._trigger_rising = True # Type of interrupt trigger
self._trigger_falling = True
self.init(mode, pull, af)
[docs] def init(self, mode: int = IN, pull: int = PULL_NONE,
af: int = -1):
"""Initialize Pin"""
self._mode = mode
self._pull = pull
self._af = af
[docs] def value(self, value: int = None) -> Optional[int]:
"""Set or get pin value"""
if value is None:
return self._values[self.pin_id]
self._values[self.pin_id] = value
[docs] def name(self) -> str:
"""Get internal pin name"""
return self.pin_id
[docs] def on(self):
"""Set pin value to 1"""
self._values[self.pin_id] = 1
[docs] def off(self):
"""Set pin value to 0"""
self._values[self.pin_id] = 0
[docs] def mode(self, mode=None) -> Optional[int]:
"""Get or set pin _mode"""
if mode is None:
return self._mode
self._mode = mode
[docs] def pull(self, pull=None) -> Optional[int]:
"""Get or set pin _mode"""
if pull is None:
return self._pull
self._pull = pull
[docs] def irq(self, handler: Optional[Callable] = None, trigger: int = None,
priority: int = 1, wake=None, hard=False):
"""Create pin interrupt
`trigger` can be an OR combination of IRQ flags
"""
self._callback = handler
if trigger is None:
self._trigger_rising = self._trigger_falling = False # pragma: no cover
else:
self._trigger_rising = (trigger & self.IRQ_RISING != 0)
self._trigger_falling = (trigger & self.IRQ_FALLING != 0)
[docs] def test_set_value(self, value: int):
"""Set a pin value
Write a pin value, even when it is in input _mode.
Also trigger IRQ callback if one was set.
"""
old_value = self._values[self.pin_id]
value = int(value)
# Trigger interrupts
if self._callback is not None:
if value < old_value and self._trigger_falling:
self._callback()
if value > old_value and self._trigger_rising:
self._callback()
self._values[self.pin_id] = value
[docs] def test_push(self, value: int = 1):
"""Set a temporary pin value and return it again"""
old_value = self.value()
# Change value (triggering callbacks)
self.test_set_value(value)
time.sleep(0.10) # Give it a little time
# Restore state
self.test_set_value(old_value)