Using the Omega’s GPIOs

The Omega2 has twelve General Purpose Input/Output pins (commonly referred to as GPIOs) that can be fully controlled by you, the user. GPIO pins on most chips generally go unused, but on the Omega we can use these GPIOs to connect to, communicate with, and control external circuits.

On the Omega, we can control GPIO pins with a command-line tool known as gpioctl. This article will go through how gpioctl works, and the ways in which you can use it.

GPIO Electrical Ratings

The Omega2’s GPIOs are not 5V input tolerant!

See the table below for the GPIOs’ operating voltages:

Parameter Minimum (V) Maximum (V)
Input HIGH 2.0 3.6
Input LOW -0.3 0.8
Output HIGH 2.4 3.3
Output LOW 0.4

Warning: Connecting a signal to an input pin below the minimum LOW or above the maximum HIGH voltages may damage your Omega!

Standard 5V logic devices typically accept 3.3V as a logical HIGH, however, they output logical HIGH in the range of 4.4V to 5V. This means that the Omega can output to a 5V logical device, but input from the 5V logic device would damage the GPIO input circuitry.

Multiplexed Pins

A number of the available pins can be used for multiple purposes other than general purpose input/output when needed. Such pins are referred to as multiplexed pins. For example, the UART pins are designated as UART, but are multiplexed so that you can designate and use them as GPIO pins when you want. This is used to incorporate the largest number of protocol support in the smallest possible package.

omega2-pinout-diagram

You can use the omega2-ctrl tool to change the function of your pins.

To get the current mode of the Omega’s multiplexed pins, use the command:

omega2-ctrl gpiomux get

and you’ll be given a list as a result:

root@Omega-2757:/# omega2-ctrl gpiomux get
Group i2c - [i2c] gpio
Group uart0 - [uart] gpio
Group uart1 - [uart] gpio
Group uart2 - [uart] gpio pwm
Group pwm0 - [pwm] gpio
Group pwm1 - [pwm] gpio
Group refclk - refclk [gpio]
Group spi_s - spi_s [gpio]
Group spi_cs1 - [spi_cs1] gpio refclk
Group i2s - i2s [gpio] pcm
Group ephy - [ephy] gpio
Group wled - wled [gpio]

The current mode for each group is indicated with the [].

Let’s examine the UART1 line:

Group uart1 - [uart] gpio

Here we see the group is uart1, and the available modes are [uart] gpio, with the current mode being [uart].

Changing the Pin Function

To set a particular group of hardware pins to a specified mode, use the following command:

To illustrate the above, the following command will set UART1 pins to operate in GPIO mode:

omega2-ctrl gpiomux set uart1 gpio

and running the get command from above to confirm our changes:

root@Omega-2757:/# omega2-ctrl gpiomux get
Group i2c - [i2c] gpio
Group uart0 - [uart] gpio
Group uart1 - uart [gpio]
Group uart2 - [uart] gpio pwm
Group pwm0 - [pwm] gpio
Group pwm1 - [pwm] gpio
Group refclk - refclk [gpio]
Group spi_s - spi_s [gpio]
Group spi_cs1 - [spi_cs1] gpio refclk
Group i2s - i2s [gpio] pcm
Group ephy - [ephy] gpio
Group wled - wled [gpio]

We see:

Group uart1 - uart [gpio]

indicating that our change has indeed been applied.

Important & Special Pins

A few important notes on the Omega’s GPIOs, specifically:

Pins Important for Booting the Omega

There is a number of pins that affect the Omega’s Boot Sequence and require special attention. The pins fall into two categories:

  1. Pins that must be floating at boot time. They cannot be pulled up or pulled down, or else the Omega cannot boot
  2. Pins that must be floating or pulled down at boot time. They cannot be pulled up, or else the Omega cannot boot
GPIO Description Boot Time
GPIO1 GPIO / I2S SDO Must be floating or pulled down
GPIO6 SPI CS1/ GPIO Must be floating
GPIO7 SPI CLK Must be floating
GPIO8 SPI MOSI Must be floating
GPIO12 UART TX0 Must be floating or pulled down
GPIO45 UART TX1 / GPIO Must be floating
GPIO36 GPIO / PERST_N (Omega2S Only) Must be floating

Once the Omega has booted, these pins can be used normally.

SPI Pins & Onboard Flash Storage

The Omega’s processor communicates with the on-board flash storage using the SPI protocol. It’s configured as Chip Select 0 on the Omega’s SPI bus. Since there are two SPI Chip Select signals it’s possible to connect an additional SPI device to the Omega using Chip Select 1. As such, the SPI communication pins - CLK, MOSI, and MISO - are exposed on the Omega’s Expansion header as GPIOs 7, 8, and 9.

Since the Omega’s storage uses SPI, the SPI communication pins - GPIOs 7, 8, and 9 - must be used for the SPI protocol and cannot be used as regular GPIOs. If you wish to use these GPIOs, they are reserved for use only with SPI devices. These SPI devices will be use Chip Select 1 - GPIO6 - as their Chip Select signal on the Omega’s SPI bus.

To reiterate:

  • GPIOs 7, 8, and 9 cannot be used as regular GPIOs - they must be used for the SPI bus
  • Connecting non-SPI circuitry to these pins may prevent your Omega from booting or cause other damage to your unit.
  • The SPI CS1 pin, GPIO 6, may be used to control an additional external SPI device
  • The SPI CS1 pin, GPIO 6, may be still used as a regular GPIO when configured as a GPIO using omega2-ctrl.

LED & Reset GPIOs

The Omega’s hardware design uses dedicated GPIOs to control the Omega’s LED and accept an incoming Reset signals:

GPIO Function Exposed on Omega’s Headers? Omega2S Pin Number
GPIO38 FW_RST Active-High Yes 4
- HW_RST Active-Low Yes 5
GPIO44 Omega LED No 19

Pin Behaviour during Boot

Most of the Omega’s pins will remain at the default digital low state during the boot process. However, there are a few pins that will behave differently:

GPIO Omega2S Pin Number Behavior
GPIO11 38 Will settle at Digital High - Used to provide power for reset button on Omega2 Docks
GPIO14 to GPIO21 45 - 51 Will fluctuate around 2.5V during boot. Will settle at digital low when boot is complete. Stable at Power-on-Reset value during boot. (Previous issue resolved in 2019-10-17 release of omega2-bootloader)

The behavior of these pins during boot is goverened by the Omega’s bootloader.

The Omega2 Bootloader is open source and can be found on GitHub: https://github.com/OnionIoT/omega2-bootloader

From the Command Line

The command-line tool gpioctl comes pre-installed on your Omega. gpioctl is based on setting file values inside the /sys/class/gpio directory. This is made possible with sysfs, a pseudo-file system that holds information about the Omega’s hardware in files, and lets the user control the hardware by editing the files.

The tool abstracts a lot of the more detailed commands from the user and simplifies them into easy-to-run commands that can control the GPIOs.

Using gpioctl

There are 7 options associated with gpioctl. The syntax of the command is as follows:

gpioctl <OPTION> <GPIO NUMBER>

Here are some examples on how you can use gpioctl to interact with the Omega’s GPIOs.

Reading an Input

If you want your Omega to interface with a switch or button then you’ll need to use a GPIO to read the input of the switch.

To read an input of a GPIO we’ll need to first set the direction to input, connect an external circuit, and then read the value.

To set the direction of GPIO1 to input, enter the follow command:

root@Omega-2757:/# gpioctl dirin 1
Using gpio pin 1.

Now you’re ready to read from an external circuit!

Note: You will damage your Omega if your GPIO is set to output and you try to drive external current to the pin.

Let’s try reading GPIO1 with get:

root@Omega-2757:/# gpioctl get 1
Using gpio pin 1.
Pin 1 is LOW

Here we see that the GPIO pin is reading a digital LOW or 0.

Setting a Value

You can configure your GPIO pin to supply power to a load with your Omega, for example, if you were powering an LED.

We first set a GPIO pin’s direction via the dirout command:

root@Omega-2757:/# gpioctl dirout 1
Using gpio pin 1.

We then use the dirout-high option, which sets the GPIO to HIGH or 1:

root@Omega-2757:/# gpioctl dirout-high 1
Using gpio pin 1.
root@Omega-2757:/# gpioctl get 1
Using gpio pin 1.
Pin 1 is HIGH

Or we use the dirout-low option, which sets the value of the GPIO to LOW or 0:

root@Omega-2757:/# gpioctl dirout-low 1
Using gpio pin 1.
root@Omega-2757:/# gpioctl get 1
Using gpio pin 1.
Pin 1 is LOW

You can use the gpioctl get <PIN> command to read a pin regardless of its direction.

Fast-GPIO

The fast-gpio command is similar to gpioctl in that it is used to control the Omega’s GPIOs. The difference is that while gpioctl worked by setting file values inside the /sys/class/gpio directory, fast-gpio works by setting GPIO registers directly on the processor and is inherently a faster process.

Command Usage:

For a print-out of the usage, run fast-gpio on the command line:

root@Omega-2757:/# fast-gpio
Usage:
 fast-gpio set-input <gpio>
 fast-gpio set-output <gpio>
 fast-gpio get-direction <gpio>
 fast-gpio read <gpio>
 fast-gpio set <gpio> <value: 0 or 1>
 fast-gpio pwm <gpio> <freq in Hz> <duty cycle percentage>

Setting a GPIO pin’s direction:

A pin can be configured to either be input or output.

To avoid damaging your Omega, set a pin to the input direction before driving any voltage to it!!

Reading a GPIO pin’s direction:

It may be handy to check a pin’s programmed direction before doing anything with it. The command to check a GPIO looks like the following:

For example, if GPIO 14 is set to output and 13 to input:

fast-gpio get-direction 14
> Get direction GPIO14: output
fast-gpio get-direction 13
> Get direction GPIO13: input

Reading a GPIO pin’s value:

You can read a pin’s value whether it’s in input or output mode.

fast-gpio read <gpio pin>

For example, to read pin 14:

root@Omega-2757:/# fast-gpio read 14
> Read GPIO14: 0

Setting a GPIO pin’s value:

This will drive the selected pin to the value desired.

fast-gpio set <gpio pin number> <value to set; 0 or 1>

If the pin is not in output mode, fast-gpio will silently change it to output before setting the value.

Generating a PWM signal on a GPIO:

Generate a software-based Pulse Width Modulated (PWM) signal on a selected pin. Specify the desired duty cycle and frequency of the PWM signal.

fast-gpio pwm <gpio> <freq in Hz> <duty cycle percentage>

This will launch a background process that will generate the PWM signal.

Software-based PWM is implemented by a program that usually waits for a defined amount of time before toggling the GPIO output. This has the potential to be inaccurate since the CPU might be interrupted with other processes and tasks. Software PWM is generally good enough for dimming an LED but not for something requiring more accuracy, such as driving a servo.

To stop the PWM signal, set the GPIO’s value:

fast-gpio set <gpio> 0