Module interconnect

Source
Available on crate feature 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§

InputSignal
An input signal between a peripheral and a GPIO pin.
OutputSignal
An (input and) output signal between a peripheral and a GPIO pin.

Traits§

PeripheralInput
A signal that can be connected to a peripheral input.
PeripheralOutput
A signal that can be connected to a peripheral input and/or output.
PeripheralSignal
The base of all peripheral signals.