<<<
: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_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)
| 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 unit provides simple uni-directional input and output port. These ports can be used
chip-externally (for example to drive status LEDs, connect buttons, etc.) or chip-internally to provide control
signals for other IP modules. The input port features programmable pin-individual level or edge interrupts
capabilities.

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 in `gpio_o` and `gpio_i` are actually connected while the remaining
bits 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).


**Input Pin 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` | -              | 31:0   | r/- | _reserved_, read as zero
| `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)`
|=======================
