2015-03-11 06:07 AM
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-i2cSolved! Go to Solution.
2015-03-24 02:31 AM
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 */ }
2015-03-13 08:05 AM
About MSSL :Master/Slave mode select. Upon reset, this bit is cleared. When this bit is changed from 0 to 1, aSTART signal is generated on the bus and the master mode is selected. When this bit is changed from1 to 0, a STOP signal is generated and the operation mode changes from master to slave. A STOPsignal 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 Mode0 Slave Mode Best Regards Erwan
2015-03-17 07:43 AM
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,Fab2015-03-24 02:31 AM
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 */ }
2015-03-27 03:23 AM
2017-09-06 10:37 PM
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.
2017-09-07 04:30 AM
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
IBIEI-Bus Interrupt Enable.0 Interrupts from the I2C Bus module are disabled. This does not clear any currentlypending interrupt condition.1 Interrupts from the I2C Bus module are enabled. An I2C Bus interrupt occursprovided 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