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`_ 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) 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,