cancel
Showing results for 
Search instead for 
Did you mean: 

SPC56 I2C - stop bit and bus idle condition

fabien23
Associate II
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 discussion has been locked for participation. If you have a question, please start a new topic in order to ask your question
1 ACCEPTED SOLUTION

Accepted Solutions
fabien23
Associate II
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 */ }

View solution in original post

6 REPLIES 6
Erwan YVIN
ST Employee
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
Associate II
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
Associate II
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 */ }

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

good news ;)

               Erwan

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.

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