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

Subversion Repositories neorv32

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

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 69 zero_gravi
the interrupt is triggered. Once triggered, the interrupt has to be explicitly cleared again by setting the according
78
`mip` CSR bit.
79 65 zero_gravi
 
80
 
81 64 zero_gravi
.TWI register map (`struct NEORV32_TWI`)
82 60 zero_gravi
[cols="<2,<2,<4,^1,<7"]
83
[options="header",grid="all"]
84
|=======================
85
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
86 68 zero_gravi
.9+<| `0xffffffb0` .9+<| `NEORV32_TWI.CTRL` <|`0` _TWI_CTRL_EN_     ^| r/w <| TWI enable
87
                                            <|`1` _TWI_CTRL_START_  ^| r/w <| generate START condition
88
                                            <|`2` _TWI_CTRL_STOP_   ^| r/w <| generate STOP condition
89
                                            <|`3` _TWI_CTRL_PRSC0_  ^| r/w .3+<| 3-bit clock prescaler select
90
                                            <|`4` _TWI_CTRL_PRSC1_  ^| r/w
91
                                            <|`5` _TWI_CTRL_PRSC2_  ^| r/w
92
                                            <|`6` _TWI_CTRL_MACK_   ^| r/w <| generate controller ACK for each transmission ("MACK")
93
                                            <|`30` _TWI_CTRL_ACK_   ^| r/- <| ACK received when set
94
                                            <|`31` _TWI_CTRL_BUSY_  ^| r/- <| transfer/START/STOP in progress when set
95 64 zero_gravi
| `0xffffffb4` | `NEORV32_TWI.DATA` |`7:0` _TWI_DATA_MSB_ : TWI_DATA_LSB_ | r/w | receive/transmit data
96 60 zero_gravi
|=======================

powered by: WebSVN 2.1.0

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