A5E-HVIO-Example¶
Overview¶
The A5E HVIO example adds the HVIO subsystem to the base reference design. This addition allows for the use of the HVIO pins that are accessible via connectors P8 and P9 on the development kit. The HVIO pins are set to 3.3V LVCMOS in this example.
HVIO Subsystem¶
The HVIO subsystem contains four major blocks:- pio_# - three PIO controllers that export and connect to the HVIO pins
- clock_bridge_0 - provides the internal subsystem clock
- mm_bridge_0 - bridges the fabric-side Avalon-MM interface to the HVIO
- reset_bridge_0 - provides the internal subsystem reset
At the top level of the design:
- The subsystem clock is driven from hps_subsys.intel_agilex_5_soc_0_h2f_user0_clk
- The subsystem reset is driven from fabric_reset_bridge_0.out_reset
- The HVIO pins are exported to the FPGA-side PIO interface pins
hps_subsys.intel_agilex_5_soc_0_h2f_user0_clk (100 MHz example)
│
▼
┌──────────────────────────┐
│ clock_bridge_0 │ ┌──────────────────────────┐
└────────────┬─────────────┘ │ │
│ │ pio_{0,1,2} │
┌──clock────────────────────►│ │────►hvio_subsys.pio_{0,1,2}_external_connection
│ │ └──────────────────────────┘
│ │ ▲ ▲
│ │ │ │
│ ▼ │ │
│ ┌──────────────────────────┐ │ │
│ │ mm_bridge_0 │◄────────────┘ │
│ │ (Avalon-MM to PIO) │ │
│ └──────────────────────────┘ │
│ ▲ │
│ │reset │reset
▼ │ │
┌─────────────────┴────────────────────────────────────┴┐
fabric_reset_bridge_0.out_reset ───► │ reset_bridge_0 │
└───────────────────────────────────────────────────────┘
What This Project Offers¶
This project provides:- Pin out of all the HVIO pins on connectors P8 and P9.
- Inclusion of GPIO controllers in the device tree to allow for control of the HVIO via sysfs and libgpiod in Linux.
- Framework for utilizing the HVIO pins in projects.
- Ability to connect additional hardware via P8 and P9 connectors to interface via the HVIO.
Controlling HVIO from Linux¶
Toggling the HVIO pins from Linux can be achieved through sysfs and libgpiod. It should be noted that sysfs is considered deprecated and that libgpiod is the recommended method for interfacing with this pins. In the device tree, the pins are named after their connector and pin number following a "{Connector Number}_{Pin Number}" format (for example, if the HVIO pin was on connector P8, pin 22, it's name would be "P8_22").
sysfs
To toggle pins using sysfs, first determine the pin number using debugfs which should be mounted automatically for you. To do so, run cat /sys/kernel/debug/gpio, which should yield a similar output to below:
root@mity-a5e:~# cat /sys/kernel/debug/gpio gpiochip0: GPIOs 512-543, parent: platform/10d120e4.gpio, 10d120e4.gpio: gpio-512 (FABRIC_RESET ) gpio-513 (DEBUG_LED1 |:status-0 ) out lo gpio-514 (DEBUG_LED2 |:status-1 ) out lo gpiochip1: GPIOs 544-567, parent: platform/10c03200.gpio, 10c03200.gpio: gpio-547 (USB_RESETN ) gpio-548 (SDCARD_PRESENT ) gpiochip2: GPIOs 568-591, parent: platform/10c03300.gpio, 10c03300.gpio: gpio-588 (ETH1_RESETN ) gpio-591 (FAN_EN ) gpiochip3: GPIOs 592-603, parent: platform/20000440.gpio, /soc@0/bus@20000000/gpio@440: gpio-592 (P8_24 ) gpio-593 (P8_26 ) gpio-594 (P8_28 ) gpio-595 (P8_30 ) gpio-596 (P8_32 ) gpio-597 (P8_34 ) gpio-598 (P8_36 ) gpio-599 (P8_38 ) gpio-600 (P8_40 ) gpio-601 (P8_42 ) gpio-602 (P8_44 ) gpio-603 (P8_46 ) gpiochip4: GPIOs 604-635, parent: platform/20000420.gpio, /soc@0/bus@20000000/gpio@420: gpio-604 (P8_3 ) gpio-605 (P8_5 ) gpio-606 (P8_7 ) gpio-607 (P8_9 ) gpio-608 (P8_11 ) gpio-609 (P8_13 ) gpio-610 (P8_15 ) gpio-611 (P8_17 ) gpio-612 (P8_19 ) gpio-613 (P8_21 ) gpio-614 (P8_23 ) gpio-615 (P8_25 ) gpio-616 (P8_27 ) gpio-617 (P8_29 ) gpio-618 (P8_31 ) gpio-619 (P8_33 ) gpio-620 (P8_35 ) gpio-621 (P8_37 ) gpio-622 (P8_39 ) gpio-623 (P8_41 ) gpio-624 (P8_43 ) gpio-625 (P8_45 ) gpio-626 (P8_4 ) gpio-627 (P8_6 ) gpio-628 (P8_8 ) gpio-629 (P8_10 ) gpio-630 (P8_12 ) gpio-631 (P8_14 ) gpio-632 (P8_16 ) gpio-633 (P8_18 ) gpio-634 (P8_20 ) gpio-635 (P8_22 ) gpiochip5: GPIOs 636-667, parent: platform/20000400.gpio, /soc@0/bus@20000000/gpio@400: gpio-636 (P9_9 ) gpio-637 (P9_11 ) gpio-638 (P9_13 ) gpio-639 (P9_15 ) gpio-640 (P9_17 ) gpio-641 (P9_19 ) gpio-642 (P9_21 ) gpio-643 (P9_23 ) gpio-644 (P9_25 ) gpio-645 (P9_27 ) gpio-646 (P9_29 ) gpio-647 (P9_31 ) gpio-648 (P9_33 ) gpio-649 (P9_35 ) gpio-650 (P9_37 ) gpio-651 (P9_39 ) gpio-652 (P9_41 ) gpio-653 (P9_10 ) gpio-654 (P9_12 ) gpio-655 (P9_14 ) gpio-656 (P9_16 ) gpio-657 (P9_18 ) gpio-658 (P9_20 ) gpio-659 (P9_22 ) gpio-660 (P9_24 ) gpio-661 (P9_26 ) gpio-662 (P9_28 ) gpio-663 (P9_30 ) gpio-664 (P9_36 ) gpio-665 (P9_38 ) gpio-666 (P9_40 ) gpio-667 (P9_42 )
From here, you can see the GPIO chip number and what GPIO number a specific named pin is. To toggle one of these pins, you must echo the GPIO number to the "export" file in
/sys/class/gpio/. For example, to toggle pin "P8_26," you would determine the GPIO number to be 593 using the above output. Then, run echo 593 > /sys/class/gpio/export, which will reveal a directory named "gpio593" in "/sys/class/gpio/". This directory includes a "direction" and "value" file when can be read and written to both see and set the direction and value of the pin. To set the pin to input or output, you can run echo {in|out} > /sys/class/gpio/gpio593/direction, where "in" or "out" sets the pin to input or output respectively. With the pin set to output, you can run echo {1|0} > /sys/class/gpio/gpio593/value to set the output state, where "1" or "0" sets the pin to high or low respectively. To see what state the pin is at simply cat the "value" file and to see what direction the pin is set to simply cat the "direction" file. Below is a general flow of exporting the pin, checking its state, setting it to out an output, toggling it, and then setting it to an input.root@mity-a5e:~# ls /sys/class/gpio/ export gpiochip512 gpiochip544 gpiochip568 gpiochip592 gpiochip604 gpiochip636 gpiochip668 unexport root@mity-a5e:~# echo 593 > /sys/class/gpio/export root@mity-a5e:~# ls /sys/class/gpio export gpio593 gpiochip512 gpiochip544 gpiochip568 gpiochip592 gpiochip604 gpiochip636 gpiochip668 unexport root@mity-a5e:~# ls /sys/class/gpio/gpio593/ active_low device direction power subsystem uevent value root@mity-a5e:~# cat /sys/class/gpio/gpio593/direction in root@mity-a5e:~# cat /sys/class/gpio/gpio593/value 1 root@mity-a5e:~# echo out > /sys/class/gpio/gpio593/direction root@mity-a5e:~# cat /sys/class/gpio/gpio593/direction out root@mity-a5e:~# cat /sys/class/gpio/gpio593/value 0 root@mity-a5e:~# echo 1 > /sys/class/gpio/gpio593/value root@mity-a5e:~# cat /sys/class/gpio/gpio593/value 1 root@mity-a5e:~# echo 0 > /sys/class/gpio/gpio593/value root@mity-a5e:~# cat /sys/class/gpio/gpio593/value 0 root@mity-a5e:~# cat /sys/class/gpio/gpio593/direction out root@mity-a5e:~# echo in > /sys/class/gpio/gpio593/direction root@mity-a5e:~# cat /sys/class/gpio/gpio593/direction in
These are the basics of toggling the HVIO pins via the sysfs GPIO interface.
libgpiod
The primary commands to toggle pins with libgpiod are gpioinfo, gpioset, and gpioget. These commands let you print info on all the pins (gpioinfo), set a pin to a specific state via a process (gpioset), and get the current state of a pin (gpioget). An example of the output of gpioinfo can be seen below, where it prints the line of the respective chip its on, the name of the pin in the device tree, and the state.
gpiochip4 - 32 lines:
line 0: "P9_9" input consumer="sysfs"
line 1: "P9_11" input consumer="sysfs"
line 2: "P9_13" input consumer="sysfs"
line 3: "P9_15" input consumer="sysfs"
line 4: "P9_17" input consumer="sysfs"
line 5: "P9_19" input consumer="sysfs"
line 6: "P9_21" input consumer="sysfs"
line 7: "P9_23" input consumer="sysfs"
line 8: "P9_25" input consumer="sysfs"
line 9: "P9_27" input consumer="sysfs"
line 10: "P9_29" input consumer="sysfs"
line 11: "P9_31" input consumer="sysfs"
line 12: "P9_33" input consumer="sysfs"
line 13: "P9_35" input consumer="sysfs"
line 14: "P9_37" input consumer="sysfs"
line 15: "P9_39" input consumer="sysfs"
line 16: "P9_41" input consumer="sysfs"
line 17: "P9_10" input consumer="sysfs"
line 18: "P9_12" input consumer="sysfs"
line 19: "P9_14" input consumer="sysfs"
line 20: "P9_16" input consumer="sysfs"
line 21: "P9_18" input consumer="sysfs"
line 22: "P9_20" input consumer="sysfs"
line 23: "P9_22" input consumer="sysfs"
line 24: "P9_24" input consumer="sysfs"
line 25: "P9_26" input consumer="sysfs"
line 26: "P9_28" input consumer="sysfs"
line 27: "P9_30" input consumer="sysfs"
line 28: "P9_36" input consumer="sysfs"
line 29: "P9_38" input consumer="sysfs"
line 30: "P9_40" input consumer="sysfs"
line 31: "P9_42" input consumer="sysfs"
gpiochip5 - 32 lines:
line 0: "P8_3" input consumer="sysfs"
line 1: "P8_5" input consumer="sysfs"
line 2: "P8_7" input consumer="sysfs"
line 3: "P8_9" input consumer="sysfs"
line 4: "P8_11" input consumer="sysfs"
line 5: "P8_13" input consumer="sysfs"
line 6: "P8_15" input consumer="sysfs"
line 7: "P8_17" input consumer="sysfs"
line 8: "P8_19" input consumer="sysfs"
line 9: "P8_21" input consumer="sysfs"
line 10: "P8_23" input consumer="sysfs"
line 11: "P8_25" input consumer="sysfs"
line 12: "P8_27" input consumer="sysfs"
line 13: "P8_29" input consumer="sysfs"
line 14: "P8_31" input consumer="sysfs"
line 15: "P8_33" input consumer="sysfs"
line 16: "P8_35" input consumer="sysfs"
line 17: "P8_37" input consumer="sysfs"
line 18: "P8_39" input consumer="sysfs"
line 19: "P8_41" input consumer="sysfs"
line 20: "P8_43" input consumer="sysfs"
line 21: "P8_45" input consumer="sysfs"
line 22: "P8_4" input
line 23: "P8_6" input consumer="sysfs"
line 24: "P8_8" input consumer="sysfs"
line 25: "P8_10" input consumer="sysfs"
line 26: "P8_12" input consumer="sysfs"
line 27: "P8_14" input consumer="sysfs"
line 28: "P8_16" input consumer="sysfs"
line 29: "P8_18" input consumer="sysfs"
line 30: "P8_20" input consumer="sysfs"
line 31: "P8_22" input consumer="sysfs"
gpiochip6 - 12 lines:
line 0: "P8_24" input consumer="sysfs"
line 1: "P8_26" input consumer="sysfs"
line 2: "P8_28" input consumer="sysfs"
line 3: "P8_30" input consumer="sysfs"
line 4: "P8_32" input consumer="sysfs"
line 5: "P8_34" input consumer="sysfs"
line 6: "P8_36" input consumer="sysfs"
line 7: "P8_38" input consumer="sysfs"
line 8: "P8_40" input consumer="sysfs"
line 9: "P8_42" input consumer="sysfs"
line 10: "P8_44" input consumer="sysfs"
line 11: "P8_46" input consumer="sysfs"
To set one of these specific pins to a value, the format is
gpioset {PIN_NAME}={VALUE}, where "PIN_NAME" is the string printed from gpioinfo and "VALUE" is 0 or 1 for low or high. To get/read the value of a specific pin, the format is gpioget {PIN_NAME}, where "PIN_NAME" is, once again, the string printed from gpioinfo. This will result in an output similar to below.root@mity-a5e:~# gpioget P8_26 "P8_26"=inactive
For more info on libgpiod, the documentation can be found here.
Memory Offsets¶
The three PIO controllers have a base address of 0x20000400 with offsets of 0x0000, 0x0020, and 0x0040 respectively.
Building the HVIO Example¶
Compile the FPGA design¶
Refer to Building_fpga_2531pro for building the FPGA design. Navigate into the mitysom-a5e-mini-ref-hvio example project before compiling the design.
- Ensure to flash the resulting a5e.hps.jic onto the hardware
- Ensure to replace the a5e.core.rbf on the SD card
References¶
Go to top