From 7ddfaae2a38820c6148cd0156b5d436d6e803a32 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 4 Dec 2024 15:35:52 +0100 Subject: [PATCH] lib/opta: Add support for running on CPython. Signed-off-by: iabdalkader --- lib/opta/example.py | 2 ++ lib/opta/opta.py | 85 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 72 insertions(+), 15 deletions(-) diff --git a/lib/opta/example.py b/lib/opta/example.py index e4bfae5..838e825 100644 --- a/lib/opta/example.py +++ b/lib/opta/example.py @@ -14,6 +14,8 @@ level=logging.INFO # Switch to DEBUG to see raw commands ) + # On CPython, something like the following should be used: + # opta = opta.Opta(bus_id=3, pin_id=("/dev/gpiochip1", 5)) opta = opta.Opta(bus_id=3) # enum_devices initializes the bus, resets all expansions, and returns a list of diff --git a/lib/opta/opta.py b/lib/opta/opta.py index 29dc8ab..f4ed1f8 100644 --- a/lib/opta/opta.py +++ b/lib/opta/opta.py @@ -5,10 +5,24 @@ # file, You can obtain one at https://mozilla.org/MPL/2.0/. import struct import logging -from time import sleep_ms -from machine import I2C -from machine import Pin -from micropython import const +from time import sleep +import sys + +_is_micropython = sys.implementation.name == "micropython" + +if _is_micropython: + from machine import Pin + from machine import I2C + from micropython import const +else: + import gpiod + from gpiod.line import Direction + from gpiod.line import Value + from smbus2 import SMBus, i2c_msg + + def const(x): + return x + _MIN_ADDRESS = const(0x0B) _TMP_ADDRESS = const(0x0A) @@ -70,6 +84,47 @@ _CHANNEL_TYPES = const(("adc", "dac", "rtd", "pwm", "hiz", "din")) +class IOPin: + def __init__(self, pin_id): + if _is_micropython: + self.pin = Pin(pin_id, Pin.IN, Pin.PULL_UP) + else: + self.pin = gpiod.request_lines( + pin_id[0], + consumer="Opta", + config={pin_id[1]: gpiod.LineSettings(direction=Direction.INPUT)}, + ) + + def read(self): + if _is_micropython: + return self.pin.value() + else: + return self.pin.get_values()[0] == Value.ACTIVE + + +class I2CBus: + def __init__(self, bus_id, freq): + if _is_micropython: + self.bus = I2C(bus_id, freq=freq) + else: + self.bus = SMBus(bus_id) + + def read(self, addr, buf): + if _is_micropython: + self.bus.readfrom_into(addr, buf) + else: + msg = i2c_msg.read(addr, len(buf)) + self.bus.i2c_rdwr(msg) + buf[:] = msg.buf[0:len(buf)] + + def write(self, addr, buf): + if _is_micropython: + self.bus.writeto(addr, buf) + else: + msg = i2c_msg.write(addr, buf) + self.bus.i2c_rdwr(msg) + + class Expansion: def __init__(self, opta, type, addr, name): self.opta = opta @@ -274,7 +329,7 @@ def get_bool(k, d): if "default_value" in kwargs: value = kwargs["default_value"] self.opta._cmd(self.addr, _CMD_SET_ANALOG_DAC_DEF, "