|
| 1 | +# OpenTitan I2C Transport |
| 2 | + |
| 3 | +The `ot-i2c-transport` device provides a way to execute I2C transactions with QEMU I2C bus devices |
| 4 | +through an externally driven socket `chardev` interface. |
| 5 | + |
| 6 | +The device can issue read or write transactions with devices and is intended to be used to drive |
| 7 | +the Opentitan I2C device Target mode functionality through OpenTitanTool, but the protocol is |
| 8 | +simple enough that it can be used manually using `netcat` to type out issued commands. |
| 9 | + |
| 10 | +## Configuration |
| 11 | + |
| 12 | +A socket and transport device can be created in QEMU with the following arguments: |
| 13 | + |
| 14 | +`-chardev socket,id=i2ctp,file=<name>,server=on,wait=off` |
| 15 | +`-device ot-i2c-transport,bus=<bus>,chardev=i2ctp` |
| 16 | + |
| 17 | +Where `bus` is any of the system's I2C buses. On earlgrey, these are `ot-i2c0`, `ot-i2c1`, |
| 18 | +and `ot-i2c2`. |
| 19 | + |
| 20 | +## Protocol |
| 21 | + |
| 22 | +- There are no timing restrictions on the protocol, and the I2C bus is held while a command is |
| 23 | +active. Received command bytes are processed immediately by the QEMU I2C subsystem, therefore it is |
| 24 | +recommended to buffer commands to the OpenTitan I2C target device to allow OT software to fill its |
| 25 | +FIFO with response data. Readiness of response should be indicated via another mechanism or an |
| 26 | +expected value can be attempted to be read after a timeout. There is no requirement to do this |
| 27 | +for other devices on the QEMU I2C bus. |
| 28 | + |
| 29 | +The protocol for executing transactions is as follows: |
| 30 | + |
| 31 | +* All bytes values are encoded as a pair of case-insensitive ASCII hex digits. For example, decimal |
| 32 | +value 161 is encoded as `A1` or `a1`. |
| 33 | + |
| 34 | +* Whitespace sent may appear anywhere except between the pair of hex digits making up a byte, and |
| 35 | +is ignored. Unexpected characters will cause the current transaction to end and the parser to enter |
| 36 | +an error state. |
| 37 | + |
| 38 | +* A transaction begins with an address byte to select the target device. |
| 39 | + |
| 40 | +* This is followed by `R` or `W` to indicate a read or write transaction. After this point a |
| 41 | +transaction is active. If the transaction is started successfully, the address byte provided will |
| 42 | +be sent back, otherwise `!!` will be sent on failure. |
| 43 | + |
| 44 | +* During a read transaction, a `B` byte can be written to read a byte from the device. |
| 45 | + |
| 46 | +* During a write transaction, written bytes are sent to the device. These will be written back on |
| 47 | +success, or `!!` will be sent back on NACK. |
| 48 | + |
| 49 | +* During a transaction, the direction may be changed by writing another `R` or `W` to change the |
| 50 | +transaction direction without releasing the bus (a 'repeated start' condition). This will also send |
| 51 | +the original address byte on success or `!!` on failure. |
| 52 | + |
| 53 | +* End of a transaction is indicated with an `S`. A transaction should be ended immediately if it |
| 54 | +failed to start. |
| 55 | + |
| 56 | +### Examples |
| 57 | + |
| 58 | +Writing bytes hex AB, hex CD, hex EF, to a device with address hex 51 is done with |
| 59 | +```51 W AB CD EF S```. The expected output is the address byte `51` if the transaction started |
| 60 | +successfully, followed by `ABCDEF` if the device acknowledged all bytes. |
| 61 | + |
| 62 | +Reading 4 bytes from the device with address hex 51 is done with ```51 R B B B B S```. The |
| 63 | +expected output is address byte `51` if the transaction started successfully, followed by the 4 read |
| 64 | +data bytes - for example `AABBCCDD`. |
| 65 | + |
| 66 | +To perform both the write and read within a single transaction, this can be done with |
| 67 | +```51 W AB CD EF R B B B B S```. On success this will return `51ABCDEF51AABBCCDD`, using the |
| 68 | +example values above. |
0 commit comments