Skip to main content
fabien23
Associate
March 11, 2015
Solved

SPC56 I2C - stop bit and bus idle condition

  • March 11, 2015
  • 4 replies
  • 2194 views
Posted on March 11, 2015 at 14:07

Hi,

I'm developing an I2C driver for a SPC560B54L5 micro, and I have problems generating the stop bit.

At the end of a write operation, I run the following pseudo code:

   while  (0 == IBSR. IBIF) { /* wait */ }

   IBCR.MSSL = 0 /* generate stop bit */

   while (1 == IBSR.IBB) { /* wait */ }

After a few successful transfers (including the stop condition and return to idle), the driver gets stuck while waiting for the IBB bit to return to 0.

I monitored the SDA and SCL signals: some times the Stop condition is not generated, and some other times the Stop is generated but IBB does not drop. 

The I2C is run in Master mode, and interrupts are disabled.

Also, when I run the driver in step-by-step debug, the problem appears after a few frames are sent (including Stop condition and return to idle).

The problem appears on the first frame when I run the driver without stopping the CPU.

Could you please help me find why the stop condition is not generated or not detected?

Best regards,

Fab

#sp56-i2c
    This topic has been closed for replies.
    Best answer by fabien23
    Posted on March 24, 2015 at 10:31

    Problem was solved by waiting for TCF:

       while  (0 == IBSR.IBIF) { /* wait */ }

       while  (0 == IBSR.TCF) { /* wait */ }

       IBCR.MSSL = 0 /* generate stop bit */

       while (1 == IBSR.IBB) { /* wait */ }

    4 replies

    Erwan YVIN
    ST Employee
    March 13, 2015
    Posted on March 13, 2015 at 16:05

    Hello Fabien ,

    Maybe the master has lost arbitration. (cf Rerefence Manual)

      

    About MSSL :

    Master/Slave mode select. Upon reset, this bit is cleared. When this bit is changed from 0 to 1, a

    START signal is generated on the bus and the master mode is selected. When this bit is changed from

    1 to 0, a STOP signal is generated and the operation mode changes from master to slave. A STOP

    signal should be generated only if the IBIF flag is set.

    MSSL is cleared without generating a STOP

     

    signal when the master loses arbitration.

    1 Master Mode

    0 Slave Mode

                        Best Regards

                                     Erwan

    fabien23
    fabien23Author
    Associate
    March 17, 2015
    Posted on March 17, 2015 at 15:43

    Hello Erwan,

    Thanks for your reply. Unfortunately, it does not look like an arbitration loss, since IBSR.IBAL is not set when the software is stuck waiting for IBB to drop. Also, there is only one (other) device on the link I'm testing, and it only runs as a slave.

    I debugged some more, and this problem only appears when using DMA to write the data. The Stop condition is generated on SDA/SCL, but IBB does not drop.

    Would you know some way to unlock this situation, e.g. generating a restart then a stop ?

    Is there any application note for I2C and DMA ? The reference manual is a bit vague concerning this interface, and I'm not sure what needs to be done on the I2C controller at the end of a DMA transfer (either for sending or receiving). 

    Best regards,

    Fab

    fabien23
    fabien23AuthorBest answer
    Associate
    March 24, 2015
    Posted on March 24, 2015 at 10:31

    Problem was solved by waiting for TCF:

       while  (0 == IBSR.IBIF) { /* wait */ }

       while  (0 == IBSR.TCF) { /* wait */ }

       IBCR.MSSL = 0 /* generate stop bit */

       while (1 == IBSR.IBB) { /* wait */ }

    Birdy Toh
    Associate
    September 7, 2017
    Posted on September 07, 2017 at 05:37

    Would you happen to know if the checking of TCF is necessary if I were to implement the transfer driven by interrupt routines? Thanks in advance.

    Erwan YVIN
    ST Employee
    September 7, 2017
    Posted on September 07, 2017 at 11:30

    Hello Birdy ,

    By Software routine , you have to check.

    if you are in Interrupt Mode. I think that you have not to check TCF bit

    1

    IBIE

    I-Bus Interrupt Enable.

    0 Interrupts from the I2C Bus module are disabled. This does not clear any currently

    pending interrupt condition.

    1 Interrupts from the I2C Bus module are enabled. An I2C Bus interrupt occurs

    provided the IBIF bit in the status register is also set.

    because The IBIF bit is set when one of the following conditions occurs:

    – Arbitration lost (IBAL bit set)

    – Byte transfer complete (TCF bit set and DMAEN bit not set)

    – Addressed as slave (IAAS bit set)

    – NoAck from Slave (MS & Tx bits set)

    – I2C Bus going idle (IBB high-low transition and enabled by BIIE)

        Best regards

                      Erwan

    Erwan YVIN
    ST Employee
    March 27, 2015
    Posted on March 27, 2015 at 11:23

    good news ;)

                   Erwan