Module gpio

GPIO driver module.

Description

This module provides functions for interacting with micro-controller GPIO (General Purpose Input and Output) pins.

Note: -type pin() used in this driver refers to a pin number on Espressif chips and normal Raspberry Pi Pico pins, or a tuple {GPIO_BANK, PIN} for STM32 chips and the “extra” GPIOs available on the Pico-W.

Data Types

direction()


direction() = input | output | output_od | mode_config()

The direction is used to set the mode of operation for a GPIO pin, either as an input, an output, or output with open drain. On the STM32 platform pull mode and output_speed must be set at the same time as direction. See @type mode_config()

gpio()


gpio() = pid()

This is the pid returned by gpio:start/0.

gpio_bank()


gpio_bank() = a | b | c | d | e | f | g | h | i | j | k | wl

STM32 gpio banks vary by board, some only break out a thru h. The extra “WL” pins on Pico-W use bank wl.

high_level()


high_level() = high | 1

level()


level() = low_level() | high_level()

Valid pin levels can be atom or binary representation.

low_level()


low_level() = low | 0

mode_config()


mode_config() = {direction(), pull()} | {output, pull(), output_speed()}

Extended mode configuration options on STM32. Default pull() is floating, default output_speed() is mhz_2 if options are omitted.

output_speed()


output_speed() = mhz_2 | mhz_25 | mhz_50 | mhz_100

Output clock speed. Only available on STM32, default is mhz_2.

pin()


pin() = non_neg_integer() | pin_tuple()

The pin definition for ESP32 and PR2040 is a non-negative integer. A tuple is used on the STM32 platform and for the extra “WL” pins on the Pico-W.

pin_tuple()


pin_tuple() = {gpio_bank(), 0..15}

A pin parameter on STM32 is a tuple consisting of a GPIO bank and pin number, also used on the Pico-W for the extra “WL” pins 0..2.

pull()


pull() = up | down | up_down | floating

Internal resistor pull mode. STM32 does not support up_down.

trigger()


trigger() = none | rising | falling | both | low | high

Event type that will trigger a gpio_interrupt. STM32 only supports rising, falling, or both.

Function Index

attach_interrupt/2 Convenience function for gpio:set_int/3
close/1 Stop the GPIO interrupt port.
deep_sleep_hold_dis/0 Disable all gpio pad functions during Deep-sleep.
deep_sleep_hold_en/0 Enable all hold functions to continue in deep sleep.
deinit/1 Reset a pin back to the NULL function.
detach_interrupt/1 Convenience function for gpio:remove_int/2
digital_read/1 Read the digital state of a GPIO pin.
digital_write/2 Set GPIO digital output level.
hold_dis/1 Release a pin from a hold state.
hold_en/1 Hold the state of a pin.
init/1 Initialize a pin to be used as GPIO.
open/0 Start the GPIO driver port.
read/2 Read the digital state of a GPIO pin.
remove_int/2 Remove a GPIO interrupt.
set_direction/3 Set the operational mode of a pin.
set_int/3 Set a GPIO interrupt.
set_int/4 Set a GPIO interrupt.
set_level/3 Set GPIO digital output level.
set_pin_mode/2 Set the operational mode of a pin.
set_pin_pull/2 Set the internal resistor of a pin.
start/0 Start the GPIO driver port.
stop/0 Stop the GPIO interrupt port.

Function Details

attach_interrupt/2


attach_interrupt(Pin::pin(), Trigger::trigger()) -> ok | {error, Reason::atom()} | error

Pin: number of the pin to set the interrupt on
Trigger: is the state that will trigger an interrupt

returns: ok | error | {error, Reason}

Convenience function for gpio:set_int/3

This is a convenience function for gpio:set_int/3 that allows an interrupt to be set using only the pin number and trigger as arguments.

This function should only be used when only one gpio trigger is used in an application. If multiple pins are being configured with interrupt triggers gpio:set_int/3 should be used otherwise there is a race condition when start() is called internally by this function.

The rp2040 (Pico) port does not support gpio interrupts at this time.

close/1


close(GPIO::gpio()) -> ok | {error, Reason::atom()} | error

GPIO: pid that was returned from gpio:start/0

returns: ok | error | {error, Reason}

Stop the GPIO interrupt port

This function disables any interrupts that are set, stops the listening port, and frees all of its resources.

Not currently available on rp2040 (Pico) port, use nif functions.

deep_sleep_hold_dis/0


deep_sleep_hold_dis() -> ok

returns: ok

Disable all gpio pad functions during Deep-sleep.

This function is only supported on ESP32.

deep_sleep_hold_en/0


deep_sleep_hold_en() -> ok

returns: ok

Enable all hold functions to continue in deep sleep.

The gpio pad hold function works in both input and output modes, but must be output-capable gpios.

When the chip is in Deep-sleep mode, all digital gpio will hold the state before sleep, and when the chip is woken up, the status of digital gpio will not be held. Note that the pad hold feature only works when the chip is in Deep-sleep mode, when not in sleep mode, the digital gpio state can be changed even you have called this function.

Power down or call gpio_hold_dis will disable this function, otherwise, the digital gpio hold feature works as long as the chip enters Deep-sleep.

This function is only supported on ESP32.

deinit/1


deinit(Pin::pin()) -> ok

Pin: number to deinitialize

returns: ok

Reset a pin back to the NULL function. Currently only implemented for RP2040 (Pico).

detach_interrupt/1


detach_interrupt(Pin::pin()) -> ok | {error, Reason::atom()} | error

Pin: number of the pin to remove the interrupt

returns: ok | error | {error, Reason}

Convenience function for gpio:remove_int/2

This is a convenience function for gpio:remove_int/2 that allows an interrupt to be removed using only the pin number as an argument.

Unlike gpio:attach_interrupt/2 this function can be safely used regardless of the number of interrupt pins used in the application.

The rp2040 (Pico) port does not support gpio interrupts at this time.

digital_read/1


digital_read(Pin::pin()) -> high | low | {error, Reason::atom()} | error

Pin: number of the pin to read

returns: high | low | error | {error, Reason}

Read the digital state of a GPIO pin

Read if an input pin state is high or low. Warning: if the pin was not previously configured as an input using gpio:set_pin_mode/2 it will always read as low.

The VBUS detect pin on the Pico-W can be read on the extended pin {wl, 2}, and does not require or accept set_pin_mode or set_pin_pull before use.

digital_write/2


digital_write(Pin::pin(), Level::level()) -> ok | {error, Reason::atom()} | error

Pin: number of the pin to write
Level: the desired output level to set

returns: ok | error | {error, Reason}

Set GPIO digital output level

Set a pin to high (1) or low (0).

The STM32 is capable of setting the state for any, or all of the output pins on a single bank at the same time, this is done by passing a list of pins numbers in the pin tuple. For example, setting all of the even numbered pins to a high state, and all of the odd numbered pins to a low state can be accomplished in two lines:

     gpio:digital_write({c, [0,2,4,6,8,10,12,14]}, high}),
     gpio:digital_write({c, [1,3,5,7,9,11,13,15]}, low}).

To set the same state for all of the pins that have been previously configured as outputs on a specific bank the atom all may be used, this will have no effect on any pins on the same bank that have been configured as inputs, so it is safe to use with mixed direction modes on a bank.

The LED pin on the Pico-W can be controlled on the extended pin {wl, 0}, and does not require or accept set_pin_mode or set_pin_pull before use.

hold_dis/1


hold_dis(Pin::pin()) -> ok | error

Pin: number of the pin to be released

returns: ok | error

Release a pin from a hold state.

When the chip is woken up from Deep-sleep, the gpio will be set to the default mode, so, the gpio will output the default level if this function is called. If you don’t want the level changes, the gpio should be configured to a known state before this function is called. e.g. If you hold gpio18 high during Deep-sleep, after the chip is woken up and gpio:hold_dis is called, gpio18 will output low level(because gpio18 is input mode by default). If you don’t want this behavior, you should configure gpio18 as output mode and set it to hight level before calling gpio:hold_dis.

This function is only supported on ESP32.

hold_en/1


hold_en(Pin::pin()) -> ok | error

Pin: number of the pin to be held

returns: ok | error

Hold the state of a pin

The gpio pad hold function works in both input and output modes, but must be output-capable gpios.

If pad hold enabled: In output mode: the output level of the pad will be force locked and can not be changed. In input mode: the input value read will not change, regardless the changes of input signal.

The state of digital gpio cannot be held during Deep-sleep, and it will resume the hold function when the chip wakes up from Deep-sleep. If the digital gpio also needs to be held during Deep-sleep gpio:deep_sleep_hold_en should also be called.

This function is only supported on ESP32.

init/1


init(Pin::pin()) -> ok

Pin: number to initialize

returns: ok

Initialize a pin to be used as GPIO. Currently only implemented (and required) for RP2040 (Pico).

open/0


open() -> gpio() | {error, Reason::atom()} | error

returns: Pid | error | {error, Reason}

Start the GPIO driver port

The GPIO port driver will be stared and registered as gpio. If the port has already been started through the gpio:open/0 or gpio:start/0 the command will fail. The use of gpio:open/0 or gpio:start/0 is required before using any functions that require a GPIO pid as a parameter.

Not currently available on rp2040 (Pico) port, use nif functions.

read/2


read(GPIO::gpio(), Pin::pin()) -> high | low | {error, Reason::atom()} | error

GPIO: pid that was returned from gpio:start/0
Pin: number of the pin to read

returns: high | low | error | {error, Reason}

Read the digital state of a GPIO pin

Read if an input pin state is high or low. Warning: if the pin was not previously configured as an input using gpio:set_direction/3 it will always read as low.

Not supported on rp2040 (Pico), use gpio:digital_read/1 instead.

remove_int/2


remove_int(GPIO::gpio(), Pin::pin()) -> ok | {error, Reason::atom()} | error

GPIO: pid that was returned from gpio:start/0
Pin: number of the pin to remove the interrupt

returns: ok | error | {error, Reason}

Remove a GPIO interrupt

Removes an interrupt from the specified pin.

The rp2040 (Pico) port does not support gpio interrupts at this time.

set_direction/3


set_direction(GPIO::gpio(), Pin::pin(), Direction::direction()) -> ok | {error, Reason::atom()} | error

GPIO: pid that was returned from gpio:start/0
Pin: number of the pin to configure
Direction: is input, output, or output_od

returns: ok | error | {error, Reason}

Set the operational mode of a pin

Pins can be used for input, output, or output with open drain.

The STM32 platform has extended direction mode configuration options. See @type mode_config() for details. All configuration must be set using set_direction/3, including pull() mode, unlike the ESP32 which has a separate function (set_pin_pull/2). If you are configuring multiple pins on the same GPIO bank with the same options the pins may be configured all at the same time by giving a list of pin numbers in the pin tuple.

Example to configure all of the leds on a Nucleo board:

     gpio:set_direction({b, [0,7,14], output)

Not supported on rp2040 (Pico), use gpio:set_pin_mode/2 instead.

set_int/3


set_int(GPIO::gpio(), Pin::pin(), Trigger::trigger()) -> ok | {error, Reason::atom()} | error

GPIO: pid that was returned from gpio:start/0
Pin: number of the pin to set the interrupt on
Trigger: is the state that will trigger an interrupt

returns: ok | error | {error, Reason}

Set a GPIO interrupt

Available triggers are none (which is the same as disabling an interrupt), rising, falling, both (rising or falling), low, and high. When the interrupt is triggered it will send a tuple: {gpio_interrupt, Pin} to the process that set the interrupt. Pin will be the number of the pin that triggered the interrupt.

The STM32 port only supports rising, falling, or both.

The rp2040 (Pico) port does not support gpio interrupts at this time.

set_int/4


set_int(GPIO::gpio(), Pin::pin(), Trigger::trigger(), Pid::pid()) -> ok | {error, Reason::atom()} | error

GPIO: pid that was returned from gpio:start/0
Pin: number of the pin to set the interrupt on
Trigger: is the state that will trigger an interrupt
Pid: is the process that will receive the interrupt message

returns: ok | error | {error, Reason}

Set a GPIO interrupt

Available triggers are none (which is the same as disabling an interrupt), rising, falling, both (rising or falling), low, and high. When the interrupt is triggered it will send a tuple: {gpio_interrupt, Pin} to the process that set the interrupt. Pin will be the number of the pin that triggered the interrupt.

The STM32 port only supports rising, falling, or both.

The rp2040 (Pico) port does not support gpio interrupts at this time.

set_level/3


set_level(GPIO::gpio(), Pin::pin(), Level::level()) -> ok | {error, Reason::atom()} | error

GPIO: pid that was returned from gpio:start/0
Pin: number of the pin to write
Level: the desired output level to set

returns: ok | error | {error, Reason}

Set GPIO digital output level

Set a pin to high (1) or low (0).

The STM32 is capable of setting the state for any, or all of the output pins on a single bank at the same time, this is done by passing a list of pins numbers in the pin tuple.

For example, setting all of the even numbered pins to a high state, and all of the odd numbered pins to a low state can be accomplished in two lines:

     gpio:digital_write({c, [0,2,4,6,8,10,12,14]}, high}),
     gpio:digital_write({c, [1,3,5,7,9,11,13,15]}, low}).

To set the same state for all of the pins that have been previously configured as outputs on a specific bank the atom all may be used, this will have no effect on any pins on the same bank that have been configured as inputs, so it is safe to use with mixed direction modes on a bank.

Not supported on rp2040 (Pico), use gpio:digital_write/2 instead.

set_pin_mode/2


set_pin_mode(Pin::pin(), Direction::direction()) -> ok | {error, Reason::atom()} | error

Pin: number to set operational mode
Direction: is input, output, or output_od

returns: ok | error | {error, Reason}

Set the operational mode of a pin

Pins can be used for input, output, or output with open drain.

The STM32 platform has extended direction mode configuration options. See @type mode_config() for details. All configuration must be set using set_direction/3, including pull() mode, unlike the ESP32 which has a separate function (set_pin_pull/2). If you are configuring multiple pins on the same GPIO bank with the same options the pins may be configured all at the same time by giving a list of pin numbers in the pin tuple. Example to configure all of the leds on a Nucleo board:

     gpio:set_direction({b, [0,7,14], output)

set_pin_pull/2


set_pin_pull(Pin::pin(), Pull::pull()) -> ok | error

Pin: number to set internal resistor direction
Pull: is the internal resistor state

returns: ok | error

Set the internal resistor of a pin

Pins can be internally pulled up, down, up_down (pulled in both directions), or left floating.

This function is not supported on STM32, the internal resistor must be configured when setting the direction mode, see set_direction/3 or set_pin_mode/2.

start/0


start() -> gpio() | {error, Reason::atom()} | error

returns: Pid | error | {error, Reason}

Start the GPIO driver port

Returns the pid of the active GPIO port driver, otherwise the GPIO port driver will be stared and registered as gpio. The use of gpio:open/0 or gpio:start/0 is required before using any functions that require a GPIO pid as a parameter.

Not currently available on rp2040 (Pico) port, use nif functions.

stop/0


stop() -> ok | {error, Reason::atom()} | error

returns: ok | error | {error, Reason}

Stop the GPIO interrupt port

This function disables any interrupts that are set, stops the listening port, and frees all of its resources.

Not currently available on rp2040 (Pico) port, use nif functions.