Using GPIO on the Red Pitaya Board
Configuring the GPIO Hardware
Pavel Demin's red-pitaya-notes configuration and build infrastructure is used to build the Zynq FPGA bitstream and associated Linux kernel. The required GPIO pin mappings are configured as part of this.
In red-pitaya-notes/cfg/ports.tcl
the GPIO ports exp_p_tri_io
and exp_n_tri_io
are defined as:
The package pin mappings are in red-pitaya-notes/cfg/ports.xdc
:
set_property PACKAGE_PIN G17 [get_ports {exp_p_tri_io[0]}] set_property PACKAGE_PIN G18 [get_ports {exp_n_tri_io[0]}] set_property PACKAGE_PIN H16 [get_ports {exp_p_tri_io[1]}] set_property PACKAGE_PIN H17 [get_ports {exp_n_tri_io[1]}] set_property PACKAGE_PIN J18 [get_ports {exp_p_tri_io[2]}] set_property PACKAGE_PIN H18 [get_ports {exp_n_tri_io[2]}] set_property PACKAGE_PIN K17 [get_ports {exp_p_tri_io[3]}] set_property PACKAGE_PIN K18 [get_ports {exp_n_tri_io[3]}] set_property PACKAGE_PIN L14 [get_ports {exp_p_tri_io[4]}] set_property PACKAGE_PIN L15 [get_ports {exp_n_tri_io[4]}] set_property PACKAGE_PIN L16 [get_ports {exp_p_tri_io[5]}] set_property PACKAGE_PIN L17 [get_ports {exp_n_tri_io[5]}] set_property PACKAGE_PIN K16 [get_ports {exp_p_tri_io[6]}] set_property PACKAGE_PIN J16 [get_ports {exp_n_tri_io[6]}] set_property PACKAGE_PIN M14 [get_ports {exp_p_tri_io[7]}] set_property PACKAGE_PIN M15 [get_ports {exp_n_tri_io[7]}]
The GPIO port package pins are routed to the E1
expansion connector on the Red
Pitaya board. Table 1 shows the mappings from the GPIO signal lines to the E1
pins.
Port |
GPIO Signal |
E1 Pin |
---|---|---|
exp_p_tri_io[0] |
|
3 |
exp_n_tri_io[0] |
|
4 |
exp_p_tri_io[1] |
|
5 |
exp_n_tri_io[1] |
|
6 |
exp_p_tri_io[2] |
|
7 |
exp_n_tri_io[2] |
|
8 |
exp_p_tri_io[3] |
|
9 |
exp_n_tri_io[3] |
|
10 |
exp_p_tri_io[4] |
|
11 |
exp_n_tri_io[4] |
|
12 |
exp_p_tri_io[5] |
|
13 |
exp_n_tri_io[5] |
|
14 |
exp_p_tri_io[6] |
|
15 |
exp_n_tri_io[6] |
|
16 |
exp_p_tri_io[7] |
|
17 |
exp_n_tri_io[7] |
|
18 |
For this example, we make use of the 'negative' half of the GPIO outputs. The associated input/output ports are first deleted and then an interface port containing these lines is created:
delete_bd_objs [get_bd_ports exp_n_tri_io] create_bd_intf_port -mode Master -vlnv xilinx.com:interface:gpio_rtl:1.0 exp_n
Now an instance of axi_gpio
is created in the Vivado block design using
the above interface:
Vivado will generate the following device tree entry for the GPIO hardware:
axi_gpio_0: gpio@41200000 { #gpio-cells = <3>; clock-names = "s_axi_aclk"; clocks = <&misc_clk_0>; compatible = "xlnx,axi-gpio-2.0", "xlnx,xps-gpio-1.00.a"; gpio-controller ; reg = <0x41200000 0x10000>; xlnx,all-inputs = <0x0>; xlnx,all-inputs-2 = <0x0>; xlnx,all-outputs = <0x0>; xlnx,all-outputs-2 = <0x0>; xlnx,dout-default = <0x00000000>; xlnx,dout-default-2 = <0x00000000>; xlnx,gpio-width = <0x8>; xlnx,gpio2-width = <0x20>; xlnx,interrupt-present = <0x0>; xlnx,is-dual = <0x0>; xlnx,tri-default = <0xFFFFFFFF>; xlnx,tri-default-2 = <0xFFFFFFFF>; };
Note that this uses the Xilinx GPIO driver (drivers/gpio/gpio-xilinx.d
) and the
following kernel config. options are set in arch/arm/configs/xilinx_zynq_defconfig
:
This builds the GPIO kernel driver as a module which loads at boot
time. The GPIO module creates the /dev/gpiochip1
device.
The Running System
The GPIO device is available as /dev/gpiochip1
. The ownership and
permissions should be changed appropriately in order to allow access
from the application.
chgrp dyadic /dev/gpiochip1 chmod g+rw /dev/gpiochip1 # ls -l /dev/gpiochip1 crw-rw---- 1 root dyadic 254, 1 Oct 14 20:17 /dev/gpiochip1
Red Pitaya board top showing GPIO pins in expansion connectors
Accessing the GPIO device
We make use of the Python periphery module to access the GPIO device.
$ python Python 3.9.7 (default, Sep 19 2021, 17:26:23) [GCC 10.2.1 20210110] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from periphery import GPIO >>> >>> gpio_in = GPIO("/dev/gpiochip1", 1, "in") >>> gpio_out = GPIO("/dev/gpiochip1", 2, "out") >>> >>> value = gpio_in.read() >>> value False >>> gpio_out.write(not value) >>> >>> gpio_in.close() >>> gpio_out.close()
Useful tools
The gpiod
package contains a number of tools which are useful when
dealing with Linux GPIO devices.