modify: DI 输入监听
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""从设备树复算 gpio-in-N 对应的全局 GPIO 号。"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from .config import DEVICETREE_BASE
|
||||
|
||||
|
||||
def _read_be32(path: Path, offset: int = 0):
|
||||
try:
|
||||
data = path.read_bytes()
|
||||
except OSError:
|
||||
return None
|
||||
if len(data) < offset + 4:
|
||||
return None
|
||||
return int.from_bytes(data[offset:offset + 4], "big")
|
||||
|
||||
|
||||
def derive_gpio(n: int, base_dir: str = DEVICETREE_BASE):
|
||||
"""从设备树复算 IN<n> 的全局 GPIO 号。
|
||||
|
||||
返回 (gpio_num, label, pin) 或 None。
|
||||
"""
|
||||
base = Path(base_dir)
|
||||
f = base / f"gpio-in-{n}" / "control-gpios"
|
||||
if not f.exists():
|
||||
return None
|
||||
|
||||
try:
|
||||
data = f.read_bytes()
|
||||
except OSError:
|
||||
return None
|
||||
if len(data) < 8:
|
||||
return None
|
||||
|
||||
ph = int.from_bytes(data[0:4], "big")
|
||||
pin = int.from_bytes(data[4:8], "big")
|
||||
|
||||
# phandle -> gpio-controller 节点
|
||||
ctrl = None
|
||||
for c in base.glob("gpio@*/gpio-controller@*"):
|
||||
cph = _read_be32(c / "phandle")
|
||||
if cph == ph:
|
||||
ctrl = c
|
||||
break
|
||||
if ctrl is None:
|
||||
return None
|
||||
|
||||
bank = ctrl.parent.name
|
||||
if bank.startswith("gpio@"):
|
||||
bank = bank[len("gpio@"):]
|
||||
label = f"{bank}.gpio"
|
||||
|
||||
# label -> gpiochip base
|
||||
gpio_class = Path("/sys/class/gpio")
|
||||
if not gpio_class.exists():
|
||||
return None
|
||||
for g in gpio_class.glob("gpiochip*"):
|
||||
try:
|
||||
if (g / "label").read_text().strip() == label:
|
||||
chip_base = int((g / "base").read_text().strip())
|
||||
return chip_base + pin, label, pin
|
||||
except (OSError, ValueError):
|
||||
continue
|
||||
return None
|
||||
Reference in New Issue
Block a user