<<<
:sectnums:
==== General Purpose Input and Output Port (GPIO)

[cols="<3,<3,<4"]
[grid="none"]
|=======================
| Hardware source files:  | neorv32_gpio.vhd   |
| Software driver files:  | neorv32_gpio.c     | link:https://stnolting.github.io/neorv32/sw/neorv32__gpio_8c.html[Online software reference (Doxygen)]
|                         | neorv32_gpio.h     | link:https://stnolting.github.io/neorv32/sw/neorv32__gpio_8h.html[Online software reference (Doxygen)]
| Top entity ports:       | `gpio_dir_o`       | 32-bit direction control output port
|                         | `gpio_o`           | 32-bit parallel output port
|                         | `gpio_i`           | 32-bit parallel input port
| Configuration generics: | `IO_GPIO_NUM`      | number of input/output pairs to implement (0..32)
|                         | `IO_GPIO_DIR_EN`   | enable direction control feature when _true_
| CPU interrupts:         | fast IRQ channel 8 | input-pin change interrupt (see <<_processor_interrupts>>)
|=======================

**Key Features**

* Up to 32 inputs and 32 outputs
* Each input pin is interrupt-capable
* Configurable interrupt triggers (positive/negative level or edge)


**Overview**

The general purpose IO module provides simple unidirectional - or optionally bidirectional - inputs and outputs.
These connections can be used externally (for example, to control status LEDs, connect buttons, etc.) or internally
to provide control signals for other IP modules. The input port features programmable, pin-specific level- or
edge-triggered interrupts.

Data written to the `PORT_OUT` will appear on the processor's `gpio_o` port. Vice versa, the `PORT_IN` register
represents the current state of the processor's `gpio_i`.

The actual number of input/output pairs is defined by the `IO_GPIO_NUM` generic. When set to zero, the GPIO module
is excluded from synthesis and the output port `gpio_o` is tied to all-zero. If `IO_GPIO_NUM` is less than the
maximum value of 32, only the LSB-aligned bits of `gpio_o` and `gpio_i` are actually connected while the remaining
ones are tied to zero or are left unconnected, respectively. This also applies to all memory-mapped interface
registers of the GPIO module (i.e. the according most-significant bits are hardwired to zero and are read-only).


**Direction Control**

The IO ports can also be used as bidirectional ports. The direction feature must be explicitly enabled via the
`IO_GPIO_DIR_EN` generic. When enabled, the `PORT_DIR` register is used to control the direction of each individual
IO signal by directly driving the top's `gpio_dir_o` port. Setting bit _i_ to `1` configures the according pin as
output. Clearing bit _i_ configures the according pin as input. Note that the `PORT_DIR` register resets to all-zero
configuring all bi-directional IOs as inputs.

.GPIO Tristate Driver Wiring
----
gpio_dir_o[i] -------+    0 = input (default)
                     |    1 = output
                   |\|
                   | \
gpio_o[i] -------->|  >---+---<> GPIO pin [i]
                   | /    |
                   |/     |
                          |
gpio_i[i] <---------------+
----

.GPIO VHDL Tristate Driver Example (external `gpio_io` port is of type `std_logic_vector`)
[source,VHDL]
----
gpio_tristate_gen:
for i in 0 to IO_GPIO_NUM-1 generate
  gpio_io(i) <= std_logic(gpio_o(i)) when (gpio_dir_o(i) = '1') else 'Z'; -- drive
end generate;

gpio_i(IO_GPIO_NUM-1 downto 0) <= std_ulogic_vector(gpio_io(IO_GPIO_NUM-1 downto 0)); -- sense
----

.`GPIO_DIR` As Additional Output Port
[TIP]
If the bi-directional feature is not required, the `gpio_dir_o` port can be used as additional output port.


**Interrupts**

Each input pin (`gpio_i`) provides an individual programmable interrupt trigger. The actual interrupt trigger
type can be configured individually for each input pin using the `IRQ_TYPE` and `IRQ_POLARITY` registers.
`IRQ_TYPE` defines the actual trigger type (level-triggered or edge-triggered), while `IRQ_POLARITY` defines
the trigger's polarity (low-level/falling-edge or high-level/rising-edge). The position of each bit in these
registers corresponds the according `gpio_i` input pin.

Each pin interrupt channel can be enabled or disabled individually using the `IRQ_ENABLE` register. Each bit
in this register corresponds to the according input pin. If the programmed trigger of a disabled input
(`IRQ_ENABLE(i) = 0`) fires, the interrupt request is entirely ignored.

.GPIO Trigger Configuration for Pin _i_
[cols="^2,^2,^2,<4"]
[options="header",grid="all"]
|=======================
| `IRQ_ENABLE(i)` | `IRQ_TYPE(i)` | `IRQ_POLARITY(i)` | Resulting trigger of `gpio_i(i)`
| `1`             | `0`           | `0`               | low-level (`GPIO_TRIG_LEVEL_LOW`)
| `1`             | `0`           | `1`               | high-level (`GPIO_TRIG_LEVEL_HIGH`)
| `1`             | `1`           | `0`               | falling-edge (`GPIO_TRIG_EDGE_FALLING`)
| `1`             | `1`           | `1`               | rising-edge (`GPIO_TRIG_EDGE_RISING`)
| `0`             | `-`           | `-`               | interrupt disabled
|=======================

If the configured trigger of an enabled input pin (`IRQ_ENABLE(i) = 1`) fires, the according interrupt request
is buffered internally in the `IRQ_PENDING` register. When this register contains a non-zero value (i.e. any
bit becomes set) an interrupt request is sent to the CPU via FIRQ channel 8 (see <<_processor_interrupts>>).

The CPU can determine the interrupt-triggering pins by reading the `IRQ_PENDING` register. Each set bit in this
register indicates that the according input pin's interrupt trigger has fired. Then, the CPU can clear those
pending interrupt pin by setting all set bits to zero.

.GPIO Interrupts Demo Program
[TIP]
A demo program for the GPIO input interrupts can be found in `sw/example/demo_gpio`.


**Register Map**

.GPIO unit register map (`struct NEORV32_GPIO`)
[cols="<2,<2,^1,^1,<6"]
[options="header",grid="rows"]
|=======================
| Address      | Name [C]       | Bit(s) | R/W | Function
| `0xfffc0000` | `PORT_IN`      | 31:0   | r/- | Parallel input port; `PORT_IN(i)` corresponds to `gpio_i(i)`
| `0xfffc0004` | `PORT_OUT`     | 31:0   | r/w | Parallel output port; `PORT_OUT(i)` corresponds to `gpio_o(i)`
| `0xfffc0008` | `PORT_DIR`     | 31:0   | r/w | Port direction; `PORT_DIR(i)` corresponds to `gpio_o(i)`; `0` = input (default), `1` = output; this register is hardwired to all-zero if `IO_GPIO_DIR_EN = false`
| `0xfffc000c` | -              | 31:0   | r/- | _reserved_, read as zero
| `0xfffc0010` | `IRQ_TYPE`     | 31:0   | r/w | Trigger type select (`0` = level trigger, `1` = edge trigger); `IRQ_TYPE(i)` corresponds to `gpio_i(i)`
| `0xfffc0014` | `IRQ_POLARITY` | 31:0   | r/w | Trigger polarity select (`0` = low-level/falling-edge, `1` = high-level/rising-edge); `IRQ_POLARITY(i)` corresponds to `gpio_i(i)`
| `0xfffc0018` | `IRQ_ENABLE`   | 31:0   | r/w | Per-pin interrupt enable; `IRQ_ENABLE(i)` corresponds to `gpio_i(i)`
| `0xfffc001c` | `IRQ_PENDING`  | 31:0   | r/c | Per-pin interrupt pending, can be cleared by writing zero to the according bit(s); `IRQ_PENDING(i)` corresponds to `gpio_i(i)`
|=======================
