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, or a tuple {GPIO_BANK, PIN} for stm32 chips.
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 onTrigger
: 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
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/0Pin
: 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 configureDirection
: 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 onTrigger
: 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 onTrigger
: is the state that will trigger an interruptPid
: 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
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 modeDirection
: 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 directionPull
: 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.