aboutsummaryrefslogtreecommitdiff
path: root/recipes-demo/de10-nano-gpio-apps/files
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-demo/de10-nano-gpio-apps/files')
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/LICENSE22
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/README_first.txt31
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/README_gpio-keys.txt232
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/README_gpio-leds.txt182
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/README_gpio.txt358
-rwxr-xr-xrecipes-demo/de10-nano-gpio-apps/files/build_poll_KEY0_pb_state.sh22
-rwxr-xr-xrecipes-demo/de10-nano-gpio-apps/files/build_show_KEY0_pb_state.sh22
-rwxr-xr-xrecipes-demo/de10-nano-gpio-apps/files/build_toggle_fpga_leds.sh22
-rwxr-xr-xrecipes-demo/de10-nano-gpio-apps/files/build_watch_switch_events.sh22
-rwxr-xr-xrecipes-demo/de10-nano-gpio-apps/files/build_watch_switch_events_ioctl.sh22
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/find_gpio_controllers_dt.src27
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/find_gpio_keys_dt.src36
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/find_gpio_leds_dt.src34
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/poll_KEY0_pb_state.c221
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/show_KEY0_pb_state.c186
-rwxr-xr-xrecipes-demo/de10-nano-gpio-apps/files/show_KEY0_pb_state.sh24
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/toggle_fpga_leds.c133
-rwxr-xr-xrecipes-demo/de10-nano-gpio-apps/files/toggle_fpga_leds.sh28
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/watch_switch_events.c60
-rwxr-xr-xrecipes-demo/de10-nano-gpio-apps/files/watch_switch_events.sh47
-rw-r--r--recipes-demo/de10-nano-gpio-apps/files/watch_switch_events_ioctl.c74
21 files changed, 1805 insertions, 0 deletions
diff --git a/recipes-demo/de10-nano-gpio-apps/files/LICENSE b/recipes-demo/de10-nano-gpio-apps/files/LICENSE
new file mode 100644
index 0000000..ab84792
--- /dev/null
+++ b/recipes-demo/de10-nano-gpio-apps/files/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+Copyright (c) 2016 Intel Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
diff --git a/recipes-demo/de10-nano-gpio-apps/files/README_first.txt b/recipes-demo/de10-nano-gpio-apps/files/README_first.txt
new file mode 100644
index 0000000..fd26d84
--- /dev/null
+++ b/recipes-demo/de10-nano-gpio-apps/files/README_first.txt
@@ -0,0 +1,31 @@
+This directory contains three different example directories that contain
+documentation and examples for interacting with the GPIO resources on the Altas
+board.
+
+raw-gpio - contains a README file that describes how to discover and interact
+ with the gpio framework provided by the linux environment on the
+ DE10-Nano target. There is a script and two C programs that
+ demonstrate how to programmatically detect the state of the KEY0 push
+ button on the DE10-Nano board. The script and one C program simply
+ read the state, output it and exit, the second C program enables the
+ interrupt functionality for the GPIO and waits for the push button
+ press to generate the interrupt that it waits for.
+
+gpio-keys - contains a README file that describes how to discover and interact
+ with the gpio-keys framework provided by the linux environment on
+ the DE10-Nano target. There is a script and two C programs that
+ demonstrate how to programmatically detect the input events
+ generated by the SW0, SW1, SW2 and SW3 switches on the DE10-Nano
+ board. The script and one C program simply report the input events
+ as they are detected, the second C program adds a call to the
+ ioctl() function to read the current state of all four switches as
+ each input event is processed.
+
+gpio-leds - contains a README file that describes how to discover and interact
+ with the gpio-leds framework provided by the linux environment on
+ the DE10-Nano target. There is a script and a C program that
+ demonstrate how to programmatically control the LEDS on the
+ DE10-Nano board.
+
+Please see the README files in each sub directory for more information.
+
diff --git a/recipes-demo/de10-nano-gpio-apps/files/README_gpio-keys.txt b/recipes-demo/de10-nano-gpio-apps/files/README_gpio-keys.txt
new file mode 100644
index 0000000..d5b0ac2
--- /dev/null
+++ b/recipes-demo/de10-nano-gpio-apps/files/README_gpio-keys.txt
@@ -0,0 +1,232 @@
+This readme describes the linux kernel gpio-keys 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/input/input.txt
+<linux-source-tree>/Documentation/input/event-codes.txt
+<linux-source-tree>/Documentation/input/input-programming.txt
+<linux-source-tree>/Documentation/devicetree/bindings/gpio/gpio.txt
+<linux-source-tree>/Documentation/devicetree/bindings/input/gpio-keys.txt
+<linux-source-tree>/Documentation/devicetree/bindings/input/gpio-keys-polled.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-keys in device tree
+################################################################################
+function find_gpio_keys_dt ()
+{
+ for NEXT in $(find -L /proc/device-tree -name "compatible" | sort);
+ do
+ cat ${NEXT} | grep -xz "gpio-keys" > /dev/null && {
+ KEYS_DIRNAME="$(dirname ${NEXT})";
+ KEYS_COMPATIBLE="$(cat ${KEYS_DIRNAME}/compatible)";
+ echo "${KEYS_DIRNAME}";
+ echo -e "\tcompatible = '${KEYS_COMPATIBLE}'";
+ for NEXT_KEY in $(find -L "${KEYS_DIRNAME}" -name "gpios" | sort);
+ do
+ NEXT_KEY_DIR="$(dirname ${NEXT_KEY})";
+ echo "${NEXT_KEY_DIR}";
+ KEYS_GPIOS="$(hexdump -v -e '"0x" 4/1 "%02x" " "' "${NEXT_KEY}")";
+ CONTROLLER_PHANDLE_HEX=$(echo ${KEYS_GPIOS} | cut -d ' ' -f 1);
+ GPIO_BIT_HEX=$(echo ${KEYS_GPIOS} | cut -d ' ' -f 2);
+ INVERTED_FLAG_HEX=$(echo ${KEYS_GPIOS} | cut -d ' ' -f 3);
+ printf " gpios = ('%d', '%d', '%d') : ('%s', '%s', '%s')\n" "${CONTROLLER_PHANDLE_HEX}" "${GPIO_BIT_HEX}" "${INVERTED_FLAG_HEX}" "controller" "bit" "flag";
+ KEYS_CODE="$(hexdump -v -e '"0x" 4/1 "%02x"' "${NEXT_KEY_DIR}/linux,code")";
+ printf " code = '%d'\n" "${KEYS_CODE}";
+ GPIO_CONTROLLER="unknown";
+ CONTROLLER_PHANDLE_DEC="$(printf "%d" "${CONTROLLER_PHANDLE_HEX}")";
+ for NEXT in $(find -L /proc/device-tree -name "phandle" | sort);
+ do
+ PHANDLE_HEX="$(hexdump -v -e '"0x" 4/1 "%02x"' "${NEXT}")";
+ PHANDLE_DEC="$(printf "%d" "${PHANDLE_HEX}")";
+ [ "${PHANDLE_DEC}" -eq "${CONTROLLER_PHANDLE_DEC}" ] && {
+ GPIO_CONTROLLER="$(dirname ${NEXT})"
+ };
+ done;
+ printf " controller = '%s'\n" "${GPIO_CONTROLLER}";
+ done
+ };
+ done
+}
+################################################################################
+
+The function above is provided in the file 'find_gpio_keys_dt.src', which you
+can source into your environment by running 'source find_gpio_keys_dt.src'.
+
+When we run the function above on the DE10-Nano target it searches for nodes
+containing the 'compatible' string 'gpio-keys', there should be only one node
+located. The function then prints the path to the node that it found and
+extracts the 'gpios' binding and the 'linux,code' binding for each key node and
+prints these statistics.
+
+root@DE10-Nano:~# find_gpio_keys_dt
+/proc/device-tree/soc/keys
+ compatible = 'gpio-keys'
+/proc/device-tree/soc/keys/sw0
+ gpios = ('50', '0', '1') : ('controller', 'bit', 'flag')
+ code = '64'
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100004000'
+/proc/device-tree/soc/keys/sw1
+ gpios = ('50', '1', '1') : ('controller', 'bit', 'flag')
+ code = '65'
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100004000'
+/proc/device-tree/soc/keys/sw2
+ gpios = ('50', '2', '1') : ('controller', 'bit', 'flag')
+ code = '66'
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100004000'
+/proc/device-tree/soc/keys/sw3
+ gpios = ('50', '3', '1') : ('controller', 'bit', 'flag')
+ code = '67'
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100004000'
+root@DE10-Nano:~#
+
+For more information on the gpio controllers framework, please read the
+README_gpio.txt document. The 'gpio@0x100004000' controller identified above
+maps to the 'dipsw_pio' controller that provides a 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.
+
+The gpio-keys framework will register an input event device that will post input
+events when the gpios above change their state. The 'code' associated with each
+gpio above will be encoded in the input event message along with the state of
+the switch. We can see the input device in the devfs like this:
+
+root@DE10-Nano:~# ls -lR /dev/input
+/dev/input:
+total 0
+drwxr-xr-x 2 root root 80 Jul 9 16:25 by-path
+crw-rw---- 1 root input 13, 64 Jan 1 1970 event0
+crw-rw---- 1 root input 13, 65 Jul 9 16:25 event1
+crw-rw---- 1 root input 13, 63 Jan 1 1970 mice
+crw-rw---- 1 root input 13, 32 Jan 1 1970 mouse0
+
+/dev/input/by-path:
+total 0
+lrwxrwxrwx 1 root root 9 Jan 1 1970 platform-ffc04000.i2c-event -> ../event0
+lrwxrwxrwx 1 root root 9 Jul 9 16:25 platform-soc:base-fpga-region:keys-event -> ../event1
+
+In this case the event1 device is the device for our gpio-keys input, we can
+tell this from the '/dev/input/by-path' links that have more descriptive names.
+
+The sysfs also describes the input device environment for us in a useful way.
+
+root@DE10-Nano:~# ls -l /sys/class/input/
+total 0
+lrwxrwxrwx 1 root root 0 Jan 1 1970 event0 -> ../../devices/platform/soc/ffc04000.i2c/i2c-0/0-0053/input/input0/event0
+lrwxrwxrwx 1 root root 0 Jul 14 19:17 event1 -> ../../devices/platform/soc/soc:keys/input/input1/event1
+lrwxrwxrwx 1 root root 0 Jan 1 1970 input0 -> ../../devices/platform/soc/ffc04000.i2c/i2c-0/0-0053/input/input0
+lrwxrwxrwx 1 root root 0 Jul 14 19:17 input1 -> ../../devices/platform/soc/soc:keys/input/input1
+lrwxrwxrwx 1 root root 0 Jan 1 1970 mice -> ../../devices/virtual/input/mice
+lrwxrwxrwx 1 root root 0 Jan 1 1970 mouse0 -> ../../devices/platform/soc/ffc04000.i2c/i2c-0/0-0053/input/input0/mouse0
+
+And from the above we can see that the 'soc:keys' device exists in the sysfs.
+
+root@DE10-Nano:~# ls /sys/devices/platform/soc/soc:keys
+disabled_keys driver_override modalias switches
+disabled_switches input power uevent
+driver keys subsystem
+root@DE10-Nano:~# ls /sys/devices/platform/soc/soc:keys/input
+input1
+root@DE10-Nano:~# ls /sys/devices/platform/soc/soc:keys/input/input1
+capabilities event1 modalias phys properties uevent
+device id name power subsystem uniq
+root@DE10-Nano:~# ls /sys/devices/platform/soc/soc:keys/input/input1/event1
+dev device power subsystem uevent
+root@DE10-Nano:~# cat /sys/devices/platform/soc/soc:keys/input/input1/name
+soc:keys
+root@DE10-Nano:~# cat /sys/devices/platform/soc/soc:keys/input/input1/event1/dev
+13:65
+root@DE10-Nano:~# ls -l /dev/input/event1
+crw-rw---- 1 root input 13, 65 Jul 9 16:25 /dev/input/event1
+
+So now that we know what our input event device is, we can simply read from it
+to capture the input events as they arrive. The device will block until the
+next event message is received. We can do this like so:
+
+root@DE10-Nano:~# hexdump -C /dev/input/event1
+00000000 ca 61 a5 55 a4 44 08 00 01 00 40 00 00 00 00 00 |.a.U.D....@.....|
+00000010 ca 61 a5 55 a4 44 08 00 00 00 00 00 00 00 00 00 |.a.U.D..........|
+00000020 cc 61 a5 55 24 2a 02 00 01 00 40 00 01 00 00 00 |.a.U$*....@.....|
+00000030 cc 61 a5 55 24 2a 02 00 00 00 00 00 00 00 00 00 |.a.U$*..........|
+00000040 cd 61 a5 55 04 a0 0b 00 01 00 41 00 00 00 00 00 |.a.U......A.....|
+00000050 cd 61 a5 55 04 a0 0b 00 00 00 00 00 00 00 00 00 |.a.U............|
+00000060 cf 61 a5 55 bf 21 06 00 01 00 41 00 01 00 00 00 |.a.U.!....A.....|
+00000070 cf 61 a5 55 bf 21 06 00 00 00 00 00 00 00 00 00 |.a.U.!..........|
+00000080 d1 61 a5 55 7c 14 03 00 01 00 42 00 00 00 00 00 |.a.U|.....B.....|
+00000090 d1 61 a5 55 7c 14 03 00 00 00 00 00 00 00 00 00 |.a.U|...........|
+000000a0 d2 61 a5 55 22 2a 02 00 01 00 42 00 01 00 00 00 |.a.U"*....B.....|
+000000b0 d2 61 a5 55 22 2a 02 00 00 00 00 00 00 00 00 00 |.a.U"*..........|
+000000c0 d4 61 a5 55 8d ac 05 00 01 00 43 00 00 00 00 00 |.a.U......C.....|
+000000d0 d4 61 a5 55 8d ac 05 00 00 00 00 00 00 00 00 00 |.a.U............|
+000000e0 d7 61 a5 55 8c ac 05 00 01 00 43 00 01 00 00 00 |.a.U......C.....|
+000000f0 d7 61 a5 55 8c ac 05 00 00 00 00 00 00 00 00 00 |.a.U............|
+^C
+
+The output above results after we start hexdump reading from the input event1
+device, and then we toggle SW0 on and off, then we toggle SW1 on and off, then
+we toggle SW2 on and off, and then we toggle SW3 on and off. In 16 byte event
+messages that appear above, we can see the first 4 bytes that represent the
+second of the event, followed by the next 4 bytes that represent the millisecond
+of the event, followed by the next 2 bytes that represent the event type,
+followed by the next 2 bytes that represent the event code, followed by the
+last 4 bytes that represent the event value. So we can see the first line 0x00
+is an EV_KEY event for SW0 with code 0x40 and value 0. Then line 0x10 is an
+EV_SYN event, followed by line 0x20 which is the next EV_KEY event for SW0 with
+code 0x40 and value 1. Then line 0x30 is another EV_SYN event. This pattern
+repeats itself for the SW1 events with code 0x41, then the SW2 events with code
+0x42 and finally the SW3 events with code 0xx43.
+
+--------------------------------------------------------------------------------
+Example programs and scripts
+--------------------------------------------------------------------------------
+This directory contains a few examples to demonstrate how to interact with the
+switches on the DE10-Nano board that have been registered in the gpio-keys
+framework. There is a shell script called 'watch_switch_events.sh' and a C
+program called 'watch_switch_events.c'. Each of these examples monitor the FPGA
+gpio-keys input event in exactly the same way. Then there is a C program called
+'watch_switch_events_ioctl.c' which simply adds an ioctl() call to the
+'watch_switch_events.c' program so that it can detect the current state of all
+the switches, which can only be accomplished with the ioctl() call.
+
+To build the 'watch_switch_events.c' application simply run the
+'build_watch_switch_events.sh' shell script. That will compile the
+'watch_switch_events.c' source file and produce the executable
+'watch_switch_events' application. Refer to the 'build_watch_switch_events.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 'watch_switch_events_ioctl.c' application simply run the
+'build_watch_switch_events_ioctl.sh' shell script. That will compile the
+'watch_switch_events_ioctl.c' source file and produce the executable
+'watch_switch_events_ioctl' application. Refer to the
+'build_watch_switch_events_ioctl.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 'watch_switch_events.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:
+
+./watch_switch_events.sh <<< to run the script
+./watch_switch_events <<< to run the program
+./watch_switch_events_ioctl <<< to run the program with ioctl()
+
+The programs and script will monitor the input events for the gpio-keys device
+registered in the system. To generate an input event slide the switches SW0,
+SW1, SW2 and SW3 on the DE10-Nano board. As you slide the switches you will see
+the programs and script print out the input events that they receive from the
+system. The ioctl version of the program will additionally print out the
+current state of all the switches at each input event as well. To terminate the
+script or programs just type CTRL-C on the console that you launched them from.
+
+Both the programs and the script monitor the switches by interacting with the
+input event device node provided by the gpio-keys framework which leverages the
+linux gpio controller framework.
+
diff --git a/recipes-demo/de10-nano-gpio-apps/files/README_gpio-leds.txt b/recipes-demo/de10-nano-gpio-apps/files/README_gpio-leds.txt
new file mode 100644
index 0000000..21cc5dc
--- /dev/null
+++ b/recipes-demo/de10-nano-gpio-apps/files/README_gpio-leds.txt
@@ -0,0 +1,182 @@
+This readme describes the linux kernel gpio-leds 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/leds/leds-class.txt
+<linux-source-tree>/Documentation/devicetree/bindings/leds/common.txt
+<linux-source-tree>/Documentation/devicetree/bindings/leds/leds-gpio.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-leds in device tree
+################################################################################
+function find_gpio_leds_dt ()
+{
+ for NEXT in $(find -L /proc/device-tree -name "compatible" | sort);
+ do
+ cat ${NEXT} | grep -xz "gpio-leds" > /dev/null && {
+ LEDS_DIRNAME="$(dirname ${NEXT})";
+ LEDS_COMPATIBLE="$(cat ${LEDS_DIRNAME}/compatible)";
+ echo "${LEDS_DIRNAME}";
+ echo -e "\tcompatible = '${LEDS_COMPATIBLE}'";
+ for NEXT_LED in $(find -L "${LEDS_DIRNAME}" -name "gpios" | sort);
+ do
+ NEXT_LED_DIR="$(dirname ${NEXT_LED})";
+ echo "${NEXT_LED_DIR}";
+ LEDS_GPIOS="$(hexdump -v -e '"0x" 4/1 "%02x" " "' "${NEXT_LED}")";
+ CONTROLLER_PHANDLE_HEX=$(echo ${LEDS_GPIOS} | cut -d ' ' -f 1);
+ GPIO_BIT_HEX=$(echo ${LEDS_GPIOS} | cut -d ' ' -f 2);
+ INVERTED_FLAG_HEX=$(echo ${LEDS_GPIOS} | cut -d ' ' -f 3);
+ printf " gpios = ('%d', '%d', '%d') : ('%s', '%s', '%s')\n" "${CONTROLLER_PHANDLE_HEX}" "${GPIO_BIT_HEX}" "${INVERTED_FLAG_HEX}" "controller" "bit" "flag";
+ GPIO_CONTROLLER="unknown";
+ CONTROLLER_PHANDLE_DEC="$(printf "%d" "${CONTROLLER_PHANDLE_HEX}")";
+ for NEXT in $(find -L /proc/device-tree -name "phandle" | sort);
+ do
+ PHANDLE_HEX="$(hexdump -v -e '"0x" 4/1 "%02x"' "${NEXT}")";
+ PHANDLE_DEC="$(printf "%d" "${PHANDLE_HEX}")";
+ [ "${PHANDLE_DEC}" -eq "${CONTROLLER_PHANDLE_DEC}" ] && {
+ GPIO_CONTROLLER="$(dirname ${NEXT})"
+ };
+ done;
+ printf " controller = '%s'\n" "${GPIO_CONTROLLER}";
+ done
+ };
+ done
+}
+################################################################################
+
+The function above is provided in the file 'find_gpio_leds_dt.src', which you
+can source into your environment by running 'source find_gpio_leds_dt.src'.
+
+When we run the function above on the DE10-Nano target it searches for nodes
+containing the 'compatible' string 'gpio-leds', there should be only one node
+located. The function then prints the path to the node that it found and
+extracts the 'gpios' binding for each led node and prints these statistics.
+
+root@DE10-Nano:~# find_gpio_leds_dt
+/proc/device-tree/leds
+ compatible = 'gpio-leds'
+/proc/device-tree/leds/hps0
+ gpios = ('51', '24', '0') : ('controller', 'bit', 'flag')
+ controller = '/proc/device-tree/soc/gpio@ff709000/gpio-controller@0'
+/proc/device-tree/soc/leds
+ compatible = 'gpio-leds'
+/proc/device-tree/soc/leds/fpga0
+ gpios = ('49', '0', '0') : ('controller', 'bit', 'flag')
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100003000'
+/proc/device-tree/soc/leds/fpga1
+ gpios = ('49', '1', '0') : ('controller', 'bit', 'flag')
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100003000'
+/proc/device-tree/soc/leds/fpga2
+ gpios = ('49', '2', '0') : ('controller', 'bit', 'flag')
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100003000'
+/proc/device-tree/soc/leds/fpga3
+ gpios = ('49', '3', '0') : ('controller', 'bit', 'flag')
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100003000'
+/proc/device-tree/soc/leds/fpga4
+ gpios = ('49', '4', '0') : ('controller', 'bit', 'flag')
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100003000'
+/proc/device-tree/soc/leds/fpga5
+ gpios = ('49', '5', '0') : ('controller', 'bit', 'flag')
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100003000'
+/proc/device-tree/soc/leds/fpga6
+ gpios = ('49', '6', '0') : ('controller', 'bit', 'flag')
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100003000'
+/proc/device-tree/soc/leds/fpga7
+ gpios = ('49', '7', '0') : ('controller', 'bit', 'flag')
+ controller = '/proc/device-tree/soc/bridge@0xc0000000/gpio@0x100003000'
+
+For more information on the gpio controllers framework, please read the
+README_gpio.txt document. The 'gpio@0x100003000' controller identified above
+maps to the 'led_pio' controller that provides an 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. The 'gpio@ff709000'
+controller identified above maps to the 'gpio1' controller that provides a
+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 gpio-led framework will register sysfs entries for each led port, and
+provide files that we can use to control and query the state of the leds. If we
+look at the sysfs led class directory like this:
+
+root@DE10-Nano:~# ls /sys/class/leds/
+fpga_led0 fpga_led2 fpga_led4 fpga_led6 hps_led0
+fpga_led1 fpga_led3 fpga_led5 fpga_led7
+
+We see all the led entries that the gpio-leds framework has registered for us.
+Each of these directories contain the following format:
+
+root@DE10-Nano:~# ls /sys/class/leds/fpga_led0
+brightness max_brightness subsystem uevent
+device power trigger
+root@DE10-Nano:~# ls /sys/class/leds/hps_led0
+brightness max_brightness subsystem uevent
+device power trigger
+
+There are two files in these entries that are particularly useful to us, the
+'trigger' file and the 'brightness' file. The 'trigger' file identifies what
+automatic triggers get applied to the led port, by default the 'hps_led0' port
+is assigned to be triggered as 'heartbeat' and if we examine the 'trigger' file
+we should see that:
+
+root@DE10-Nano:~# cat /sys/class/leds/hps_led0/trigger
+none nand-disk mmc0 timer oneshot [heartbeat] backlight gpio cpu0 cpu1 default-on
+
+If we look at any of the 'fpga_led*' entiries we should see no trigger applied
+to them;
+
+root@DE10-Nano:~# cat /sys/class/leds/fpga_led0/trigger
+[none] nand-disk mmc0 timer oneshot heartbeat backlight gpio cpu0 cpu1 default-on
+
+The 'brightness' file allows us to turn the led on or off and query the state of
+the led. Like this
+
+root@DE10-Nano:~# cat /sys/class/leds/fpga_led0/brightness
+0
+
+The 'fpga_led0' port is currently off, so if we set this port to anything but
+zero, we will turn that led on, like this:
+
+root@DE10-Nano:~# echo 1 > /sys/class/leds/fpga_led0/brightness
+root@DE10-Nano:~# cat /sys/class/leds/fpga_led0/brightness
+1
+
+Now the 'fpga_led0' port is on, if we sest this port back to zero the we will
+turn that led off, like this:
+
+root@DE10-Nano:~# echo 0 > /sys/class/leds/fpga_led0/brightness
+root@DE10-Nano:~# cat /sys/class/leds/fpga_led0/brightness
+0
+
+--------------------------------------------------------------------------------
+Example programs and scripts
+--------------------------------------------------------------------------------
+This directory contains a few examples to demonstrate how to control the LEDs on
+the DE10-Nano board. There is a shell script called 'toggle_fpga_leds.sh' and a C
+program called 'toggle_fpga_leds.c'. Each of these examples toggle the FPGA
+LEDs in exactly the same way.
+
+To build the 'toggle_fpga_leds' application simply run the
+'build_toggle_fpga_leds.sh' shell script. That will compile the
+'toggle_fpga_leds.c' source file and produce the executable 'toggle_fpga_leds'
+application. Refer to the 'build_toggle_fpga_leds.sh' script to see how the
+application is actually compiled and refer to the C program source file and the
+shell script source file for more details on how they actually work.
+
+Once you've built the application, you can run both the script and the
+application like this:
+
+./toggle_fpga_leds.sh <<< to run the script
+./toggle_fpga_leds <<< to run the program
+
+The program and script will exit automatically after they sequentially turn each
+led on and then off.
+
+Both the program and the script manipulate the LEDs by interacting with the
+sysfs file entries provided by the linux gpio-led framework which leverages the
+linux gpio controller framework.
+
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 ${NEX