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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [datasheet/] [soc_twi.adoc] - Blame information for rev 68

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 60 zero_gravi
<<<
2
:sectnums:
3
==== Two-Wire Serial Interface Controller (TWI)
4
 
5
[cols="<3,<3,<4"]
6
[frame="topbot",grid="none"]
7
|=======================
8
| Hardware source file(s): | neorv32_twi.vhd |
9
| Software driver file(s): | neorv32_twi.c |
10
|                          | neorv32_twi.h |
11
| Top entity port:         | `twi_sda_io` | 1-bit bi-directional serial data
12
|                          | `twi_scl_io` | 1-bit bi-directional serial clock
13
| Configuration generics:  | _IO_TWI_EN_ | implement TWI controller when _true_
14
| CPU interrupts:          | fast IRQ channel 7 | transmission done interrupt (see <<_processor_interrupts>>)
15
|=======================
16
 
17
**Theory of Operation**
18
 
19 65 zero_gravi
The two wire interface - also called "I²C" - is a quite famous interface for connecting several on-board
20 60 zero_gravi
components. Since this interface only needs two signals (the serial data line `twi_sda_io` and the serial
21 65 zero_gravi
clock line `twi_scl_io`) - despite of the number of connected devices - it allows easy interconnections of
22 60 zero_gravi
several peripheral nodes.
23
 
24 68 zero_gravi
The NEORV32 TWI implements a **TWI controller**. It supports "clock so a slow peripheral can halt
25
the transmission by pulling the SCL line low. Currently, **no multi-controller
26 60 zero_gravi
support** is available. Also, the NEORV32 TWI unit cannot operate in peripheral mode.
27
 
28 64 zero_gravi
The TWI is enabled via the _TWI_CTRL_EN_ bit in the `CTRL` control register. The user program can start / stop a
29 60 zero_gravi
transmission by issuing a START or STOP condition. These conditions are generated by setting the
30 64 zero_gravi
according bits (_TWI_CTRL_START_ or _TWI_CTRL_STOP_) in the control register.
31 60 zero_gravi
 
32 64 zero_gravi
Data is send by writing a byte to the `DATA` register. Received data can also be read from this
33 60 zero_gravi
register. The TWI controller is busy (transmitting data or performing a START or STOP condition) as long as the
34 64 zero_gravi
_TWI_CTRL_BUSY_ bit in the control register is set.
35 60 zero_gravi
 
36 64 zero_gravi
An accessed peripheral has to acknowledge each transferred byte. When the _TWI_CTRL_ACK_ bit is set after a
37 60 zero_gravi
completed transmission, the accessed peripheral has send an acknowledge. If it is cleared after a
38
transmission, the peripheral has send a not-acknowledge (NACK). The NEORV32 TWI controller can also
39
send an ACK by itself ("controller acknowledge _MACK_") after a transmission by pulling SDA low during the
40 64 zero_gravi
ACK time slot. Set the _TWI_CTRL_MACK_ bit to activate this feature. If this bit is cleared, the ACK/NACK of the
41 60 zero_gravi
peripheral is sampled in this time slot instead (normal mode).
42
 
43
In summary, the following independent TWI operations can be triggered by the application program:
44
 
45
* send START condition (also as REPEATED START condition)
46
* send STOP condition
47
* send (at least) one byte while also sampling one byte from the bus
48
 
49 66 zero_gravi
[TIP]
50
A transmission can be terminated at any time by disabling the TWI module
51
by clearing the _TWI_CTRL_EN_ control register bit.
52
 
53 60 zero_gravi
[IMPORTANT]
54
The serial clock (SCL) and the serial data (SDA) lines can only be actively driven low by the
55
controller. Hence, external pull-up resistors are required for these lines.
56
 
57 64 zero_gravi
The TWI clock frequency is defined via the 3-bit _TWI_CTRL_PRSCx_ clock prescaler. The following prescalers
58 60 zero_gravi
are available:
59
 
60
.TWI prescaler configuration
61
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
62
[options="header",grid="rows"]
63
|=======================
64 64 zero_gravi
| **`TWI_CTRL_PRSCx`**        | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
65 60 zero_gravi
| Resulting `clock_prescaler` |       2 |       4 |       8 |      64 |     128 |    1024 |    2048 |    4096
66
|=======================
67
 
68 64 zero_gravi
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:
69 60 zero_gravi
 
70
_**f~SCL~**_ = _f~main~[Hz]_ / (4 * `clock_prescaler`)
71
 
72 65 zero_gravi
 
73 68 zero_gravi
**TWI Interrupt**
74 65 zero_gravi
 
75 68 zero_gravi
The SPI module provides a single interrupt to signal "operation done" to the CPU. Whenever the TWI
76
module completes the current operation (generate stop condition, generate start conditions or transfer byte),
77
the interrupt request is set. A pending interrupt request is cleared is cleared by any of
78
the following operations:
79
* read or write access to `NEORV32_TWI.DATA` (for example to trigger a new transmission)
80
* write access to `NEORV32_TWI.CTRL`
81
* disabling the TWI module
82 65 zero_gravi
 
83 68 zero_gravi
[TIP]
84
A dummy read from `NEORV32_TWI.DATA` can be executed to acknowledge the interrupt without affecting data
85
or the state of the TWI module.
86 65 zero_gravi
 
87 68 zero_gravi
 
88 64 zero_gravi
.TWI register map (`struct NEORV32_TWI`)
89 60 zero_gravi
[cols="<2,<2,<4,^1,<7"]
90
[options="header",grid="all"]
91
|=======================
92
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
93 68 zero_gravi
.9+<| `0xffffffb0` .9+<| `NEORV32_TWI.CTRL` <|`0` _TWI_CTRL_EN_     ^| r/w <| TWI enable
94
                                            <|`1` _TWI_CTRL_START_  ^| r/w <| generate START condition
95
                                            <|`2` _TWI_CTRL_STOP_   ^| r/w <| generate STOP condition
96
                                            <|`3` _TWI_CTRL_PRSC0_  ^| r/w .3+<| 3-bit clock prescaler select
97
                                            <|`4` _TWI_CTRL_PRSC1_  ^| r/w
98
                                            <|`5` _TWI_CTRL_PRSC2_  ^| r/w
99
                                            <|`6` _TWI_CTRL_MACK_   ^| r/w <| generate controller ACK for each transmission ("MACK")
100
                                            <|`30` _TWI_CTRL_ACK_   ^| r/- <| ACK received when set
101
                                            <|`31` _TWI_CTRL_BUSY_  ^| r/- <| transfer/START/STOP in progress when set
102 64 zero_gravi
| `0xffffffb4` | `NEORV32_TWI.DATA` |`7:0` _TWI_DATA_MSB_ : TWI_DATA_LSB_ | r/w | receive/transmit data
103 60 zero_gravi
|=======================

powered by: WebSVN 2.1.0

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