This driver has been tested on the Raspberry Pi, and should also work on Banana Pi, BeagleBone, Pine64 (et al.) and other single board computers, and potentially on other platforms.
1. Purpose
This driver allows the use of GPIO pins in a way analogous to the parallel port driver on x86 PCs. It can use the same step generators, encoder counters and similar components.
2. Usage
loadrt hal_gpio inputs=GPIO5,GPIO6,GPIO12,GPIO13,GPIO16,GPIO17,GPIO18,GPIO19 \
outputs=GPIO20,GPIO21,GPIO22,GPIO23,GPIO24,GPIO25,GPIO26,GPIO27 \
invert=GPIO20,GPIO27 \
reset=GPIO21,GPIO22
This driver relies on the libgpiod-dev library and the gpiod package, which contains a number of utilities for configuring and querying GPIO. The GPIO pin names in the "loadrt" line of the HAL given above should be the names given by the gpioinfo
command.
Sample output (truncated):
$ gpioinfo
gpiochip0 - 54 lines:
line 0: "ID_SDA" unused input active-high
line 1: "ID_SCL" unused input active-high
line 2: "SDA1" unused input active-high
line 3: "SCL1" unused input active-high
line 4: "GPIO_GCLK" unused input active-high
line 5: "GPIO5" unused input active-high
line 6: "GPIO6" unused input active-high
line 7: "SPI_CE1_N" unused input active-high
line 8: "SPI_CE0_N" unused input active-high
line 9: "SPI_MISO" unused input active-high
line 10: "SPI_MOSI" unused input active-high
line 11: "SPI_SCLK" unused input active-high
line 12: "GPIO12" unused input active-high
line 13: "GPIO13" unused input active-high
line 14: "TXD1" unused input active-high
line 15: "RXD1" unused input active-high
line 16: "GPIO16" unused input active-high
line 17: "GPIO17" unused input active-high
line 18: "GPIO18" unused input active-high
line 19: "GPIO19" unused input active-high
line 20: "GPIO20" unused output active-high
...
A list of input and/or output pins should be specified as shown in the sample above. The \ character is used for line continuation in HAL, and is used to improve readability. The pin names are case-sensitive and there must be no spaces in the strings, neither between the comma-separated pins lists nor the "=" signs.
- Additional modifiers are
-
- invert
-
(valid for outputs only). Inverts the sense of the physical pin relative to the value in HAL.
- reset
-
(valid for outputs only). If any pins are allocated to the "reset" list then a HAL parameter hal_gpio.reset_ns will be created. This will have no effect unless the hal_gpio.reset function is added to a realtime thread. This should be placed after the hal_gpio.write function and must be in the same thread. The behaviour of this function is equivalent to the same function in the hal_parport driver, and it allows a step pulse every thread cycle. If the hal_gpio.reset_ns time is set longer than 1/4 of the period of the thread that it is added to, then the value will be reduced to 1/4 the thread period. There is a lower limit to how long the pulse can be. With 8 pins in the output list the pulse width can not reduce lower than 5000 ns on an RPi4, for example.
The following functions are accepted in all versions, but are only effective if a version of libgpiod_dev >= 1.6 is installed. They should be used in the same way as the parameters described above, and will alter the electrical parameters of the GPIO pins if this is supported by the hardware.
opendrain
opensource
biasdisable
pulldown
pullup
The version of libgpiod-dev installed can be determined by the command gpioinfo -v
3. Pins
-
hal_gpio.NAME-in - HAL_OUT The value of an input pin presented in to HAL
-
hal_gpio.NAME-in-not - HAL_OUT An inverted version of the above, for convenience
-
hal_gpio.NAME-out - HAL_IN use this pin to transfer a HAL bit value to a physical output
4. Parameters
-
hal_gpio.reset_ns - HAL_RW - "setp" this parameter to control the pulse length of pins added to the "reset" list. The value will be limited between 0 and thread-period / 4.
5. Functions
-
hal_gpio.read - Add this to the base thread to update the HAL pin values to match the physical input values.
-
hal_gpio.write - Add this to the base thread to update the physical pins to match the HAL values.
-
hal_gpio.reset - Only exported if there are pins defined in the reset list. This should be placed after the "write" function, and should be in the same thread.
Typically, the read function will be early in the call list, before any encoder counters and the write function will be later in the call list, after stepgen.make-pulses
.
6. Pin Identification
Use the pin names returned by the gpioinfo
utility. This uses the device-tree data. If the installed OS does not have a device-tree database then the pins will all be called "unnamed" (or similar) and this driver can not be used.
A further update to this driver might allow access by index number, but this is not currently supported.
7. Troubleshooting permissions problems.
If "access denied" messages are returned on loading the driver, try the following recipe: (Should not be needed for Raspbian, and will need to be modified to match the actual GPIO chip name on non-Pi platforms)
-
Create a new group
gpio
with the commandsudo groupadd gpio
-
Then to setup permissions for the "gpio" group, create a file called
90-gpio-access
in the/etc/udev/rules.d/
directory with the following contents (this is copied from the Raspbian install)SUBSYSTEM=="bcm2835-gpiomem", GROUP="gpio", MODE="0660" SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660" SUBSYSTEM=="gpio*", PROGRAM="/bin/sh -c '\ chown -R root:gpio /sys/class/gpio && chmod -R 770 /sys/class/gpio;\ chown -R root:gpio /sys/devices/virtual/gpio &&\ chmod -R 770 /sys/devices/virtual/gpio;\ chown -R root:gpio /sys$devpath && chmod -R 770 /sys$devpath\ '" SUBSYSTEM=="pwm*", PROGRAM="/bin/sh -c '\ chown -R root:gpio /sys/class/pwm && chmod -R 770 /sys/class/pwm;\ chown -R root:gpio /sys/devices/platform/soc/*.pwm/pwm/pwmchip* &&\ chmod -R 770 /sys/devices/platform/soc/*.pwm/pwm/pwmchip*\ '"
-
Add the user who runs LinuxCNC to the
gpio
group withsudo usermod -aG gpio <username>
8. Author
Andy Pugh
9. Known Bugs
None at this time.