This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1294NCPDT: I2C Simultaneous Operation as both a Master and a Slave

Part Number: TM4C1294NCPDT

Hi, the TivaWare Peripheral Driver Library document (SW-TM4C-DRL-UG-2.1.3.156) states "the Tiva I2C modules support both sending and receiving data as either a master or a slave, and also support the simultaneous operation as both a master and a slave".  Are there any examples for how to do this?

I've used the Tiva as an I2C master on numerous projects, but not a slave and looking at the documentation I'm not seeing what functions can be called to set it up as both a master and a slave at the same time.

  • HI

    Are there any examples for how to do this

    There is a slave specific example at C:\ti\TivaWare_C_Series-2.2.0.295\examples\peripherals\i2c\slave_receive_int.c. There is a also a master slave example from C:\ti\TivaWare_C_Series-2.2.0.295\examples\peripherals\i2c\master_slave_loopback.c. Please reference these examples. 

  • Hi Charles thanks for the reply.  At first I thought the master_slave_loopback example might be what I was looking for, but it seems it's really just an I2C master example that uses the Tiva loopback feature to make the same I2C pin *act* like a slave for debugging purposes, but is not an actual slave.

    What I'm looking for is a way to use two Tiva Dev Boards to do I2C communication between each other where either can switch into master mode at will, and the other board will switch into slave mode.

    I'm not sure if the I2C specification allows for this. I'm going to start looking into the spec now, but wanted to post back just in case you or anyone else on the forum knew offhand.

    If the Tiva does not allow for this, I suppose I'll just need to use a separate GPIO pin on both Tiva Boards to communicate which one needs to be master and which one needs to be slave at any given time.

  • What I'm looking for is a way to use two Tiva Dev Boards to do I2C communication between each other where either can switch into master mode at will, and the other board will switch into slave mode.

    No, I don't think this is possible. How will each node know when to switch from master to slave and vice versa? A master is initiating SCL clock and the slave does not initiate SCL clock. In order for a slave to change to a master, a reconfiguration of the I2C module is needed. 

    Did you have a chance to look at C:\ti\TivaWare_C_Series-2.2.0.295\examples\peripherals\i2c\slave_receive_int.c.? If you look at the code it is enabling the slave although it also enables the master to transmit data to itself. 

    //
    // Enable the I2C0 slave module.
    //
    I2CSlaveEnable(I2C0_BASE);

    //
    // Set the slave address to SLAVE_ADDRESS. In loopback mode, it's an
    // arbitrary 7-bit number (set in a macro above) that is sent to the
    // I2CMasterSlaveAddrSet function.
    //
    I2CSlaveInit(I2C0_BASE, SLAVE_ADDRESS);

    //
    // Tell the master module what address it will place on the bus when
    // communicating with the slave. Set the address to SLAVE_ADDRESS
    // (as set in the slave module). The receive parameter is set to false
    // which indicates the I2C Master is initiating a writes to the slave. If
    // true, that would indicate that the I2C Master is initiating reads from
    // the slave.
    //
    I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, false);

    //
    // Set up the serial console to use for displaying messages. This is just
    // for this example program and is not needed for proper I2C operation.
    //
    InitConsole();

    //
    // Enable interrupts to the processor.
    //
    IntMasterEnable();

    Please note that the I2C module can operate in four different modes. 

  • I2C Spec (UM10204 r6)  Sec 3.1.8 allows, but doesn't require, a master that loses arbitration to switch to slave mode on the fly and accept the transaction. The TRM (SPMS433B) Sec 18.3.1.8 treats loss of arbitration as a fatal error, which I think means (as Charles says) it doesn't do this.

    The Tiva has multiple I2C units. There's presumably no reason that each side couldn't use 2x I2C units, one master and one slave, with all 4x on the same bus.

  • Thanks Bruce for your insights!

    Just to add that the datasheet presents a command flowchart for I2C slave operation. There are also flowcharts for master operations.  

  • Did you have a chance to look at C:\ti\TivaWare_C_Series-2.2.0.295\examples\peripherals\i2c\slave_receive_int.c.?

    Hi Charles - Yes, I reviewed it just now.  It looks very similar to the other example where it uses the Tiva's loopback feature to send data to itself.  It looks like this is only useful for a *single* Tiva MCU being able to be master and slave to *itself*.  Not the same as my needed use case of having two Tiva's talk to each other over where both uses a single I2C unit but can switch between being a master and slave depending on what the other Tiva is trying to be at the time (a master or slave).

  • I2C Spec (UM10204 r6)  Sec 3.1.8 allows, but doesn't require, a master that loses arbitration to switch to slave mode on the fly and accept the transaction.

    Thanks, Bruce.  Yes, I see where the spec says that...  Specifically this part:

    "If a controller (master) also incorporates a target (slave) function and it loses arbitration during the addressing stage, it is possible that the winning controller (master) is trying to address it. The losing controller (master) must therefore switch over immediately to its target (slave) mode."

    The TRM (SPMS433B) Sec 18.3.1.8 treats loss of arbitration as a fatal error,

    I'm seeing this in section18.3.1.8:

    "If arbitration is lost when the I2C master is initiating a BURST with the TX FIFO enabled, the application should execute the following steps to correctly handle the arbitration loss:
    1. Flush and disable the TX FIFO
    2. Clear and mask the TXFE interrupt by clearing the TXFEIM bit in the I2CMIMR register.
    Once the bus is IDLE, the TXFIFO can be filled and enabled, the TXFE bit can be unmasked and a new BURST transaction can be initiated."

    Basically, I take that to mean that it won't switch to slave mode, but instead it will remain in master mode.  Agree?

    The Tiva has multiple I2C units. There's presumably no reason that each side couldn't use 2x I2C units, one master and one slave, with all 4x on the same bus.

    The electrical engineer designing this board tells me he's used all of the I2C units available and asked me (the firmware engineer) to look into the possibility of doing this type of master/slave switching with the TIva.  Apparently there are still some pins available on the Tiva.  Because it seems this type of master/slave switching is not possible, I think our next best plan will be to use one of the pins to indicate when it should be in master or slave mode.

  • One possible strategy might be to keep each side in slave mode except when it has a master operation to perform, after which it switches back to slave mode immediately.

    It's always possible that the two will try to send master transactions to each other simultaneously. If so, I expect one will get an arbitration-lost condition and the other a NACK. A possible tactic for this would be to have the arbitration-losing side reconfigure (in firmware) as a slave, and the winning one retry the NACK some small number of times. This is much the same as what you were asking about, just not automated.

    I haven't tried this but it seems like it would work.