I2C Slave simulation

I2C Bus Adapter

The PROTOS miniHIL I2C abstraction offers an eTrice actor which provides an interface to connect multiple i2c slave simulations to one physical i2c bus. The bus adapter (AI2CBusAdapter) contains the hardware abstraction as well as a registration mechanism for the slave simulations.

To allow the simulations to react to incoming address requests in a timely manner the slaves register a callback function with the bus adapter. The registered callback is called from within the interrupt context once an address match occurred.

Note The I2C Abstraction currently only supports the simulation of I2C slaves.
Note Due to hardware restrictions currently all 10-Bit addressed slaves on the same bus must share the same value for the upper two address bits. I.e. 0x105 and 0x110 can be simulated using the same AI2CBusAdapter. 0x205 and 0x110 cannot be simulate using the same adapter.
Note If it is necessary to control the ACK/NACK reply for every received byte the I2CSlave_startReceive method must always be called with size = 1. As soon as a size > 1 is passed the single byte control (SBC) mode is exited. Outside of SBC mode a NACK will only be send after the next byte has been received. The current byte will be automatically ACKed.

Structure and usage flow

I2C Stack Example
An example I2C stack with 3 simulated slaves. The I2C Bus Hardware is provided by the miniHIL MCU. The I2C Bus adapter is part of the miniHILLib.
i2c sequence
A typical usage flow between one I2C Slave simulation, the Bus Adapter and the actual I2C Bus.

Details

The callback function type which can be registered with the i2c bus adapter
/**
 * type: Reason why this callback was called
 * direction: Transfer direction
 * packageBuffer: Buffer containing received bytes if a rx transfer was stated before
 * context: context to be used with i2c operations call from within the callback
 * userContext: a void pointer to a user defined target
 */
typedef void (i2cSlaveCallback_ft)(const I2CSlaveCallbackType type, const I2CTransferDirection direction, uint8_t * const packageBuffer, I2CContext * const context, void * const userContext);

The I2C hardware is configured to use clock stretching to stall the I2C clock till the user application is ready to provide new data. To end the clock stretching period the callback function must call one of the following I2C operations. If none of the operations is called the I2C bus will be stalled (clock is pulled low) till the master aborts the transfer by sending a stop condition.

I2C operations defined in I2C.h (SimRuntime/inc-platform). Each of the operations needs to be called with the i2c context passed into the callback function of the i2c simulation actor.
/**
 * Acks the current byte and starts transmitting size bytes from the contexts buffer.
 */
void I2CSlave_startTransmit(I2CContext * const context, uint8_t size);

/**
 * Acks the current byte and starts receiving size bytes.
 * context,
 * size: number of bytes to receive till the next callback
 */
void I2CSlave_startReceive(I2CContext * const context, uint8_t size);

/**
 * Nacks the current byte
 */
void I2CSlave_endTransfer(I2CContext const * const context);
Note Currently you can only create one instance of each AI2CBusAdapter actor in any given ROOM subsystem.

I2C Master

The PROTOS miniHIL I2C abstraction also offers an eTrice actor which provides an interface to connect to a physical i2c bus as an i2c master. Hardware i2c master adapters are provided by the following actor classes:

  • AI2CMaster2Adapter - uses I2C hardware interface 2 (pins PF0/PF1)

  • AI2CMaster3Adapter - uses I2C hardware interface 3 (pins PH8/PH7)

An additional soft I2C interface is provided by the ASlowSpeedI2CMaster actor. The software i2c master adapter uses general purpose i/o pins to emulate an i2c master interface. It is limited to low speed applications (~2.4 kHz) and only supports minimal configuration options.

Hardware I2C configuration

The miniHILs hardware I2C interfaces support:

  • Standard-mode (up to 100 kHz)

  • Fast-mode (up to 400 kHz)

  • Fast-mode Plus (up to 1 MHz)

each with 7-bit and 10-bit addressing.

Note The actual baudrate achieved by the I2C interface may be slightly different from the configured baudrate. This is due to the fact that the I2C hardware interface must observe bus rise and fall times to be able to adhere to the I2C specification. If the assumed rise and fall times used during baudrate calculation differ from the actual bus characteristics the effective baudrate will differ from the configured baudrate. You may manually configure the rise and fall time assumptions via the manuallySetBusRiseAndFallTimes message before configuring the baudrate using the configureBaudrate message.

Master control protocol (PI2CMasterCtrl)

Table 1. Incoming Messages
Message Type Description

write

DI2CWriteRequest

Write data to an I2C slave device. The bus is not released after the write, a subsequent read/write or releaseBus message is required. A read/write before bus release will trigger a repeated start condition on the bus.

read

DI2CReadRequest

Read data from an I2C slave device. The bus is not released after the read, a subsequent read/write or releaseBus message is required. A read/write before bus release will trigger a repeated start condition on the bus.

writeLarge

DI2CWriteRequestLarge

Write data to an I2C slave device. The bus is not released after the write, a subsequent read/write or releaseBus message is required. A read/write before bus release will trigger a repeated start condition on the bus.

Write large takes a data buffer pointer which must live throughout the whole transfer. It must not be stack allocated in the sending actor.

readLarge

DI2CReadRequestLarge

Read data from an I2C slave device. The bus is not released after the read, a subsequent read/write or releaseBus message is required. A read/write before bus release will trigger a repeated start condition on the bus.

Read large takes a data buffer pointer which must live throughout the whole transfer. It must not be stack allocated in the sending actor. The buffer must be large enough for the configured read length.

releaseBus

void

Release the I2C bus after a series of read/write operations.

configureBaudrate

uint32

Configure the I2C baudrate. Payload is baudrate in Hz. Supported baudrates depend on the hardware peripheral but are generally between 13 kHz and 1 MHz.

estimateBusRiseAndFallTimes

void

Estimate the I2C bus rise and fall times based on actual signal measurements on the bus lines.

manuallySetBusRiseAndFallTimes

I2CBusRiseAndFallTimes

Manually configure the I2C bus rise and fall times which are used to calculate the baudrate settings.

Table 2. Outgoing Messages
Message Type Description

writeComplete

void

Notify that a write operation has completed successfully. The bus is not released after this message.

readComplete

DI2CReadResult

Notify that a read operation has completed successfully. The bus is not released after this message. Payload contains the read data.

readCompleteLarge

DI2CReadResultLarge

Notify that a large read operation has completed successfully. The bus is not released after this message. Payload contains the pointer to the passed read buffer and the actual read length.

busReleased

void

Notify that the I2C bus has been released after a releaseBus message.

nack

void

Reply to a write or read operation indicating that the addressed slave did not acknowledge.

error

void

Reply to any request indicating a general error.

baudrateConfigurationSuccessful

void

Reply to a configureBaudrate request indicating success.

baudrateConfigurationFailed

uint32

Reply to a configureBaudrate request indicating failure. Payload is the error code returned by the c api

busRiseAndFallTimesEstimated

void

Reply to an estimateBusRiseAndFallTimes request indicating success.

busRiseAndFallTimesManuallySet

void

Reply to a manuallySetBusRiseAndFallTimes request indicating success.