From 39ab4fe23cf17e33da6ec3fecbdc9369e14d82fd Mon Sep 17 00:00:00 2001 From: Perry Melange Date: Mon, 27 Jan 2025 10:26:07 +0100 Subject: [PATCH 1/3] SysfsGpio: add invert attribute (active-low) to the SysfsGPIO classes The resources SysfsGPIO, NetworkSysfsGPIO and MatchedSysfsGPIO, the GPIOSysFSExport, the driver GpioDigitalOutputDriver and the GpioDigitalOutput agent have been modified to have an additional optional invert (active-low) attribute (default False) which can be used to invert the logical value used on the gpio line. Signed-off-by: Perry Melange --- labgrid/driver/gpiodriver.py | 4 ++-- labgrid/remote/exporter.py | 3 +++ labgrid/resource/base.py | 4 +++- labgrid/resource/remote.py | 1 + labgrid/resource/udev.py | 4 +++- labgrid/util/agents/sysfsgpio.py | 21 ++++++++++++--------- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/labgrid/driver/gpiodriver.py b/labgrid/driver/gpiodriver.py index 2de90618e..a98601ea2 100644 --- a/labgrid/driver/gpiodriver.py +++ b/labgrid/driver/gpiodriver.py @@ -37,9 +37,9 @@ def on_deactivate(self): @Driver.check_active @step(args=['status']) def set(self, status): - self.proxy.set(self.gpio.index, status) + self.proxy.set(self.gpio.index, self.gpio.invert, status) @Driver.check_active @step(result=True) def get(self): - return self.proxy.get(self.gpio.index) + return self.proxy.get(self.gpio.index, self.gpio.invert) diff --git a/labgrid/remote/exporter.py b/labgrid/remote/exporter.py index d3b406503..28779bf9b 100755 --- a/labgrid/remote/exporter.py +++ b/labgrid/remote/exporter.py @@ -642,16 +642,19 @@ def _get_params(self): return { "host": self.host, "index": self.local.index, + "invert": self.local.invert, } def _get_start_params(self): return { "index": self.local.index, + "invert": self.local.invert, } def _start(self, start_params): """Start a GPIO export to userspace""" index = start_params["index"] + invert = start_params["invert"] # pylint: disable=unused-variable if self.export_path.exists(): self.system_exported = True diff --git a/labgrid/resource/base.py b/labgrid/resource/base.py index d8cdb984c..0df31a8f1 100644 --- a/labgrid/resource/base.py +++ b/labgrid/resource/base.py @@ -42,5 +42,7 @@ class SysfsGPIO(Resource): """The basic SysfsGPIO contains an index Args: - index (int): index of target gpio line.""" + index (int): index of target gpio line. + invert (bool) : optional, whether the logic level is inverted (active-low)""" index = attr.ib(default=None, validator=attr.validators.instance_of(int)) + invert = attr.ib(default=False, validator=attr.validators.instance_of(bool)) diff --git a/labgrid/resource/remote.py b/labgrid/resource/remote.py index a29e58ee8..6ab0f51d4 100644 --- a/labgrid/resource/remote.py +++ b/labgrid/resource/remote.py @@ -340,6 +340,7 @@ class NetworkSysfsGPIO(NetworkResource, ManagedResource): """The NetworkSysfsGPIO describes a remotely accessible gpio line""" index = attr.ib(validator=attr.validators.optional(attr.validators.instance_of(int))) + invert = attr.ib(default=False, validator=attr.validators.instance_of(bool)) def __attrs_post_init__(self): self.timeout = 10.0 super().__attrs_post_init__() diff --git a/labgrid/resource/udev.py b/labgrid/resource/udev.py index eb553cfb2..fd66d892d 100644 --- a/labgrid/resource/udev.py +++ b/labgrid/resource/udev.py @@ -758,8 +758,10 @@ class MatchedSysfsGPIO(USBResource): """The MatchedSysfsGPIO described a SysfsGPIO matched by Udev Args: - pin (int): gpio pin number within the matched gpiochip.""" + pin (int): gpio pin number within the matched gpiochip. + invert (bool): optional, whether the logic level is inverted (active-low)""" pin = attr.ib(default=None, validator=attr.validators.instance_of(int)) + invert = attr.ib(default=False, validator=attr.validators.instance_of(bool)) index = None def __attrs_post_init__(self): diff --git a/labgrid/util/agents/sysfsgpio.py b/labgrid/util/agents/sysfsgpio.py index 362eab5ce..dfea4203e 100644 --- a/labgrid/util/agents/sysfsgpio.py +++ b/labgrid/util/agents/sysfsgpio.py @@ -2,6 +2,7 @@ This module implements switching GPIOs via sysfs GPIO kernel interface. Takes an integer property 'index' which refers to the already exported GPIO device. +Takes a boolean property 'invert' which inverts logical values if set to True (active-low) """ import logging @@ -23,7 +24,7 @@ def _assert_gpio_line_is_exported(index): if not os.path.exists(gpio_sysfs_path): raise ValueError("Device not found") - def __init__(self, index): + def __init__(self, index, invert): self._logger = logging.getLogger("Device: ") GpioDigitalOutput._assert_gpio_line_is_exported(index) gpio_sysfs_path = os.path.join(GpioDigitalOutput._gpio_sysfs_path_prefix, @@ -40,6 +41,10 @@ def __init__(self, index): gpio_sysfs_value_path = os.path.join(gpio_sysfs_path, 'value') self.gpio_sysfs_value_fd = os.open(gpio_sysfs_value_path, flags=(os.O_RDWR | os.O_SYNC)) + gpio_sysfs_active_low_path = os.path.join(gpio_sysfs_path, 'active_low') + with open(gpio_sysfs_active_low_path, 'w') as active_low_fd: + active_low_fd.write(str(int(invert))) + def __del__(self): os.close(self.gpio_sysfs_value_fd) self.gpio_sysfs_value_fd = None @@ -66,24 +71,22 @@ def set(self, status): os.write(self.gpio_sysfs_value_fd, binary_value) - _gpios = {} -def _get_gpio_line(index): +def _get_gpio_line(index, invert): if index not in _gpios: - _gpios[index] = GpioDigitalOutput(index=index) + _gpios[index] = GpioDigitalOutput(index=index, invert=invert) return _gpios[index] -def handle_set(index, status): - gpio_line = _get_gpio_line(index) +def handle_set(index, invert, status): + gpio_line = _get_gpio_line(index, invert) gpio_line.set(status) -def handle_get(index): - gpio_line = _get_gpio_line(index) +def handle_get(index, invert): + gpio_line = _get_gpio_line(index, invert) return gpio_line.get() - methods = { 'set': handle_set, 'get': handle_get, From 7c210f632cb3e8a191bd81a49a2b85208ef9fbf7 Mon Sep 17 00:00:00 2001 From: Perry Melange Date: Mon, 27 Jan 2025 11:04:44 +0100 Subject: [PATCH 2/3] doc/configuration.rst: Add documentation for the new invert attribute for SysfsGPIO Update the SysfsGPIO, MatchedSysfsGPIO to add the new invert (active-low) attribute. Signed-off-by: Perry Melange --- doc/configuration.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/configuration.rst b/doc/configuration.rst index fef3bfbba..832cdf99f 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -556,9 +556,11 @@ A :any:`SysfsGPIO` resource describes a GPIO line. SysfsGPIO: index: 12 + invert: False Arguments: - index (int): index of the GPIO line + - invert (bool, default=False): optional, whether the logic level is inverted(active-low) Used by: - `GpioDigitalOutputDriver`_ @@ -577,6 +579,7 @@ USB based gpiochips. '@SUBSYSTEM': 'usb' '@ID_SERIAL_SHORT': 'D38EJ8LF' pin: 0 + invert: False The example would search for a USB gpiochip with the key `ID_SERIAL_SHORT` and the value `D38EJ8LF` and use the pin 0 of this device. @@ -585,6 +588,7 @@ The `ID_SERIAL_SHORT` property is set by the usb_id builtin helper program. Arguments: - match (dict): key and value pairs for a udev match, see `udev Matching`_ - pin (int): gpio pin number within the matched gpiochip. + - invert (bool, default=False): optional, whether the logic level is inverted (active-low) Used by: - `GpioDigitalOutputDriver`_ From dd6d9a189ce6ba055aa36fbd828b10ee3ef18f0d Mon Sep 17 00:00:00 2001 From: Perry Melange Date: Mon, 27 Jan 2025 11:24:03 +0100 Subject: [PATCH 3/3] examples/sysfsgpio: add invert (active-low) attribute to examples Add the new invert (active-low) attribute to the examples and add calls to the new invert method Signed-off-by: Perry Melange --- examples/sysfsgpio/export-gpio.yaml | 3 ++- examples/sysfsgpio/import-gpio.yaml | 2 -- examples/sysfsgpio/sysfsgpio.py | 3 ++- examples/sysfsgpio/sysfsgpio_remote.py | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/sysfsgpio/export-gpio.yaml b/examples/sysfsgpio/export-gpio.yaml index 489befd16..808a82c2a 100644 --- a/examples/sysfsgpio/export-gpio.yaml +++ b/examples/sysfsgpio/export-gpio.yaml @@ -1,3 +1,4 @@ desk: - GpioDigitalOutputDriver: + SysfsGPIO: index: 60 + invert: False diff --git a/examples/sysfsgpio/import-gpio.yaml b/examples/sysfsgpio/import-gpio.yaml index 4ba7b223f..40954a448 100644 --- a/examples/sysfsgpio/import-gpio.yaml +++ b/examples/sysfsgpio/import-gpio.yaml @@ -5,5 +5,3 @@ targets: name: gpio drivers: GpioDigitalOutputDriver: {} -options: - coordinator_address: 'labgrid:20408' diff --git a/examples/sysfsgpio/sysfsgpio.py b/examples/sysfsgpio/sysfsgpio.py index 98acf0ac1..3a09ad90c 100644 --- a/examples/sysfsgpio/sysfsgpio.py +++ b/examples/sysfsgpio/sysfsgpio.py @@ -13,11 +13,12 @@ StepLogger.start() t = Target("main") -r = SysfsGPIO(t, name=None, index=60) +r = SysfsGPIO(t, name=None, index=60, invert=True) d = GpioDigitalOutputDriver(t, name=None) p = t.get_driver("DigitalOutputProtocol") print(t.resources) +print("Testing IO") p.set(True) print(p.get()) time.sleep(2) diff --git a/examples/sysfsgpio/sysfsgpio_remote.py b/examples/sysfsgpio/sysfsgpio_remote.py index 4b16b8466..37976b673 100644 --- a/examples/sysfsgpio/sysfsgpio_remote.py +++ b/examples/sysfsgpio/sysfsgpio_remote.py @@ -15,6 +15,7 @@ p = t.get_driver("DigitalOutputProtocol") print(t.resources) +print("Testing IO") p.set(True) print(p.get()) time.sleep(2)