Hardware GPIO - monkeymia/orangepizero GitHub Wiki
The general-purpose input/output (GPIO) pins are supported in the Kernel. From User-Space there are following options to access/control the GPIO pins:
- libraries are using /dev/mem to do a "mmap" directly to SoC registers
(located at 0x01C20800), which is faster and allows also to access to Pn_PUL0/Pn_PUL1 registers. This solution is hardware-specific
- sysfs interface (/sys/class/gpio) to access GPIOs.
Since linux 4.8 the GPIO sysfs interface is deprecated.
- Since linux 4.8 User space should use the character device instead.
This library encapsulates the ioctl calls and data structures behind a straightforward API. https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/tree/README
-
The first thing a driver must do with a GPIO is setting its direction.
-
Description of GPIOs with open drain/source support:
-
GPIO capabilities may include: * GPIO pins can be configured to be input or output * Output values are writable/readable * Input values are readable (typically high or low) * Input values can often be used as IRQs
Install software support:
sudo apt install gpiod sudo apt install libgpiod-dev
Installs:
/usr/bin/gpiodetect /usr/bin/gpiofind /usr/bin/gpioget /usr/bin/gpioinfo /usr/bin/gpiomon /usr/bin/gpioset /usr/lib/arm-linux-gnueabihf/libgpiod.so
Source code: https://github.com/brgl/libgpiod
sudo gpiodetect gpiochip0 [1c20800.pinctrl] (224 lines) gpiochip1 [1f02c00.pinctrl] (32 lines) demonstrator@orangepizero:~$
sudo gpioget gpiochip0 10 gpioget: error reading GPIO values: Device or resource busy sudo gpioget gpiochip1 17 gpioget: error reading GPIO values: Device or resource busy
sudo gpioinfo gpiochip0 - 224 lines: line 0: unnamed unused input active-high line 1: unnamed unused input active-high line 2: unnamed unused input active-high line 3: unnamed unused input active-high line 4: unnamed unused input active-high line 5: unnamed unused input active-high line 6: unnamed unused input active-high line 7: unnamed unused input active-high line 8: unnamed unused input active-high line 9: unnamed unused input active-high line 10: unnamed unused input active-high line 11: unnamed unused input active-high line 12: unnamed unused input active-high line 13: unnamed unused input active-high line 14: unnamed unused input active-high line 15: unnamed unused input active-high line 16: unnamed unused input active-high line 17: unnamed "orangepi:red:status" output active-high [used] line 18: unnamed unused input active-high line 19: unnamed unused input active-high line 20: unnamed "vcc-wifi" output active-high [used] line 21: unnamed unused input active-high line 22: unnamed unused input active-high line 23: unnamed unused input active-high .... line 164: unnamed unused input active-high line 165: unnamed unused input active-high line 166: unnamed "cd" input active-high [used] line 167: unnamed unused input active-high line 168: unnamed unused input active-high .... line 200: unnamed unused input active-high line 201: unnamed unused input active-high line 202: unnamed "interrupt" input active-high [used] line 203: unnamed unused input active-high line 204: unnamed "usb0_id_det" input active-high [used] line 205: unnamed unused input active-high line 206: unnamed unused input active-high line 207: unnamed unused input active-high line 208: unnamed unused input active-high line 209: unnamed unused input active-high line 210: unnamed unused input active-high line 211: unnamed unused input active-high line 212: unnamed unused input active-high line 213: unnamed unused input active-high line 214: unnamed unused input active-high line 215: unnamed unused input active-high line 216: unnamed unused input active-high line 217: unnamed unused input active-high line 218: unnamed unused input active-high line 219: unnamed unused input active-high line 220: unnamed unused input active-high line 221: unnamed unused input active-high line 222: unnamed unused input active-high line 223: unnamed unused input active-high gpiochip1 - 32 lines: line 0: unnamed unused input active-high line 1: unnamed unused input active-high line 2: unnamed unused input active-high line 3: unnamed unused input active-high line 4: unnamed unused input active-high line 5: unnamed unused input active-high line 6: unnamed "?" output active-high [used] line 7: unnamed "reset" output active-low [used] line 8: unnamed unused input active-high line 9: unnamed unused input active-high line 10: unnamed "orangepi:green:pwr" output active-high [used] line 11: unnamed unused input active-high line 12: unnamed unused input active-high line 13: unnamed unused input active-high line 14: unnamed unused input active-high line 15: unnamed unused input active-high line 16: unnamed unused input active-high line 17: unnamed unused input active-high line 18: unnamed unused input active-high line 19: unnamed unused input active-high line 20: unnamed unused input active-high line 21: unnamed unused input active-high line 22: unnamed unused input active-high line 23: unnamed unused input active-high line 24: unnamed unused input active-high line 25: unnamed unused input active-high line 26: unnamed unused input active-high line 27: unnamed unused input active-high line 28: unnamed unused input active-high line 29: unnamed unused input active-high line 30: unnamed unused input active-high line 31: unnamed unused input active-high
Note: The columns are: offset name consumer, direction, active_state
Device Tree file https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts provides following infos:
status_led <&pio 0 17 GPIO_ACTIVE_HIGH> reg_vcc_wifi: reg_vcc_wifi <&pio 0 20 GPIO_ACTIVE_HIGH> reg_vdd_cpux: vdd-cpux-regulator <&r_pio 0 6 GPIO_ACTIVE_HIGH> wifi_pwrseq: wifi_pwrseq <&r_pio 0 7 GPIO_ACTIVE_LOW> pwr_led <&r_pio 0 10 GPIO_ACTIVE_HIGH>
with gpio definitions in
- https://elixir.bootlin.com/linux/v4.14.65/source/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c
- https://elixir.bootlin.com/linux/v4.14.65/source/drivers/pinctrl/sunxi/pinctrl-sun8i-h3-r.c
sudo gpioset gpiochip0 10=1 gpioset: error reading GPIO values: Device or resource busy sudo gpioset gpiochip1 17=1 gpioset: error reading GPIO values: Device or resource busy
Note: There are a couple of optional arguments (for example mode, background, ...)
- According to the schematic, Component: LED0805
- Connection to CPU:
CPU-PIN | Define | CFG | Function | CPU Ball# | GPIO-Port (sysfs Interface) |
---|---|---|---|---|---|
PA17 | STATUS-LED | 1 | LED (red) | C14 | (1 -0) * 32 + 17 = 17 |
PL10 | PWR-LED | 1 | (green) | V2 | (12 - 1) * 32 + 10 = 362 |
Note: Depending on hardware-version the pin might be different. See armbian forum.
In the past handled like Output GPIO (sysfs Interface).
Now LED are handled within Kernel and the LED controlled via triggers ("events"). https://www.kernel.org/doc/Documentation/leds/leds-class.txt
In short available LEDs:
ls -l /sys/class/leds total 0 lrwxrwxrwx 1 root root 0 Jan 1 1970 orangepi:green:pwr -> ../../devices/platform/leds/leds/orangepi:green:pwr lrwxrwxrwx 1 root root 0 Jan 1 1970 orangepi:red:status -> ../../devices/platform/leds/leds/orangepi:red:status demonstrator@orangepizero:~$
Introspect triggers :
more /sys/class/leds/orangepi\:red\:status/trigger more /sys/class/leds/orangepi\:green\:pwr/trigger
returns
[none] rc-feedback kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock usbport mmc0 disk-activity ide-disk mtd nand-disk heartbeat cpu cpu0 cpu1 cpu2 cpu3 default-on panic mmc1 rfkill-any rfkill0 phy0rx phy0tx phy0assoc phy0radio 0.1:01:100Mbps 0.1:01:10Mbps
Change trigger with:
demonstrator@orangepizero:/sys/class/leds/orangepi:green:pwr$ sudo sh -c "echo heartbeat > trigger" demonstrator@orangepizero:/sys/class/leds/orangepi:green:pwr$ cat trigger
[none] indicates direct control:
demonstrator@orangepizero:~$ cd /sys/class/leds/orangepi\:red\:status/ demonstrator@orangepizero:/sys/class/leds/orangepi:red:status$ ls brightness device max_brightness power subsystem trigger uevent demonstrator@orangepizero:/sys/class/leds/orangepi:red:status$ cat brightness 0 demonstrator@orangepizero:/sys/class/leds/orangepi:red:status$ sudo sh -c "echo 1 > brightness" demonstrator@orangepizero:/sys/class/leds/orangepi:red:status$ sudo sh -c "echo 0 > brightness" demonstrator@orangepizero:/sys/class/leds/orangepi:red:status$ demonstrator@orangepizero:/sys/class/leds$ cd ../orangepi\:green\:pwr/ demonstrator@orangepizero:/sys/class/leds/orangepi:green:pwr$ cat brightness 255
A 26-pin GPIO interface on the Orange Pi Zero is the same as Model A and Model B of Raspberry Pi. The picture below is GPIO pin define of Orange Pi Zero.
Official Layout
Pin | Function | Ball | IO | Pin | Function | Ball | IO |
---|---|---|---|---|---|---|---|
CON3-P01 | VCC-3V3 | CON3-P02 | VCC-5V | ||||
CON3-P03 | TWI0-SDA | PA12 | GPIO12 | CON3-P04 | VCC-5V | ||
CON3-P05 | TWI0-SCK | PA11 | GPIO11 | CON3-P06 | GND | ||
CON3-P07 | PWM1 | PA6 | GPIO6 | CON3-P08 | UART2_TX | PA0 | GPIO198 |
CON3-P09 | GND | CON3-P10 | UART2_RX | PA1 | GPIO199 | ||
CON3-P11 | S-TWI-SCK | PL0 | GPIO1 | CON3-P12 | PD11 | PD11 | GPIO7 |
CON3-P13 | S-TWI-SDA | PL1 | GPIO0 | CON3-P14 | GND | ||
CON3-P15 | UART2_CTS | PA3 | GPIO3 | CON3-P16 | TWI1-SDA | PA19 | GPIO19 |
CON3-P17 | VCC3V3-EXT | CON3-P18 | TWI1-SCK | PA18 | GPIO18 | ||
CON3-P19 | SPI1_MOSI | PA15 | GPIO15 | CON3-P20 | GND | ||
CON3-P21 | SPI1_MISO | PA16 | GPIO16 | CON3-P22 | UART2_RTS | PA2 | GPIO2 |
CON3-P23 | SPI1_CLK | PA14 | GPIO14 | CON3-P24 | SPI1_CS | PA13 | GPIO13 |
CON3-P25 | GND | CON3-P26 | SIM_DET | PA10 | GPIO10 |
A 13-pin GPIO interface on the Orange Pi Zero
Official Layout
Pin | Function | Ball | Comment |
---|---|---|---|
CON5-P01 | 5V | ||
CON5-P02 | GND | ||
CON5-P03 | USB-DM2 | A8 | A I/O |
CON5-P04 | USB-DP2 | A7 | A I/O |
CON5-P05 | USB-DM3 | B9 | A I/O |
CON5-P06 | USB-DP3 | B8 | A I/O |
CON5-P07 | LINEOUTR | Y4 | A O Line-OUT Right Channel Output |
CON5-P08 | LINEOUTL | AA3 | A O Line-OUT Left Channel Output |
CON5-P09 | TV-OUT | F10 | A |
CON5-P10 | MIC-BIAS | W3 | A O Bias voltage output for main microphone |
CON5-P11 | MIC1P | W2 | A I First microphone positive input |
CON5-P12 | MIC1N | Y1 | A I First microphone negative input |
CON5-P13 | IR-RX | U2 | PL11 S_CIR_RX/S_PL_EINT12 |
According to H3 Datasheet all relevant PA and PD Pins:
- Default Function = GPIO
- Default Type = I/O (Input/Output)
- Reset State = Z (high-impedance)
- Default Pull Up/Down = NO_PULL (floating; no presence of internal resistor)
- Buffer Strength (mA) = 20
PL0; PL1 pins :
- Default Function = GPIO
- Default Type = I/O (Input/Output)
- Reset State = Z (high-impedance)
- Default Pull Up/Down = Pull Up
- Buffer Strength (mA) = 20
From mainline Linux kernel perspective all unused in-circuit type interfaces should be disabled by default and all pins muxed with those interfaces should be available as standard GPIOs. More infos see https://docs.armbian.com/Hardware_Allwinner_overlays/
and the referenced :
/boot/dtb/overlay/README.sun7i-a20-overlays
Source https://github.com/armbian/sunxi-DT-overlays/tree/master/sun7i-a20
If nothing defined, then pin is disabled or GPIO.
Note: Linux is no real-time system. Without any optimization no accurate timing is possible.
Test script:
sudo gpioset --mode=time --sec=0 --usec=0 gpiochip0 12=0 sudo gpioset --mode=time --sec=0 --usec=0 gpiochip0 12=1 sudo gpioset --mode=time --sec=0 --usec=0 gpiochip0 12=0 sudo gpioset --mode=time --sec=0 --usec=0 gpiochip0 12=1 sudo gpioset --mode=time --sec=0 --usec=0 gpiochip0 12=0 sudo gpioset --mode=time --sec=0 --usec=0 gpiochip0 12=1 sudo gpioset --mode=time --sec=0 --usec=0 gpiochip0 12=0 sudo gpioset --mode=time --sec=0 --usec=0 gpiochip0 12=1
Result:
-
pin toggled between 100mV and 3.4 V every 35.8 msec
-
if --usec=12000 then the duration is approx 50 usec (38 + 12)
-
if --usec=5000 then sometimes the duration is not constant for example the first low is longer. On the osciloscope it looks like:
test code (python bindings) :
info = g.get_output_value (chip_number, line_number) for i in range (5) : info = g.set_output_value (chip_number, line_number, 1) info = g.set_output_value (chip_number, line_number, 0) time.sleep (0.001)
Result:
- no major delay
- very responsive :

- https://forum.armbian.com/topic/5956-trigger-led-on-orange-pi-zero-plus/
- https://forum.armbian.com/topic/5662-pygpio-a-more-general-python-gpio-library/
- https://forum.armbian.com/topic/5655-armbianio-api-proposal/
- https://github.com/sgjava/userspaceio
- https://github.com/vsergeev/c-periphery
sudo apt-get install libffi sudo apt-get install libffi-dev sudo apt-get install python3-dev sudo pip3 install setuptools sudo pip3 install cffi Installing collected packages: cffi Running setup.py install for cffi ... done Successfully installed cffi-1.11.5