Enum simics_api_sys::bindings::i3c_ack_t

source ·
#[repr(u32)]
pub enum i3c_ack_t { I3C_ack = 0, I3C_noack = 1, }
Expand description

The interfaces i3c_master i3c_slave and i3c_daa_snoop are used together to model communication over an I3C bus. There are four kinds of devices roles on the I3C bus: Main Master, Secondary Master, Slave and Legacy I2C Slave. Exactly one device must be the Main Master; this is typically configured statically. Main Master should implement the i3c_master interface, while slave should implement the i3c_slave interface. Secondary Master should implement both. Most calls to a method in the slave device interfaces expect a response call to a method in the master device interfaces. One exception is the method sdr_write in the i3c_slave interface, master expects no response when calling it. It is up to each device to find the caller’s interfaces; usually it is configured with attributes in both the master and slave device.

Two I3C devices can communicate directly if one implements the i3c_master interface and the other one implements the i3c_slave interface. An I3C bus with multiple masters or slaves is typically modelled using an i3c-link object, where each device is connected to an endpoint object.

An I3C bus consists of a number of master devices and a number of slave devices. Each I3C slave device listens to one or more 7-bit addresses. The slave devices can be I3C slave devices or Legacy I2C slave devices. This is because I3C protocol is compatible with I2C protocol, so that I3C master device can communicate with I2C slave devices. For legacy I2C slave device, the address it listens to is pre-configured by the device, i.e. static address. For I3C slave device, the address it listens to can be either static address or dynamic address. The dynamic address is assigned by master during Dynamic Address Assignment process. It is an error to connect two slave devices to the same bus if they listen to the same address. In a communication, the Current Master refers to the device who now drives the bus. It can be Main Master, or Secondary Master. Usually, communication over the bus is initiated by the Current Master, which can communicate with one or more slave devices at a time. A slave device can request to initiate an communication, i.e., issue an ibi_request, in three cases: Hot-Join, In-Band Interrupt and as a Secondary Master other than the Current Master requesting to become Current Master. Only one device on a bus can communicate at a time.

The start method starts a transfer. The address parameter is the address header combined with read/write bit encoded as an 8-bit number. The least significant bit is the read/write bit and the other bits is the 7-bit address header. If the start method is called from master, the address header can be address pattern 0x7E for broadcast, or specific slave address (either I2C slave static address or I3C slave dynamic address).

In I3C bus or link implementation, every start request will broadcast to all other devices. So does the stop request. This will monitor bus/link status to all devices.

Normally, master starts a transfer, then the slave responds to start using the acknowledge method (implemented by master side interface). The ack parameter may be I3C_ack or I3C_noack if the start is acked or noacked, respectively.

There are five types of different start requests:

I3C master read transaction
If a master's start with specific slave address was acked by other device, and read/write bit in the address parameter of the start method was 1, then master proceeds with a sequence of read calls. Each call is followed by a read_response call from the slave. Parameter data in the method read_response is the data transferred. The procedure is no difference with regard to read from I3C slave or read from I2C slave. In hardware, the ACK/T bit is handled differently for i2c and i3c, and the master is supposed to know whether the slave is an i2c or i3c device. In the i3c case, the slave is supposed to pass the T bit in the more argument of read_response, while an i2c device always passes more as true. Further more, in the i2c case, a master sends an ACK bit, which is not represented explicitly in the interface. The value of this bit can be deduced from whether the following operation is START/STOP or READ. For i3c case, parameter more in method read_response indicates if there are still data waiting to be transferred from slave to master. more is true when there are still data left, false otherwise.
I3C master write transaction (write to I3C slave)
If a master's start with specific slave address was acked by other device, and the read/write bit in the address parameter of start method was 0, the master proceeds with a sdr_write call, no response is expected. Parameter data in method write is the data transferred. The parity bit is not passed explicitly in sdr_write, and that the slave can assume the parity bit is correctly set.
I3C master write transaction (write to I2C slave)
When the master's start request is to write to I2C slave, i.e., master issues a start request to I2C slave address with read/write bit is 0, then master proceeds with a sequence of write calls, each call expects a response call to a method acknowledge. This is quite similar to I2C write transaction.
I3C broadcast transaction
When master starts a transfer with I3C Broadcast Address 0x7E which is passed as address header, i.e., address 0xFC passed in the address argument of method start, a typical I3C message transfer is initiated.

Multiple I3C slave devices may acknowledge the start request. The master will conceive a request as being acknowledged if it was acknowledged by at least one of the slaves. Note that there will be a single acknowledge call in the master; the link or bus handles aggregation of acks.

Master sends the I3C Commands (Common Command Code, CCC) using sdr_write method after receiving ACK, showing to communicate with either all Slaves (Broadcast CCCs) or specific individual Slaves (Direct CCCs). This operation expects no response, and master will proceed.

If Broadcast CCC sent previously, master calls sdr_write method to transfer data to all slaves who acked the initial access.

I3C direct transaction
After sending a Direct CCC, master continues with a repeated start request along with one specific I3C slave address. The transaction goes on just like master is communicating with only one slave. After the communication with one slave, master may be issue a repeated start request to another slave. Further communication is routed only to the targeted slave device.

After sending a number of reads or a number of writes, the master may choose to either call the stop method to issue a stop condition which terminates the transfer, or to call the start method again to issue a repeated start condition. The repeated start condition works like a normal start condition.

The start method and read method in the slave interfaces are allowed to respond synchronously; i.e., the acknowledge or read method may be called before the corresponding method in the slave interfaces has returned. A master that needs to connect directly to a slave device needs to take this into consideration; however, when communicating via an i3c-link object, the link guarantees that all responses are asynchronous.

The method daa_read and method daa_response are used in Dynamic Address Assignment process. Method daa_read is called from master to signal a daa read request. Method daa_response is called from slave to send slave specific 8-bytes data (48-bit Unique ID, BCR, DCR) to master. The parameter

id, bcr and dcr in method daa_response represent the slave specific daa data. If multiple slaves response daa data, the slave with the lowest data wins and it will get the assigned address this time. Master calls method write in slave interfaces to send assigned dynamic address to the slave who wins. This operation expects a response call to method acknowledge in master side. Parameter data in method write stores the assigned address.

Master should implement the method stop in the interface i3c_slave in case there is secondary master in the configuration which may issue start request.

Slave can request to start a communication through ibi_request. The request is sent to Current Master which drives the bus now. If the master chooses to continue the slave request, ibi_start is called, this ibi start will broadcast to all devices in the configuration. Then slave can send its address header with ibi_address argument address. The address header can be 0x02 for Hot-Join, or the address of the slave itself for IBI and secondary master with read/write bit 1 and 0 respectively. If more than one slave issues ibi_address, arbitration occurs, the slave with lowest address header wins and the winning address will be delivered to master by link or bus. At that time, master issues ibi_acknowledge to the slave who wins. Other slaves which do not receive ibi_acknowledge will consume it lost arbitration already.

Cell Context for all methods.

Variants§

§

I3C_ack = 0

§

I3C_noack = 1

Trait Implementations§

source§

impl Clone for i3c_ack_t

source§

fn clone(&self) -> i3c_ack_t

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for i3c_ack_t

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Hash for i3c_ack_t

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for i3c_ack_t

source§

fn cmp(&self, other: &i3c_ack_t) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for i3c_ack_t

source§

fn eq(&self, other: &i3c_ack_t) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for i3c_ack_t

source§

fn partial_cmp(&self, other: &i3c_ack_t) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl Copy for i3c_ack_t

source§

impl Eq for i3c_ack_t

source§

impl StructuralPartialEq for i3c_ack_t

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> CloneToUninit for T
where T: Clone,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

source§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.