Hardware GPIO - monkeymia/orangepizero GitHub Wiki

Hardware GPIO

Introduction

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

Installation

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

Default Output

gpiofind

sudo gpiodetect
gpiochip0 [1c20800.pinctrl] (224 lines)
gpiochip1 [1f02c00.pinctrl] (32 lines)
demonstrator@orangepizero:~$

gpioget

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

gpioinfo

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

gpioset

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, ...)

Light Emitting Diode (LED)

  • 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

Expansion Port CON3

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

Expansion Port CON3

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

Pin Characteristics

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

GPIO Multiplexing Function

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.

Real Life

Bash

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:

    https://github.com/monkeymia/orangepizero/wiki/gpio5000.jpg

libgpiod

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://github.com/monkeymia/orangepizero/wiki/gpiod1msec.jpg

Other pages

Foreign Function Interface for Python calling C code (CFFI)

Installation

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
⚠️ **GitHub.com Fallback** ⚠️