<<<
:sectnums:
==== Two-Wire Serial Interface Controller (TWI)

[cols="<3,<3,<4"]
[grid="none"]
|=======================
| Hardware source files:  | neorv32_twi.vhd    |
| Software driver files:  | neorv32_twi.c      | link:https://stnolting.github.io/neorv32/sw/neorv32__twi_8c.html[Online software reference (Doxygen)]
|                         | neorv32_twi.h      | link:https://stnolting.github.io/neorv32/sw/neorv32__twi_8h.html[Online software reference (Doxygen)]
| Top entity ports:       | `twi_sda_i`        | 1-bit serial data line sense input
|                         | `twi_sda_o`        | 1-bit serial data line output (pull low only)
|                         | `twi_scl_i`        | 1-bit serial clock line sense input
|                         | `twi_scl_o`        | 1-bit serial clock line output (pull low only)
| Configuration generics: | `IO_TWI_EN`        | implement TWI controller when `true`
|                         | `IO_TWI_FIFO`      | FIFO depth, has to be a power of two, min 1
| CPU interrupts:         | fast IRQ channel 7 | FIFO empty and module idle interrupt (see <<_processor_interrupts>>)
|=======================

**Key Features**

* Philips I²C-compatible host controller
* Programmable clock speed
* Support for host-ACK generated by the controller
* Optional support for clock stretching
* Optional data/command FIFO
* Interrupt based on FIFO status


**Overview**

The NEORV32 TWI implements an I2C-compatible host controller to communicate with arbitrary I2C-devices.
Note that multi-controller mode and bus arbitration are not supported.

.Host-Mode Only
[NOTE]
The NEORV32 TWI controller only supports **host mode**. Transmission are initiated by the processor's TWI controller
and not by an external I²C module. If you are looking for a _device-mode_ module (transactions
initiated by an external host) check out the <<_two_wire_serial_device_controller_twd>>.

The TWI controller provides two memory-mapped registers that are used for configuration & status check (`CTRL`) and
for accessing transmission data (`DATA`). The `DATA` register is transparently buffered by separate RX and TX FIFOs.
The size of those FIFOs can be configured by the `IO_TWI_RX_FIFO` and `IO_TWI_TX_FIFO` generics. Software can determine
the FIFO size via the control register's `TWI_CTRL_FIFO_*` bits. The current status of the RX and TX FIFO can be polled
by software via the `TWD_CTRL_RX_*` and `TWI_CTRL_TX_*` flags.

The module is globally enabled by setting the control register's `TWI_CTRL_EN` bit. Clearing this bit will disable
and reset the entire module also clearing the internal RX and TX FIFOs.

.Current Bus State
[TIP]
The current state of the I2C bus lines (SCL and SDA) can be checked by software via the `TWI_CTRL_SENSE_*` control
register bits. Note that the TWI module needs to be enabled in order to sample the bus state.


**TWI Clock Speed**

The TWI clock frequency is programmed by two bit-fields in the device's control register `CTRL`: a 3-bit clock prescaler
(`TWI_CTRL_PRSCx`) is used for a coarse clock configuration and a 4-bit clock divider (`TWI_CTRL_CDIVx`) is used for a fine
clock configuration.

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

Based on the clock configuration, the actual TWI clock frequency f~SCL~ is derived
from the processor's main clock f~main~ according to the following equation:

_**f~SCL~**_ = _f~main~[Hz]_ / (4 * `clock_prescaler` * (1 + TWI_CTRL_CDIV))

Hence, the maximum TWI clock is f~main~ / 8 and the lowest TWI clock is f~main~ / 262144. The generated TWI clock is
always symmetric having a duty cycle of exactly 50% (if the clock is not haled by a device during clock stretching).

.Clock Stretching
[NOTE]
An accessed peripheral can slow down/halt the controller's bus clock by using clock stretching (= actively keeping the
SCL line low). The controller will halt operation in this case. Clock stretching is enabled by setting the
`TWI_CTRL_CLKSTR` bit in the module's control register `CTRL`.


**TWI Transfers**

All TWI operations are controlled by the `DCMD` register, which is buffered by a FIFO. This command/data FIFO is internally
split into a TX FIFO and a RX FIFO. Writing to `DCMD` will write to the TX FIFO while reading from `DCMD` will read from the
RX FIFO. Thus, complete TWI sequences can be programmed and executed without further CPU intervention. The actual operation
is selected by a 2-bit value that is written to the register's `TWI_DCMD_CMD_*` bit-field:

* `00`: NOP (no-operation); all further bit-fields in `DCMD` are ignored; no bus operation is executed
* `01`: Generate a (repeated) START condition; all further bit-fields in `DCMD` are ignored
* `10`: Generate a STOP condition; all further bit-fields in `DCMD` are ignored
* `11`: Trigger a data transmission; see below

For any transmission the data to be send has to be written to the register's `TWI_DCMD_MSB : TWI_DCMD_LSB` bit-field.
If `TWI_DCMD_ACK` is set the controller will generate an ACK by it's own. If `TWI_DCMD_ACK` is cleared the controller will
sample ACK/NACK from the accessed device. Vice versa, the device's data response can be read from `TWI_DCMD_MSB : TWI_DCMD_LSB`
bit-field. The ACK/NACK generated by the device can be read from the `TWI_DCMD_ACK` bit.

The control register's busy flag `TWI_CTRL_BUSY` is set as long as the TX FIFO contains data (i.e. programmed TWI operations
that have not been executed yet) or if the TWI bus engine is still processing an operation. An active transmission can be
terminated at any time by disabling the TWI module. This will also clear the data/command FIFO.


**Tristate Drivers**

The TWI module requires two tristate drivers (actually: open-drain drivers - signals can only be actively driven low) for
the SDA and SCL lines, which have to be implemented by the user in the setup's top module / IO ring. A generic VHDL example
is shown below (here, `sda_io` and `scl_io` are the actual I²C bus lines, which are of type `std_logic`).

.TWI VHDL Tristate Driver Example
[source,VHDL]
----
sda_io    <= '0' when (twi_sda_o = '0') else 'Z'; -- drive
scl_io    <= '0' when (twi_scl_o = '0') else 'Z'; -- drive
twi_sda_i <= std_ulogic(sda_io); -- sense
twi_scl_i <= std_ulogic(scl_io); -- sense
----


**TWI Interrupt**

The TWI module provides a single interrupt to signal "idle condition" to the CPU. The interrupt becomes active when the
TWI module is enabled (`TWI_CTRL_EN` = `1`) and the TX FIFO is empty and the TWI bus engine is idle.


**Register Map**

.TWI register map (`struct NEORV32_TWI`)
[cols="<2,<1,<4,^1,<7"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.12+<| `0xfff90000` .12+<| `CTRL` <|`0`     `TWI_CTRL_EN`                           ^| r/w <| TWI enable, reset if cleared
                                  <|`3:1`   `TWI_CTRL_PRSC2 : TWI_CTRL_PRSC0`       ^| r/w <| 3-bit clock prescaler select
                                  <|`7:4`   `TWI_CTRL_CDIV3 : TWI_CTRL_CDIV0`       ^| r/w <| 4-bit clock divider
                                  <|`8`     `TWI_CTRL_CLKSTR`                       ^| r/w <| Enable (allow) clock stretching
                                  <|`14:9`   -                                      ^| r/- <| _reserved_, read as zero
                                  <|`18:15` `TWI_CTRL_FIFO_MSB : TWI_CTRL_FIFO_LSB` ^| r/- <| FIFO depth; log2(`IO_TWI_FIFO`)
                                  <|`26:12`  -                                      ^| r/- <| _reserved_, read as zero
                                  <|`27`    `TWI_CTRL_SENSE_SCL`                    ^| r/- <| current state of the SCL bus line
                                  <|`28`    `TWI_CTRL_SENSE_SDA`                    ^| r/- <| current state of the SDA bus line
                                  <|`29`    `TWI_CTRL_TX_FULL`                      ^| r/- <| set if the TWI bus is claimed by any controller
                                  <|`30`    `TWI_CTRL_RX_AVAIL`                     ^| r/- <| RX FIFO data available
                                  <|`31`    `TWI_CTRL_BUSY`                         ^| r/- <| TWI bus engine busy or TX FIFO not empty
.4+<| `0xfff90004` .4+<| `DCMD`   <|`7:0`   `TWI_DCMD_MSB : TWI_DCMD_LSB`           ^| r/w <| write: TX data byte; read: RX data byte
                                  <|`8`     `TWI_DCMD_ACK`                          ^| r/w <| write: ACK issued by controller; read: `1` = device NACK, `0` = device ACK
                                  <|`10:9`  `TWI_DCMD_CMD_HI : TWI_DCMD_CMD_LO`     ^| -/w <| TWI operation (`00` = NOP, `01` = START conditions, `10` = STOP condition, `11` = data transmission)
                                  <|`31:11`  -                                      ^| r/- <| _reserved_, read as zero
|=======================
