SPI Bus

SPI device behaviour is emulated using the temu_SpiBus2 bus model. The temu_SpiBus bus model has been deprecated as of TEMU 5.0.0, it should not be used for new models and existing models should be migrated to the new bus model.

SpiBus2Interface

Transmissions are performed through the temu_SpiBus2Iface interface provided by an instanced object of the bus model.

Connecting

To create a connection through an SPI bus an "SpiBus2" object needs to be instantiated. This manages the slave and master connections.

Connecting a master to the bus works as with any other model. The master is connected to the bus object’s temu_SpiBus2Iface and stores it as a temu_SpiBus2IfaceRef.

Connecting a master via the API
temu_connect(spiMaster, "spiBus", spiBus, "SpiBus2Iface")
Connecting a master via Command Line
connect a=spiMaster.spiBus b=spiBus:SpiBus2Iface

For slave devices a special procedure is required. The temu_SpiBus2Iface provides connect and disconnect functions which register a slave device with it’s corresponding chip number chipNum. This number is used to relate the chipSelect raising and lowering to a specific device. These should be used in favour or the typical connect functions. When connecting or disconnecting a device the slave’s connected or disconnected functions will be called respectively. The slaves should use these to store the interface reference to the temu_SpiBus2. Minimal implementations might look like this:

void
connected(temu_Object *Obj, uint8_t chipNum, temu_SpiBus2IfaceRef Device)
{
  SPICTRL *spi = reinterpret_cast<SPICTRL *>(Obj);
  spi->Super.ChipNum = chipNum;
  spi->Bus = Device;
}

void
disconnected(temu_Object *Obj, uint8_t chipNum)
{
  SPICTRL *spi = reinterpret_cast<SPICTRL *>(Obj);
  spi->Bus.Iface = nullptr;
  spi->Bus.Obj = nullptr;
}
Connecting a slave via the command line
connect-spi-slave slave=spidev0:SpiSlaveDevice2Iface chipNum=0 bus=spiBus:SpiBus2Iface
Connecting a slave via the API
// Using the API directly
auto spiBusIf = reinterpret_cast<temu_SpiBus2Iface*>(
        temu_getInterface(spiBus, "SpiBus2Iface", 0));
temu_SpiSlaveDevice2IfaceRef deviceRef = {(temu_Object *)spiDevice,
                                          &spiSlaveDevIface};
uint8_t chipNum = 0;
spiBusIf->connect(spiBus, chipNum, deviceRef);

// or Calling the connect command
temu_execCommand("connect-spi-slave slave=spidev0:SpiSlaveDevice2Iface "
                     "chipNum=0 bus=spiBus:SpiBus2Iface");

Modelling

SPI-Slave models should expose their chip select number as a property to allow assigning distinct numbers to all devices in accordance to the real wire layout being emulated. To simplify this a model may use a struct of type temu_SpiSlaveDevice2 as its first data member in place of the typical temu_Object. During the registration of the model a call to temu_spiDevice2Register will register the property.

Most SPI slave device behaviour can be modelled nicely as a state machine starting when the chip select is raised, resetting when it is lowered and operating on each incoming character separately.

Transmitting

A transmissions starts with raising the chip select signal of a slave using the raiseChipSelect function of the interface. This may be done by the SPI Controller used as the bus master or through any other means such as an IO pin model which raises and lowers the chip select signal. Using the transfer function of the bus allows the master to initiate the transfer of data with the currently selected slave.

The contents of the temu_SpiTransaction being transferred allow for the modeling of various SPI transmission setups. When initiating the transfer the master should have filled out all relevant values in the temu_SpiTransaction struct. If the transmission was bi-directional the slave should immediately reply by storing the requested ammount of data into the provided buffer.

Unresolved include directive in modules/buses/pages/spi.adoc - include::partial$auto-BusModels-meta-SPIBus2.adoc[]

Unresolved include directive in modules/buses/pages/spi.adoc - include::partial$auto-BusModels-SPIBus2.adoc[]

Limitations

Only one chip select signal may be active at the same time.