OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [datasheet/] [soc_twi.adoc] - Diff between revs 68 and 69

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 68 Rev 69
<<<
<<<
:sectnums:
:sectnums:
==== Two-Wire Serial Interface Controller (TWI)
==== Two-Wire Serial Interface Controller (TWI)
[cols="<3,<3,<4"]
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
[frame="topbot",grid="none"]
|=======================
|=======================
| Hardware source file(s): | neorv32_twi.vhd |
| Hardware source file(s): | neorv32_twi.vhd |
| Software driver file(s): | neorv32_twi.c |
| Software driver file(s): | neorv32_twi.c |
|                          | neorv32_twi.h |
|                          | neorv32_twi.h |
| Top entity port:         | `twi_sda_io` | 1-bit bi-directional serial data
| Top entity port:         | `twi_sda_io` | 1-bit bi-directional serial data
|                          | `twi_scl_io` | 1-bit bi-directional serial clock
|                          | `twi_scl_io` | 1-bit bi-directional serial clock
| Configuration generics:  | _IO_TWI_EN_ | implement TWI controller when _true_
| Configuration generics:  | _IO_TWI_EN_ | implement TWI controller when _true_
| CPU interrupts:          | fast IRQ channel 7 | transmission done interrupt (see <<_processor_interrupts>>)
| CPU interrupts:          | fast IRQ channel 7 | transmission done interrupt (see <<_processor_interrupts>>)
|=======================
|=======================
**Theory of Operation**
**Theory of Operation**
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 supports "clock so a slow peripheral can halt
The NEORV32 TWI implements a **TWI controller**. It supports "clock 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.
Data is send by writing a byte to the `DATA` register. Received data can also be read from this
Data is send by writing a byte to the `DATA` register. Received data can also be read from this
register. The TWI controller is busy (transmitting data or performing a START or STOP condition) as long as the
register. The TWI controller is busy (transmitting data or performing a START or STOP condition) as long as the
_TWI_CTRL_BUSY_ bit in the control register is set.
_TWI_CTRL_BUSY_ bit in the control register is set.
An accessed peripheral has to acknowledge each transferred byte. When the _TWI_CTRL_ACK_ bit is set after a
An accessed peripheral has to acknowledge each transferred byte. When the _TWI_CTRL_ACK_ bit is set after a
completed transmission, the accessed peripheral has send an acknowledge. If it is cleared after a
completed transmission, the accessed peripheral has send an acknowledge. If it is cleared after a
transmission, the peripheral has send a not-acknowledge (NACK). The NEORV32 TWI controller can also
transmission, the peripheral has send a not-acknowledge (NACK). The NEORV32 TWI controller can also
send an ACK by itself ("controller acknowledge _MACK_") after a transmission by pulling SDA low during the
send an ACK by itself ("controller acknowledge _MACK_") after a transmission by pulling SDA low during the
ACK time slot. Set the _TWI_CTRL_MACK_ bit to activate this feature. If this bit is cleared, the ACK/NACK of the
ACK time slot. Set the _TWI_CTRL_MACK_ bit to activate this feature. If this bit is cleared, the ACK/NACK of the
peripheral is sampled in this time slot instead (normal mode).
peripheral is sampled in this time slot instead (normal mode).
In summary, the following independent TWI operations can be triggered by the application program:
In summary, the following independent TWI operations can be triggered by the application program:
* send START condition (also as REPEATED START condition)
* send START condition (also as REPEATED START condition)
* send STOP condition
* send STOP condition
* send (at least) one byte while also sampling one byte from the bus
* send (at least) one byte while also sampling one byte from the bus
[TIP]
[TIP]
A transmission can be terminated at any time by disabling the TWI module
A transmission can be terminated at any time by disabling the TWI module
by clearing the _TWI_CTRL_EN_ control register bit.
by clearing the _TWI_CTRL_EN_ control register bit.
[IMPORTANT]
[IMPORTANT]
The serial clock (SCL) and the serial data (SDA) lines can only be actively driven low by the
The serial clock (SCL) and the serial data (SDA) lines can only be actively driven low by the
controller. Hence, external pull-up resistors are required for these lines.
controller. Hence, external pull-up resistors are required for these lines.
The TWI clock frequency is defined via the 3-bit _TWI_CTRL_PRSCx_ clock prescaler. The following prescalers
The TWI clock frequency is defined via the 3-bit _TWI_CTRL_PRSCx_ clock prescaler. The following prescalers
are available:
are available:
.TWI prescaler configuration
.TWI prescaler configuration
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
[options="header",grid="rows"]
[options="header",grid="rows"]
|=======================
|=======================
| **`TWI_CTRL_PRSCx`**        | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
| **`TWI_CTRL_PRSCx`**        | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
| Resulting `clock_prescaler` |       2 |       4 |       8 |      64 |     128 |    1024 |    2048 |    4096
| Resulting `clock_prescaler` |       2 |       4 |       8 |      64 |     128 |    1024 |    2048 |    4096
|=======================
|=======================
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`)
**TWI Interrupt**
**TWI Interrupt**
The SPI module provides a single interrupt to signal "operation done" to the CPU. Whenever the TWI
The SPI module provides a single interrupt to signal "operation done" to the CPU. Whenever the TWI
module completes the current operation (generate stop condition, generate start conditions or transfer byte),
module completes the current operation (generate stop condition, generate start conditions or transfer byte),
the interrupt request is set. A pending interrupt request is cleared is cleared by any of
the interrupt is triggered. Once triggered, the interrupt has to be explicitly cleared again by setting the according
the following operations:
`mip` CSR bit.
* 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
.9+<| `0xffffffb0` .9+<| `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")
                                            <|`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
|=======================
|=======================
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.