unstable
only.Expand description
§Peripheral signal interconnect using the GPIO matrix.
The GPIO matrix offers flexible connection options between GPIO pins and peripherals. This module offers capabilities not covered by GPIO pin types and drivers, like routing fixed logic levels to peripheral inputs, or inverting input and output signals.
Note that routing a signal through the GPIO matrix adds some latency to the signal. This is not a problem for most peripherals, but it can be an issue for high-speed peripherals like SPI or I2S.
esp-hal
tries to bypass the GPIO matrix when possible (e.g. when the pin can be configured as a suitable Alternate Function for the peripheral signal, and other settings are compatible), but silently falls back to the GPIO matrix for flexibility.
§Relation to the Technical Reference Manual
The GPIO drivers implement IO MUX and pin functionality (input/output
buffers, pull resistors, etc.). The GPIO matrix is represented by signals
and the PeripheralInput
and PeripheralOutput
traits. There is some
overlap between them: signal routing depends on what type is passed to a
peripheral driver’s pin setter functions.
§Signals
GPIO signals are represented by the InputSignal
and OutputSignal
structs. Peripheral drivers accept PeripheralInput
and
PeripheralOutput
implementations which are implemented for anything that
can be converted into the signal types:
Note that some of these exist for convenience only. Level
is meaningful as
a peripheral input, but not as a peripheral output. NoPin
is a placeholder
for when a peripheral driver does not require a pin, but the API requires
one. It is equivalent to Level::Low
.
§Splitting drivers into signals
Each GPIO pin driver such as Input
, can be converted
into input or output signals. Flex
, which can be either input or output,
can be split
into both signals at once. These signals can
then be individually connected to a peripheral input or output signal. This
allows for flexible routing of signals between peripherals and GPIO pins.
Note that only configured GPIO drivers can be safely turned into signals. This conversion freezes the pin configuration, otherwise it would be possible for multiple peripheral drivers to configure the same GPIO pin at the same time, which is undefined behavior.
§Splitting pins into signals
GPIO pin types such as GPIO0
or AnyPin
can be unsafely
split into signals. In this case you need to carefully
ensure that only a single driver configures the split pin, by selectively
freezing the signals.
For example, if you want to route GPIO3 to both a Pulse Counter input and a UART RX line, you will need to make sure one of the signals is frozen, otherwise the driver that is configured later will overwrite the other driver’s configuration. Configuring the signals on multiple cores is undefined behaviour unless you ensure the configuration does not happen at the same time.
§Using pins and signals
A GPIO pin can be configured either with a GPIO driver such as Input
, or
by a peripheral driver using a pin assignment method such as
Spi::with_mosi
. The peripheral drivers’ preferences can be overridden by
passing a pin driver to the peripheral driver. When converting a driver to
signals, the underlying signals will be initially
frozen to support this use case.
§Inverting inputs and outputs
The GPIO matrix allows for inverting the input and output signals. This can
be configured via InputSignal::with_input_inverter
and
OutputSignal::with_input_inverter
. The hardware is configured
accordingly when the signal is connected to a peripheral input or output.
§Connection rules
Peripheral signals and GPIOs can be connected with the following constraints:
- A peripheral input signal must be driven by exactly one signal, which can be a GPIO input or a constant level.
- A peripheral output signal can be connected to any number of GPIOs. These
GPIOs can be configured differently. The peripheral drivers will only
support a single connection (that is, they disconnect previously
configured signals on repeat calls to the same function), but you can use
esp_hal::gpio::OutputSignal::connect_to
(note that the type is currently hidden from the documentation) to connect multiple GPIOs to the same output signal. - A GPIO input signal can be connected to any number of peripheral inputs.
- A GPIO output can be driven by only one peripheral output.
Structs§
- Input
Signal - An input signal between a peripheral and a GPIO pin.
- Output
Signal - An (input and) output signal between a peripheral and a GPIO pin.
Traits§
- Peripheral
Input - A signal that can be connected to a peripheral input.
- Peripheral
Output - A signal that can be connected to a peripheral input and/or output.
- Peripheral
Signal - The base of all peripheral signals.