URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
[/] [neorv32/] [trunk/] [docs/] [datasheet/] [soc_twi.adoc] - Rev 66
Go to most recent revision | Compare with Previous | Blame | View Log
<<<:sectnums:==== Two-Wire Serial Interface Controller (TWI)[cols="<3,<3,<4"][frame="topbot",grid="none"]|=======================| Hardware source file(s): | neorv32_twi.vhd || Software driver file(s): | neorv32_twi.c || | neorv32_twi.h || Top entity port: | `twi_sda_io` | 1-bit bi-directional serial data| | `twi_scl_io` | 1-bit bi-directional serial clock| Configuration generics: | _IO_TWI_EN_ | implement TWI controller when _true_| CPU interrupts: | fast IRQ channel 7 | transmission done interrupt (see <<_processor_interrupts>>)|=======================**Theory of Operation**The two wire interface - also called "I²C" - is a quite famous interface for connecting several on-boardcomponents. Since this interface only needs two signals (the serial data line `twi_sda_io` and the serialclock line `twi_scl_io`) - despite of the number of connected devices - it allows easy interconnections ofseveral peripheral nodes.The NEORV32 TWI implements a **TWI controller**. It features "clock stretching" (if enabled via the controlregister), so a slow peripheral can halt the transmission by pulling the SCL line low. Currently, **no multi-controllersupport** 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 atransmission by issuing a START or STOP condition. These conditions are generated by setting theaccording 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 thisregister. 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.An accessed peripheral has to acknowledge each transferred byte. When the _TWI_CTRL_ACK_ bit is set after acompleted transmission, the accessed peripheral has send an acknowledge. If it is cleared after atransmission, the peripheral has send a not-acknowledge (NACK). The NEORV32 TWI controller can alsosend an ACK by itself ("controller acknowledge _MACK_") after a transmission by pulling SDA low during theACK time slot. Set the _TWI_CTRL_MACK_ bit to activate this feature. If this bit is cleared, the ACK/NACK of theperipheral is sampled in this time slot instead (normal mode).In summary, the following independent TWI operations can be triggered by the application program:* send START condition (also as REPEATED START condition)* send STOP condition* send (at least) one byte while also sampling one byte from the bus[TIP]A transmission can be terminated at any time by disabling the TWI moduleby clearing the _TWI_CTRL_EN_ control register bit.[IMPORTANT]The serial clock (SCL) and the serial data (SDA) lines can only be actively driven low by thecontroller. 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 prescalersare available:.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 _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`)**Interrupt**The TWI module provides a single interrupt to signal _idle state_ (= read for new transmission) to the CPU. Whenever TWI SPI moduleis currently idle (and enabled), the interrupt request is active. A pending interrupt request is clearedby triggering a new TWI transmission or by disabling the device..TWI register map (`struct NEORV32_TWI`)[cols="<2,<2,<4,^1,<7"][options="header",grid="all"]|=======================| Address | Name [C] | Bit(s), Name [C] | R/W | Function.10+<| `0xffffffb0` .10+<| `NEORV32_TWI.CTRL` <|`0` _TWI_CTRL_EN_ ^| r/w <| TWI enable<|`1` _TWI_CTRL_START_ ^| r/w <| generate START condition<|`2` _TWI_CTRL_STOP_ ^| r/w <| generate STOP condition<|`3` _TWI_CTRL_PRSC0_ ^| r/w .3+<| 3-bit clock prescaler select<|`4` _TWI_CTRL_PRSC1_ ^| r/w<|`5` _TWI_CTRL_PRSC2_ ^| r/w<|`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<|`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|=======================
Go to most recent revision | Compare with Previous | Blame | View Log
