aboutsummaryrefslogtreecommitdiff
path: root/recipes-demo/de10-nano-gpio-apps/files/README_gpio.txt
diff options
context:
space:
mode:
authorWestergreen, Dalon <dalon.westergreen@intel.com>2017-03-29 15:41:36 -0700
committerWestergreen, Dalon <dalon.westergreen@intel.com>2017-03-30 16:35:30 -0700
commit9a293641b9abf9e4fca34f46a2de781f50847da9 (patch)
tree743a6aaa5f9834987a2e69881ced6eaf9efb3592 /recipes-demo/de10-nano-gpio-apps/files/README_gpio.txt
parent8abd3fefd939f796ae49191d6f5af641f2d624d0 (diff)
downloadmeta-de10-nano-9a293641b9abf9e4fca34f46a2de781f50847da9.tar.xz
Initial commit of de10-nano recipes
Please note that this is purely for development. Only superficial efforts have been made to resolve security concerns, and it should be noted that the board ships with an EMPTY ROOT PASSWORD and support for root login via ssh. This allows passwordless access to the board via ssh. recipes-bsp/u-boot: Contains the uboot 2017.03rc2 recipe and patches to support the de10-nano board recipes-connectivity/avahi: bbappend to remove unwanted packages recipes-connectivity/bluez: bbappend to add --compat to the bluetooth service to support legacy SDP APIs recipes-connectivity/openssh: bbappend to add a custom sshd_config recipes-core/base-files: bbappend to customize fstab and inputrc recipes-core/imagemagick: bbappend to change build configuration for the de10-nano board recipes-core/packagegroups: bbappend to remove an unwanted package recipes-core/webkit: bbappend to remove support for opengl recipes-demo: Various demo applications recipes-devtools: MRAA and UPM recipes recipes-images/angstrom/de10-nano-image.bb: DE10-Nano image definition recipes-kernel/de10-nano-linux-firmware: FPGA related firmware required for fpga configuration and devicetree overlay support recipes-kernel/linux: bbappend to customize configuration of linux kernel as well as patch in the de10-nano devicetree recipes-misc: various initialization and systemd scripts recipes-qt/qt5: bbappend to modify qt build options recipes-support/neon: bbappend to remove unwanted package recipes-support/upower: bbappend to remove unwanted package recipes-webserver: webserver configuration and webcontent for board hostedweb portal recipes-xfce/thunar-volman: bbappend to remove unwanted package recipes-xfce/xfce-pointers: add configuration so that xfce does not use the adxl input as a mouse recipes-xfce/xfce4-settings: bbappend to remove unwanted package Signed-off-by: Westergreen, Dalon <dalon.westergreen@intel.com>
Diffstat (limited to 'recipes-demo/de10-nano-gpio-apps/files/README_gpio.txt')
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/README_gpio.txt358
1 files changed, 358 insertions, 0 deletions
diff --git a/recipes-demo/de10-nano-gpio-apps/files/README_gpio.txt b/recipes-demo/de10-nano-gpio-apps/files/README_gpio.txt
new file mode 100644
index 0000000..ba0b0f4
--- /dev/null
+++ b/recipes-demo/de10-nano-gpio-apps/files/README_gpio.txt
@@ -0,0 +1,358 @@
+This readme describes the linux kernel gpio framework as it deploys on the
+DE10-Nano target environment. You may find the following references useful for
+more information on this topic as well.
+
+<linux-source-tree>/Documentation/gpio/gpio.txt
+<linux-source-tree>/Documentation/gpio/sysfs.txt
+<linux-source-tree>/Documentation/devicetree/bindings/gpio/gpio.txt
+<linux-source-tree>/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
+<linux-source-tree>/Documentation/devicetree/bindings/gpio/gpio-altera.txt
+
+If you cut and paste the following function into a console running on the
+DE10-Nano target you can extract the useful information contained in the run
+time devicetree maintained by the kernel in the procfs.
+
+################################################################################
+# find gpio controllers in device tree
+################################################################################
+function find_gpio_controllers_dt ()
+{
+ for NEXT in $(find -L /proc/device-tree -name "compatible" | sort);
+ do
+ cat ${NEXT} | grep -xz "snps,dw-apb-gpio" > /dev/null && {
+ GPIO_DIRNAME="$(dirname ${NEXT})";
+ echo ${GPIO_DIRNAME};
+ GPIO_COMPATIBLE="$(cat ${GPIO_DIRNAME}/compatible)";
+ echo -e "\tcompatible = '${GPIO_COMPATIBLE}'";
+ WF="${GPIO_DIRNAME}/gpio-controller@0/snps,nr-gpios";
+ GPIO_HEX_WIDTH="$(hexdump -v -e '"0x"' -e '4/1 "%02x"' "${WF}")";
+ GPIO_WIDTH=$(printf "%d" ${GPIO_HEX_WIDTH});
+ echo -e "\t width = '${GPIO_WIDTH}'"
+ };
+ cat ${NEXT} | grep -e "altr,pio" > /dev/null && {
+ GPIO_DIRNAME="$(dirname ${NEXT})";
+ echo ${GPIO_DIRNAME};
+ GPIO_COMPATIBLE="$(cat ${GPIO_DIRNAME}/compatible)";
+ echo -e "\tcompatible = '${GPIO_COMPATIBLE}'";
+ WF="${GPIO_DIRNAME}/altr,gpio-bank-width";
+ GPIO_HEX_WIDTH="$(hexdump -v -e '"0x"' -e '4/1 "%02x"' "${WF}")";
+ GPIO_WIDTH=$(printf "%d" ${GPIO_HEX_WIDTH});
+ echo -e "\t width = '${GPIO_WIDTH}'"
+ };
+ done
+}
+################################################################################
+
+The function above is provided in the file 'find_gpio_controllers_dt.src', which
+you can source into your environment by running
+'source find_gpio_controllers_dt.src'.
+
+When we run the function above on the DE10-Nano target it searches for nodes
+containing the 'compatible' string fragments of 'snps,dw-apb-gpio' or 'altr,pio'
+which are the identifiers for the hard GPIO controllers and the soft GPIO
+controllers, respectively, in our system. The function then prints the path to
+the node that it found and extracts the compatible string and width of the gpio
+controller and prints those statistics out as well. It does this for all gpio
+controller nodes that it locates in the device tree.
+
+root@DE10-Nano:~# find_gpio_controllers_dt
+/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100003000
+ compatible = 'altr,pio-15.0altr,pio-1.0'
+ width = '8'
+/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100004000
+ compatible = 'altr,pio-15.0altr,pio-1.0'
+ width = '4'
+/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100005000
+ compatible = 'altr,pio-15.0altr,pio-1.0'
+ width = '2'
+/proc/device-tree/soc/gpio@ff708000
+ compatible = 'snps,dw-apb-gpio'
+ width = '29'
+/proc/device-tree/soc/gpio@ff709000
+ compatible = 'snps,dw-apb-gpio'
+ width = '29'
+/proc/device-tree/soc/gpio@ff70a000
+ compatible = 'snps,dw-apb-gpio'
+ width = '27'
+
+Now the run time binary device tree blob does not contain some of the useful
+labels that were used in the original DTS source files that can help us
+understand what gpio controllers belong to what functions on the board. These
+fragments out of the original DTS source file contain the labels which show
+the functions of the various gpio controllers a little better:
+
+led_pio: gpio@0x100003000 {
+};
+dipsw_pio: gpio@0x100004000 {
+};
+button_pio: gpio@0x100005000 {
+};
+gpio@ff708000 {
+ gpio0: gpio-controller@0 {
+ };
+};
+gpio@ff709000 {
+ gpio1: gpio-controller@0 {
+ };
+};
+gpio@ff70a000 {
+ gpio2: gpio-controller@0 {
+ };
+};
+
+This is how these gpio controllers are implemented on the DE10-Nano target:
+
+led_pio - 8-bit output, fpga based gpio, registered as 'gpio-leds' in the device
+ tree to be used in the gpio-leds framework to drive LED0-LED7 on the
+ DE10-Nano board.
+
+dipsw_pio - 4-bit input, fpga based gpio, registered as 'gpio-keys' in the
+ device tree to be used in the gpio-keys framework to receive input
+ events from switches SW0-SW3 on the DE10-Nano board.
+
+button_pio - 2-bit input, fpga based gpio, receives input from push buttons
+ KEY0 and KEY1 on the DE10-Nano board.
+
+gpio0 - 29-bit, hps based gpio controller, no interfaces connected to these pins
+ on the Altas board.
+
+gpio1 - 29-bit, hps based gpio controller, the HPS GPIO53 port served by this
+ controller is registered as 'gpio-leds' in the device tree to be used in
+ the gpio-leds framework to drive the USERLED on the Altas board. The
+ HPS GPIO54 port served by this controller receives input from push
+ button KEY2 on the DE10-Nano board.
+
+gpio2 - 27-bit, hps based gpio controller, no interfaces connected to these pins
+ on the DE10-Nano board.
+
+The kernel gpio framework creates some sysfs entries for all the gpio
+controllers that we can interact with to gain access to and manipulate the gpio
+ports that we are interested in. These sysfs entries are located in
+'/sys/class/gpio', like this:
+
+root@DE10-Nano:~# ls /sys/class/gpio
+export gpiochip415 gpiochip427 gpiochip483
+gpiochip413 gpiochip419 gpiochip454 unexport
+
+Each of the gpio controllers is represented by a gpiochip* entry in the display
+above. To determine which gpiochip* entry corresponds to which gpio controller
+we can run a loop like this to discover them:
+
+for NEXT in $(find /sys/class/gpio/ -name "gpiochip*" | sort)
+do
+echo ${NEXT} = $(cat ${NEXT}/label)
+done
+
+/sys/class/gpio/gpiochip413 = /soc/bridge@0xc0000000/gpio@0x100005000
+/sys/class/gpio/gpiochip415 = /soc/bridge@0xc0000000/gpio@0x100004000
+/sys/class/gpio/gpiochip419 = /soc/bridge@0xc0000000/gpio@0x100003000
+/sys/class/gpio/gpiochip427 = ff70a000.gpio
+/sys/class/gpio/gpiochip454 = ff709000.gpio
+/sys/class/gpio/gpiochip483 = ff708000.gpio
+
+You should be able to correlate the string from the 'label' file with the output
+that we saw from the device tree entries. We can also extract the width of each
+gpio controller from the sysfs entries like this:
+
+for NEXT in $(find /sys/class/gpio/ -name "gpiochip*" | sort)
+do
+echo ${NEXT} = $(cat ${NEXT}/ngpio)
+done
+
+/sys/class/gpio/gpiochip413 = 2
+/sys/class/gpio/gpiochip415 = 4
+/sys/class/gpio/gpiochip419 = 8
+/sys/class/gpio/gpiochip427 = 27
+/sys/class/gpio/gpiochip454 = 29
+/sys/class/gpio/gpiochip483 = 29
+
+These widths should correlate to what was reported out of the device tree.
+
+Now if we want to work with a raw gpio we can use the gpio framework to do so.
+There are a few raw gpios on the DE10-Nano system that we can demonstrate. We
+cannot demonstrate any interaction with the gpios that were registered with the
+gpio-leds or gpio-keys framework since those frameworks are in control of those
+gpio ports, but those are demonstrated in their own specific readme files.
+
+Let's try to read the state of the 'button_pio' ports that are controlled by the
+'gpio@0x100005000' controller which maps into 'gpiochip157' for the 2-bits that
+are connected to the KEY0 and KEY1 push buttons. To being we 'export' the two
+gpio ports that we're interested in like this:
+
+root@DE10-Nano:~# echo 413 > /sys/class/gpio/export
+root@DE10-Nano:~# echo 414 > /sys/class/gpio/export
+
+And now you can see that we have two new entires in the sysfs, each representing
+the individual gpio port that we exported.
+
+root@DE10-Nano:~# ls /sys/class/gpio
+export gpio414 gpiochip415 gpiochip427 gpiochip483
+gpio413 gpiochip413 gpiochip419 gpiochip454 unexport
+
+Each of these individual gpio directories contain the following files:
+
+root@DE10-Nano:~# ls /sys/class/gpio/gpio413
+active_low direction edge power subsystem uevent value
+root@DE10-Nano:~# cat /sys/class/gpio/gpio413/active_low
+0
+root@DE10-Nano:~# cat /sys/class/gpio/gpio413/direction
+in
+root@DE10-Nano:~# cat /sys/class/gpio/gpio413/edge
+none
+root@DE10-Nano:~# cat /sys/class/gpio/gpio413/value
+1
+
+We can see from above that this port is defined as an active high input with no
+edge detection interrupt currently enabled and the value of the port is
+currently 1. Reading the 'value' sysfs file will always return the live state
+of this gpio port. If we read the 'value' file a few times as we press and
+release the KEY0 push button we can see the live state change:
+
+root@DE10-Nano:~# cat /sys/class/gpio/gpio413/value
+1
+root@DE10-Nano:~# cat /sys/class/gpio/gpio413/value
+0
+root@DE10-Nano:~# cat /sys/class/gpio/gpio413/value
+1
+root@DE10-Nano:~# cat /sys/class/gpio/gpio413/value
+0
+root@DE10-Nano:~# cat /sys/class/gpio/gpio413/value
+1
+
+Now if we write the phrase 'falling' into the 'edge' file then the edge capture
+interrupt functionality will be enabled for this gpio:
+
+root@DE10-Nano:~# echo falling > /sys/class/gpio/gpio413/edge
+root@DE10-Nano:~# cat /sys/class/gpio/gpio413/edge
+falling
+
+At this point two things occur, if we could call poll() or select() against the
+file descriptor for the 'value' file, it would block until the interrupt fired,
+if we simply read() the 'value' file then we will continue to see the live state
+of the port. The second thing that we can observe is that the
+'/proc/interrupts' file shows our newly active IRQ for this PIO that has been
+registered:
+
+root@DE10-Nano:~# cat /proc/interrupts | grep 144
+144: 1 0 altera-gpio 0 gpiolib
+
+If we press and release the KEY0 push button a few times we should see the
+interrupt count increase.
+
+root@DE10-Nano:~# cat /proc/interrupts | grep 144
+144: 5 0 altera-gpio 0 gpiolib
+
+Now the gpio414 that we exported for the KEY1 push button will operate the same
+way. If we press and release KEY1 while we monitor the 'value' file for gpio414
+we should see the same behavior appear:
+
+root@DE10-Nano:~# cat /sys/class/gpio/gpio414/value
+1
+root@DE10-Nano:~# cat /sys/class/gpio/gpio414/value
+0
+root@DE10-Nano:~# cat /sys/class/gpio/gpio414/value
+1
+root@DE10-Nano:~# cat /sys/class/gpio/gpio414/value
+0
+
+There is one other raw gpio on the DE10-Nano board that we could interact with,
+it's the KEY2 push button connected to the HPS GPIO54 input which comes in
+through the gpio1 controller that is assigned to gpiochip198. To export this
+gpio port we calculate it's position in gpio1 by using this equation:
+
+root@DE10-Nano:~# expr 454 + 54 - 29
+479
+ ^ ^ ^
+ | | |
+ | | +--- the number of HPS GPIO ports in gpio0
+ | +-------- the HPS GPIO we want
+ +-------------- the base gpio in gpiochip454
+
+So we want to export gpio 479 to gain access to this port, like this:
+
+root@DE10-Nano:~# echo 479 > /sys/class/gpio/export
+root@DE10-Nano:~# ls /sys/class/gpio/
+export gpio414 gpiochip413 gpiochip419 gpiochip454 unexport
+gpio413 gpio479 gpiochip415 gpiochip427 gpiochip483
+
+And we see the gpio479 file in the sysfs now. We can interact with this gpio
+the same way that we did the others:
+
+root@DE10-Nano:~# cat /sys/class/gpio/gpio479/value
+1
+root@DE10-Nano:~# cat /sys/class/gpio/gpio479/value
+0
+root@DE10-Nano:~# cat /sys/class/gpio/gpio479/value
+1
+
+And if we enable interrupts for this port like we did on the other port:
+
+root@DE10-Nano:~# echo falling > /sys/class/gpio/gpio479/edge
+root@DE10-Nano:~# cat /sys/class/gpio/gpio479/edge
+falling
+
+Then we see this gpio controller appear in the '/proc/interrupts' listing:
+
+root@DE10-Nano:~# cat /proc/interrupts | grep 116
+116: 0 0 gpio-dwapb 3 0-0053
+
+When we are done using these gpio ports that we have exported into user space we
+can 'unexport' them by passing the same values into the 'unexport' sysfs file
+that we used to export the ports originally:
+
+root@DE10-Nano:~# echo 413 > /sys/class/gpio/unexport
+root@DE10-Nano:~# echo 414 > /sys/class/gpio/unexport
+root@DE10-Nano:~# echo 479 > /sys/class/gpio/unexport
+root@DE10-Nano:~# ls /sys/class/gpio
+export gpiochip415 gpiochip427 gpiochip483
+gpiochip413 gpiochip419 gpiochip454 unexport
+
+And we can see that the exported entries have been removed from the sysfs.
+
+--------------------------------------------------------------------------------
+Example programs and scripts
+--------------------------------------------------------------------------------
+This directory contains a few examples to demonstrate how to interact with the
+push buttons on the DE10-Nano board that have been registered in the gpio
+framework. There is a shell script called 'show_KEY0_pb_state.sh' and a C
+program called 'show_KEY0_pb_state.c'. Each of these examples query the gpio
+state in exactly the same way. Then there is a C program called
+'poll_KEY0_pb_state.c' which simply adds a poll() call to the
+'show_KEY0_pb_state.sh' program to demonstrate the interrupt functionality
+provided by the gpio framework to detect the push button press via a hardware
+interrupt, which can only be accomplished with the poll() or select() type of
+system call.
+
+To build the 'show_KEY0_pb_state.c' application simply run the
+'build_show_KEY0_pb_state.sh' shell script. That will compile the
+'show_KEY0_pb_state.c' source file and produce the executable
+'show_KEY0_pb_state' application. Refer to the 'build_show_KEY0_pb_state.sh'
+script to see how the application is actually compiled and refer to the C
+program source file for more details on how it actually works.
+
+To build the 'poll_KEY0_pb_state.c' application simply run the
+'build_poll_KEY0_pb_state.sh' shell script. That will compile the
+'poll_KEY0_pb_state.c' source file and produce the executable
+'poll_KEY0_pb_state' application. Refer to the 'build_poll_KEY0_pb_state.sh'
+script to see how the application is actually compiled and refer to the C
+program source file for more details on how it actually works.
+
+Refer to the 'show_KEY0_pb_state.sh' source file for more details on how it
+actually works.
+
+Once you've built the applications, you can run both the script and the
+applications like this:
+
+./show_KEY0_pb_state.sh <<< to run the script
+./show_KEY0_pb_state <<< to run the program
+./poll_KEY0_pb_state <<< to run the program with poll()
+
+The 'show' program and script will read the current state of the KEY0 push
+button input and print it out, and then exit. The 'poll' program will enable
+the KEY0 push button to generate a falling edge interrupt when it is pressed and
+then ask you to press the KEY0 push button. When the 'poll' program detects the
+interrupt event it prints that status out and exits.
+
+Both the programs and the script monitor the push buttons by interacting with
+the linux gpio controller framework.
+