<<<
:sectnums:
==== Primary Universal Asynchronous Receiver and Transmitter (UART0)

[cols="<3,<3,<4"]
[grid="none"]
|=======================
| Hardware source files:  | neorv32_uart.vhd   |
| Software driver files:  | neorv32_uart.c     | link:https://stnolting.github.io/neorv32/sw/neorv32__uart_8c.html[Online software reference (Doxygen)]
|                         | neorv32_uart.h     | link:https://stnolting.github.io/neorv32/sw/neorv32__uart_8h.html[Online software reference (Doxygen)]
| Top entity ports:       | `uart0_txd_o`      | serial transmitter output
|                         | `uart0_rxd_i`      | serial receiver input
|                         | `uart0_rtsn_o`     | flow control: RX ready to receive, low-active
|                         | `uart0_ctsn_i`     | flow control: RX ready to receive, low-active
| Configuration generics: | `IO_UART0_EN`      | implement UART0 when `true`
|                         | `UART0_RX_FIFO`    | RX FIFO depth (power of 2, min 1)
|                         | `UART0_TX_FIFO`    | TX FIFO depth (power of 2, min 1)
| CPU interrupts:         | fast IRQ channel 2 | Programmable FIFO status interrupt (see <<_processor_interrupts>>)
|=======================

**Key Features**

* Independent RX and TX lines
* Fixed format: 8 data bits, 1 stop bit, no parity bit
* Programmable baud rate
* Optional RX and TX FIFO buffers
* Optional support for hardware flow-control
* Interrupt based on FIFO buffer status


**Overview**

The NEORV32 UART provides a a standard universal asynchronous serial interface with independent transmitter and
receiver channels, each equipped with a configurable FIFO. The transmission frame is fixed to **8-N-1**: 8 data bits,
no parity bit, 1 stop bit. The actual transmission baud rate is programmable via software.

.Standard Console
[NOTE]
All default example programs and software libraries of the NEORV32 software framework (including the bootloader
and the runtime environment) use the primary UART (UART0) as default user console interface. Furthermore, UART0
is used to implement the standard consoles `STDIN`, `STDOUT` and `STDERR`.


**Theory of Operation**

The module is enabled by setting the `UART_CTRL_EN` bit in the control register `CTRL`. A new TX transmission is
started by writing to the `DATA` register. RX data is available via the `DATA` register. The baud rate is configured
via a 10-bit `UART_CTRL_BAUDx` baud divisor (`baud_div`) and a 3-bit `UART_CTRL_PRSCx` clock prescaler select
(`clock_prescaler`).

.UART0 Clock Configuration
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
[options="header",grid="rows"]
|=======================
| **`UART_CTRL_PRSC[2:0]`**   | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
| Resulting `clock_prescaler` |       2 |       4 |       8 |      64 |     128 |    1024 |    2048 |    4096
|=======================

****
_**Baud rate**_ = (_f~main~[Hz]_ / `clock_prescaler`) / (`baud_div` + 1)
****


**RX and TX FIFOs**

The UART provides individual data FIFOs for RX and TX to allow data transmission without CPU intervention. The sizes
of these FIFOs can be configured via the according configuration generics (`UART0_RX_FIFO` and `UART0_TX_FIFO`). Write
to `DATA` and reads from `DATA` are automatically buffered by the according FIFO. Both FIFOs are automatically cleared
when disabling the module via the `UART_CTRL_EN` flag. The control register's `UART_CTRL_RX_*` and `UART_CTRL_TX_*`
flags provide information about the RX and TX
FIFO fill level.

.RX/TX FIFO Size
[TIP]
Software can retrieve the configured sizes of the RX and TX FIFO via the according `UART_DATA_RX_FIFO` and
`UART_DATA_TX_FIFO` bits from the `DATA` register.


**UART Interrupt**

The UART module provides a single interrupt line that can be used to signal certain RX/TX data FIFO conditions. The
interrupt conditions are based on the RX/TX FIFO status flags (`UART_CTRL_RX_*` / `UART_CTRL_TX_*`) and are configured
via the according `UART_CTRL_IRQ_RX_*` / `UART_CTRL_IRQ_TX_*` bits. The UART interrupt will fire when the module is
enabled (`SLINK_CTRL_EN`) and **any** of the enabled interrupt conditions is met. Hence, all enabled interrupt
conditions are logically OR-ed. The interrupt remains active until all interrupt-causing conditions are resolved.


**RTS/CTS Hardware Flow Control**

The NEORV32 UART supports optional hardware flow control using the standard CTS `uart0_ctsn_i` ("clear to send") and
RTS `uart0_rtsn_o` ("ready to send" / "ready to receive (RTR)") signals. Both signals are low-active. Hardware flow
control is enabled by setting the `UART_CTRL_HWFC_EN` bit in the modules control register `CTRL`.

When hardware flow control is enabled:

* The UART's transmitter will not start a new transmission until the `uart0_ctsn_i` signal goes low. During this time
the UART busy flag `UART_CTRL_TX_BUSY` remains set.
* The UART will set `uart0_rtsn_o` signal low if the RX FIFO is not already full. `uart0_rtsn_o` is always low if
hardware flow-control is disabled. Disabling the UART (setting `UART_CTRL_EN` low) while having hardware flow-control
enabled, will set `uart0_rtsn_o` high to indicate that the UART is not capable of receiving data.


**Simulation Mode**

The simulation mode of the UART allows to redirect TX data to the simulator console instead of sending it via the
physical `uart0_txd_o` signal. Simulation mode is enabled by setting the `UART_CTRL_SIM_MODE` bit. When enabled,
all data written to the `DATA` register is sent to the simulator and printed as ASCII characters to the simulator console.
Note that this feature is only available within a simulation.


**Register Map**

.UART0 register map (`struct NEORV32_UART0`)
[cols="<4,<2,<5,^2,<5"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.16+<| `0xfff50000` .16+<| `CTRL` <|`0`     `UART_CTRL_EN`                            ^| r/w <| UART enable
                                  <|`1`     `UART_CTRL_SIM_MODE`                      ^| r/w <| enable **simulation mode**
                                  <|`2`     `UART_CTRL_HWFC_EN`                       ^| r/w <| enable RTS/CTS hardware flow-control
                                  <|`5:3`   `UART_CTRL_PRSC_MSB : UART_CTRL_PRSC_LSB` ^| r/w <| baud rate clock prescaler select
                                  <|`15:6`  `UART_CTRL_BAUD_MSB : UART_CTRL_BAUD_LSB` ^| r/w <| 10-bit baud value configuration value
                                  <|`16`    `UART_CTRL_RX_NEMPTY`                     ^| r/- <| RX FIFO not empty (data available)
                                  <|`17`    `UART_CTRL_RX_FULL`                       ^| r/- <| RX FIFO full
                                  <|`18`    `UART_CTRL_TX_EMPTY`                      ^| r/- <| TX FIFO empty
                                  <|`19`    `UART_CTRL_TX_NFULL`                      ^| r/- <| TX FIFO not full
                                  <|`20`    `UART_CTRL_IRQ_RX_NEMPTY`                 ^| r/w <| fire RX-IRQ if RX FIFO not empty
                                  <|`21`    `UART_CTRL_IRQ_RX_FULL`                   ^| r/w <| fire RX-IRQ if RX FIFO full
                                  <|`22`    `UART_CTRL_IRQ_TX_EMPTY`                  ^| r/w <| fire TX-IRQ if TX FIFO empty
                                  <|`23`    `UART_CTRL_IRQ_TX_NFULL`                  ^| r/w <| fire TX-IRQ if TX not full
                                  <|`29:24` -                                         ^| r/- <| _reserved_, read as zero
                                  <|`30`    `UART_CTRL_RX_OVER`                       ^| r/- <| RX FIFO overflow; cleared on read access
                                  <|`31`    `UART_CTRL_TX_BUSY`                       ^| r/- <| TX busy or TX FIFO not empty
.4+<| `0xfff50004` .4+<| `DATA` <|`7:0`   `UART_DATA_RTX_MSB : UART_DATA_RTX_LSB`         ^| r/w <| receive/transmit data
                                <|`11:8`  `UART_DATA_RX_FIFO_MSB : UART_DATA_RX_FIFO_LSB` ^| r/- <| log2(RX FIFO size)
                                <|`15:12` `UART_DATA_TX_FIFO_MSB : UART_DATA_TX_FIFO_LSB` ^| r/- <| log2(TX FIFO size)
                                <|`31:16` ^| r/- <| _reserved_, read as zero
|=======================



<<<
// ####################################################################################################################
:sectnums:
==== Secondary Universal Asynchronous Receiver and Transmitter (UART1)

[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source files:  | neorv32_uart.vhd   |
| Software driver files:  | neorv32_uart.c     | link:https://stnolting.github.io/neorv32/sw/neorv32__uart_8c.html[Online software reference (Doxygen)]
|                         | neorv32_uart.h     | link:https://stnolting.github.io/neorv32/sw/neorv32__uart_8h.html[Online software reference (Doxygen)]
| Top entity ports:       | `uart1_txd_o`      | serial transmitter output
|                         | `uart1_rxd_i`      | serial receiver input
|                         | `uart1_rtsn_o`     | flow control: RX ready to receive, low-active
|                         | `uart1_ctsn_i`     | flow control: RX ready to receive, low-active
| Configuration generics: | `IO_UART1_EN`      | implement UART1 when `true`
|                         | `UART1_RX_FIFO`    | RX FIFO depth (power of 2, min 1)
|                         | `UART1_TX_FIFO`    | TX FIFO depth (power of 2, min 1)
| CPU interrupts:         | fast IRQ channel 3 | Programmable FIFO status interrupt (see <<_processor_interrupts>>)
|=======================


**Overview**

The secondary UART (UART1) is functionally identical to the primary UART
(<<_primary_universal_asynchronous_receiver_and_transmitter_uart0>>). UART1 uses different addresses for the
control register (`CTRL`) and the data register (`DATA`) and uses a different CPU fast interrupt (FIRQ) channel.


**Register Map**

.UART1 register map (`struct NEORV32_UART1`)
[cols="<2,<1,<1,^1,<2"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
| `0xfff60000` | `CTRL` | ... | ... | Same as UART0
| `0xfff60004` | `DATA` | ... | ... | Same as UART0
|=======================
