Line 19... |
Line 19... |
The two wire interface - also called "I²C" - is a quite famous interface for connecting several on-board
|
The two wire interface - also called "I²C" - is a quite famous interface for connecting several on-board
|
components. Since this interface only needs two signals (the serial data line `twi_sda_io` and the serial
|
components. Since this interface only needs two signals (the serial data line `twi_sda_io` and the serial
|
clock line `twi_scl_io`) - despite of the number of connected devices - it allows easy interconnections of
|
clock line `twi_scl_io`) - despite of the number of connected devices - it allows easy interconnections of
|
several peripheral nodes.
|
several peripheral nodes.
|
|
|
The NEORV32 TWI implements a **TWI controller**. It features "clock stretching" (if enabled via the control
|
The NEORV32 TWI implements a **TWI controller**. It supports "clock so a slow peripheral can halt
|
register), so a slow peripheral can halt the transmission by pulling the SCL line low. Currently, **no multi-controller
|
the transmission by pulling the SCL line low. Currently, **no multi-controller
|
support** is available. Also, the NEORV32 TWI unit cannot operate in peripheral mode.
|
support** is available. Also, the NEORV32 TWI unit cannot operate in peripheral mode.
|
|
|
The TWI is enabled via the _TWI_CTRL_EN_ bit in the `CTRL` control register. The user program can start / stop a
|
The TWI is enabled via the _TWI_CTRL_EN_ bit in the `CTRL` control register. The user program can start / stop a
|
transmission by issuing a START or STOP condition. These conditions are generated by setting the
|
transmission by issuing a START or STOP condition. These conditions are generated by setting the
|
according bits (_TWI_CTRL_START_ or _TWI_CTRL_STOP_) in the control register.
|
according bits (_TWI_CTRL_START_ or _TWI_CTRL_STOP_) in the control register.
|
Line 68... |
Line 68... |
Based on the _TWI_CTRL_PRSCx_ configuration, the actual TWI clock frequency f~SCL~ is derived from the processor main clock f~main~ and is determined by:
|
Based on the _TWI_CTRL_PRSCx_ configuration, the actual TWI clock frequency f~SCL~ is derived from the processor main clock f~main~ and is determined by:
|
|
|
_**f~SCL~**_ = _f~main~[Hz]_ / (4 * `clock_prescaler`)
|
_**f~SCL~**_ = _f~main~[Hz]_ / (4 * `clock_prescaler`)
|
|
|
|
|
**Interrupt**
|
**TWI Interrupt**
|
|
|
The TWI module provides a single interrupt to signal _idle state_ (= read for new transmission) to the CPU. Whenever TWI SPI module
|
The SPI module provides a single interrupt to signal "operation done" to the CPU. Whenever the TWI
|
is currently idle (and enabled), the interrupt request is active. A pending interrupt request is cleared
|
module completes the current operation (generate stop condition, generate start conditions or transfer byte),
|
by triggering a new TWI transmission or by disabling the device.
|
the interrupt request is set. A pending interrupt request is cleared is cleared by any of
|
|
the following operations:
|
|
* read or write access to `NEORV32_TWI.DATA` (for example to trigger a new transmission)
|
|
* write access to `NEORV32_TWI.CTRL`
|
|
* disabling the TWI module
|
|
|
|
[TIP]
|
|
A dummy read from `NEORV32_TWI.DATA` can be executed to acknowledge the interrupt without affecting data
|
|
or the state of the TWI module.
|
|
|
|
|
.TWI register map (`struct NEORV32_TWI`)
|
.TWI register map (`struct NEORV32_TWI`)
|
[cols="<2,<2,<4,^1,<7"]
|
[cols="<2,<2,<4,^1,<7"]
|
[options="header",grid="all"]
|
[options="header",grid="all"]
|
|=======================
|
|=======================
|
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
|
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
|
.10+<| `0xffffffb0` .10+<| `NEORV32_TWI.CTRL` <|`0` _TWI_CTRL_EN_ ^| r/w <| TWI enable
|
.9+<| `0xffffffb0` .9+<| `NEORV32_TWI.CTRL` <|`0` _TWI_CTRL_EN_ ^| r/w <| TWI enable
|
<|`1` _TWI_CTRL_START_ ^| r/w <| generate START condition
|
<|`1` _TWI_CTRL_START_ ^| r/w <| generate START condition
|
<|`2` _TWI_CTRL_STOP_ ^| r/w <| generate STOP condition
|
<|`2` _TWI_CTRL_STOP_ ^| r/w <| generate STOP condition
|
<|`3` _TWI_CTRL_PRSC0_ ^| r/w .3+<| 3-bit clock prescaler select
|
<|`3` _TWI_CTRL_PRSC0_ ^| r/w .3+<| 3-bit clock prescaler select
|
<|`4` _TWI_CTRL_PRSC1_ ^| r/w
|
<|`4` _TWI_CTRL_PRSC1_ ^| r/w
|
<|`5` _TWI_CTRL_PRSC2_ ^| r/w
|
<|`5` _TWI_CTRL_PRSC2_ ^| r/w
|
<|`6` _TWI_CTRL_MACK_ ^| r/w <| generate controller ACK for each transmission ("MACK")
|
<|`6` _TWI_CTRL_MACK_ ^| r/w <| generate controller ACK for each transmission ("MACK")
|
<|`7` _TWI_CTRL_CKSTEN_ ^| r/w <| allow clock-stretching by peripherals when set
|
|
<|`30` _TWI_CTRL_ACK_ ^| r/- <| ACK received when set
|
<|`30` _TWI_CTRL_ACK_ ^| r/- <| ACK received when set
|
<|`31` _TWI_CTRL_BUSY_ ^| r/- <| transfer/START/STOP in progress when set
|
<|`31` _TWI_CTRL_BUSY_ ^| r/- <| transfer/START/STOP in progress when set
|
| `0xffffffb4` | `NEORV32_TWI.DATA` |`7:0` _TWI_DATA_MSB_ : TWI_DATA_LSB_ | r/w | receive/transmit data
|
| `0xffffffb4` | `NEORV32_TWI.DATA` |`7:0` _TWI_DATA_MSB_ : TWI_DATA_LSB_ | r/w | receive/transmit data
|
|=======================
|
|=======================
|