GPIO control through libgpiod using the command gpiocli

Since /sys/class/gpio is deprecated, we need to use libgpiod to take control over the gpio pins.

However, using the command gpioset to set the output on a gpio-pin, it is not persistent! After the gpioset command is finished, the state of the pin is undetermined (either unchanged or set to default). The lock on the pin is released and the state of the pin is uncertain.

So they have come up with a dbus-daemon: Implement DBus API #47

It is however still a RFC patch. So you’ll need to build it from source here:

https://github.com/brgl/libgpiod-private/tree/b4/dbus

On archlinuxarm I have a prebuild package for it (PKGBUILD), so install with:

pacman -Syu libgpiod-dbus-git

Then do:

systemctl start gpio-manager
systemctl enable gpio-manager

Then you’re all set to use the gpiocli command.

[root@rk3588 ~]# gpiocli --help
Usage:
  gpiocli [OPTION?] CMD [ARGS?] ...

Simple command-line client for controlling gpio-manager.

...

Available commands:
  detect - list GPIO chips and print their properties
  find - take a line name and find its parent chip's name and offset within it
  info - print information about GPIO lines
  get - get values of GPIO lines
  monitor - notify the user about edge events
  notify - notify the user about line property changes
  reconfigure - change the line configuration for an existing request
  release - release one of the line requests controlled by the manager
  request - request a set of GPIO lines for exclusive usage by the manager
  requests - list all line requests controlled by the manager
  set - set values of GPIO lines
  wait - wait for the gpio-manager interface to appear
1 Like

The next problem to solve using a gpio output, is how to make sure the controlled hardware is not unintentionally activated before gpio-manager is in control. The same is also needed if the gpio is added somewhere in the devicetree.

Since the switching capability of the gpio pin is limited, one would use a mosfet or similar, to control the hardware, perhaps using a relay in between.

The problem is that before the gpio-pin is set as output, it could be set as input between cold startup / reset and the moment it is set as output. If you’re unlucky, it could even be that a pullup resistor is active. The gpio-pin will have high (+3.3 usually) voltage. This could easilly activate a mosfet or similar, resulting unwanted switching of the hardware.

To make sure the hardware is not switched, one could use a opto-coupler. I used a PC817, it will need at least roughly 1 mA to be activated. I use a 1.5kOhm resistor in series with the internal led, when the gpio-pin is 3.3V… The output of the optocoupler will only be activated when the gpio-pin is set as output, setup in push-pull mode and set active. The current through the pullup-resistor cannot be high enough to activate the opto-coupler.

In my case, I needed a ‘closed contact’ when starting up the board, so I used yet another opto-coupler to invert the signal. I used it for the enable pin of a buck-converter. The buck-converter now is only active, when the gpio-pin is set as output, push-pull, active.

It is now mainline:

https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/commit/?id=a5ab76da1e0a7475c42336829c611f438bffd584

The package above does not build, the branch is gone…

I’ve updated the package and rebuild it, it builds fine, but haven’t tested it.