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

[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source files:  | neorv32_twi.vhd    |
| Software driver files:  | neorv32_twi.c      |
|                         | neorv32_twi.h      |
| 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>>)
| Access restrictions:  2+| privileged access only, non-32-bit write accesses are ignored
|=======================


**Overview**

The NEORV32 TWI implements an I2C-compatible host controller to communicate with arbitrary I2C-devices.
Note that peripheral-mode (controller acts as a device) and multi-controller mode are not supported yet.

The TWI controller provides two memory-mapped registers that are used for configuring the module and
for triggering operation: `CTRL` is the control and status register, `DCMD` is the command and data register.


Key features:

* Programmable clock speed
* Optional clock stretching
* Generate START / repeated-START and STOP conditions
* Sending & receiving 8 data bits including ACK/NACK
* Generating a host-ACK (ACK send by the TWI controller)
* Configurable data/command FIFO to "program" large TWI sequences without further involvement of the CPU


**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 TWI 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 Clock Speed**

The TWI clock frequency is programmed by two bit-fields in the device's control register `CTRL`: a 3-bit `TWI_CTRL_PRSCx`
clock prescaler is sued 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_PRSCx`**        | `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%.

.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**

The TWI is enabled via the `TWI_CTRL_EN` bit in the `CTRL` control register. All TWI operations are controlled by
the `DCMD` register. 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
* `01`: Generate a (repeated) START conditions; all further bit-fields in `DCMD` are ignored
* `10`: Generate a STOP conditions; all further bit-fields in `DCMD` are ignored
* `11`: Trigger a data 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 send a host-ACK in the ACK/NACK time slot; after the transmission
is completed `TWI_DCMD_MSB : TWI_DCMD_LSB` contains the RX data and `TWI_DCMD_ACK` the device's response if no host-ACK was
configured (`0` = ACK, `1` = ACK)

All operations/data written to the `DCMD` register are buffered by a configurable data/command FIFO. The depth of the FIFO is
configured by the `IO_TWI_FIFO` top generic. Software can retrieve this size by reading the control register's `TWI_CTRL_FIFO` bits.

The 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. The TX FIFO is full when the `TWI_CTRL_TX_FULL` flag is set. Accordingly, the RX FIFO contains valid
data when the `TWI_CTRL_RX_AVAIL` flag is set.

The control register's busy flag `TWI_CTRL_BUSY` is set as long as the TX FIFO contains valid data (i.e. programmed TWI operations
that have not been executed yet) or of the TWI bus engine is still processing an operation.

[TIP]
An active transmission can be terminated at any time by disabling the TWI module. This will also clear the data/command FIFO.

[NOTE]
When reading data from a device, an all-one byte (`0xFF`) has to be written to TWI data register `NEORV32_TWI.DATA`
so the accessed device can actively pull-down SDA when required.


**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
.10+<| `0xfffff900` .10+<| `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`)
                                  <|`28:12`  -                                      ^| r/- <| _reserved_, read as zero
                                  <|`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
.3+<| `0xfffff904` .3+<| `DCMD`   <|`7:0`   `TWI_DCMD_MSB : TWI_DCMD_LSB`           ^| r/w <| RX/TX data byte
                                  <|`8`     `TWI_DCMD_ACK`                          ^| r/w <| write: ACK bit sent by controller; read: `1` = device NACK, `0` = device ACK
                                  <|`10:9`  `TWI_DCMD_CMD_HI : TWI_DCMD_CMD_LO`     ^| r/w <| TWI operation (`00` = NOP, `01` = START conditions, `10` = STOP condition, `11` = data transmission)
|=======================
